簡體   English   中英

如何在Symfony2應用程序的控制器中執行命令,並在Twig模板中實時打印輸出

[英]How to execute a command within a controller of a Symfony2 application and print in real-time the output in a Twig template

我需要在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>

更多信息在這里

希望這有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM