Должны ли закрываться соединения SQL, открытые с PDO в PHP?
Когда я открываю соединение MySQL в PHP с помощью встроенных функций MySQL MySQL, я делаю следующее:
$link = mysql_connect($servername, $username, $password); mysql_select_db($dbname); //queries etcetera mysql_close($link);
Когда я открываю соединение с PDO, он выглядит так:
$link = new PDO("mysql:dbname=$dbname;host=$servername",$username,$password); //prepare statements, perform queries
Должен ли я явно закрывать соединение, как я делаю с mysql_connect() и mysql_close() ? Если нет, то как PHP знает, когда я закончил с моим соединением?
Используйте $link = null чтобы PDO знал, что может закрыть соединение.
PHP: подключения и управление PDO
После успешного подключения к базе данных экземпляр класса PDO возвращается в ваш скрипт. Соединение остается активным для времени жизни этого объекта PDO. Чтобы закрыть соединение, вам нужно уничтожить объект, убедившись, что все остальные ссылки на него удалены – вы делаете это, назначая NULL переменной, которая содержит объект. Если вы не сделаете это явно, PHP автоматически закроет соединение, когда ваш скрипт закончится.
PDO не предлагает такую функцию самостоятельно. Подключения через PDO косвенно управляются с помощью PDO-объектов refcount в PHP.
Но иногда вы хотите закрыть соединение в любом случае, независимо от суммы. Либо потому, что вы не можете управлять им, вам нужно его для тестирования или аналогичного.
Вы можете закрыть соединение Mysql с PDO , выполнив SQL-запрос. Каждый пользователь, который может подключиться к серверу Mysql, способен KILL хотя бы свой собственный поток:
/* * Close Mysql Connection (PDO) */ $pdo_mysql_close = function (PDO $connection) < $query = 'SHOW PROCESSLIST -- ' . uniqid('pdo_mysql_close ', 1); $list = $connection->query($query)->fetchAll(PDO::FETCH_ASSOC); foreach ($list as $thread) < if ($thread['Info'] === $query) < return $connection->query('KILL ' . $thread['Id']); > > return false; >; $pdo_mysql_close($conn);
Связанная документация Mysql:
Связанные вопросы о стеке:
Когда скрипт PHP завершит выполнение, все соединения будут закрыты. Также вам не нужно явно закрывать соединение с mysql_close() .
Вы также можете ограничить свои подключения локальными функциями. Таким образом, соединение закрывается, как только функция будет завершена.
Хорошо видя, что $link для PDO назначается объекту, PHP будет устанавливать это как null, как только скрипт будет запущен, так что он больше не является объектом. Поэтому вы можете просто сделать:
$link = new PDO("mysql:dbname=$dbname;host=$servername",$username,$password); //prepare statements, perform queries $link = null;
Из того, что я собираю, я не мог все равно закрыть его в руководстве по php, и примеры сценариев, которые я быстро посмотрел, никогда не закрывали соединение, в любом случае, из того, что я мог видеть.
Нужно ли закрывать соединения PDO?
Я заметил, что для PDO нет закрытой функции. Должен ли я закрыть соединение или нет необходимости в PDO?
3 ответа
После успешного подключения к базе данных экземпляр класса PDO возвращается на ваш script. Соединение остается активным для времени жизни этого объекта PDO. Чтобы закрыть соединение, вам нужно уничтожить объект, убедившись, что все остальные ссылки на него удалены — вы делаете это, назначая NULL переменной, которая содержит объект. Если вы не сделаете это явно, PHP автоматически закроет соединение, когда закончится ваш script.
http://php.net/manual/en/pdo.connections.php Итак, ответ отрицательный, вам не нужно ничего делать, если вам не нужно явно закрывать соединение во время выполнения script по какой-либо причине, и в этом случае просто установите для вашего объекта PDO значение null.
Хотя было бы неплохо закрыть соединение. Другие языки не так велики, когда дело доходит до утечек памяти.
@RPM Это очень верно. Я согласен, что это также хорошая идея, если сценарий написан плохо и работает в бесконечном цикле или иным образом занимает слишком много времени. Если соединение не используется, нет необходимости держать его включенным.
@RPM Бессмысленно закрывать его, если у вас нет особой причины для этого. Кроме того, если ваш скрипт выполняется слишком долго, он будет уничтожен и соединение будет закрыто.
@Brad, нет смысла закрывать соединение. Каждое соединение занимает ресурсы на сервере базы данных. Большинство серверов настроены с максимальным количеством одновременных подключений. Если вы активно закрываете соединения, вы освобождаете этот слот для другого потока и в целом получаете лучшую пропускную способность.
@BillKarwin Если вы пишете сценарии, которые в любом случае заканчиваются немедленно, это бессмысленно. Я полностью согласен с тем, что если вы пишете что-то долгое время, которому не нужны данные после первоначального запроса, то вы должны закрыть его.
@Brad, да, не все скрипты созданы одинаковыми, и некоторые выполняют некоторую работу по форматированию и выводу HTML после того, как они выполнили всю свою работу с базой данных. Но есть некоторые сайты с таким высоким трафиком, что даже сокращение на 20 миллисекунд от длины соединения дБ имеет большое значение, когда вы умножаете на тысячи запросов в секунду.
По этой ссылке: phpdelusion.net/pdo#prepared , почему сказано: «Соединение должно быть сделано только один раз! Нет соединений в каждой функции. Нет соединений в каждом конструкторе класса. В противном случае будет создано несколько соединений, которые будут в конечном итоге убить ваш сервер базы данных. Таким образом, необходимо создать отдельный экземпляр PDO, а затем использовать его при выполнении всего скрипта ». Проверка с помощью: показать статус, где variable_name = ‘Threads_connected’; Я вижу, что всегда можно открыть только 2 соединения одновременно (предположительно, мое приложение sql и мой сайт).
Это не совсем правильно. Есть случаи, когда вы должны закрыть соединение, например, при использовании потоков pcntl.
Этот вопрос немного зависит от типа проекта и типа подключения.
Почти во всех моих проектах я никогда не закрываю соединение вручную. В PHP соединение (если оно не является постоянным соединением) будет открыто только во время запроса. Поэтому ручное закрытие в любом случае бесполезно.
При просмотре моих проектов, где не было постоянного соединения, было бы очень трудно узнать, когда вручную закрыть соединение в любом случае. Как только проект становится больше, чем несколько файлов (и отдельные компоненты не имеют представления об афоризме, как они должны), становится очень сложно узнать, когда соединение будет по-прежнему необходимо.
И снова открытие соединения при необходимости будет более дорогостоящим, чем просто оставить его открытым во время запроса.
Что-то, хотя при работе с постоянным подключением возникнут ситуации, когда вы захотите вручную закрыть соединение.
Итак, чтобы ответить на ваш вопрос:
Я заметил, что для PDO нет закрытой функции.
Вы можете аннулировать ссылку на объект (и все ссылки на объект), чтобы вручную закрыть соединение в PHP.
Должен ли я закрыть соединение или нет необходимости в PDO?
В большинстве случаев это необязательно.
Если я явно установлю для объекта PDO значение NULL ( $pdo = NULL ) и $pdo = NULL объект PDO с помощью PDO::ATTR_PERSISTENT => true (постоянное соединение), он закроет соединение или PHP проигнорирует инструкцию, потому что соединение является постоянным ?
После успешного подключения к базе данных экземпляр класса PDO возвращается на ваш script. Соединение остается активным для времени жизни этого объекта PDO. Чтобы закрыть соединение, вам нужно уничтожить объект, убедившись, что все остальные ссылки на него удалены — вы делаете это, назначая NULL переменной, которая содержит объект.
Если вы не сделаете это явно, PHP автоматически закроет соединение, когда ваш script закончится.
ИЗМЕНИТЬ
Я бы предпочел использовать постоянное соединение. Хотя, это хорошая практика, чтобы закрыть все соединения в конце script.
Нужно ли закрывать соединения SQL, открытые с помощью PDO в PHP?
Должен ли я явно закрыть соединение, как я делаю с mysql_connect() и mysql_close() ? Если нет, то как PHP знает, когда я закончил с моим подключением? ТИА.
6 ответов
Используйте $link = null , чтобы PDO знал, что он может закрыть соединение. PHP: PDO Connections и управление подключением
После успешного подключения к базе данных экземпляр класса PDO возвращается на ваш script. Соединение остается активным для времени жизни этого объекта PDO. Чтобы закрыть соединение, вам нужно уничтожить объект, убедившись, что все остальные ссылки на него удалены — вы делаете это, назначая NULL переменной, которая содержит объект. Если вы не сделаете это явно, PHP автоматически закроет соединение, когда закончится ваш script.
Интересно, PDO dtor явно закрывает соединение или оставляет его PHP, как это происходит, когда mysql_close() не используется в конце скрипта (или в __destruct() вашего класса db)? Из руководства это звучит так, как будто объект PDO разрушен, соединение также закрывается. Важно из-за этого: stackoverflow.com/a/2960656/372654 . Кажется, так из исходного кода PDO, но .
Не будет ли один unset() объект PDO вместо установки его в NULL? Я действительно хочу получить разъяснения по этому поводу!
Стоит отметить, что официальное руководство по PHP (по ссылке выше) рекомендует устанавливать значение null и не упоминает «unset ()». У вас проблемы с использованием официального подхода или вы спрашиваете академически? Если первое, пожалуйста, уточните детали. Если последнее, возможно, вы захотите обратиться к разработчикам PHP, они лучше всего подойдут для решения альтернатив их официально документированному решению. (Например, даже если unset () работает в одной версии, он может не работать в другой, если разработчики явно не обеспечивают такой подход.)
ИМХО, это не имеет значения, если вы unset () или установлен в NULL. AFAIK, в любом случае метод destruct PDO :: __ вызывается так же, как если бы вы позволяли переменной длиться до конца сценария, и соединение в этом методе закрывается.
Как насчет сферы? Если объект соединения создается и не возвращается в конце функции / метода, то умрет ли соединение?
@MadaraUchiha см. Ответ JDelage: «Вы также можете ограничить свои соединения внутри локальных функций. Таким образом, соединение будет закрыто, как только функция будет завершена». 🙂
PDO не предлагает такую функцию самостоятельно. Подключения через PDO косвенно управляются с помощью PDO-объектов refcount в PHP.
Но иногда вы хотите закрыть соединение в любом случае, вне зависимости от того, какая сумма была пересчитана. Либо потому, что вы не можете контролировать его, нуждаетесь в нем для целей тестирования или аналогичного.
Вы можете закрыть соединение Mysql с PDO, выполнив SQL-запрос. Каждый пользователь, который может подключиться к серверу Mysql, способен KILL по крайней мере собственный поток:
/* * Close Mysql Connection (PDO) */ $pdo_mysql_close = function (PDO $connection) < $query = 'SHOW PROCESSLIST -- ' . uniqid('pdo_mysql_close ', 1); $list = $connection->query($query)->fetchAll(PDO::FETCH_ASSOC); foreach ($list as $thread) < if ($thread['Info'] === $query) < return $connection->query('KILL ' . $thread['Id']); > > return false; >; $pdo_mysql_close($conn);
Связанная Документация Mysql:
Связанные вопросы о стеке:
$connection->query(‘KILL CONNECTION_ID();’); Протестировано на mysql 5.7 на debian из локального клиента командной строки mysql и из рабочей среды на рабочей станции Windows. Согласно dev.mysql.com/doc/refman/5.5/en/show-processlist.html Id столбца SHOW PROCESSLIST — это «. идентификатор соединения. Это значение того же типа, что и в столбце идентификатора INFORMATION_SCHEMA. Таблица PROCESSLIST и возвращена функцией CONNECTION_ID() . » (примечание: я комментирую ответ, которому почти 6 лет)
Когда PHP script завершает выполнение, все соединения закрываются. Также вам не нужно явно закрывать ваше соединение с помощью mysql_close() .