Я пытаюсь создать 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
профи
минусы
Ресурсы
время ожидания завивки менее 1000 мс всегда терпит неудачу?
http://www.php.net/manual/en/function.curl-setopt.php#104597
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]"; ?>