Я пытаюсь создать PHP script, у меня закончен script, но для завершения процесса, который он предназначен, требуется всего 10 минут. Это не проблема, однако я полагаю, что мне приходится постоянно загружать страницу, что раздражает. Могу ли я использовать его для запуска процесса, а затем вернуться через 10 минут и просто просмотреть файл журнала, который он сгенерировал?
Ответ 1
Ну, вы можете использовать ignore_user_abort (true)"
Итак, script продолжит работу (следите за продолжительностью script, возможно добавьте " set_time_limit (0)" )
Но предупреждение здесь: вы не сможете остановить script с помощью этих двух строк:
ignore_user_abort(true);
set_time_limit(0);
Кроме того, вы можете напрямую обращаться к серверу и убить процесс там! (Был там, совершил бесконечный цикл, снова и снова называя себя, заставляя сервер заходить в визг остановки, кричал на...)
Ответ 2
Похоже, вы должны иметь очередь и внешний script для обработки очереди.
Например, ваш PHP script должен помещать запись в таблицу базы данных и сразу же возвращаться. Затем, cron, выполняющий каждую минуту, проверяет очередь и разворачивает процесс для каждого задания.
Преимущество в том, что вы не блокируете поток apache в течение 10 минут.
Ответ 3
У меня было много проблем с подобным процессом под окнами; Моя ситуация немного отличалась от того, что меня не волновала реакция "script" - я хотел, чтобы script запускался и разрешал другим запросам страницы проходить, пока он был занят работой.
По какой-то причине; У меня были проблемы с ним, либо навешивая другие запросы, либо время истекает через 60 секунд (оба apache и php были настроены на тайм-аут примерно через 20 минут); Также выясняется, что firefox отключается через 5 минут (по умолчанию), так что после этого момента вы не можете знать, что происходит через браузер, не изменяя настройки в firefox.
Я закончил использование открытого процесса и обработал методы закрытия, чтобы открыть php в режиме cli следующим образом:
pclose(popen("start php myscript.php", "r"));
Это (используя start) откроет процесс php, а затем убьет процесс запуска, запустив php для того, чтобы он работал в течение долгого времени - снова вам нужно было бы убить процесс, чтобы вручную закрыть его. Вам не нужно было устанавливать какие-либо тайм-ауты, и вы могли бы позволить текущей странице, которая его вызвала, продолжить и вывести несколько подробностей.
Единственная проблема заключается в том, что если вам нужно отправить script любые данные, вы либо сделаете это через другой источник, либо передадите его по "командной строке" в качестве параметров; который не настолько безопасен.
Хорошо работает для того, что нам нужно, и гарантирует, что script всегда запускается и может запускаться без каких-либо перерывов.
Ответ 4
Это может быть полезно также: Асинхронная оболочка exec в PHP
Ответ 5
Я думаю, что команда shell_exec - это то, что вы ищете.
Однако он отключается в безопасном режиме.
Справочная статья PHP об этом находится здесь: http://php.net/shell_exec
Здесь есть статья об этом: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
Ответ 6
Существует еще один вариант, который вы можете использовать, запустите script CLI... Он будет работать в фоновом режиме, и вы даже можете запустить его как cronjob, если хотите.
e.g
> #!/usr/bin/php -q
<?php
//process logs
?>
Это может быть настроено как cronjob и будет выполняться без ограничения по времени.... эти примеры относятся к операционной системе на основе unix.
FYI У меня есть php script, работающий с бесконечным циклом, который выполняет некоторую обработку и работает в течение последних 3 месяцев без остановки.
Ответ 7
Вы можете использовать ignore_user_abort()
- таким образом, script будет продолжать работать, даже если вы закроете свой браузер или перейдете к другая страница.
Ответ 8
Подумайте о Gearman
Gearman - это общая структура приложений для ведения нескольких машин или процессов. Это позволяет приложениям завершать задачи параллельно, для обработки баланса нагрузки и для вызова функций между языками. Структура может использоваться в различных приложений, с веб-сайтов высокой доступности до транспорта события репликации базы данных.
Это расширение предоставляет классы для написания клиентов Gearman и работников. - Руководство по исходным php
Официальный веб-сайт Gearman
Ответ 9
В дополнение к ответу 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, хотя есть ошибка / "feature" на "Unix-like систем", что приводит к немедленному выходу libcurl, если значение равно < 1000 мс с ошибкой "cURL Error (28): время ожидания было достигнуто". Объяснение этого поведения:
[...]
Решение состоит в отключении сигналов с использованием CURLOPT_NOSIGNAL
профи
- Не нужно переключать методы (совместимые окна и Linux)
- Не нужно реализовывать обработку подключений через заголовки и буфер (независимо от версии браузера и PHP)
против
- Требуется расширение curl
Ресурсы
Ответ 10
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]";
?>