WARNING: You are browsing the documentation for Symfony 2.3 which is not maintained anymore. Consider upgrading your projects to Symfony 5.0.

How to Call a Command from a Controller

2.3 version
Unmaintained
2.6

How to Call a Command from a Controller

The Console component documentation covers how to create a console command. This cookbook article covers how to use a console command directly from your controller.

You may have the need to execute some function that is only available in a console command. Usually, you should refactor the command and move some logic into a service that can be reused in the controller. However, when the command is part of a third-party library, you wouldn't want to modify or duplicate their code. Instead, you can execute the command directly.

Caution

In comparison with a direct call from the console, calling a command from a controller has a slight performance impact because of the request stack overhead.

Imagine you want to send spooled Swift Mailer messages by using the swiftmailer:spool:send command. Run this command from inside your controller via:

 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
// 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\StreamOutput;
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
        $output = new StreamOutput(tmpfile(), StreamOutput::VERBOSITY_NORMAL);
        $application->run($input, $output);

        // return the output, don't use if you used NullOutput()
        rewind($output->getStream());
        $content = stream_get_contents($output->getStream());
        fclose($output->getStream());

        // return new Response(""), if you used NullOutput()
        return new Response($content);
    }
}

Showing Colorized Command Output

By telling the StreamOutput it is decorated via the third parameter, it will return the Ansi color-coded content. The SensioLabs AnsiToHtml converter can be used to convert this to colorful HTML.

First, require the package:

1
$ composer require sensiolabs/ansi-to-html

Now, use it in your controller:

 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
// src/AppBundle/Controller/SpoolController.php
namespace AppBundle\Controller;

use SensioLabs\AnsiConverter\AnsiToHtmlConverter;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\HttpFoundation\Response;
// ...

class SpoolController extends Controller
{
    public function sendSpoolAction($messages = 10)
    {
        // ...
        $output = new StreamOutput(tmpfile(), StreamOutput::VERBOSITY_NORMAL, true);
        // ...

        // return the output
        $converter = new AnsiToHtmlConverter();
        rewind($output->getStream());
        $content = stream_get_contents($output->getStream());
        fclose($output->getStream());

        return new Response($converter->convert($content));
    }
}

The AnsiToHtmlConverter can also be registered as a Twig Extension, and supports optional themes.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.