2015-05-18 1 views
1

Встроенный веб-сервер PHP, похоже, не правильно обрабатывает фоновые процессы shell_exec(); запрос зависает, пока фоновый процесс не будет завершен, даже если он явно помещен в фоновом режиме с &.Запуск фонового процесса с помощью shell_exec с встроенного веб-сервера PHP

Пример:

$ ls 
runit.php 
$ cat runit.php 
<?php 
echo "Here we are\n"; 
shell_exec("sleep 5 &"); 
echo "and the command is done\n"; 
?> 
$ php -S localhost:7891 
PHP 5.5.9-1ubuntu4.9 Development Server started at Mon May 18 19:20:12 2015 
Listening on http://localhost:7891 
Press Ctrl-C to quit. 

, а затем в другой оболочке:

$ GET http://localhost:7891/runit.php 
(...waits five seconds...) 
Here we are 
and the command is done 

Это не должно произойти, и на самом деле не так, если использовать производственно-класса веб-сервер. Есть ли способ обойти это?

. (Примечание: это не проблема смыва Добавление flush() после первого эхо-сигнала, не делает это произойдет, и запрос все еще висит, пока фоновый процесс не будет завершен.)

ответ

1

Это acknowledged as a bug by PHP, but won't be fixed in the built-in webserver. Тем не менее, отчет об ошибке также предлагает обходное решение; установите правильный ответ , а затем получающий браузер закроет запрос на стороне клиента после получения большого количества данных, тем самым обойдя проблему.

-1

ваши варианты:

1) Используйте отдельный поток для запуска процессов

<?php 
for ($i = 1; $i <= 5; ++$i) { 
     $pid = pcntl_fork(); 

     if (!$pid) { 
      sleep(1); 
      print "In child $i\n"; 
      exit($i); 
     } 
    } 

    while (pcntl_waitpid(0, $status) != -1) { 
     $status = pcntl_wexitstatus($status); 
     echo "Child $status completed\n"; 
    } 
?> 

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

shell_exec('sleep 5 > /dev/null 2>/dev/null &');

+0

К сожалению, ни один подход не работает. Я хочу, чтобы PHP-запрос возвращался немедленно, и фоновый процесс для продолжения работы после запроса PHP вернулся. Переадресация stdout и stderr на/dev/null ничего не меняет (запрос все еще занимает 5 секунд), и fork() не работает, боюсь. Они могут работать на «правильном» веб-сервере, но не на встроенном сервере PHP. – sil

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