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

时间:2013-12-20 07:48:44

标签: php oop pdo

问题:当我使用load对象加载模型时,它不会返回第二个模型。

查看使用Test对象加载模型的类load。代码$this->two将返回对象One(应该加载对象2)。

问:如何解决这个问题?我打开你的建议/想法/代码

当前结果:

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

正确的结果:

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

PHP:

one_model.php

<?php

class One extends Model {

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

}

two_model.php

<?php

class Two extends Model {

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

}

的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();

2 个答案:

答案 0 :(得分:0)

我将PDO包装器从Model移到了单独的类并为数据库连接创建了对象。

这是好方法吗?这是“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();
    }

}

答案 1 :(得分:-1)

问题似乎是你将PDO::ATTR_PERSISTENT => true传递给PDO构造函数。这将告诉PDO缓存和重用连接 - 正如您无疑的那样 - 但它似乎也会导致PDO生成在单个脚本范围内生成的第一个PDO实例的克隆,包括用于创建第一个实例的子类。 (虽然似乎没有很多关于此的文档。)

如果您需要持久连接,我的建议是以不要求从PDO扩展模式的方式定义模型。在任何情况下,这都不应该是必要的。

例如,如果您的代码使用CRUD模型,将其从模型中抽象出来,并将数据库代码放入 而不是实际模型的基础中,则可以很好地解决这个问题。例如,将这些作为基础:

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->...
    }
}

然后您的模型可以简单地定义为:

的孩子
abstract class Model extends Crud {

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

使用单身人士提供的单个PDO实例,Crud中定义的CRUD功能可供他们使用。