В свежем symfony2-проекте (установка как описано Вот), Я хотел бы запустить консольный процесс как часть запроса. Приложение работает на «стандартной» коробке Ubuntu 14.04 с nginx + php-fpm.
Рассмотрим этот код контроллера:
<?php
namespace AppBundle\Controller;use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Process\Process;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class CommandController extends Controller
{
/**
* @Route("/command")
* @return JsonResponse
*/
public function commandAction ()
{
$rootDir = $this->get('kernel')->getRootDir();
$env = $this->get('kernel')->getEnvironment();
$commandline = $rootDir . '/console --env=' . $env . ' acme:hello --who jojo'
$process = new Process($commandline);
$process->start();
return new JsonResponse(array('command' => $commandline));
}
}
Когда я отправляю запрос / command, я получаю ожидаемый результат, и процесс начинается, например, Я вижу это с htop и тому подобное.
Когда я повторяю этот запрос, я получаю ожидаемый результат, но процесс, который нужно запустить, нигде не отображается. Нет ошибок, нет ничего.
Перезапуск службы php5-fpm позволяет мне снова запустить один процесс через запрос, поэтому в основном мне нужно перезапускать весь php-сервис после каждого запроса. Так что, возможно, это не проблема программирования. Но я пока не знаю, честно.
Проблема была описана на stackoverflow раньше, Symfony2 — процесс запуска команды symfony2, но обходной путь с exec не работает для меня.
У кого-нибудь есть подсказка?
С уважением,
Jojo
Ваш процесс, скорее всего, умирает, прежде чем ему удастся завершить свою работу. Это потому, что PHP убивает его после того, как ответ возвращается клиенту и соединение закрывается.
Process::start()
используется для запустить процесс асинхронно. Вам нужно либо wait()
чтобы он закончил или проверил, закончил ли он еще isRunning()
:
$process->start();
$process->wait(function ($type, $buffer) {
// do sth while you wait
});
В качестве альтернативы используйте Process::run()
вместо Process:start()
,
Используйте очереди сообщений, если вы хотите что-то обрабатывать в фоновом режиме.
Других решений пока нет …