Выполнить код после HTTP-запроса в PHP?

PHP предоставляет механизм регистрации функции выключения:

register_shutdown_function('shutdown_func'); 

Проблема в том, что в последних версиях PHP эта функция все еще выполняется ВО ВРЕМЯ запроса.

У меня есть платформа (в Zend Framework, если это имеет значение), где любой фрагмент кода во всем запросе может регистрировать запись, которая будет регистрироваться в базе данных. Вместо того, чтобы иметь тонны отдельных инструкций вставки по всему запросу, замедление страницы вниз, я помещаю их в очередь, чтобы их вставлять в конце запроса. Я хотел бы иметь возможность сделать это после того, как HTTP-запрос будет завершен с пользователем, так что время для регистрации или выполнения каких-либо других задач очистки не влияет на время загрузки пользователя на странице.

Есть ли встроенный метод в PHP для этого? Или мне нужно сконфигурировать какую-то общую схему пространства памяти с внешним процессом и сигнализировать о том, что процесс ведения журнала?

Solutions Collecting From Web of "Выполнить код после HTTP-запроса в PHP?"

Если вы действительно обеспокоены временем вставки MySQL, вы, вероятно, обращаетесь к симптомам, а не к причине.

Например, если ваш PHP / Apache-процесс выполняется после того, как пользователь получает свой HTML-код, ваш процесс PHP / Apache все еще заблокирован в этом запросе. Поскольку он занят, если приходит другой запрос, Apache должен разветвлять другой поток, выделять ему больше памяти, открывать дополнительные подключения к базе данных и т. Д.

Если вы столкнулись с проблемами производительности, вам нужно удалить тяжелую работу с вашего исполнения PHP / Apache. Если у вас много задач очистки, вы сжигаете драгоценные процессы Apache.

Я бы рассмотрел возможность регистрации ваших записей в файле и загрузки crontab в вашу базу данных вне диапазона. Если у вас есть другие сверхмощные задачи, используйте систему обработки очередей / заданий для выполнения работы вне диапазона.

Помимо register_shutdown_function (), не существует встроенных методов для определения того, когда скрипт вышел. Однако Zend Framework имеет несколько перехватов для запуска кода в определенных точках процесса отправки. Для ваших требований наиболее релевантным был бы пост-диспетчерский манипулятор контроллера действия, который происходит сразу после отправки действия, и событие dispatchLoopShutdown для брокера-плагина контроллера.

Вы должны прочитать руководство, чтобы определить, какая из них лучше подходит вам.

EDIT: Я думаю, я не понял полностью. Из этих крючков вы могли бы развить текущий процесс в той или иной форме. PHP имеет несколько способов для вилки процессов, которые вы можете прочитать в руководстве при выполнении программы . Я бы предложил перейти через расширение pcntl – прочитайте это сообщение в блоге, чтобы увидеть пример обработки дочерних процессов forking в фоновом режиме.

Комментарии к блогу этого случайного парня похожи на то, что вы хотите. Если этот трюк заголовка не работает, один из комментариев в этом блоге предлагает exec() использовать отдельный PHP-скрипт для работы в фоновом режиме, если конфигурация вашего веб-хоста позволяет такое.

Это может быть немного хаки для вашего вкуса, но это будет эффективным и простым способом.

Вы можете создать «очередь», управляемую вашей БД по выбору, и сначала сохранить запрос в вашей таблице очередей в базе данных, а затем вывести iframe, который приведет к скрипту, который будет запускать инструкции, которые совпадают с queue_id в вашем база данных.

например:

 <?php mysql_query('INSERT INTO queue ('instructions') VALUES ('something would go here'); echo('<iframe src="/yourapp/execute_queue/id?' . mysql_insert_id() . '" />'); ?> 

и рамка будет делать что-то вроде

например:

 <?php $result = mysql_query('SELECT instructions FROM queue WHERE id = ' . $_GET['id']); // From here, simply execute some instruction based on the "instructions" field, then delete the instruction from the database. ?> 

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

Надеюсь, это по крайней мере указывает на вас в правильном направлении.

Ура!