问题是,对于一个漫长的过程,无论客户端浏览器当前是否连接,PHP脚本都会继续执行。有没有可能,如果客户端已经终止了对脚本的Ajax调用,那么脚本也会在服务器上终止?我发现这是处理这个超时问题最简单的办法如果HTTP请求被取消/关闭,PHP会自动终止脚本
回答
正如指出的@metadings PHP确实有一个函数来检查是否存在名为connection_aborted连接中止()。它将返回1,如果连接否则为0
终止在一个长长的服务器端程序,用户可能需要知道,如果客户端 从服务器断开或者他已经关闭了浏览器,则 服务器可以安全地关闭该过程。
尤其是在应用程序使用php会话的情况下,如果我们在客户端断开连接后仍然运行长进程,那么服务器将无法响应此会话。并且来自同一客户端的任何其他请求将等到先前的进程完全执行。造成这种情况的原因是会话文件在进程运行时被锁定。然而,你可以通过调用session_write_close()方法来解锁它。但是这在所有情况下都不可行,可能需要在流程结束时写入会话。
现在,如果我们只在一个循环中调用connection_aborted(),那么它总是会返回0,无论连接是否关闭。
0意味着连接不中止。这是误导。但是,经过重新搜索和实验后,如果发现输出缓冲区中的是php的原因。
首先,为了检查中止,循环中的开发人员必须通过回显一些文本向客户端发送一些输出。例如:
print " ";
由于进程仍在运行,输出将不会发送到客户端。现在发送输出,然后我们需要刷新输出缓冲区。
flush();
ob_flush();
然后,如果我们检查中止,那么它会给出正确的结果。
if (connection_aborted() != 0) {
die();
}
以下是工作的例子,这会即使您正在使用PHP会议的工作:
session_start();
ignore_user_abort (TRUE);
file_put_contents ("con-status.txt", "Process started..\n\n");
for($i = 1; $i <= 15; $i ++) {
print " ";
file_put_contents ("con-status.txt", "Running process unit $i \n", FILE_APPEND);
sleep (1);
// Send output to client
flush();
ob_flush();
// Check for connection abort
if (connection_aborted() != 0) {
file_put_contents ("con-status.txt", "\nUser terminated the process", FILE_APPEND);
die();
}
}
file_put_contents ("con-status.txt", "\nAll units completed.", FILE_APPEND);
EDIT 07-APR-2017
如果有人使用快速-Cgi在Windows上,然后他实际上可以终止 CGI线程从内存中断连接时使用以下代码:
if (connection_aborted() != 0) { apache_child_terminate(); exit; }
请注意,'ob_flush'应该在'flush'前调用,如果输出缓冲正在使用中(甚至可能是ob_end_flush?)http://stackoverflow.com/questions/4191385/php-buffer-ob-flush-vs-flush – metadings 2013-07-24 04:04:48
一种方法是这样:
1:服务器为“处理”上设置的值。开始一个独立的线程来处理。
2:初始ajax调用返回成功
3:页面上的javascript进入'等待模式',每10或30或60秒或5或10分钟或其他任何事情发送新的ajax请求(取决于您的情况)来确定服务器上的值是否仍然设置为'处理'。
4:独立线程完成。它将服务器上的值设置为“完成”。
5:页面上的javascript进行下一个等待模式查询,并返回'完成'和相应的数据。
4B:如果时间淫秽量的推移没有“完成”时,它注册为失败。多少时间是淫秽取决于你的情况。发送ajax调用,将值从'处理'更新为'取消'。 5b:独立线程定期检查状态以确保它仍然被设置为'正在处理'。如果它看到模式转换为“取消”,它将自行取消。
这是你在找什么: http://php.net/manual/en/function.ignore-user-abort.php
在执行过程中停止脚本可能会导致意想不到的结果,所以买者自负
退房PHP connection_aborted()函数。在进行处理时,您可以检查中止的连接以正常取消进度,就像人们在交互式线程模型中所做的那样。
哇。我甚至不知道这是在那里。谢谢! – 2013-05-13 14:52:37
@metadings这似乎不适用于Ajax请求。 ajax请求被终止,并且connection_aborted()仍然返回0.即使我已经通过关闭网页仍尝试执行脚本。可能是什么原因? – 2013-05-13 19:15:06
@metadings函数connection_aborted()有一个错误,它会一直返回0看到这个bug:https://bugs.php.net/bug.php?id=54062 ...有没有其他的选择? – 2013-05-13 19:34:12
- 1. HTTP请求不会关闭
- 2. 请求被中止:请求被取消
- 3. 如果脚本被取消,如何终止从Ant任务启动的进程?
- 4. 取消HTTP请求
- 5. 使用http获取请求终止的线程终止
- 6. 如何取消http请求?
- 7. HttpWebRequest:请求被中止:请求被取消
- 8. HTTP脚本请求“中止”状态
- 9. 自动取消jqGrid请求
- 10. Python脚本自动关闭
- 11. 用于HTTP POST请求的PHP脚本
- 12. 关闭和/或终止php脚本中的mysqli连接?
- 13. 来自Adobe InDesign脚本的HTTP请求?
- 14. 来自Chrome扩展程序的HTTP发布请求被取消
- 15. HttpWebRequest的:请求已中止:请求已被取消
- 16. System.Net.WebException:请求已中止:请求已被取消
- 17. Curl - 7.21.5 HTTP请求取消
- 18. 打开进程终止时文件会自动关闭
- 19. PHP如果脚本被URL提取
- 20. “申请被要求关闭与ShutdownRequested称之为”消息ReSharper的终极选择
- 21. php自动每日http登录请求
- 22. 如何在http请求中关闭会话
- 23. Alamofire请求被取消
- 24. 每次终止会话关闭时都会取消设置的环境变量
- 25. 关闭浏览器会阻止PHP脚本执行完吗?
- 26. 如果关闭JVM,sql连接会自动关闭吗?
- 27. 如何在执行HTTP请求后自行关闭卡?
- 28. 连接到Dynamics CRM抛出“请求被中止:请求被取消。”异常
- 29. 如何取消Ruby Net :: HTTP请求?
- 30. 如何取消图片的http请求?
其中的困难是,一个新的AJAX调用必须到服务器上,这涉及到运行第二个PHP脚本来进行。第二个PHP脚本需要访问由第一个PHP脚本生成的线程。我可以想到多种方式来做到这一点 - 但它不会是自动的。您需要确保编写您的PHP代码,以便通过新的独立创建的线程以某种方式访问或控制原始线程。 – 2013-05-13 14:17:54
实际上,PHP的默认行为是在客户端断开连接时中止进程。 – Jon 2013-05-16 16:39:10
@jon在我的Windows服务器的情况下,它断开连接后继续运行。不过,我也不希望PHP仅仅关闭这个过程。我需要ROLLBACK数据库事务并安全地关闭它。 – 2013-05-16 16:43:46