基本上,我的想法是做某种形式的"实时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 调用中,这是不可能的,您只能编写一次响应并返回它。
在您的情况下,您可以使用flush
或ob_flush
。此命令将强制将输出的数据发送到浏览器,但在某些情况下可以在中间软件(例如nginx)中停止
还有一个问题。在脚本发送数据之前,页面不会触发加载的事件。如此多的 js 脚本将无法正常工作。
在你的情况下,我将制作另一个系统。
- 您的脚本在短时间内从 crontab 运行。
- curl 的所有结果都保存在数据库中。
- Ajax 脚本调用输出最后结果并将其从数据库中删除的 php 后端。
这在任何情况下(大部分)都有效:)
我看到两种方法可以实现你的目标。
- 为每个 cURL 请求执行单独的 AJAX 请求。这样,您就不必"找到棘手的解决方案",一切都会按预期工作
- 使用
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请求的结果,在这种情况下,你需要使用推送方法而不是拉取方法。
要了解有关我在此处使用的功能的更多信息:
- array_push
- array_shift
- window.setInterval
Ajax 对 PHP 脚本的请求的概念是,当你调用 Ajax 时,它会执行请求的 PHP 脚本和发送到 Ajax 的整个响应。
根据您的要求,PHP 脚本不会向 Ajax 调用发送部分响应,而是 PHP 脚本可以一次发送 cUrl 响应的集合。
要解决此问题,您可以执行以下步骤
-
在 PHP 中创建两个操作和两个 Ajax 调用。
-
一个操作将所有 URls 从表发送到第一个 Ajax 调用。
-
获得第一个响应(URL 列表)后,您可以执行系列的 Ajax 调用(在每个获取的 URls 的循环中)。
-
这个 Ajax 调用将请求执行 cURL 的第二个 PHP 脚本以获取响应。
-
然后,将此响应发送回已启动的 Ajax 调用。 然后执行您想对该 cUrl 响应执行的操作。
希望对您有所帮助。