4

PHP 提供了一种注册关闭函数的机制:

register_shutdown_function('shutdown_func');

问题是在最近的 PHP 版本中,这个函数仍然在请求期间执行。

我有一个平台(如果重要的话,在 Zend 框架中),整个请求中的任何一段代码都可以注册一个要登录到数据库的条目。我没有在整个请求中使用大量单独的插入语句来减慢页面速度,而是将它们排队以在请求结束时插入。我希望能够在用户完成 HTTP 请求后执行此操作,因此记录或执行任何其他清理任务的时间长度不会影响用户感知的页面加载时间。

PHP中是否有内置方法可以做到这一点?或者我是否需要使用外部进程配置某种共享内存空间方案并指示该进程进行日志记录?

4

4 回答 4

4

如果您真的关心 MySQL 的插入时间,那么您可能是在解决症状而不是原因。

例如,如果您的 PHP/Apache 进程在用户获取他们的 HTML 之后执行,那么您的 PHP/Apache 进程仍被锁定在该请求中。由于它很忙,如果出现另一个请求,Apache 必须分叉另一个线程,为其分配更多内存,打开额外的数据库连接等。

如果您遇到性能问题,您需要从 PHP/Apache 执行中移除繁重的工作。如果您有很多清理任务正在进行,那么您正在烧毁宝贵的 Apache 进程。

我会考虑将您的条目记录到文件中,并让 crontab 将这些条目带外加载到您的数据库中。如果您有其他繁重的任务,请使用排队/作业处理系统来完成带外工作。

于 2008-11-16T06:30:20.347 回答
1

除了 register_shutdown_function() 之外,没有用于确定脚本何时退出的内置方法。然而,Zend 框架有几个钩子用于在调度过程的特定点运行代码。对于您的要求,最相关的是动作控制器的调度后钩子,它发生在动作被调度之后,以及控制器插件代理的dispatchLoopShutdown 事件

您应该阅读手册以确定哪个更适合您。

编辑:我想我没有完全理解。从这些钩子中,您可以以某种形式分叉当前进程。PHP 有几种方法可以派生进程,您可以在手册中的程序执行部分阅读。我建议查看 pcntl 扩展 - 阅读这篇博文以查看分叉子进程以在后台运行的示例。

于 2008-11-16T03:10:44.510 回答
0

这个随机家伙的博客上的评论听起来与您想要的相似。如果该标头技巧不起作用,则该博客上的一条评论建议exec()使用单独的 PHP 脚本在后台运行,如果您的 Web 主机的配置允许这样的话。

于 2008-11-16T04:09:37.777 回答
0

对于您的口味,这可能有点骇人听闻,但这将是一种有效且简单的解决方法。

您可以创建一个由您选择的数据库管理的“队列”,首先,将请求存储在数据库的队列表中,然后输出一个 iframe,该 iframe 会导致一个脚本,该脚本将触发与您的 queue_id 匹配的指令数据库。

前任:

<?php
mysql_query('INSERT INTO queue ('instructions') VALUES ('something would go here');
echo('<iframe src="/yourapp/execute_queue/id?' . mysql_insert_id() . '" />');
?>

框架会做类似的事情

前任:

<?php
$result = mysql_query('SELECT instructions FROM queue WHERE id = ' . $_GET['id']);
// From here, simply execute some instruction based on the "instructions" field, then delete the instruction from the database.
?>

就像我说的,我可以看到你怎么会认为这个 hackish,但是框架将独立于它的父页面加载,所以它可以实现你想要的,而不需要在后台运行一些其他应用程序。

希望这至少可以为您指明正确的方向。

干杯!

于 2008-11-16T04:14:12.557 回答