Php Symfony从服务器上的控制器运行命令
我想从控制器中清除缓存。我已经将命令定义为服务并调用它Php Symfony从服务器上的控制器运行命令,php,symfony,symfony-console,Php,Symfony,Symfony Console,我想从控制器中清除缓存。我已经将命令定义为服务并调用它 clear_cache_command_service: class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand calls: - [setContainer, ["@service_container"] ] 在我的控制器中,我有一个表单来选择命令,当选择缓存清除命令时,它将运行: $clearCacheCommand = $t
clear_cache_command_service:
class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
calls:
- [setContainer, ["@service_container"] ]
在我的控制器中,我有一个表单来选择命令,当选择缓存清除命令时,它将运行:
$clearCacheCommand = $this->container->get('clear_cache_command_service');
$clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());
不过,这会运行一段时间,因为它也会使缓存升温(实际上我希望它也会升温)。它也会超时,所以我也需要设置时间限制
有没有办法在浏览器中返回响应,让命令在服务器上运行并完成?我不想让客户一直等它结束 由于
php
是如何同步工作的,所以不可能以“经典”的方式执行,即需要等到命令完成后才能终止并发送响应。这里的解决方案是合并worker
模式。你可以找到一些有用的信息。基本上,您需要将“清除缓存”任务添加到队列中,并让其他进程处理此队列,以便在您的情况下调用clearcache
命令
在这种情况下,symfony中使用的一种常见解决方案是使用,这方面有很多资源:
要在响应后运行命令,您必须在内核上使用侦听器。终止事件。此事件的目的是在响应已送达客户端后执行任务
// send the headers and echo the content
$response->send();
// triggers the kernel.terminate event
$kernel->terminate($request, $response);
我找到了一个方法。这将立即返回响应,并使命令在后台运行。不知道这是多么糟糕的做法
/**
* @Service("background_command_runner")
*/
class BackgroundCommandRunner
{
private $kernelDir;
/**
* @InjectParams({
* "kernelDir" = @Inject("%kernel.root_dir%")
* })
*/
public function __construct($kernelDir)
{
$this->kernelDir = $kernelDir;
}
public function run($cmd)
{
$path = $this->kernelDir . '\console ';
$fullCmd = "php " . $path . $cmd;
if (substr(php_uname(), 0, 7) == "Windows") {
pclose(popen("start /B " . $fullCmd, "r"));
} else {
exec($fullCmd . " >> logs/theme.log &");
}
}
public function clearCache($env = "dev", $warm = true)
{
$toWarm = $warm ? "" : " --no-warmup";
$cmd = "cache:clear " . "--env=" . $env . $toWarm;
$this->run($cmd);
}
}
作为前面提到的RabbitMQ的替代方案,您可以查看JMSJobBundle
我在这里给出了一些代码示例,我以前对类似问题的回答是:kernel.terminate的问题是它会侦听每个请求,当我只在一个地方需要它时,它就没有意义了。另一个问题是为request、response、terminate添加太多事件,我相信这会使应用程序运行缓慢。我可能错了,但每次提出要求都要这个还是没有意义的。这有点老套。它可能会工作(我不确定linux中的“\”目录分隔符),但它不是干净的代码-让我们想象一下,命令名称将更改为
cache:clear now
,或者console
将更改为ezpublish
(事实上,它在ezpublish
cms中以这种方式命名)它将不再工作,然后这些可以添加为上述参数。即便如此,它们也很可能不会改变(尽管我们不应该依赖这一事实,有相当多的项目在部署脚本中的某个地方硬编码了该命令),而且它应该只对Symfony有效。我已经对其进行了更改,以便可以向其添加更多命令。到目前为止,它的工作非常出色。