加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 如何在Symfony2应用程序的控制器中执行命令,并在Twig模板

发布时间:2020-12-13 16:55:55 所属栏目:PHP教程 来源:网络整理
导读:我需要在Symfony2应用程序的控制器中执行一个持久的命令,并实时返回给用户终端的输出. 我读过这个: http://symfony.com/doc/current/components/process.html#getting-real-time-process-output 我无法弄清楚如何在Twig模板中实时打印终端输出. 编辑: 感谢
我需要在Symfony2应用程序的控制器中执行一个持久的命令,并实时返回给用户终端的输出.

我读过这个:

http://symfony.com/doc/current/components/process.html#getting-real-time-process-output

我无法弄清楚如何在Twig模板中实时打印终端输出.

编辑:
感谢Matteo的代码和用户评论,最终的实现是:

/**
 * @Route("/genera-xxx-r",name="commission_generate_r_xxx")
 * @Method({"GET"})
 */
public function generateRXXXsAction()
{
    //remove time constraints if your script last very long
    set_time_limit(0);        

    $rFolderPath = $this->container->getParameter('xxx_settings')['r_setting_folder_path'];
    $script = 'R --slave -f ' . $rFolderPath . 'main.R';

    $response = new StreamedResponse();
    $process = new Process($script);
    $response->setCallback(function() use ($process) {
        $process->run(function ($type,$buffer) {
            //if you don't want to render a template,please refer to the @Matteo's reply
            echo $this->renderView('AppBundle:Commission:_process.html.twig',array(
                    'type' => $type,'buffer' => $buffer
                ));
            //according to @Ilmari Karonen a flush call could fix some buffering issues
            flush();
        });
    });
    $response->setStatusCode(200);
    return $response;
}

解决方法

如果您需要启动一个简单的shell脚本并捕获输出,则可以将 StreamedResponse与您发布的Process回调结合使用.

例如,假设您有一个非常简单的bash脚本,如下所示:

loop.sh

for i in {1..500}
do
   echo "Welcome $i times"
done

您可以执行以下操作:

/**
 * @Route("/process",name="_processaction")
 */
public function processAction()
{
    // If your script take a very long time:
    // set_time_limit(0);
    $script='/path-script/.../loop.sh';
    $process = new Process($script);

    $response->setCallback(function() use ($process) {
        $process->run(function ($type,$buffer) {
            if (Process::ERR === $type) {
                echo 'ERR > '.$buffer;
            } else {
                echo 'OUT > '.$buffer;
                echo '<br>';
            }
        });
    });
    $response->setStatusCode(200);
    return $response;
}

并且取决于缓冲区长度,您可以输出如下:

.....
OUT > Welcome 40 times Welcome 41 times 
OUT > Welcome 42 times Welcome 43 times 
OUT > Welcome 44 times Welcome 45 times 
OUT > Welcome 46 times Welcome 47 times 
OUT > Welcome 48 times 
OUT > Welcome 49 times Welcome 50 times 
OUT > Welcome 51 times Welcome 52 times 
OUT > Welcome 53 times 
.....

您可以使用渲染控制器将其包装在页面的一部分中,例如:

<div id="process">
    {{ render(controller(
        'AcmeDemoBundle:Test:processAction'
    )) }}
</div>

更多信息here

希望这有帮助

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读