来自服务器控制器的 Symfony 运行 命令
Symfony run command from controller on the server
我想清除控制器的缓存。我已将命令定义为服务并调用它。
clear_cache_command_service:
class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
calls:
- [setContainer, ["@service_container"] ]
In my controller I have a form to choose a command, and when the cache-clearing command is chosen it 运行s:
$clearCacheCommand = $this->container->get('clear_cache_command_service');
$clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());
这 运行 会持续一段时间,因为它还会预热缓存(我实际上希望它也预热缓存)。它也会超时,所以我也需要 set_time_limit
它。
有没有办法在浏览器中 return 响应并让命令 运行 在服务器上完成?我不希望客户继续等待它完成。
由于 php
的工作方式 - 同步 - 不可能以 "classic" 方式执行,您需要等到命令完成才能终止并发送响应。这里的解决方案是合并 worker
模式。您可以找到一些有用的信息 here。基本上你需要将 "clear cache" 任务添加到队列并让其他进程处理这个队列,所以在你的情况下调用 clear cache
命令。
symfony 在这种情况下使用的一个常见解决方案是使用 RabbitMQ,有很多关于它的资源:
对于响应后的 运行 命令,您必须在 kernel.terminate 事件上使用侦听器。此事件的目的是在已向客户端提供响应后执行任务。
// send the headers and echo the content
$response->send();
// triggers the kernel.terminate event
$kernel->terminate($request, $response);
我找到了一种方法。这将立即 return 响应并在后台运行命令 运行。不确定这是多么糟糕的做法。
/**
* @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
http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation
我在此给出的一些代码示例是我对类似问题的较早回答:
我想清除控制器的缓存。我已将命令定义为服务并调用它。
clear_cache_command_service:
class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
calls:
- [setContainer, ["@service_container"] ]
In my controller I have a form to choose a command, and when the cache-clearing command is chosen it 运行s:
$clearCacheCommand = $this->container->get('clear_cache_command_service');
$clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());
这 运行 会持续一段时间,因为它还会预热缓存(我实际上希望它也预热缓存)。它也会超时,所以我也需要 set_time_limit
它。
有没有办法在浏览器中 return 响应并让命令 运行 在服务器上完成?我不希望客户继续等待它完成。
由于 php
的工作方式 - 同步 - 不可能以 "classic" 方式执行,您需要等到命令完成才能终止并发送响应。这里的解决方案是合并 worker
模式。您可以找到一些有用的信息 here。基本上你需要将 "clear cache" 任务添加到队列并让其他进程处理这个队列,所以在你的情况下调用 clear cache
命令。
symfony 在这种情况下使用的一个常见解决方案是使用 RabbitMQ,有很多关于它的资源:
对于响应后的 运行 命令,您必须在 kernel.terminate 事件上使用侦听器。此事件的目的是在已向客户端提供响应后执行任务。
// send the headers and echo the content
$response->send();
// triggers the kernel.terminate event
$kernel->terminate($request, $response);
我找到了一种方法。这将立即 return 响应并在后台运行命令 运行。不确定这是多么糟糕的做法。
/**
* @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 http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation
我在此给出的一些代码示例是我对类似问题的较早回答: