Bu örneğimizde, konsol komutunu controller içinden çağırıp, çıktısını tek tek ekranda görüntüleyeceğiz. Bunun için symfony içindeki StreamedResponse class'ını ve kendi yazacağımız class'ı kullanacağız.


SayHelloCommand


namespace Football\FrontendBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class SayHelloCommand extends Command
{
protected function configure()
{
$this
->setName('say:hello')
->addOption('name', null, InputOption::VALUE_REQUIRED)
->addOption('iteration', null, InputOption::VALUE_REQUIRED);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
for ($i = 1; $i <= $input->getOption('iteration'); $i++) {
$output->writeln(sprintf('%d: Hello %s', $i, $input->getOption('name')));

sleep(1);
}
}
}

services:
football_frontend.command.say_hello:
class: Football\FrontendBundle\Command\SayHelloCommand
tags:
- { name: console.command }

Konsol komutunun test çıktısı.


football$ bin/console say:hello --name=Inanzzz --iteration=5
1: Hello Inanzzz
2: Hello Inanzzz
3: Hello Inanzzz
4: Hello Inanzzz
5: Hello Inanzzz

DefaultController


namespace Football\FrontendBundle\Controller;

use Football\FrontendBundle\Command\SayHelloCommand;
use Football\FrontendBundle\Service\StreamedOutput;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

/**
* @Route("", service="football_frontend.controller.default")
*/
class DefaultController
{
private $sayHelloCommand;

public function __construct(
SayHelloCommand $sayHelloCommand
) {
$this->sayHelloCommand = $sayHelloCommand;
}

/**
* @Method({"GET"})
* @Route("")
*
* @return Response
*/
public function streamAction()
{
$response = new StreamedResponse(function() {
$input = new ArrayInput([
'--name' => 'Inanzzz',
'--iteration' => 5,
]);
$input->setInteractive(false);

$output = new StreamedOutput(fopen('php://stdout', 'w'));

$this->sayHelloCommand->run($input, $output);
});

return $response;
}
}

services:
football_frontend.controller.default:
class: Football\FrontendBundle\Controller\DefaultController
arguments:
- '@football_frontend.command.say_hello'

StreamedOutput class


namespace Football\FrontendBundle\Service;

use RuntimeException;
use Symfony\Component\Console\Output\StreamOutput;

class StreamedOutput extends StreamOutput
{
protected function doWrite($message, $newline)
{
if (
false === @fwrite($this->getStream(), $message) ||
(
$newline &&
(false === @fwrite($this->getStream(), PHP_EOL))
)
) {
throw new RuntimeException('Unable to write output.');
}

echo $message;

ob_flush();
flush();
}
}

Test


Eğer uygulamanızın ana sayfasına giderseniz, sonucun ekranda her 1 saniyede bir görüntüleneceğini göreceksiniz.


1: Hello Inanzzz2: Hello Inanzzz3: Hello Inanzzz4: Hello Inanzzz5: Hello Inanzzz