简体   繁体   English

OOP PHP加载未返回正确的对象

[英]OOP PHP load not returning correct object

Problem: When I load model with load object, it will NOT return second model. 问题:当我用load对象加载模型时,它不会返回第二个模型。

Take a look at class Test where I load model with load object. 看一看Test类,在其中我用load对象加载模型。 Code $this->two will return object One ( should load object Two ). 代码$this->two将返回对象One(应加载对象Two)。

Q: How to solve this problem? 问:如何解决这个问题? I am open your suggestions/ideas/code 我打开您的建议/想法/代码

Current Result: 当前结果:

one is working
object(One)#3 (1) { ["error":"Model":private]=> NULL }
one is working
object(One)#4 (1) { ["error":"Model":private]=> NULL }

Correct result: 正确结果:

one is working
object(One)#3 (1) { ["error":"Model":private]=> NULL }
two is working
object(Two)#4 (1) { ["error":"Model":private]=> NULL }

PHP: PHP:

one_model.php one_model.php

<?php

class One extends Model {

    public function test() {
        echo '<p>one is working</p>';
    }

}

two_model.php two_model.php

<?php

class Two extends Model {

    public function test() {
        echo '<p>two is working</p>';
    }

}

index.php index.php

<?php

class Controller {

    public $load;

    public function __construct() {
        $this->load = new Load();
    }

}

class Load {

    public function model($name) {
        if (!class_exists($name)) {
            require(strtolower($name) . '_model.php');
        }
        $model = new $name;
        return $model;
    }

}

class Model extends PDO {

    private $error;

    public function __construct() {

        $options = array(
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        try {
            $dsn = "mysql:dbname=test;host=localhost;charset=utf8";
            parent::__construct($dsn, 'root', '', $options);
        }
        catch (PDOException $e) {
            $this->error = $e->getMessage();
        }
    }

}

class Test extends Controller {

    public $one;
    public $two;

    public function __construct() {
        parent::__construct();

        $this->one = $this->load->model('one');
        $this->two = $this->load->model('two');
    }

    public function testing() {
        $this->one->test();
        var_dump($this->one);
        $this->two->test();
        var_dump($this->two);
    }

}

// Usage
$test = new Test();
$test->testing();

I moved PDO wrapper from Model to separate class and create object for database connection. 我将PDO包装器从Model移到了单独的类,并创建了用于数据库连接的对象。

Is this good approach ? 这是好方法吗? Is this " waste of resources "? 这是“ waste of resources ”吗?

class Database extends PDO {

    private $error;

    public function __construct() {

        $options = array(
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );

        try {
            $dsn = "mysql:dbname=test;host=localhost;charset=utf8";
            parent::__construct($dsn, 'root', '', $options);
        }
        catch (PDOException $e) {
            $this->error = $e->getMessage();
        }
    }

}


class Model {

    public $db;

    public function __construct() {
        $this->db = new Database();
    }

}

The problem there seems to be that you are passing PDO::ATTR_PERSISTENT => true to the PDO constructor. 似乎存在的问题是您正在将PDO::ATTR_PERSISTENT => true传递给PDO构造函数。 This will tell PDO to cache and reuse connections - as you no doubt intended - but it also appears to cause PDO to produce clones of the first PDO instance generated within the scope of a single script, including the child class used to create that first instance. 这将告诉PDO缓存和重用连接-毫无疑问,您会发现-但这似乎也会导致PDO生成在单个脚本范围内生成的第一个PDO实例的克隆,包括用于创建该第一个实例的子类。 。 (Doesn't seem to be a lot of documentation on this though.) (不过,关于这方面似乎没有很多文档。)

If you require persistent connections, my recommendation would be to define the models in a way that doesn't require them to be extended from PDO. 如果需要持久连接,我的建议是以不要求从PDO扩展模型的方式定义模型。 That really shouldn't be a necessary in any case. 在任何情况下,这都不是必须的。

For example, if your code uses a CRUD model, abstracting that away from the model, and putting the database code into the base of that instead of the actual Model, might solve this nicely. 例如,如果您的代码使用CRUD模型,则将其从模型中抽象出来,然后将数据库代码放入该模型的基础中而不是实际的模型中,则可以很好地解决此问题。 For instance, given these as a base: 例如,以这些为基础:

class DatabaseSingleton {
    private static $instance;

    public static function get() {
        if (!self::$instance) {
            $options = array(
                PDO::ATTR_PERSISTENT => true,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
            );
            $dsn = "mysql:dbname=test;host=localhost;charset=utf8";
            self::$instance = new PDO($dsn, 'root', '', $options);
        }
        return self::$instance;
    }
}

abstract class Crud {
    private $pdo;

    public function __construct() {
        $this->pdo = DatabaseSingleton::get();
    }

    public function create(...) {
        $this->pdo->...
    }
    public function retrieve(...) {
        $this->pdo->...
    }
    public function update(...) {
        $this->pdo->...
    }
    public function delete(...) {
        $this->pdo->...
    }
}

Then your models could simply be defined as children of: 然后,您的模型可以简单地定义为以下子项:

abstract class Model extends Crud {

    public function __construct() {
        parent::__construct();
        // Etc...
    }
}

And the CRUD functionality defined in Crud would be available to to them, using the single PDO instance provided by the singleton. 使用单例提供的单个PDO实例, Crud定义的CRUD功能将可供他们使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM