Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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 всегда запускается и может запускаться без каких-либо перерывов.

Ответ 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]";

?>