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

Posted

技术标签:

【中文标题】PHP:所有脚本中的ignore_user_abort(true)【英文标题】:PHP: ignore_user_abort(true) in all scripts 【发布时间】:2010-03-07 17:20:18 【问题描述】:

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

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

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

我怎样才能避免这个问题?我认为只需使用ignore_user_abort(true),对吗?

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

【问题讨论】:

【参考方案1】:

对于您的具体示例,使用数据库事务(如 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 语句并不能保证信息已发送

【讨论】:

【参考方案2】:

如果您需要多个查询完全发生或根本不发生,那么您应该使用事务正确执行此操作,而不是在问题上缠上绷带。

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

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

以上是关于PHP:所有脚本中的ignore_user_abort(true)的主要内容,如果未能解决你的问题,请参考以下文章

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

我们需要一个脚本来使用 PHP 中的第三方 Cpanel 详细信息创建所有文件、数据库和电子邮件的备份

PHP 在脚本中列出所有包/过程/功能及其内容主体

PHP基础

PHP 路径在 localhost 中的运行脚本上加倍

PHP