2012-03-02 76 views
3

PHP脚本需要25秒才能完成(对于1人),并且可能需要更长时间才能完成高通信量。我不希望浏览器超时(PHP不会 - 我set_time_limit(0);)。如何防止浏览器超时(长PHP脚本)

有人可以提供示例代码关于如何确保浏览器不超时(或者详细解释怎么做)?什么是最好的方法?阿贾克斯?

谢谢。

编辑:

布赖恩·格雷厄姆说,“一旦JavaScript的开始一个Ajax请求,它运行直到它完成,退出或错误,据我所知,如果用户离开它甚至应该做到这一点。页。”

所以,我可以简单地通过Ajax调用长PHP脚本,然后它将运行不管超时是否需要(即使脚本没有返回任何内容)?

+1

^同意。你会发现很多人在栈上更有帮助,当他们看到你确实接受,并给他们的声誉,当他们把自己的时间来帮助你与你的问题;) – Brian 2012-03-02 20:46:18

+0

你需要的是分析,这样你就可以找出哪些部分是什么你页面需要很长时间才能完成然后你可以加速这些部分。 – Arjan 2012-03-02 20:50:56

+0

这是事情 - 大约3/4的时间涉及到联系远程服务器。无论我的网站有多少流量,此服务器的速度都不会改变。您是否认为即使我通过URL直接运行脚本,浏览器仍然有机会以高流量超时运行? – Hope4You 2012-03-02 20:55:13

回答

6

这确实取决于你的脚本是做什么它发回,但如果你可以使用AJAX,这将是该方式去。它不仅会让你长时间运行请求,而且不会阻塞浏览器,让用户自由地继续使用当前页面,直到请求完成。

实现类似此类功能的最佳方式是设置ignore_user_abort并关闭时间限制。这样你可以让脚本在后台运行。这样脚本可以在用户浏览您的网站时继续运行。他们甚至不必呆在同一页面上。所以你通过AJAX发起请求来启动它。在该脚本中有一个循环,用于更新用户会话的进度。

ini_set('session.use_cookies', 0); //don't spam the user with cookies for each session_start() 
while(...) { 
    session_start(); 
    //update status to the user's session 
    session_write_close(); 
    //sleep or whatever 
} 

很明显,这不一定是一个循环。您可以在开始处理信息之前关闭会话,然后打开它,设置状态并再次关闭。一次只有一个脚本可以访问用户的会话,因此您需要确保此过程不会影响用户的会话。

然后,所有你需要做的就是让您网站上,让用户知道什么时候不管它是你正在做的是完成和/或为他们提供文件/输出/等的网页运行的脚本。

这样就减少了用户继续浏览您的网站的脚本运行时,不会强迫他们坐在一个页面在加载指示灯59。。

+0

这看起来像是我最好的解决方案。通过Ajax启动进程,然后使用Ajax检查会话的值,一旦进程结束,显示结果。这应该会阻止浏览器超时,因为即使浏览器中止了浏览器,该进程仍将继续运行。 – Hope4You 2012-03-02 20:53:03

+0

这是正确的:)只要你不需要直接从该脚本返回任何结果到浏览器,这是有效的。如果您需要将任何输出写入浏览器,则需要编写自己的通信通道,使用Comet-like轮询系统从会话中检索更新。祝你好运;) – Brian 2012-03-02 20:56:11

2

您需要使用AJAX请求启动主进程,然后不断轮询服务器以检查进度。没有办法告诉浏览器不要超时。 (可以理解的是,如果我的浏览器挂了5分钟,我会很困惑)

我建议为脚本的每次运行分配一个唯一的ID,然后在AJAX请求中传回。然后,在未来的状态轮询中,只需传递该ID,轮询脚本就可以返回状态。你如何处理状态将取决于究竟发生了什么。

+0

我真的不知道如何处理状态。这个简单的解决方案也能工作吗? - 通过Ajax启动进程,然后每隔几秒使用Ajax从服务器请求一个像素gif(任何可以保持连接的活动)。这将保持脚本连接? (我将使用onreadystatechange来知道进程何时完成)。 – Hope4You 2012-03-02 20:43:09

+0

一旦javascript开始一个ajax请求,它会运行,直到它完成,退出或错误。据我所知,如果用户离开页面,甚至应该这样做。 – 2012-03-02 20:45:04

+0

保持活动状态的连接将挂起大请求。在转移到下一个请求之前,持续连接完成请求。最简单的(尽管也许不是最好的)方式做处理事情(虽然你应该考虑的一些乔纳森希巴德的建议,试图找出为什么脚本需要很长时间),是创建一个名为无论状态ID是在开始脚本,然后在脚本结尾删除文件。您的状态检查将只是:如果文件存在,仍在运行,否则,完成。 – Corbin 2012-03-02 20:46:08

1

如果你不想让浏览器超时,那么这里是我可能为你考虑的唯一解决方案....只要知道这一点:我设置PHP 10秒后超时。如果花费比这更长的时间处理 - 那么脚本不适合访问我的网站的用户。

1)优化你的代码 - 找出你的代码中哪些部分花费的时间过长,并确定你可以做些什么来使其更快。

2)使用推/拉解决方案。将请求推送到服务器并告诉它执行一个应用程序。应用程序被放入要运行的队列中,并且服务器返回进程ID。服务器上的守护进程检查队列并执行脚本cli而不是浏览器。

3)创建单独的例程,需要单独的ajax风格的方法调用。调用例程1启动一段脚本。调用例程2发出另一个ajax请求,并在第一个返回完成后启动第二个。等等

4)老实说 - 我只是找到另一种解决方案。很明显,如果你的脚本采取这一长期执行,事情是可怕 ...

+1

大部分时间(大概3/4)都是联系远程服务器 - 我无法控制的速度。 – Hope4You 2012-03-02 20:45:55

+0

再次,这是你想分离出来的东西。创建一个由守护进程/ cron脚本处理的队列或者你想做的任何事情就是如何“控制”它。 在一天结束的时候,你要问自己这样一个问题:是用户要等到我得到回应,或者是他们将要离开我的网页之前,我甚至可以给他们一个答复。 – 2012-03-02 20:56:03

+0

希望他们等待 - 脚本实际上用于处理订单!这就是为什么我要确保浏览器不超时。谢谢您的帮助。 – Hope4You 2012-03-02 21:00:29