У меня был вопрос, касаемый,
почему возникает ошибка 2006. К счастью мне удалось её воспроизвести. Она возникает после повторного получения данных из базы через длительное время.
Кратко поясняю суть скрипта: скрипт поддерживает вечное соединение с камерой и опрашивает её на новые видео, записывая путь к файлу каждого видео в БД. В случае разрыва соединения, он обращается к базе и получает информацию о последнем удачном полученном видео с камеры. В тот момент, когда соединение будет восстановлено, он должен проверить: "не появилось ли новых видео с момента возникновения ошибки, до успешного переподключения".
Если сократить, то код у меня выглядит вот так:
# ----------------------------
# PDO
$pdo = new PDO('mysql:host=127.0.0.1;dbname=cam;charset=utf8mb4', $usr, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false]);
# ----------------------------
# Получение данных из БД
function getDB($action, $data = false) {
global $pdo;
if ($action === "getlast") {
$sql ="SELECT * FROM joblist ORDER BY id DESC LIMIT 1";
}
return $pdo->query($sql)->fetchAll();
}
# ----------------------------
# Цикличная функция writer
function writer($ch, $data) {
# обрабатываем данные...
return strlen($data);
}
# здесь у меня вечное curl подключение к камере с CURLOPT_TIMEOUT => 0 и CURLOPT_WRITEFUNCTION => 'writer'
restart:
$curl_result = curl_exec($ch);
# если возникает ошибка (свет отключился), то мы выходим из вечного цикла функции writer
if ($status === 1) {
# меняем статус
$status = 0;
# получаем время возникновения ошибки
$time_err = getDB("getlast")[0]["time"] ?? date("Y-m-d H:i:s");
}
# возвращаемся выше для переподключения к камере
goto restart; # опустим момент с goto. здесь было проще реализовать, чем for.
Вчера и симулирую отключение камеры и скрипт фиксирует время отключения, после я восстанавливаю коннект с камерой (не перезапуская скрипт). Спустя 12 часов я повторил отключение камеры и мне выдало ошибку 2006. То есть ошибка возникает, когда я через какое-то время снова пытаюсь получить данные с БД.
Я так понимаю, что когда он первый раз опрашивает БД он создаёт подключение к БД и не отключает его. В сети писали, что mysql подключение нужно разрывать, а pdo подключение достаточно обнулить. То есть вместо global $pdo; я должен выполнять условную функцию initPDO(), которая будет делать что-то типа такого:
function initPDO() {
return new PDO('mysql:host=127.0.0.1....
}
а в самой функции получения данных из бд вместо
global $pdo
делать
$pdo = initPDO();
?
Я прав?