Php 如何在控制器内调用Symfony2控制台命令并进行流式输出?

Php 如何在控制器内调用Symfony2控制台命令并进行流式输出?,php,symfony,console,output,command-line-interface,Php,Symfony,Console,Output,Command Line Interface,所以我有一个基本要求:我需要从控制器调用Symfony2的定制控制台命令(CRON作业也会调用脚本,但我希望它可以从web浏览器调用) 我遵循了这一点,让它发挥作用,现在是: <?php namespace AppBundle\Controller\Admin; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfo

所以我有一个基本要求:我需要从控制器调用Symfony2的定制控制台命令(CRON作业也会调用脚本,但我希望它可以从web浏览器调用)

我遵循了这一点,让它发挥作用,现在是:

<?php

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);
        $application->setAutoExit(false);

        $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);
    }
}
<?php

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;
            flush();
        });

        $response->send();
    }
}
并根据以下内容修改控制器:

$output = new StreamedOutput();

结果是命令一执行(而不是等待命令完成),页面就流式传输命令的输出。

您必须实现自己的输出类,并注入它,而不是BufferedOutput。您可以扩展抽象类
\Symfony\Component\Console\Output\Output
或实现接口
vendor/Symfony/Symfony/src/Symfony/Component/Console/Output/OutputInterface.php:20


您的实现应该是如下所述的流式响应:而不是等待命令执行结束并一起发送所有输出。当然,只有当您的命令在执行过程中打印某些内容时,这才有效。

我是否理解您的意思:您是否试图使用webconsole从命令行调用一个应运行命令的控制器?如果我不够清楚,请原谅:我想通过运行Symfony2控制台命令的特定URL访问控制器。但是,我希望控制台的输出立即显示给用户,而不是等待命令完成后才立即显示所有内容。@D4V1D我尝试了您的示例,但它不会一个接一个地打印消息。所有的信息一次就被丢弃了。你介意分享一个简单的工作示例吗?流式传输
你好
世界
的东西。也许在。