2011-11-16 2 views
3

Можно создать дубликат (?):
php execute a background process
how can I achieve a task that should be done in thread in phpСоздание нового потока в PHP

У меня есть этот PHP скрипт, который занимает немного времени, чтобы обработать. Однако я не хочу, чтобы зритель дождался завершения сценария. Я хочу, чтобы он мог продолжить просмотр и/или закрыть браузер. Но я хочу, чтобы скрипт продолжал работать ... Как я могу это сделать? Есть ли способ создать какой-то поток, который позволит такое?

p.s. Я действительно не хочу перезаписывать сценарий на другом языке и выполнять его через os.

ответ

2

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

У вас есть два варианта здесь:

  1. Split давно работает задача на несколько (более дешевых) подзадач. Поместите их в очередь и сделайте каждый запрос исполнением некоторых из этих подзадач (но не слишком сильно задерживайте вывод на клиенте).

  2. Если вы не можете разделить эту большую задачу, просто установите для нее задание cron. Таким образом, пользователи не могут быть замечены задержкой, так как долго работающая задача выполняется системой.

    Еще одно замечание: PHP-скрипт имеет (переопределяемое) ограничение времени, которое останавливает выполнение через заданное количество секунд. Задачи, выполняемые через cron, не претерпевают этого предела.

0

Вы можете использовать Ajax,

вызов скрипт, который занимает много времени, чтобы выполнить с помощью AJAX, и когда результат будет готов, показать его пользователю

+1

Пользователь может перейти на другую страницу или закрыть браузер, тогда выполнение скрипта будет прервано/потеряно –

+0

Точно ... Вот почему я разместил свой вопрос о stackoverflow ... – JohnRoach

+0

@VladislavZorov: поскольку AJAX (JS) работает на клиента. Пользователь может прервать вызов (или вообще отключить JS), запрос может быть тайм-аут, если операция длительная, и т. Д. И вопрос был не в AJAX, а в том, что он может запускать операцию PHP в фоновом режиме. Эти два не следует путать. – kraxor

0

OK, если так и может делать другую вещь , u может поддерживать таблицу для записи состояния выполнения сценария, , затем написать код JavaScript, который выполняет ajax-вызов, чтобы проверить записанный статус, и если его истинный затем извлекает данные, а затем показывает их пользователю.

5

Если вы можете запустить свой скрипт из CLI, вы можете «разветвить» его в фоновом режиме с помощью Сценарий ваш веб-сервер обслуживает по телефону что-то вроде:

exec('php your_script.php > /dev/null &'); 

Это позволит страницу, чтобы закончить загрузку, но держать your_script.php работает.

+0

Могу ли я использовать $ _GET для отправки данных в свой скрипт по вашему пути? Образец будет выглядеть следующим образом: exec ('php my_script.php? Somevalues>/dev/null &') – JohnRoach

+1

@JohnRoach 'exec' будет запускать команду в операционной системе. Таким образом, вы должны передавать параметры таким образом, здесь не задействован HTTP (GET, POST и т. Д. - это методы HTTP). [PHP: использование командной строки] (http://php.net/manual/en/features.commandline.php) – kapa

2

Насколько я знаю, PHP не предлагает ничего для выполнения таких задач.

Одно из работающих (хотя и уродливое) решение - создать веб-службу SOAP и вызывать ее из вашего сценария с расширенным SoapClient, переопределяя параметр «$ OneWay» (http://www.php.net/manual/en/soapclient. dorequest.php).

class AsyncSoapClient extends SoapClient { 
     function __construct($wsdl, $options) { 
     parent::__construct($wsdl, $options); 
     } 

     function __doRequest($request, $location, $action, $version, $oneWay = TRUE) { 
     return parent::__doRequest($request, $location, $action, $version, TRUE); 
     } 
    } 

    $client = new AsyncSoapClient(
     NULL, 
     array(
     'location' => $location, 
     'uri'  => $uri 
    ) 
    ); 

    $client->invokeMethodOnServer($yourParameters); 

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

+0

Вы сказали, что это был уродливый способ, почему это так? Кажется, ваше решение именно то, что я хочу. – JohnRoach

+0

Было бы более естественно использовать пул событий или другую тему для таких целей. Это решение работает, хотя вам нужно создать SOAP-сервер, который принимает запрос от клиента, реализовать SOAP-клиент oneway и т. Д. ... – ioseb

Смежные вопросы