在PHP中完成HTTP请求后执行代码?

时间:2008-11-16 02:54:09

标签: php zend-framework

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

register_shutdown_function('shutdown_func');

问题是在最近的PHP版本中,在请求期间仍然执行此功能。

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

PHP中是否有内置方法来执行此操作?或者我是否需要使用外部进程配置某种共享内存空间方案并发出进行日志记录的信号?

4 个答案:

答案 0 :(得分:4)

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

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

如果遇到性能问题,则需要从PHP / Apache执行中删除繁重的工作。如果你正在进行大量的清理任务,那么你就会烧掉宝贵的Apache进程。

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

答案 1 :(得分:1)

除了register_shutdown_function()之外,还没有用于确定脚本何时退出的内置方法。但是,Zend Framework有几个钩子,用于在调度过程中的特定点运行代码。 对于您的要求,最相关的是动作控制器的post-dispatch hook,它发生在调度动作之后,而dispatchLoopShutdown event则是控制器插件代理。

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

编辑:我想我完全不理解。从这些钩子中,您可以以某种形式分叉当前进程。 PHP有几种方法来分叉流程,您可以在program execution下的手册中阅读。我建议仔细查看pcntl扩展名 - 阅读this blog post以查看分支子进程在后台运行的示例。

答案 2 :(得分:0)

this random guy's blog的评论听起来与您想要的相似。如果该标题技巧不起作用,那么该博客上的一条评论建议exec()单独的PHP脚本在后台运行,如果您的Web主机的配置允许这样的话。

答案 3 :(得分: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,但框架将加载独立于其父页面,所以它可以实现你想要的,而无需在后台运行其他应用程序。

希望这至少能指出你正确的方向。

干杯!

相关问题