代码之家  ›  专栏  ›  技术社区  ›  caw

php:忽略所有脚本中的用户中止(true)

  •  9
  • caw  · 技术社区  · 15 年前

    我有一个在服务器端与PHP一起工作的网站。

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

    假设一个用户访问一个页面,其中PHP为该用户创建一个帐户。创建由两部分组成:将注册数据插入到“用户”表中,并将此帐户的设置插入到“设置”表中。这是两个必须逐个执行的SQL查询。如果用户在第一次查询后退出页面,则“设置”中没有插入任何值。

    我怎样才能避免这个问题?我想只要使用忽略用户中止(真的),对吗?

    所以在每个PHP脚本的顶部调用ignore_user_abort(true)不是很有用吗?我不知道在什么情况下会引起问题。

    3 回复  |  直到 6 年前
        1
  •  13
  •   droidlabour CodAIK    6 年前

    对于您的特定示例,使用数据库事务(如Ignacio所提到的)将是更合适的方法。

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

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

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

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

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

        2
  •  2
  •   Ignacio Vazquez-Abrams    15 年前

    如果您需要多个查询,要么完全发生,要么根本不发生,那么您应该正确地使用事务处理,而不是在问题上使用绷带。

    如果请求涉及冗长的计算,并且用户认为他们根本不需要结果,那么远程端中止请求可能很方便。

        3
  •  1
  •   Pekka    15 年前

    你可以设定 ignore_user_abort 在php.ini中: PHP.ini configuration

    不过,我不会这么做的。我宁愿让php页面在命令行上启动另一个php实例,在后台执行查询,例如使用 exec .

    另外,它可能是您的基本流概念被扭曲了。如果用户中止了计算的执行,您可能无论如何都应该正确地回滚它——但这取决于正在执行的操作的性质。