为每个 cURL 请求返回 AJAX 结果


return AJAX result for each cURL Request

基本上,我的想法是做某种形式的"实时cURL结果"系统,该系统在每个请求执行时都会产生实时结果,例如,我将有一个表格,其中包含需要通过cURL请求访问的网站列表,其中每个cURL响应的结果我需要使用AJAX函数将数据发送回我的页面 我最初调用了该文件执行此请求循环

<?
    foreach($database['table'] as $row) {
       curl_init($row['url']);
       //the rest of the cURL request etc...
       //SEND cURL RESPONSE BACK TO AJAX AFTER EACH ROW!!!
    }
<?

然后,我希望它在发生每个 cURL 响应时返回结果,而不是等待完整脚本完成,然后再一次返回所有响应。

这可能吗?如果是这样,我还会使用正常的 AJAX 请求吗?

这个怎么样?

您将整个过程分解为 3 个

流程 1

将 ajax 请求发送到访问数据库的 php 页,并将 url 列表发送回浏览器页。[简单地回显网址][使用分隔符"|"分隔结果网址。

流程 2

上述进程的 ajax 成功处理程序函数现在将调用一个新的 JavaScript 函数,该函数执行以下操作。

将 URL 列表拆分为一个数组。

流程 3使用另一个 ajax 函数将 url 列表逐个发送到服务器。

这样一次只处理一个 url,结果在处理后立即发回

下面是 JavaScript 中函数调用的原型,代码不是真实的,但您可以大致了解它的工作原理。

function ajaxCall_1()
{
    // get url lsit from server
    .onSuccess{
        process_url(data);
    }
}

function process_url(data){
    var url_array = data.split('|')
    fetch_urls(url_array,0); // sends the first url for processing
}
function fetch_urls(url_array,position){
  if(position < url_array.lenght){ // not exceeding the array count 
    ajax_call2(url_array[position],url_array,position); 
  }
}
function ajaxCall_2(url,url_array,position)
{
    // get url acced by  curl and send back the result
    .onSuccess{
        // do whatever with the data you want
        fetch_urls(url_array,position++) // or position+1 // to fetch the next url
    }
}

在构建该网站表的 php 脚本中,只需一次执行所有 ajax 请求,并在返回时将结果返回到表行中。

您无法

在编写消息时返回消息,除非您正在写入套接字。在对 PHP 脚本的正常 AJAX 调用中,这是不可能的,您只能编写一次响应并返回它。

在您的情况下,您可以使用flushob_flush。此命令将强制将输出的数据发送到浏览器,但在某些情况下可以在中间软件(例如nginx)中停止

还有一个问题。在脚本发送数据之前,页面不会触发加载的事件。如此多的 js 脚本将无法正常工作。

在你的情况下,我将制作另一个系统。

  1. 您的脚本在短时间内从 crontab 运行。
  2. curl 的所有结果都保存在数据库中。
  3. Ajax 脚本调用输出最后结果并将其从数据库中删除的 php 后端。

这在任何情况下(大部分)都有效:)

我看到两种方法可以实现你的目标。

  1. 为每个 cURL 请求执行单独的 AJAX 请求。这样,您就不必"找到棘手的解决方案",一切都会按预期工作
  2. 使用 curl_multi_* 同时执行所有请求,然后批量返回所有数据。这样,您可以打开脚本以解决潜在的加载问题,以防有许多用户同时执行许多请求

我在不同的项目中使用了它们,如果您需要,可以提供有关每个项目的更多详细信息。

好吧,我实际上没有得到你想做的事情,我认为WebSockets会帮助你Web Sockets Tutorail

您可以逐个存储 curl 请求的结果,并通过每 N 秒(假设 5 秒)执行一个请求来检索该结果。

在这一部分中,我们将 curl 请求的输出存储在某处。这里有一些修改的源代码,它正在抓取输出并调用一个函数将其存储在队列中:

//these two lines will be mostly same for all request
//so i put them out of the loop
curl_init($ch); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//these two lines will be mostly same for all request
//so i put them out of the loop
curl_init($ch); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($database['table'] as $row) {
    // set URL and other appropriate options which
    //vaires from request to requeste
    curl_setopt($ch, CURLOPT_URL, $row['url']);
    //grabbing the output in $output
    $output = $curl_exec();
    put_it_to_the_queue($output);
}
curl_exec($ch);

现在put_it_to_the_queue($output)会怎么做?它将输出存储在某个地方,以便其他资源可以从那里获取它们。为了简单起见,让我们把它放在你的会话中。

function put_it_to_the_queue($output) {
    //Or you can store in sql lite or in a file or somewhere else
    array_push($_SESSION['outputs']);
}

问题是客户将如何应对这种不同的情况。

让客户端第一次调用服务器以开始获取 url 并完全忘记这一点。

$.get('start.php');

我们需要获得输出.如何实现这一点?创建另一个 php 页面pull.php,如果队列中有任何东西,它将发送输出。

echo array_shift($_SESSION['outputs']);

这是用于检索输出的客户端代码。在向服务器发送第一个请求后放置此代码。

//delay is in ms
//5 is the value of N seconds 
//we will retrieve the output form
var delay = 5 * 1000;
window.setInterval(function(){
    $.get('pull.php',function(response){
        //do something with the reponse here
        alert(response);
    })
}, delay);

注意

此解决方案并非万无一失。如果你有一个繁重的网站,你需要使用更精确的存储来存储html请求的结果,在这种情况下,你需要使用推送方法而不是拉取方法。

要了解有关我在此处使用的功能的更多信息:

  1. array_push
  2. array_shift
  3. window.setInterval

Ajax 对 PHP 脚本的请求的概念是,当你调用 Ajax 时,它会执行请求的 PHP 脚本和发送到 Ajax 的整个响应。

根据您的要求,PHP 脚本不会向 Ajax 调用发送部分响应,而是 PHP 脚本可以一次发送 cUrl 响应的集合。

要解决此问题,您可以执行以下步骤

  1. 在 PHP 中创建两个操作和两个 Ajax 调用。

  2. 一个操作将所有 URls 从表发送到第一个 Ajax 调用。

  3. 获得第一个响应(URL 列表)后,您可以执行系列的 Ajax 调用(在每个获取的 URls 的循环中)。

  4. 这个 Ajax 调用将请求执行 cURL 的第二个 PHP 脚本以获取响应。

  5. 然后,将此响应发送回已启动的 Ajax 调用。 然后执行您想对该 cUrl 响应执行的操作。

希望对您有所帮助。