2017-05-25 24 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添加更多逻辑,您可能会发现自己容易出现一些无意的行为。