У меня есть петля foreach, которая вилки внутри нее. После обработки вилки он обращается к базе данных. Я получаю сообщение об ошибке:
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Дело в том, что я подключаюсь к базе данных после того, как я разветвил.
Мой вопрос: зачем это происходит?
Если это произойдет, я действительно обращаюсь к базе данных перед форкированием? Будет ли ребенок наследовать соединения БД?
(примечание: я могу опубликовать код, но он довольно большой, поскольку все это в классах, что может быть причиной того, что вызывает путаницу при доступе к БД. Еще одна вещь, которую вы должны знать, это использование ZF.)
(комментарий -> ответ на запрос плаката)
Читая больше, я вижу, что разветвленные дети наследуют соединение db своего родителя, и это известная проблема: http://php.net/manual/en/function.pcntl-fork.php#70721
Это помогло мне: http://www.electrictoolbox.com/mysql-connection-php-fork/
Особенно mysql_connect($server, $username, $password, true);
Кроме того, это не проблема . Это способ, которым был разработан pcntl_fork. Любое расширение (как ясно указано в документации), которое поддерживает собственные файловые дескрипторы, будет иметь поврежденные дескрипторы, потому что все дочерние родители имеют общие дескрипторы файлов.
Вы можете избежать закрытия соединения при выходе из вилочного процессора, если вы удалите разветвленный процесс с помощью SIGKILL.
<?php $dbh = new PDO('pgsql:host=localhost', $username, $password); $pid = pcntl_fork(); if($pid == 0){ register_shutdown_function(function(){ posix_kill(getmypid(), SIGKILL); }); exit; } sleep(1); $statement = $dbh->query('select 1'); var_dump($statement);
Причина такого поведения заключается в том, что когда PHP-процесс завершается, PHP отправляется на сервер базы данных «Завершить соединение». Но сокет будет закрыт системой только тогда, когда все ссылки на сокет будут закрыты. Использование SIGKILL помогает избежать отправки команды «Завершить соединение» на сервер базы данных.