我需要在PHP中处理一个非常长的运行进程(grepping大文本文件并返回匹配的行)。当我们从命令行运行平均查询时,该过程可能需要10-15m。
我想在PHP / jQuery中实现,我开始查询,然后在回来时显示增量结果。
我实现了一些接近的东西,我有一个ajax调用进行搜索(工作正常),并且有一个定期的定时器函数运行调用类中的第二个方法来获得结果。但是,我意识到第二次调用会真正创建一个新的类实例,所以$ this->当前在主查询和期间更新计时器之间是不同的。
这是我正在尝试的javascript(单击表单按钮时我正在将其踢掉):
<script>
function update_status(data) {
alert(data);
jQuery.each(data, function(key, val) {
if ( key == "progress" )
$("#progressbar").progressbar({ value: val });
});
}
function progress_setup() {
setInterval(function() {
jQuery.ajax({
type:'POST',
dataType:'json',
complete:function(XMLHttpRequest, textStatus){
update_status(textStatus)
},
url:'<?php echo url_for("@grep_status"); ?>'
})},
2000);
}
function grep(elements) {
jQuery.ajax({
type:'POST',
dataType:'html',
data:jQuery(elements).serialize(),
success:function(data, textStatus){jQuery('#results').html(data);},
beforeSend:function(XMLHttpRequest){progress_setup()},
url:'/grep'});
}
</script>
但是,这似乎不是正确的轨道。核心问题似乎是:
TIA 麦克
答案 0 :(得分:1)
您必须使用数据库或文件共享操作状态。然后在/grep
操作中,您定期在数据库或文件中写入状态(更新状态)。
然后你需要另一个脚本(如/grep_state
)来读取状态并将其返回给客户端。
您不能做的是使用PHP对象实例共享状态,因为它的范围仅限于单个请求。你必须坚持国家。
另一个问题可能是由于网络服务器或浏览器的请求超时,您的长时间运行任务终止。我要么以CLI模式运行脚本(与webserver / request分离),要么编写一个作为守护进程运行的简单作业调度程序。
守护进程从套接字(或与其他进程通信的任何其他方式)获取参数,并使用您的worker-script启动php-CLI。该状态也使用文件或数据库共享。
答案 1 :(得分:0)
似乎最简单的事情就是在PHP中拆分任务并将某种标志发送回客户端应用程序以告知它何时完成。
也许:
虽然这不会给您一个完美的进度更新,但它会指示您搜索文件的距离。
我认为关键是使用允许您限制/过滤查询结果的参数来设置服务器。
答案 2 :(得分:0)
您可以尝试提前刷新输出 - 但这会根据您的服务器设置而有所不同。例如:
// Script starts, does first block of program
echo "1";
flush();
// Second block starts and finishes
echo "2";
flush();
// Etc...
每个块完成后,刷新响应。