Фоновые процессы PHP

Я пытаюсь создать PHP-скрипт, у меня завершен скрипт, но для завершения процесса, который он предназначен, требуется всего 10 минут. Это не проблема, однако я полагаю, что мне приходится постоянно загружать страницу, что раздражает. Могу ли я получить его, чтобы начать процесс, а затем вернуться на 10 минут позже и просто просмотреть файл журнала, который он сгенерировал?

Ну, вы можете использовать « ignore_user_abort (true)»

Таким образом, скрипт будет продолжать работать (следить за продолжительностью скрипта, возможно, добавить « set_time_limit (0)»)

Но предупреждение здесь: вы не сможете остановить скрипт с этими двумя строками:

ignore_user_abort(true); set_time_limit(0); 

Кроме того, вы можете напрямую обращаться к серверу и убить там процесс! (Был там, сделал бесконечный цикл, называя себя снова и снова, заставил сервер прийти к визгу, крикнул …)

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

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

Преимущество здесь в том, что вы не блокируете поток apache в течение 10 минут.

У меня было много проблем с подобным процессом под окнами; Моя ситуация немного отличалась от того, что меня не волновала реакция «скрипта» – я хотел, чтобы сценарий начинался и позволял другим запросам страницы проходить, пока он был занят работой.

По какой-то причине; У меня были проблемы с ним, либо навешивая другие запросы, либо время истекает через 60 секунд (оба apache и php были настроены на тайм-аут примерно через 20 минут); Также выясняется, что firefox отключается через 5 минут (по умолчанию), так что после этого момента вы не можете знать, что происходит через браузер, не изменяя настройки в firefox.

Я закончил использование процесса открытым и обработал методы закрытия, чтобы открыть php в режиме cli следующим образом:

pclose(popen("start php myscript.php", "r"));

Это (используя start) откроет процесс php, а затем убьет начало процесса, оставив php работать в течение как можно большего времени – снова вам нужно будет убить процесс, чтобы вручную закрыть его. Вам не нужно было устанавливать какие-либо тайм-ауты, и вы могли бы позволить текущей странице, которая вызвала ее, продолжить и вывести несколько подробностей.

Единственная проблема заключается в том, что если вам нужно отправить скрипту какие-либо данные, вы либо сделаете это через другой источник, либо передадите его по «командной строке» в качестве параметров; который не настолько безопасен.

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

Это может быть полезно, а также: Асинхронная оболочка exec в PHP

Я думаю, что команда shell_exec – это то, что вы ищете.

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

Справочная статья PHP об этом находится здесь: http://php.net/shell_exec

Здесь есть статья об этом: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Существует еще один вариант, который вы можете использовать, запустить CLI скрипта … Он будет работать в фоновом режиме, и вы даже можете запустить его как cronjob, если хотите.

например

 > #!/usr/bin/php -q <?php //process logs ?> 

Это может быть настроено как cronjob и будет выполняться без ограничения по времени. Однако эти примеры относятся к операционной системе, основанной на UNIX.

FYI У меня есть php-скрипт, работающий с бесконечным циклом, который выполняет некоторую обработку и работает в течение последних 3 месяцев без остановок.

Вы можете использовать ignore_user_abort() – таким образом скрипт будет продолжать работать, даже если вы закроете свой браузер или перейдете на другую страницу.

Подумайте о Gearman

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

Это расширение предоставляет классы для написания клиентов и работников Gearman. – Руководство по исходному php

Официальный сайт Gearman

В дополнение к ответу bastiandoeen вы можете комбинировать ignore_user_abort(true); с запросом cUrl .

Поддельный аборт запроса устанавливает низкий CURLOPT_TIMEOUT_MS и продолжает обработку после закрытия соединения:

 function async_curl($background_process=''){ //-------------get curl contents---------------- $ch = curl_init($background_process); curl_setopt_array($ch, array( CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER =>true, CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute CURLOPT_VERBOSE => 1, CURLOPT_HEADER => 1 )); $out = curl_exec($ch); //-------------parse curl contents---------------- //$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); //$header = substr($out, 0, $header_size); //$body = substr($out, $header_size); curl_close($ch); return true; } async_curl('http://example.com/background_process_1.php'); 

NB

Если вы хотите, чтобы cURL был тайм-аут менее чем за одну секунду, вы можете использовать CURLOPT_TIMEOUT_MS, хотя в «Unix-подобных системах» есть ошибка / «функция», что приводит к немедленному отключению libcurl, если значение <1000 мс с ошибкой " cURL Ошибка (28): время ожидания достигнуто ». Объяснение этого поведения:

[…]

Решение состоит в отключении сигналов с использованием CURLOPT_NOSIGNAL

профи

  • Нет необходимости переключать методы (совместимые окна и Linux)
  • Нет необходимости реализовывать обработку подключений через заголовки и буфер (независимо от версии браузера и PHP)

минусы

  • Требуется удлинение скручивания

Ресурсы

Zuk.

Я уверен, что это сработает:

 <?php pclose(popen('php /path/to/file/server.php &')); echo "Server started. [OK]"; ?> 

«&» Важно. Он сообщает оболочке не ждать завершения процесса.

Также вы можете использовать этот код в своем php (как сказал «bastiandoeen»)

 ignore_user_abort(true); set_time_limit(0); 

в команде остановки сервера:

 <?php $output; exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output); echo "Server stopped. [OK]"; ?>