我有一个PHP脚本(我们称之为execute.php
),它在开始时绘制整个页面(HTML标签和body标签等),并且在一开始就执行一些命令(C++程序)背景。然后它会等待这些程序终止(有些依赖于其他人的结果,因此可能会按顺序执行),然后有一个JavaScript自动将表单提交给另一个PHP脚本(我们称之为results.php
),因为results.php
需要来自前面脚本的POST信息。PHP脚本意外不会继续
execute.php
:
<?php
print"
<html>
<body>
Some HTML code here
</body>
</html>
";
// Here come some C++-program calls
$pid_program1 = run_in_background($program1)
$pid_program2 = run_in_background($program2)
while (is_running($pid_program1) or is_running($pid_program2))
{
//echo(".");
sleep(1);
}
// Here come some later C++-program calls that execute quickly
$pid_program3 = run_in_background($program3)
$pid_program4 = run_in_background($program4)
while (is_running($pid_program3) or is_running($pid_program4))
{
sleep(1);
}
...
// We are now finished
print "
<form action=\"results.php\" id=\"go_to_results\" method=\"POST\">
<input type='hidden' name=\"session_id\" value=\"XYZ\">
</form>
<script type=\"text/javascript\">
AutoSubmitForm('go_to_results');
</script>
";
这很好地工作,如果C++程序1和2的执行速度。但是,当他们花费时间(总共大约25分钟)时,PHP脚本似乎无法继续。有趣的是,C++程序3和4被执行但并产生预期的输出等
然而,当我把echo(".");
在第一while循环的sleep()
之前,它的工作原理,并且继续直到JavaScript的自动提交。
因此在我看来,剩余的PHP代码(包括自动提交)无论何种原因,在第一个循环中没有输出时都不会发送。
我也尝试过使用set_time_limit(0)
和ignore_user_abort(true)
以及其他不同的东西,比如写入输出缓冲区(不想混乱已经显示的网页)而不是echo,但这些都不起作用。
当我在具有多个内核的机器上运行相同的脚本,以便program1和2可以并行执行时,它也可以工作,不需要echo(".")
。
所以我目前非常困惑,无法在apache日志或PHP日志中找到任何错误消息,因此会真正感谢您对此问题的看法。再次感谢您的建议
编辑 感谢这么远。 我现在已经采用了一个涉及(非常简单)AJAX的解决方案,并且这种方式绝对更好。然而,如果C++程序执行时间较长,它不会自动提交到这次实际创建的结果页面(以前没有这样做)。 基本上我所做的是:
process.php:
<?php
$params = "someparam=1";
?>
<html>
<body>
<script type="text/javascript">
function run_analyses(params){
// Use AJAX to execute the programs independenantly in the background
// Allows for the user to close the process-page and come back at a later point to the results-link, w/o need to wait.
if (window.XMLHttpRequest)
{
http_request = new XMLHttpRequest();
}
else
{
//Fallback for IE5 and IE6, as these don't support the above writing/code
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
//Is http_request still false
if (!http_request)
{
alert('Ende :(Kann keine XMLHTTP-Instanz erzeugen');
}
http_request.onreadystatechange=function(){
if (http_request.readyState==4 && http_request.status==200){
// Maybe used to display the progress of the execution
//document.getElementById("output").innerHTML=http_request.responseText;
// Call of programs is finished -> Go to the results-page
document.getElementById("go_to_results").submit();
}
};
http_request.open("POST","execute.php",true);
//Send the proper header information along with the request
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", params.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(params);
};
</script>
<?php
// Do some HTML-markup
...
// Start the programs!
print "
<script type=\"text/javascript\">
run_analyses('".$params."');
</script>
<form action=\"results.html" id=\"go_to_results\" method=\"POST\">
<input type='hidden' name=\"session_id\" value=\"XYZ\">
</form>
?>
</html>
</body>
和execute.php包含C++ - 程序调用,等待例程,最后,通过“包括(” results.php“)”创建的结果页。 同样,对于“不太长”的程序执行,自动提交按预期工作,但如果需要“更长”,则不会。 “更长”我的意思是大约25分钟。
我完全不知道什么可能导致这一点再次没有错误信息被发现。 我是否缺少一个关键的配置选项(Apache,PHP等)?
编辑 事实证明,让请求的PHP脚本重复“回声”的东西可以防止超时。因此,它基本上与没有AJAX的PHP解决方案相同,但是这次由于AJAX请求的responseText不一定是必需的,所以进度页面不会混乱,可用作解决方法。具体而言,我不一定会将其推荐为一般解决方案或良好实践。
你是如何调用'execute.php'?通过'http'请求或命令行? –
通过http请求。 – Shadow