Я очень новичок в стиле 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
? Я надеялся избежать этого. (У меня все еще есть только основное понимание области переменных с классами)
Есть три способа справиться с этим. Самый портативный и рекомендуемый вариант называется «инъекция зависимостей», посредством чего вы передаете дескриптор базы данных в свой класс через свой __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 } }
Вы должны использовать Injection Dependency :
$steve = new Person($db_handle);
И да, используя синтаксис, который вы надеетесь избежать, это способ сделать это. Вы всегда можете назначить переменную класса локальному методу, указав $dbh = $this->db_handle;
который, я считаю, немного быстрее.
Если вы действительно должны выполнять работу с базой данных внутри вашего объекта Person ( разделение проблем говорит, что об этом следует позаботиться в другом месте), вы можете передать его как аргумент конструктора (в зависимости от вашего использования, похоже, что это может быть способ вы хотите пойти), или как инъекция сеттера. Для первого:
class Person { function __construct($db_handle) { // ... your existing code
Затем вы создаете экземпляр своего объекта:
$person = new Person($db_handle);
Это единственный способ избежать использования $this->db_handler
без копирования переменной в локальную область.