用户提交表单后,我想渲染一个视图文件,然后我想启动一个后台任务来处理五个MS Excel文件(每个文件最多可能有2000行),但是这样就让用户不要不必等待该过程完成才能查看该页面.任务完成后,我将通过电子邮件通知用户.
我正在使用Symfony Framework 3.我在下面包含了我的代码.它没有做我想要实现的目标.提交表单后,页面仅在整个后台任务完成时加载.
我不确定但是经过google搜索后,我认为kernel.terminate事件在这里很有用.但我似乎无法理解如何使用它.
你能告诉我如何解决这个问题吗?
这是我的代码:
我创建了一个控制台命令:
class GreetCommand extends ContainerAwareCommand {
protected function configure()
{
$this->setName('hello:world');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// My code to execute
}
}
Run Code Online (Sandbox Code Playgroud)
在我的控制器中我有
$process = new Process('ls -lsa');
$process->disableOutput();
$that = $this;
$process->start(function ($type, $buffer) use ($that) {
$command = new GreetCommand();
$command->setContainer($this->container);
$input = new ArrayInput(array());
$output = new NullOutput;
$resultCode = $command->run($input, $output);
});
return $this->render('success.html.php', array('msg' => 'Registraion Successful'));
Run Code Online (Sandbox Code Playgroud)
我已经使用PHP的连接处理功能解决了这个问题.
感谢这篇文章
Den*_*mov 20
异步运行进程
您也可以启动子进程,然后让它以异步方式运行,在您需要时检索主进程中的输出和状态.使用start()方法启动异步进程
因此,要异步启动命令,您应该使用命令创建新进程并启动它
$process = new Process('php bin/console hello:word');
$process->start();
Run Code Online (Sandbox Code Playgroud)
考虑将此更改为完整路径,例如 \usr\bin\php \var\www\html\bin\console hello:word
还有一个很好的bundle cocur/background-process你可以使用它,或者至少阅读文档以了解它是如何工作的.
在控制器中使用:
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
$myVar = new MyObject();
$this->get('event_dispatcher')->addListener(KernelEvents::TERMINATE, function(PostResponseEvent $event) use($myVar) {
//You logic here
$request = $event->getRequest();
$test = $myVar->getMyStuff();
});
Run Code Online (Sandbox Code Playgroud)
但这不是一个好习惯,请阅读有关正常注册事件侦听器的信息
kernel.terminate 事件将在向用户发送响应后调度。
小智 6
我玩游戏有点晚了,但我刚刚使用fromShellCommandLine()方法找到了解决此问题的方法:
use Symfony\Component\Process\Process;
Process::fromShellCommandline('/usr/bin/php /var/www/bin/console hello:world')->start();
Run Code Online (Sandbox Code Playgroud)
这样就可以异步启动新进程/运行命令。
有一个名为AsyncServiceCallBundle的包,它允许您在后台调用服务的方法。
您可以参考此答案以获取有关如何在内部完成的更多详细信息。您需要做的就是调用您的服务的方法,如下所示:
$this->get('krlove.async')->call('service_id', 'method', [$arg1, $arg2]);
Run Code Online (Sandbox Code Playgroud)
小智 5
简单使用 Symfony 进程选项
创建新控制台
来自 Symfony 流程来源:
/**
* Defines options to pass to the underlying proc_open().
*
* @see https://php.net/proc_open for the options supported by PHP.
*
* Enabling the "create_new_console" option allows a subprocess to continue
* to run after the main process exited, on both Windows and *nix
*/
public function setOptions(array $options)
Run Code Online (Sandbox Code Playgroud)
所以让我们这样做:
$process = new Process($cmds);
$process->setOptions(['create_new_console' => true]);
$process->start();
Run Code Online (Sandbox Code Playgroud)