2013-05-20 50 views
3

我試圖通過API運行一個大量的字段值更新,我跑到我的PHP腳本的最大執行時間。異步PHP執行

我分了我的作業分成較小的任務異步運行他們的小作業......

Asynchronous PHP calls?

我發現這個職位,它看起來約權,但評論都有點倒胃口.. 。使用curl來運行外部腳本文件會阻止調用者文件觸發最大執行時間,或者curl是否仍然等待來自服務器的響應並終止我的頁面?

問題的確是:你如何在PHP中執行異步作業?像Ajax一樣。

編輯:: ///

有一個擁有大量的數據行的項目管理工具。 我正在使用此工具API訪問數據行並將其顯示在我的頁面上。 使用我的工具的用戶將使用複選框選擇多行數據,並在框中鍵入新值。 然後用戶將按下「更新行值」按鈕,該按鈕將運行更新腳本。

此更新腳本分項目的數百或數千可能選入的100

組在這一點上我會使用一些異步方法接觸項目管理工具和更新所有100個項目。

因爲當它更新這些項目時,它可能需要很長時間來運行其進程,我需要確保我的原始頁面拆分這些作業不再等待來自該操作的請求,以便我可以引發更多更新項目的請求。並允許我的服務器頁面對我的用戶說:「好吧,更新正在發生,可能需要一段時間,我們會在完成後發送電子郵件。」

$step = 100; 
    $itemCount = GetItemCountByAppId($appId); 
    $loopsRequired = $itemCount/$step;    
    $loopsRequired = ceil($loopsRequired); 

    $process = array(); 

    for($a = 0; $a < $loopsRequired; $a++) 
    { 
     $items = GetItemsByAppId($appId, array( 
      "amount" => $step, 
      "offset" => ($step * $a) 
     )); 

     foreach($items[ "items" ] as $key => $item) 
     { 
      foreach($fieldsGroup as $fieldId => $fieldValues) 
      { 
       $itemId = $item->__attributes[ "item_id" ]; 
       /*array_push($process, array(
        "itemId" => $itemId, 
        "fieldId" => $fieldId, 
       ));*/ 
       UpdateFieldValue($itemId, $fieldId, $fieldValues); 
       // This Update function is actually calling the server and I assume it must be waiting for a response... thus my code times out after 30 secs of execution 
      } 
     } 

     //curl_post_async($url, $params); 
    } 
+3

使用隊列/工作系統! AMQP,ZeroMQ,Gearman等是你的朋友。 – deceze

+1

通過命令行啓動它們爲您提供了一個可行的選項? –

+0

這是需要自動化並且長度可變的東西。有些工作可能最終每次只需要5分鐘的時間......如果我可以將工作分成較小的數量並完成異步工作,那麼一旦操作完成,我就可以簡單地向用戶發送電子郵件......所以,說實話...我不完全確定這是一個可行的解決方案 – Jimmyt1988

回答

0

如果您使用的是PHP-CLI,嘗試Threads,或fork()非線程安全版本。

+0

如果我在新線程中關閉少量工作,這會停止最大執行嗎? – Jimmyt1988

+2

它不會。您需要set_time_limit(0)以便腳本可以無限期地繼續。然而,這背後有一個完整的機制,你如何傳遞消息,如何構建回覆等,只是使用線程或分支進程將不會有太大的幫助。你應該研究像deceze說的工作隊列,否則你最終會自己創建(使用線程或分叉進程)。 –

+0

感謝一大堆..大的幫助。 – Jimmyt1988

1

根據您的實現方式,異步PHP可能用於將Web請求從處理中分離出來,從而將Web請求與處理中的任何超時隔離(但您可以在單個線程中執行相同的操作)。將任務分解爲更小的併發部分會使其運行速度更快嗎?可能不會 - 通常這會延長完成作業的時間長度 - 關於唯一不是這種情況的時間是,當您擁有非常大的處理能力並且可以有效地分配任務時(例如,map-reduce )。 HTTP調用(curl)是一種有效的方式來分發這樣的工作嗎?沒有。還有其他的方法,包括同步和異步消息傳遞,批處理,進程分叉,線程......各有其優點和複雜性 - 我們不知道你想要解決的問題是什麼。

所以即使在我們遇到您的具體問題之前,這看起來並不是一個好策略。

將使用curl運行外部腳本文件防止來電文件觸發

它會在目標服務器上配置任何超時被限制最長執行時間 - 如果這是在同一臺服務器調用腳本,那麼它將是相同的超時。

curl是否仍然等待來自服務器的響應並終止我的頁面?

我不知道你在問什麼 - 這意味着你有沒有告訴我們有關於功能的依賴關係。

這聽起來像你選擇了一個解決方案,現在正在努力使它適合你的問題。

+0

我已將上下文添加到我的帖子中。感謝您的時間 – Jimmyt1988

+0

您的瓶頸很可能是數據庫 - 將工作分解爲並行運行並不會讓它變得更快。在Web服務器之外調用繁重的列表將避免超時問題(http://symcbean.blogspot.co.uk/2010/02/php-and-long-running-processes.html),但有更好的方法 - 例如在用戶與其交互時儘快更新每行,限制UI,以便它們一次不能更新超過100行(並複用查詢)。 – symcbean