0

我正在切换我的 MVC 以使用 PDO(我知道,过期了)。过去,我的应用程序使用了以下类层次结构:

Database.class>Main.class>User.class

(每个延伸另一个)。但在创建任何对象之前,mysql 连接已建立(mysql_connect)。一旦连接打开,我就可以使用 Database.class 作为包装类,通过它执行我的所有查询。通过扩展,可以简单地通过调用“查询”函数($this->query)在 User.class 中进行查询。

使用 PDO,我尝试模仿该过程但发现错误。我在 Database.class 中创建了一个单例函数:

function __construct()
{
    $this->db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8', DB_USER, DB_PASSWORD);
    $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}

public static function getInstance()
{
    if (!isset(self::$instance)){
        $object = __CLASS__;
        self::$instance = new $object;
    }
    return self::$instance;
}

function query($qry,$params=NULL){
    $qry = $this->db->prepare('SELECT * FROM users WHERE userID = :userID');
    $qry->execute(array(':userID' => 1));
    $results = $qry->fetchAll(PDO::FETCH_ASSOC);
    return $results;
}

然后在 Main.class 我得到实例:

function __construct()
{
    $this->db = parent::getInstance();
}

所以在 User.class 我尝试调用

function __construct(){
    parent::__construct();
}
function test(){
    return $this->db->query("test");
}

所以我可以从 Main.class 对象运行任何查询。但是,如果我尝试从 User.class 对象运行查询,则会收到错误消息:“调用非对象上的成员函数 query()”换句话说,如果 User.class 扩展 main 我应该能够访问该变量$db in Main from User.class(我在创建 User 对象时调用 Main 的构造函数)。部分问题是 Main.class 在应用程序的早期创建为它自己的对象,我相信会导致创建两个 PDO 实例 - 这就是为什么它不能通过扩展工作(通过第二个对象也扩展数据库.类)

所以我的问题是:有没有办法做到这一点?或者我最好的选择是对我创建的每个对象使用注入(因为一些脚本包含多个扩展 Main.class 的对象 - 每次都尝试创建 PDO 的实例)并将 pdo 对象传递给构造函数?我宁愿不必这样做(标记越少越好)所以另一种选择是使用所有类都使用的 STATIC 变量?最好的方法是什么?(让我知道这是否令人困惑)

我见过有人为此使用注入,并且我见过扩展 pdo 包装类的示例(但只有一次)。

谢谢!(我喜欢堆栈溢出!)

4

1 回答 1

1

您不希望其中任何一个扩展数据库类,因为这实际上会使它们成为所有单例,而您只能拥有一个实例……您想让它们改为使用数据库类。因此,您会将最抽象的 db 方法放在 the 上Database,然后为特定事物创建查询的方法将放在 theUser或 what have you 上。这意味着您Database实际上是包装PDO的,并且是所有其他类用于 db 操作的内容。除非您尝试实现活动记录或其他东西,否则甚至可能不需要Mainor类。Base

class Database {
   static protected $instance;

   /**
    * @var PDO
    */
   protected $connection;

   protected function __construct($dsn, $user, $pass, $attrs = array()) {
       // create pdo instance and assign to $this->pdo
   }

   public static function getInstance() {
       if(!self::$instance) {
           // get the arguments to the constructor from configuration somewhere
           self::$instance = new self($dsn, $user, $pass);
       }

       return self::$instance;
   }

   // proxy calls to non-existant methods on this class to PDO instance
   public function __call($method, $args) {
       $callable = array($this->pdo, $method);
       if(is_callable($callable)) {
           return call_user_func_array($callable, $args);
       }
   }
}

class Main {
   protected $db;

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

    class User extends Main{

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

       public function findById($id) {
           $qry = $this->db->prepare('SELECT * FROM users WHERE userID = :userID');
           $qry->execute(array(':userID' => $id));
           $results = $qry->fetchAll(PDO::FETCH_ASSOC);

           return $results
       }
    }
于 2013-08-07T00:11:33.237 回答