2016-10-10 74 views
3

我试图用streamedResponse输出进步到Symfony2的我的索引页面模板视图。如何使用StreamedResponse呈现在Symfony2的

下面这段代码确实表明我对API的调用进步,因为它的发生,但我有麻烦呈现在实际视图中的流信息。现在它只是在页面顶部输出纯文本,然后在视图全部完成时渲染视图。

我不想返回最终阵列,直到一切都加载关闭功能,但我似乎无法得到正规树枝模板,而我输出的进度显示。

我一直在使用渲染,但似乎没有真正输出中该视图文件到屏幕上,除非我回到尝试。

public function indexAction($countryCode) 
    { 

    //anywhere from five to fifteen api calls are going to take place 
    foreach ($Widgets as $Widget) { 

     $response = new StreamedResponse(); 

     $curlerUrl = $Widget->getApiUrl() 
      . '?action=returnWidgets' 
      . '&data=' . urlencode(serialize(array(
       'countryCode' => $countryCode 
      ))); 

     $requestStartTime = microtime(true); 
     $curler = $this->get('curler')->curlAUrl($curlerUrl); 
     $curlResult = json_decode($curler['body'], true); 


     if(isset($curlResult['data'])){ 
      //do some processing on the data 
     } 

     $response->setCallback(function() use ($Widget, $executionTime) { 
      flush(); 
      sleep(1); 
      var_dump($Widget->getName()); 
      var_dump($executionTime); 
      flush(); 
     }); 

     $response->send(); 
    } 
    //rest of indexAction with a return statement 

    return array(
     //all the vars my template will need  
    ); 
} 

此外,另一个重要的细节是,我试图渲染所有的树枝,似乎有一些有趣的问题。

+0

这15个请求是顺序吗? – Rhono

+0

@罗诺,是的,他们是顺序的。现在,页面在完成之前不会呈现,因此我试图在每个调用完成时显示进度。 – absentx

回答

0

据我了解,你只有一次机会来输出不同的是,从服务器(PHP /嫩枝)的浏览器,那么它是由JavaScript来做出任何进一步的更改(如更新进度条)。

我推荐使用多卷曲异步执行所有15个请求。这有效地使总请求时间等于最慢的请求,因此您可以更快地为页面提供服务,并且可能无需进度栏。

// Create the multiple cURL handle 
$mh = curl_multi_init(); 
$handles = array(); 
$responses = array(); 

// Create and add the cURL handles to the $mh 
foreach($widgets as $widget) { 
    $ch = $curler->getHandle($widget->getURL()); // Code that returns a cURL handle 
    $handles[] = $ch; 
    curl_multi_add_handle($mh, $ch); 
} 

// Execute the requests 
do { 
    curl_multi_exec($mh, $running); 
    curl_multi_select($mh); 
} while ($running > 0); 

// Get the request content 
foreach($handles as $handle) { 
    $responses[] = curl_multi_getcontent($handle); 

    // Close the handles 
    curl_close($handle); 
} 
curl_multi_close(); 

// Do something with the responses 
// ... 

理想情况下,这将是您的Curler服务的方法。

public function processHandles(array $widgets) 
{ 
    // most of the above 

    return $responses; 
} 
0

您可以实现所有在setCallback方法的逻辑,所以考虑下面的代码:

public function indexAction($countryCode) 
{ 

    $Widgets = []; 

    $response = new StreamedResponse(); 

    $curlerService = $this->get('curler'); 

    $response->setCallback(function() use ($Widgets, $curlerService, $countryCode) { 

     foreach ($Widgets as $Widget) { 

      $curlerUrl = $Widget->getApiUrl() 
       . '?action=returnWidgets' 
       . '&data=' . urlencode(serialize(array(
        'countryCode' => $countryCode 
       ))); 

      $requestStartTime = microtime(true); 
      $curler = $curlerService->curlAUrl($curlerUrl); 
      $curlResult = json_decode($curler['body'], true); 


      if(isset($curlResult['data'])){ 
       //do some processing on the data 
      } 
      flush(); 
      sleep(1); 
      var_dump($Widget->getName()); 
      var_dump((microtime(true) - $requestStartTime)); 
      flush(); 

     } 

    }); 

    // Directly return the streamed response object 
    return $response; 

} 

进一步阅读thisthis文章。

希望这个帮助

+0

嗨@absentx你看看这个答案吗?你有什么想法? – Matteo