2016-10-10 70 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