在页面上,我有按钮来启动和取消要在服务器端以PHP执行的任务。当这些PHP任务正在运行时,用户无法离开页面,它只会挂起,直到作业完成。我试图找到导致同步行为的原因。
Jquery的:
$(document).ready(function()
{
var id = 0;
$('#tool-execute-btn').click(function()
{
// Pull data from page
var last_response_len = false;
$.ajax(
{
xhrFields:
{
onprogress: function(e)
{
var this_response, response = e.currentTarget.response;
if(last_response_len === false)
{
this_response = response;
last_response_len = response.length;
}
else
{
this_response = response.substring(last_response_len);
last_response_len = response.length;
}
// Get the data from the stream (backend php)
$('#tool-output-area').append(this_response + '<br>');
}
},
method: 'POST',
url: 'run-tool.php', // See block below
data:
{
// Data from page
}
}) // ... Continue
后台处理PHP页面:
/* Setup the page so I can stream the content
* line by line back to the user */
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
/* Set Maximum Execution Time By Plan */
ini_set('max_execution_time', getMaxExeTime());
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
ini_set('implicit_flush', true);
ob_implicit_flush(true);
while (ob_get_level() > 0)
{
$level = ob_get_level();
ob_end_clean();
if (ob_get_level() == $level) break;
}
if (function_exists('apache_setenv'))
{
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
/* This section runs a ping and echos out the terminal window */
$descriptorspec =
[
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
];
// Input checking for the post data and interaction with a MySQL database is done here
$tool_command = 'ping 8.8.8.8 -n 10';
$process = proc_open($tool_command, $descriptorspec, $pipes);
stream_set_blocking($pipes[1], false);
stream_set_blocking($pipes[2], false);
$proc_details = proc_get_status($process);
while ($s = fgets($pipes[1]))
{
echo $s;
flush();
sleep(0.3);
}
如果在此while循环期间的任何时间用户尝试重新加载页面,他们将只获取标签加载图标。如果我尝试从jQuery运行另一个PHP脚本,它只会排队直到while循环完成。造成这个问题的原因是什么? PHP,Ajax,apache服务器,HTTP请求,还有什么?
答案 0 :(得分:1)
在脚本中使用会话变量时,一次只能有一个脚本调用访问同一个会话,而PHP会阻止来自同一客户端的任何其他脚本。
在脚本访问会话变量时使用session_write_close()
,这将允许运行另一个脚本。如果需要再次访问会话变量,则需要再次调用session_start()
。