【问题标题】:PHP and PDO class questionPHP 和 PDO 类问题
【发布时间】:2011-09-11 23:22:46
【问题描述】:

我对 OOP 风格的 PHP 非常陌生,我也在尝试实现 PDO。我在网上找到了一个处理数据库连接的不错的小类,但是我不知道如何从另一个类访问它。代码如下:

  class PDO_DBConnect {
    static $db ;
    private $dbh ;
    private function PDO_DBConnect () {
        $db_type = 'mysql';  //ex) mysql, postgresql, oracle
        $db_name = 'postGal';
        $user = 'user' ;
        $password = 'pass' ;
        $host = 'localhost' ;
        try {
            $dsn = "$db_type:host=$host;dbname=$db_name";
            $this->dbh = new PDO ( $dsn, $user, $password);
            $this->dbh->setAttribute(PDO::ATTR_PERSISTENT, true);
            $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch ( PDOException $e ) {
            print "Error!: " . $e->getMessage () . "\n" ;
            die () ;
        }
    }

    public static function getInstance (  ) {
        if (! isset ( PDO_DBConnect::$db )) {
            PDO_DBConnect::$db = new PDO_DBConnect ( ) ;
        }
        return PDO_DBConnect::$db->dbh;
    }
  }

  $db_handle = PDO_DBConnect::getInstance(); 

    class Person 
  {
    function __construct()
    {
      $STMT = $db_handle->prepare("SELECT title FROM posts WHERE id = ? AND author = ? LIMIT 20");
      $STMT->execute(array('24', 'Michael'));

      while ($result = $STMT->fetchObject()) 
      {
        echo $result->title;
        echo "<br />";
      }  
    }
  }

如何访问我的 Person 类中的 $db_handle 变量?我必须在 Person 类中实例化变量吗?如果是这样,这是否意味着我将始终将其称为 $this-&gt;db_handle ?我希望避免这种情况。 (我对类的变量作用域仍然只有非常基本的了解)

【问题讨论】:

  • 你为什么使用 PHP5 OO 构造,而不是 PHP4 时代的同名构造函数?请考虑改用__construct
  • 我不认为他编写了 PDO_DBConnect 类,因为他提到他“找到了它”。

标签: php class pdo


【解决方案1】:

你应该使用Dependency Injection:

$steve = new Person($db_handle);

是的,使用您希望避免的语法就是这样做的方法。您始终可以通过说$dbh = $this-&gt;db_handle; 将类变量分配给本地方法之一,我认为这会稍微快一些。

【讨论】:

    【解决方案2】:

    如果你真的必须从你的 Person 对象内部进行数据库工作(separation of concerns 说这应该在其他地方处理),你可以将它作为构造函数参数传递(基于你的用法,看起来这可能是您想要的方式),或者作为 setter 注入。对于前者:

    class Person
    {
        function __construct($db_handle)
        {
            // ... your existing code
    

    然后你像这样实例化你的 person 对象:

    $person = new Person($db_handle);
    

    这确实是避免使用$this-&gt;db_handler 而不将变量复制到本地范围的唯一方法。

    【讨论】:

      【解决方案3】:

      有(至少)三种方法来处理这个问题。最可移植且经常推荐的方法称为“依赖注入”,您可以通过 __construct() 将数据库句柄传递到您的类中,并将其存储在类变量中。需要使用 $this-&gt;db 访问它,就像您不想这样做一样。

      class Person {
        // Member to hold the db handle
        public $db;
      
        public function __construct($db_handle) {
          // Assign the handle to a class member variable in the constructor
          $this->db = $db_handle;
        }
        public function otherFunc() {
          $this->db; // do something
        }
      }
      
      $person = new Person($db_handle);
      

      下一个方法是在构造函数中实例化$db_handle,而不是将其传入。这有点难以测试和调试。

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

      最后,您可以在课堂上使用$db_handle 作为global 调用它。这可能是最难阅读和调试的。

      class Person {
        public function __construct() {
          global $db_handle;
        }
        public function otherFunc() {
          global $db_handle;
          $db_handle; // do something
        }
      }
      

      【讨论】:

      • 非常感谢您详细说明这一点。正是我需要知道的。我认为构造方法对于我想要使用它最有意义。谢谢!
      • 只是真的很困惑什么被调用,什么时候被调用,因为该类与它内部的函数具有相同的名称。这有什么作用吗?
      • @Eujung Kim 哪个类与其中的函数同名?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2017-05-18
      • 2012-07-09
      • 2016-05-19
      • 2018-12-03
      • 2013-09-28
      相关资源
      最近更新 更多