D4V1D D4V1D - 1 year ago 167
PHP Question

How to call Symfony2 console command within controller and have streamed output?

So I have a basic requirement: I need to call a Symfony2's custom console command from a controller (the script is also called by a CRON job but I want it to be callable from a web-browser).

I followed this tutorial to make it work and here it is:


namespace AppBundle\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class TacheController extends Controller
* @Route("/admin/taches/facebook", name="admin_tache_facebook")
* @return Response
public function facebookAction(Request $request)
ini_set('max_execution_time', -1);
$kernel = $this->get('kernel');
$application = new Application($kernel);

$input = new ArrayInput(array(
'command' => 'nrv:fetch:facebook',
// You can use NullOutput() if you don't need the output
$output = new BufferedOutput();
$application->run($input, $output);

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

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

However, the console command is quite long to run (~2mn) and therefore, the page hangs for that time until it displays all the output from the command.

My goal is to have the output as it is displayed in the console like when using the web console with
. I thought of the use of
but I don't know how to use them in this context.

Is what I'm trying to achieve even possible? How can I make it so?


As per the answer provided by @MichałSznurawa, I had to extend
and implements
method. Here it is:


namespace AppBundle\Console;

use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\StreamedResponse;

class StreamedOutput extends BufferedOutput
public function doWrite($message, $newline)
$response = new StreamedResponse();
$response->setCallback(function() use($message) {
echo $message;


And amend the controller as per the following:

$output = new StreamedOutput();

The result is the page streaming the output of the command as soon as it get executed (instead of waiting for it to finish).

Answer Source

You will have to implement own output class and inject it instead of BufferedOutput. You can extend abstract class \Symfony\Component\Console\Output\Output or implement interface vendor/symfony/symfony/src/Symfony/Component/Console/Output/OutputInterface.php:20.

Your implementation should be streaming responses like described here: http://symfony.com/doc/current/components/http_foundation/introduction.html#streaming-a-response instead of waiting for end of execution of command and sending back all output together. That will work of course only if your command prints something during an execution.