PHP和PDO类的问题

时间:2011-06-09 18:59:57

标签: php class pdo

我对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->db_handle?我希望避免这种情况。 (我仍然只对类的变量范围有一个非常基本的了解)

3 个答案:

答案 0 :(得分:5)

有(至少)三种方法来处理这个问题。最便携,最常推荐的是“依赖注入”,你可以通过它的__construct()将数据库句柄传递给你的类,并将它存储在类变量中。需要使用$this->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 } } 。这可能是最难阅读和调试的。

{{1}}

答案 1 :(得分:3)

您应该使用Dependency Injection

$steve = new Person($db_handle);

是的,使用您希望避免的语法是实现它的方法。您始终可以通过说$dbh = $this->db_handle;来将类变量分配给本地方法,我相信它会稍快一些。

答案 2 :(得分:3)

如果你真的必须从你的Person对象中做数据库工作(separation of concerns说这应该在其他地方处理),你可以将它作为构造函数参数传递(基于关于你的使用情况,它看起来可能是你想要的方式),或者作为一个二传手注射。对于前者:

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

然后你实例化你的人物对象:

$person = new Person($db_handle);

这是唯一可以避免在不将变量复制到本地范围时使用$this->db_handler的方法。