Вопрос класса PHP и PDO - PullRequest
5 голосов
/ 09 июня 2011

Я очень плохо знаком с 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 />";
      }  
    }
  }

Как я могу получить доступ к переменной $db_handle внутри моего класса Person?Нужно ли создавать экземпляр переменной внутри класса Person?Если это так, значит ли это, что мне всегда придется называть это $this->db_handle?Я надеялся избежать этого.(У меня все еще есть только базовое понимание области видимости переменных с классами)

Ответы [ 3 ]

5 голосов
/ 09 июня 2011

Есть (как минимум) три способа справиться с этим. Самый переносимый и часто рекомендуемый метод называется «внедрение зависимостей», при котором вы передаете дескриптор базы данных в свой класс через __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
  }
}
3 голосов
/ 09 июня 2011

Если вы действительно должны выполнить работу с базой данных из своего объекта Person ( разделение интересов говорит, что об этом нужно позаботиться в другом месте), вы можете передать его как конструктор аргумент (в зависимости от вашего использования, похоже, что это может быть так, как вы хотите), или как инъекция сеттера. Для бывших:

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

Затем вы создаете экземпляр своего личного объекта следующим образом:

$person = new Person($db_handle);

Это действительно единственный способ избежать использования $this->db_handler без копирования переменной в локальную область.

3 голосов
/ 09 июня 2011

Вы должны использовать Внедрение зависимостей :

$steve = new Person($db_handle);

И да, используя синтаксис, который вы надеетесь избежать, это способ сделать это. Вы всегда можете присвоить переменную класса локальному методу, сказав $dbh = $this->db_handle;, что, я считаю, немного быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...