Intereting Posts
Размещение события на стене страницы с PHP – правильная страница? С PDO, как я могу убедиться, что заявление UPDATE прошло успешно? несколько файлов PDF с html2pdf Что возвращает успешный MySQL DELETE? Как проверить успешность DELETE? PHP: отправить электронную почту через cronjob и установить количество отправки электронной почты за минуту Как преобразовать временную метку Unix в hhmmss? Объединить два массива и упорядочить этот новый массив по дате разрешить круглые скобки и другие символы в регулярном выражении Повторить результат для num строк в php маскирование удаленных субдоменов Mailgun Отправлено письмо С приложением RabbitMQ ждет завершения нескольких очередей ХРОМ НЕ ОТКРЫВАЮЩИХ ПЕЧЕНЬ ЗАКРЫТИЯ на закрытии / выходе PHP Как рассчитать длину идентификатора сеанса перед началом сеанса Как извлекать годы, месяцы, дни, часы, минуты, секунды с даты mysql?

Автоматическое подключение к PDO только при необходимости

У меня есть раздел кода, который в зависимости от запрошенного URL будет содержать один из четырнадцати других файлов. Некоторые из этих четырнадцати файлов требуют подключения к одной из трех разных баз данных, а дополнительные файлы могут быть добавлены в любое время.

Я не хочу открывать соединения PDO по умолчанию для всех трех баз данных, поскольку это пустая трата ресурсов и замедлит время выполнения. Поэтому моя мысль состоит в том, чтобы обернуть все SQL-запросы внутри функции. В первый раз, когда запрос выполняется в незащищенном PDO-соединении, обработчик ошибок try {} может его поймать, выяснить, в чем проблема (в этом случае соединение не существует), затем откройте соединение и заново выполните запрос. Таким образом, база данных подключается только по мере необходимости – пока все строки подключения (хост, база данных, имя пользователя, пароль) определены заранее, я не вижу никаких проблем в работе.

Тем не менее, мне нужно продолжать с этим и не иметь доступа к блоку dev около 7 дней, так что может ли кто-нибудь увидеть какие-либо проблемы с этим сценарием? Кроме того, может ли кто-нибудь сообщить мне сообщение об ошибке, что обработчик-> errorInfo () вернется, если соединение не будет открыто?

Related of "Автоматическое подключение к PDO только при необходимости"

Это правильная идея, но не лучшая ее реализация.

Обход операций SQL хорош. Но почему бы вам не сделать так:

 class Wrapper { private static $db; public static function someQuery() { $db = self::getDatabase(); // now go on to execute the query } private static function getDatabase() { if (self::$db === null) { self::$db = // connect here } return self::$db; } } 

Это имеет много преимуществ:

  • Позволяет логически группировать операции SQL в один (или несколько!) Классов
  • Не подключается к базе данных, если не требуется.
  • Не зависит от (хрупкой) проверки ошибок для правильной работы

В вашем конкретном случае вы, вероятно, должны пойти с 3 отдельными классами Wrapper . Включение всего в один класс выполнимо (три разные переменные $db ), но, вероятно, более запутанное, чем того стоит.

Используйте этот класс именно так, как вы бы использовали класс PDO .

 class DB extends PDO { protected $_config = array(); protected $_connected = false; public function __construct($dsn, $user = null, $pass = null, $options = null) { //Save connection details for later $this->_config = array( 'dsn' => $dsn, 'user' => $user, 'pass' => $pass, 'options' => $options ); } public function checkConnection() { if (!$this->_connected) { extract($this->_config); parent::__construct($dsn, $user, $pass, $options) $this->_connected = true; } } public function query($query) { $this->checkConnection(); return parent::query($query); } public function exec($query) { $this->checkConnection(); return parent::exec($query); } //etc. } 

Я использовал другой подход, используя метод __call magic, поэтому вам не нужно создавать отдельные обертки для каждого метода.

 class PDOLazyConnector { private $dsn; private $username; private $password; private $driver_options; private $dbh; public function __construct ($dsn, $username, $password, $driver_options = array ()) { $this->dsn = $dsn; $this->username = $username; $this->password = $password; $this->driver_options = $driver_options; } public function __call ($function, $args) { // connect to db (first time only) $this->__init_dbh (); // invoke the original method return call_user_func_array (array($this->dbh, $function), $args); } public function __get ($property) { return $this->dbh->$property; } private function __init_dbh () { // If db handler is not open yet, do it now if (empty ($this->dbh)) { $this->dbh = new PDO ($this->dsn, $this->username, $this->password, $this->driver_options); } } } 

Вам просто нужно заменить свое PDO-инстанцию ​​на PDOLazyConnector, так что:

 $dbh = new PDO($dsn, $user, $password, $driver_options); 

с:

 $dbh = new PDOLazyConnector($dsn, $user, $password, $driver_options); 

PDO имеет возможность для постоянных соединений PDO :: ATTR_PERSISTENT .

См. Комментарии в http://php.net/manual/en/book.pdo.php

 function &get_pdo() { static $_PDO = null; if ($_PDO === null) { $_PDO = new PDO('your DSN', 'username', 'password'); } return $_PDO; } 

Тогда вы просто делаете

 $stmt = get_pdo()->prepare('...'); 

Вы можете сделать то же самое, расширив класс PDO и добавив к нему статическую одноэлементную функцию. Я считаю этот подход более простым. Также дает вам возможность вызывать его из любого места в стеке, не ставя его в аргументы (что может быть хорошим или плохим, в зависимости от ситуации).