Когда удаляется static переменная в php?

207
12 марта 2017, 07:49

Ранее объект для работы с БД создавался как глобальная переменная сразу в начале выполнения скрипта. Потом я переписал это в следующий вид.

class GlobalData {
    private static $DB = null;
    public static function getDB() {
        if(!GlobalData::$DB) {
            GlobalData::$DB = new DBProvider();
        }
        return GlobalData::$DB;
    }
}

Все вроде хорошо, только стали иногда на сайте появляться ошибки типа:

exception 'PDOException' with message 'SQLSTATE[HY000] [2002] Connection refused

и иногда

exception 'PDOException' with message 'SQLSTATE[HY000] [1040] Too many connections

Ранее (когда была просто глобальная переменная) такого не было. Внутри DBProvider используется PDO. Соединение вручную не закрывается в расчете на то, что оно будет закрыто автоматически по завершении работы скрипта.

Может ли быть данная проблема связана с новой архитектурой?

Answer 1

При завершении скрипта или если чем-то заменить статическую переменную. Сборщик мусора статические переменные никогда не трогает, т.к. не без оснований полагает, что к ней могут обратиться впоследствии.

Обе приведённые ошибки никак не связаны со статическими переменными, т.к. возникают при создании подключения, а не после.

connection refused - mysql отклонил соединение. Например, упёрлись в back_log. Некоторые пояснения от percona. Или ОС отклонила соединение, там тоже лимиты есть, например упомянутый перконой tcp_max_syn_backlog.

Too many connections - соответственно, слишком много открытых соединений. Упёрлись в max_connections, есть отдельная страница в мануале.

Очевидно, вы немного выросли по посещаемости с тех пор, вот и перестало лимитов хватать. Смотрите в мониторинг.

Answer 2

Это не связанные между собой события. Возможно у вас возросло количество пользователей, либо что-то с базой сделали. Или где-то в другом месте соединения плодятся.

Как вариант, используйте постоянные соединения

$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
    PDO::ATTR_PERSISTENT => true
));

И еще, лучше делать явную проверку

if(self::$DB === null) {
READ ALSO
матрица расстояний

матрица расстояний

Есть таблица "Расстояние" с 3 столбцами:

511
php.ini - настройки почты Яндекс

php.ini - настройки почты Яндекс

Пробую отправлять почту через Яндекс из PHP:

302
Как сделать такое в php

Как сделать такое в php

Здесь прячет повтор слов, в html они остаются , а надо что б полностью удалялись спасибо всем за помощь

224
Отправить email только один раз php

Отправить email только один раз php

Добрый день! Возможно это дупликат вопроса, но я не нашел ответа

239