【问题标题】:Explanation: Calling parent::__construct, two Database() classes解释:调用 parent::__construct,两个 Database() 类
【发布时间】:2014-08-06 20:50:57
【问题描述】:

这可能根本不是一个真正的问题,但我想知道为什么会这样。

代码按照我在此处发布的方式运行。

我有一个这样的 Database() 类:

class Database extends PDO
{

    public function __construct()
    {
        $options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
        parent::__construct(DB_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8', DB_USER, DB_PASS, $options);
    }
}

这个类通过控制器调用:

class Controller
{
    function __construct()
    {
        Session::init();

        if (!isset($_SESSION['user_logged_in']) && isset($_COOKIE['rememberme'])) {
            header('location: ' . URL . 'login/loginWithCookie');
        }

        try {
            $this->db = new Database(); 
        } catch (PDOException $e) {
            die('Database connection could not be established.');
        }

        $this->view = new View();
    }
}

注意这里调用了 Database() 类。

现在,我有一个“模型”,它需要数据库连接才能与数据库通信:

class Notes extends Controller
{    
    public function __construct()
    {
        parent::__construct();
    }

    public static function getSumNotes()
    {
        $sql = "SELECT COUNT(*) FROM table WHERE user_id = :user_id";
        $query = new Database();
        $query = $query->prepare($sql);
        $query->execute(array(':user_id' => $_SESSION['user_id']));

        return $query->fetchColumn();
    }
}

让我恼火的是:方法 Notes::getSumNotes() 调用另一个新的 Database() 类,这是从表中获取我的值所必需的。没有这个连接将无法工作。

问题:为什么我必须调用 Database() 类两次,尽管来自 Notes 的 parent::__construct() 从“dads”(控制器)类中获取相同的变量和构造函数?

希望得到启发。

谢谢。

【问题讨论】:

  • 声明protected $db,然后在你的父类中使用return $this->db;,当然在你的notes类中使用private $db。
  • 您应该将全局数据库连接传递给您的Controller 类及其子类;现在您为您创建的每个对象打开一个数据库连接。在对象本身中,您应该能够使用$this->db
  • @Ohgodwhy:不工作。当我 var_dump() 或 print_r() out $this->db 时,什么也没有发生。它在我的屏幕上没有显示任何数组。
  • @jeroen:我通过了一个全局数据库连接并在我的 Notes 类中写了这个:$query = $this->db->prepare($sql); 如果这是正确的,它仍然无法正常工作。

标签: php class pdo constructor parent


【解决方案1】:

您不必调用数据库对象两次。
请注意您的 getSumNotes() 方法是 static,因此您将无法在该方法内调用 $this(这将引发 E_STRICT 错误,因此请检查您的日志)。

从您的方法中删除 static 或使用此解决方法:

class Notes extends Controller
{
    //  Notice the new variable has to be static as well
    public static $staticDb;

    public function __construct()
    {
        parent::__construct();
        //  Make sure the db variable exists in your parent class
        self::$staticDb = $this ->db;
    }

    public static function getSumNotes()
    {
        $sql = "SELECT COUNT(*) FROM table WHERE user_id = :user_id";

        //  Use the same DB connection
        $query = self::$staticDb;

        $query = $query->prepare($sql);
        $query->execute(array(':user_id' => $_SESSION['user_id']));

        return $query->fetchColumn();
    }
}

附带说明,您的 MVC 结构存在问题。模型不应该是控制器类的扩展。
更多关于 here 的内容,如果你愿意的话。

【讨论】:

  • 感谢您的解释。不幸的是,结果与上面的建议相同(var_dumped 时我的屏幕上没有数组)。关于“模型”:那些根本不是模型,这就是为什么我用双引号将它设置为:) 我只是举个例子,真正的代码有点不同。但这是我的代码现在使用的确切结构。
  • @CRoemheld 此代码有效,您绝对不必两次实例化 DB 对象。如果真正的代码像你说的不同,那么我猜不出它有什么问题。无论哪种方式,数据库连接都应该并且可以传递给子类。
  • 我将完全相同的变量传递给我的脚本。我还将protected $db 传递给Controllers 类。我还尝试删除“静态”。结果和我说的一样:数组是空的。但我真的很感谢你的解释! :) @LifeQuery
猜你喜欢
  • 1970-01-01
  • 2012-05-20
  • 2010-12-08
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 2014-06-03
  • 2019-11-02
  • 2012-01-30
相关资源
最近更新 更多