早上好, 我有更新大量数据的脚本(例如3000Lines),我必须向用户显示进度条上的db更新进度或仅显示受影响的行数。 我正在研究PHP codeigniter和AJAX 我有一个想法是使用会话codeigniter在每个Loop上的会话值上存储修改后的变量(递增),并且调用函数将会话变量作为JSON数组,但问题是会话在第一次更新后不会自行更改(例如:从0开始并修改为20,之后所有过程都在20)
我不知道如何更好地解决这个问题。如果你能帮助我,那真的很酷。 谢谢所有
答案 0 :(得分:1)
在脚本完全完成之前,PHP不会输出任何内容,但您可以更改:
ob_implicit_flush(true);
for ($i = 0; $i < ob_get_level(); $i++) {
ob_end_clean();
}
在开始处理数据之前,将它放在PHP脚本中。在处理部分数据时,输出一些东西来告诉AJAX请求进度;例如:
PHP:
$completed_updates = 0;
$last_echoed_progress = 0;
$progress_echo_interval_seconds = 2;
while ($completed_updates < $amount_of_db_updates_to_do) {
do_db_update();
$completed_updates++;
if ($last_echoed_progress + $progress_echo_interval_seconds < time()) {
echo ($completed_updates / $amount_of_db_updates_to_do) * 100;
$last_echoed_progress = time();
}
}
jQuery的.ajax(默认情况下)也不会用数据调用成功函数,直到收到所有数据(即脚本结束),因此创建一个带有事件监听器的自定义XHR对象在脚本仍在运行时接收数据:
JS:
var last_response_length = 0;
$.ajax({
... // All your other settings
xhr: function() {
var xhr = new XMLHttpRequest(); // Create a custom XHR object
xhr.onprogress = function(data) {
var response = data.currentTarget.response, // Get the output
progress = response.slice(last_response_length) | 0; // Remove old output
$( '#progress-bar' ).val(progress); // Update the progress bar
last_response_length = response.length; // Track where the old data is (so they can be removed when new data is received)
};
return xhr; // IMPORTANT! Return the custom XHR for .ajax to use
},
success: function(response) {
$( '#progress-bar' ).val(100); // All done!
}
});
显然修改代码以满足您的需求,并进行一些实验。请记住,默认情况下PHP的执行时间限制为30秒,因此您可能需要在脚本中更改此内容:
set_time_limit(0);
这允许您的脚本(并且只有那个)在没有时间限制的情况下运行。把它放在最顶端。请小心!