如何从控制器中调用一个命令

3.4 版本
维护中的版本

Console组件文档 涵盖了如何创建控制台命令。本文主打如何直接在你的控制器中使用console命令。

你可能会有“要去执行一些 [仅在命令行中可用] 的功能”之需求。通常,你应该重构命令,转移其中的逻辑到服务中,以便在controller中使用。但是,当命令是第三方类库的一部分时,你并不希望去修改或复制他们的代码。而应该直接执行这些命令。

相比从控制台直接调用,从controller中调用命令,会因为request stack开销而对性能小有冲击。

设想你需要通过 使用 swiftmailer:spool:send 命令 来滚动发送一个Swift Mailer信息。通过以下代码,可在控制器内运行此代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// src/AppBundle/Controller/SpoolController.php
namespace AppBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
 
class SpoolController extends Controller
{
    public function sendSpoolAction($messages = 10)
    {
        $kernel = $this->get('kernel');
        $application = new Application($kernel);
        $application->setAutoExit(false);
 
        $input = new ArrayInput(array(
           'command' => 'swiftmailer:spool:send',
           '--message-limit' => $messages,
        ));
        // You can use NullOutput() if you don't need the output
        // 如果不需要输出,请使用NullOutput()
        $output = new BufferedOutput();
        $application->run($input, $output);
 
        // return the output, don't use if you used NullOutput()
        // 返回output,若使用了NullOutput()则不要这么用
        $content = $output->fetch();
 
        // return new Response(""), if you used NullOutput()
        // 如果使用了NullOutput(),返回的是一个全新响应("")。
        return new Response($content);
    }
}

显示带有颜色的命令行输出 

通过告之 BufferedOutput 它需要通过第二个参数来进行装饰,即可返回Ansi标准的带颜色内容。SensioLabs AnsiToHtml converter 可用于将这个转换成带颜色的HTML。

首先,安装package:

1
$  composer require sensiolabs/ansi-to-html

现在是你的控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/AppBundle/Controller/SpoolController.php
namespace AppBundle\Controller;
 
use SensioLabs\AnsiConverter\AnsiToHtmlConverter;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\Response;
// ...
 
class SpoolController extends Controller
{
    public function sendSpoolAction($messages = 10)
    {
        // ...
        $output = new BufferedOutput(
            OutputInterface::VERBOSITY_NORMAL,
            true // true for decorated / true就是要装饰
        );
        // ...
 
        // return the output / 返回output
        $converter = new AnsiToHtmlConverter();
        $content = $output->fetch();
 
        return new Response($converter->convert($content));
    }
}

AnsiToHtmlConverter 也可以 作为一个 Twig Extension 来注册,并且支持可选的主题。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)