Как сбросить данные в php и отключить пользователя, но сохранить скрипт - PullRequest
5 голосов
/ 16 мая 2010

Это вопрос с подвохом, когда я разрабатывал php + ajax-приложение, у меня возникли некоторые длинные запросы, с ними все в порядке, но они могли бы быть выполнены в фоновом режиме.

Я знаю, что есть способ просто отправить ответ пользователю, передавая реальную обработку другому процессу с помощью exec (), однако мне это не подходит, это может привести к эксплойтам, и это не практично совместим с виртуальными серверами и кроссплатформенностью.

PHP предлагает функции ob_ *, хотя они помогают очищать кеш, но пользователь будет оставаться на связи до запуска скрипта.

Мне интересно, есть ли альтернатива exec для поддержания работы скрипта после отправки данных пользователю и закрытия соединения / потока с помощью apache, или менее "грязного" способа обработки данных, отправляемых в другой скрипт.

Ответы [ 4 ]

2 голосов
/ 16 мая 2010

Я использую на своих сайтах Gearman .

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

На стороне веб-приложения я просто делаю $GEARMAN->doBackground("task_name","task_data");, а затем задача отправляется рабочему, и выполнение немедленно возвращается к сценарию.

Это гораздо безопаснее, чем делать exec, потому что задача gearman выполняется как функция PHP.

1 голос
/ 18 мая 2010

После некоторых исследований я нашел 3 ответа на этот вопрос:

  1. Выполните ajax-запрос с низким значением времени ожидания, как только истечет время ожидания, JS перейдет к следующему шагу, в то время как php в фоновом режиме с включенным ignore_user_abort продолжит обработку.

  2. Разделяет медленные процессы от сценария, который напрямую отвечает пользователю, который выполняет немедленный или частичный ответ (если возможно, в зависимости от случая), сохраняя переменные медленного процесса в _SESSION или базе данных, отправляя работник по cURL с низким значением времени ожидания ИЛИ с задачей cron для вызова работников.

  3. Используйте Gearman.

0 голосов
/ 18 мая 2010

У меня есть класс PHP, который является демоном POSIX. Я запускаю его, и по сути сценарий имеет

while(1)
{
 // run task
}

Вы можете помещать вызовы базы данных и все в цикле - он также реагирует на сигналы POSIX - я обычно устанавливаю его в спящий режим на 120 секунд, а затем снова запускаю. Я использую это вместе с небольшим столом, который является моей очередью. Поэтому вместо использования смертельного exec() я могу использовать более безопасный подготовленный оператор для вставки идентификатора в мою таблицу очередей, который фоновый скрипт будет перехватывать в течение следующих 30 секунд.

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

edit Я не хочу публиковать весь сценарий, но могу, если кто-то захочет,

0 голосов
/ 16 мая 2010

В PHP для этого есть функция ignore_user_abort.

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

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