2017-05-25 48 views
1

我正在嘗試製作一個web應用程序,該應用程序將查明一個或多個電子商務項目是否由其用戶輸入的url(s)中缺貨。這些網址可以用逗號分隔。目前,我在javascript循環中用逗號分隔它們之後,爲每個url對我的一個PHP腳本執行ajax調用。下面是該代碼:針對PHP的多線程ajax調用

function sendRequest(urls) { 

    if (urls.length == 0) { 
     return; 
    } else { 
     var A = urls.split(','); 
     for (var i = 0; i < A.length; i++) { 
      var xmlhttp = new XMLHttpRequest(); 
      xmlhttp.onreadystatechange = function() { 
       if (this.readyState == 4 && this.status == 200) { 
        var result_set = JSON.parse(this.responseText); 
        if (result_set.flag == 1) { 
         insertRow('stock-table', result_set.url, result_set.title); // It populates a table and insert row in it. 
        } 
       } 
      }; 
      xmlhttp.open("GET", "scrapper.php?url=" + A[i], true); 
      xmlhttp.send(); 
     } 
    } 
} 

的scrapper.php是這樣:

<?php 
function get_title($data) 
{ 
    $title = preg_match('/<title[^>]*>(.*?)<\/title>/ims', $data, $matches) ? $matches[1] : null; 
    return $title; 
} 
if (!isset($_SESSION['username'])) { 
    header("Location: index.php"); 
} 
else if (isset($_GET["url"])) { 

    $url = $_GET["url"]; 
    $title = null; 
    $result_set = null; 
    $flag = 0; 
    $file = fopen($url,"r"); 
    if (!$file) { 
     echo "<p>Unable to open remote file.\n"; 
     exit; 
    } 
    while (!feof($file)) { 
     $line = fgets($file, 1024); 
     if ($title == null){ 
      $title = get_title($line); 
     } 
     if (preg_match('/<span[^>]*>Add to Cart/i', 
      $line, $matches, PREG_OFFSET_CAPTURE)) { 
      break; 
     } 
     if (preg_match('/Sold Out|Out of Stock/i', 
      $line, $matches, PREG_OFFSET_CAPTURE)) { 
      $flag = 1; 
      break; 
     } 
    } 
    fclose($file); 

    $result_set = array("flag" => $flag, 
     "url" => $url, 
     "title" => $title 
    ); 

    echo json_encode($result_set); 

} 
?> 

現在的問題是:這個程序需要太多的時間甚至兩個URL。雖然,我從file_get_contents()(甚至更慢)移到這裏(ftp解決方案)。我很少有困惑是我的想法:

  1. 考慮到我的JavaScript,它是像發送一個ajax調用,等待它的響應,然後第二個?
  2. 如果第一點不正確,那麼scrapper.php能夠響應循環中的第二個調用嗎?因爲它正忙於handeling第一次ajax調用計算。
  3. 如果第2點是真的,我怎樣才能讓它在多線程,使得AJAX保持,直到循環結束,scrapper.php激活不同的線程每次調用然後答覆回客戶端發送呼叫一旦線程執行完畢? (如何限制線程池並授予新的Ajax響應,因爲我有200個網址,因此,使200個線程不能成爲最佳解決方案)
  4. 這是一個很好的解決方案嗎?我將所有的URL(大約200)插入到數據庫中,然後獲取所有這些URL進行多線程執行。在這種情況下,我怎樣才能回覆多個線程針對單個Ajax調用的多個結果?

請幫助

回答

0
  1. 號的XMLHttpRequest默認爲異步,這意味着與所述異步將並行執行的每個新的請求。
  2. 完全取決於您如何運行PHP。在典型的設置中 - 並且不太可能會這樣做,您的http服務器將等待線程池中的可用PHP工作線程,或者直接執行PHP二進制文件。無論哪種方式,可以同時執行多個PHP程序。 (想想一個常規網站是如何工作的,你需要能夠一次支持多個用戶)
  3. 不適用
  4. 如果我的理解正確,你只是想處理所有的請求在一個Ajax調用?只需發送請求中所有URL的列表,然後循環服務器端。你目前的做法很好。很可能「慢」性質可歸因於您與遠程URL的連接。

其他一些注意事項:

  • 我會通過它進入fopen,特別是考慮到用戶可以通過簡單地傳遞一個相對路徑,並開始閱讀「私人」文件之前驗證URL。
  • 我想切換回file_get_contents。這幾乎相當於fopen,但爲你做了很多工作。
  • 不知道是否故意的,但我會用較新的const關鍵字,而不是var對XMLHttpRequest的變量在for循環的內部塊。目前,var被提升到功能範圍的頂部,你只是覆蓋它循環的每次迭代。如果您想向XMLHttpRequest添加更多邏輯,您可能會發現自己容易出現一些無意的行爲。