PHP:所有脚本中的ignore_user_abort(true)

时间:2010-03-07 17:20:18

标签: php user-interface abort

我有一个在服务器端使用PHP的网站。

用户访问页面,PHP进行一些计算,将数据写入MySQL数据库等。

想象一下,用户访问PHP为用户创建帐户的页面。创建包括两部分:将注册数据插入“用户”表,并将此帐户的设置插入表“设置”。这是两个必须一个接一个地执行的SQL查询。如果用户在第一次查询后退出页面,则“设置”中没有插入任何值。

我怎么能避免这个问题?我想只需使用ignore_user_abort(true),对吧?

在每个PHP脚本的顶部调用ignore_user_abort(true)是不是很有用?我不知道它应该导致问题的任何情况。

3 个答案:

答案 0 :(得分:13)

对于您的具体示例,使用数据库事务(如Ignacio所述)将是更合适的方法。

在其他情况下,您可能希望确保用户不能提前中止,但与数据库无关。例如,如果更新数据库然后发送邮件,则不希望用户在邮件发出之前能够停止该过程。在这种情况下,ignore_user_abort是合适的。

但是,请注意,由于客户端中断连接而导致管道损坏不会立即停止执行 ,仅在您下次尝试写入脚本输出时。这可以通过调用echoprint,或者甚至只是通过关闭PHP标记并在打开新标记之前插入一些空格(... ?> <?php ...)。因此,如果您在页面顶部拥有脚本的所有“操作”部分,那么在尝试编写任何页面内容之前,您不必担心管道损坏会影响应用程序逻辑。

当然,无论如何,你应该以这种方式将动作逻辑与页面内容分开。

来自http://php.net/manual/en/function.ignore-user-abort.php#refsect1-function.ignore-user-abort-notes

  

在尝试向客户端发送信息之前,PHP不会检测到用户已中止连接。仅使用echo语句并不能保证信息的发送

答案 1 :(得分:2)

如果您需要完全或根本不进行多次查询,那么您应该使用事务正确地执行此操作,而不是对问题进行绷带。

远程端可以方便地中止请求,例如,该请求涉及冗长的计算,用户决定他们毕竟不需要结果。

答案 2 :(得分:1)

您可以在php.ini中设置ignore_user_abortPHP.ini configuration

但是,我不会这样做。我宁愿让PHP页面在命令行上启动另一个PHP实例,在后台进行查询,例如:使用exec

另外,可能是您的基本流程概念存在偏差。如果用户中止计算的执行,你可能应该正确地回滚 - 但这取决于正在做什么的性质。