为什么这会成为非对象?

时间:2016-02-25 18:10:51

标签: php oop pdo

我正在尝试在PHP中创建一个非常简单的数据库连接类,但我遇到了一些问题。

首先,这里是我写的代码:

class db {

    protected $db;

    public function __construct() {

        $this->db = new PDO('mysql:host=127.0.0.1;dbname=main', 'root', '');
    }
}

每当我尝试从扩展我的数据库类的另一个类调用$db时,我会收到类似这样的错误:

  

致命错误:在class.php中的非对象上调用成员函数prepare()

我在其他类中调用数据库链接,如下例所示:

class example extends db {  

    public function challenge_exists($challenge) {

        $query = $this->db->prepare('SELECT * FROM challenges WHERE challenge = :challenge');
        $query->bindParam(':challenge', $challenge, PDO::PARAM_STR);
        $query->execute();

        if($query->rowCount() > 0) {
            return true;
        }           
    }   
}

我不知道我做错了什么,并希望有任何关于如何使这项工作的建议。

2 个答案:

答案 0 :(得分:3)

问题是,如果子类中有__construct()方法,则需要显式调用父类的__construct(),否则不会执行$db永远不会被实例化。虽然您没有在示例代码中显示子构造函数,但可以安全地假设存在基于行为的子构造函数,因此:

class example extends db {

    public function __construct() {    
        parent::__construct();
        //more stuff   
    }
}

如果您不需要子类中的构造函数,则删除它,并在实例化子类的对象时调用父构造函数。

至于设计,这很糟糕,您应该考虑一个数据库对象并将其注入需要它的对象或类似的方法:

class example {

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

$db = new db();              // do this once
$example = new example($db); // inject when needed

答案 1 :(得分:-1)

您绝不应该首先从数据库类扩展应用程序类。

用户不是数据库。它是一个用户。他们没有任何共同之处。数据库必须由用户用作服务,而不是父级。

更不用说从同一个脚本创建一百个连接是一个非常糟糕的主意。

关于"接受"回答,这是错的。只要在子类中没有定义构造函数(如在OP中),就使用父counstructor。欢迎来到Stack Overfraud。