【问题标题】:Running scheduled jobs运行计划作业
【发布时间】:2011-02-06 05:20:22
【问题描述】:

我想在用户提交表单 30 分钟后调用一个函数。我正在使用 javascript setTimeOut() 函数,但在页面刷新或浏览器关闭时会清除计时器。无论如何(无论浏览器是关闭还是刷新),我都想在 30 分钟后准确地调用该函数,并且我还想将剩余时间显示为 30 分钟。

我查看了 Cron 作业,但我的理解是 PHP 不能直接调用 cron 作业。

谁能告诉我最好的方法是什么?

【问题讨论】:

  • 这取决于具体情况。它需要在浏览器或服务器上运行吗?它需要多精确,±1 分钟是否可以接受?
  • ±1 是可以接受的。我想让它在后端运行,也许在服务器中。我的要求是,一旦表单提交,日程安排不应有任何中断。只要它继续运行,它在哪里运行(浏览器或服务器)并不重要

标签: php cron scheduled-tasks


【解决方案1】:
  1. at command 和关联的atd 守护程序可以安排在未来任意时间执行的操作。您可能必须编写一个专门的 php 脚本来传递给at。您可以向它传递额外的参数,以了解哪个用户提交了表单等。当然,此代码将在服务器上执行。 PHP 代码会将结果存储在数据库(或类似的全局数据存储)中。
  2. 为了显示用户还剩多少时间,我会将时间存储在会话或数据库中。请记住,服务器时间与用户计算机上的时间不同,因此最好在服务器上进行任何差异计算,而不是在 JavaScript 中。
  3. setTimeout() 调用仍可用于确保将浏览器重定向到页面(或通过 AJAX 等加载)以在适当的时间查看结果(假设事件发生时用户在您的网站上)。根据会话中的时间,在每次页面加载到正确时间时继续调用setTimeout()

请记住,第 1 步中的 PHP 代码将需要一些时间来执行,因此您可能需要在第 3 步中添加一个小延迟,以确保结果可用,并在出现错误时进行适当的错误处理。由于其他原因无法获得结果。

【讨论】:

    【解决方案2】:

    我投票支持@wuputah 方法并同意它是最好的,但如果您无法访问他的第 1 步(在共享主机等上),那么您可以在数据库中设置时间戳并设置一个 cron 作业每 1 分钟运行一次,检查数据库的“过期”时间,没有“已处理”标志...然后对该数据执行您的过程(并将数据库条目标记为“已处理”,因此它不会在下一次执行循环)。

    +---------------------------------------------+
    | RECORD ID | TIMESTAMP           | PROCESSED |
    +---------------------------------------------+
    |   1       | 2010-02-06 15:27:10 | yes       |
    |   2       | 2010-02-06 15:47:10 | no        |
    |   3       | 2010-02-06 15:49:10 | no        |
    +---------------------------------------------+
    

    【讨论】:

    • 是的,如果您可以容忍长达 60 秒的延迟,这是一个不错的选择!