PHP: как вернуть информацию в сценарий ожидания и продолжить обработку - PullRequest
6 голосов
/ 23 сентября 2008

Предположим, что есть два сценария Requester.php и Provider.php, а Requester требует обработки от поставщика и отправляет ему http-запрос (Provider.php? Data = "data"). В этой ситуации провайдер быстро находит ответ, но для поддержания системы необходимо выполнять различные обновления по всей базе данных. Есть ли способ немедленно вернуть значение реквестеру, а затем продолжить обработку в провайдере.

Код Psuedo

Provider.php 
{
   $answer = getAnswer($_GET['data']);
   echo $answer;
   //SIGNAL TO REQUESTER THAT WE ARE FINISHED
   processDBUpdates();
   return;
}

Ответы [ 7 ]

2 голосов
/ 23 сентября 2008

Я использую этот код для запуска процесса в фоновом режиме (работает в Linux).

Процесс выполняется с перенаправленным выводом в файл.

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

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

2 голосов
/ 23 сентября 2008

Вы можете очистить выходной буфер с помощью команды flush ().
Прочитайте комментарии в руководстве по PHP для получения дополнительной информации

1 голос
/ 23 сентября 2008

В основном вы хотите дать сигнал об окончании 1 процесса (возврат к исходному Requester.php) и запустить новый процесс (финиш Provider.php). Вероятно, есть более элегантный способ осуществить это, но я справился с этим несколькими способами. Все они в основном приводят к выполнению команды, чтобы отделить второй процесс.

добавление следующего > /dev/null 2>&1 & в конец вашей команды позволит ей работать в фоновом режиме, не препятствуя фактическому выполнению вашего текущего сценария

Вам может подойти что-то вроде следующего:

exec("wget -O - \"$url\" > /dev/null 2>&1 &"); 

- хотя вы также можете сделать это как PHP-процесс командной строки.

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

1 голос
/ 23 сентября 2008

Я думаю, что вам нужно, чтобы провайдер отправил данные (обязательно сбросить), а затем в реквестере используйте fopen / fread, чтобы прочитать ожидаемый объем данных, чтобы вы могли разорвать соединение с провайдером. и продолжай. Если вы не укажете ожидаемый объем данных, я бы подумал, что инициатор запроса будет сидеть там и ждать, пока провайдер закроет соединение, что, вероятно, не произойдет до конца его выполнения (т. Е. Вся вторичная интенсивная работа задачи выполнены). Вам нужно попробовать несколько POC.

Удачи.

0 голосов
/ 03 июля 2014

Вы можете запустить другой процесс php в Provider.php, используя pcntl_fork ()

Provider.php 
{
    // Fork process
    $pid = pcntl_fork();

    // You are now running both a daemon process and the parent process
    // through the rest of the code below

    if ($pid > 0) {
        // PARENT Process
        $answer = getAnswer($_GET['data']);
        echo $answer;    
        //SIGNAL TO REQUESTER THAT WE ARE FINISHED
        return;
    }

    if ($pid == 0) {
        // DAEMON Process
        processDBUpdates();
        return;
    }

    // If you get here the daemon process failed to start
    handleDaemonErrorCondition();
    return;

}
0 голосов
/ 03 июля 2009

Я собираюсь на конечности здесь, но, возможно, вам следует попробовать cURL или использовать сокет для обновления запрашивающей стороны?

0 голосов
/ 23 сентября 2008

Разделите провайдера на две части: ProviderCore и ProviderInterface. В ProviderInterface просто выполните «быструю и простую» часть, а также сохраните флаг в базе данных, что последний запрос еще не обработан. Запустите ProviderCore как задание cron, которое ищет этот флаг и завершает обработку. Если ничего не поделаешь, ProviderCore завершится и попытается (скажем) через 2 минуты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...