PHP:运行预定作业(cron作业)

时间:2008-09-23 10:27:20

标签: php cron scheduling scheduled-tasks

我的网站上有一个网站我想运行一些预定的任务。你会推荐哪些方法来实现这一目标?

到目前为止,我所想到的是在每个页面的顶部都包含一个脚本,然后让这个脚本检查是否是时候运行这个作业了。

这只是我想到的一个简单示例:

if ($alreadyDone == 0 && time() > $timeToRunMaintainance) {
   runTask();
   $timeToRunMaintainance = time() + $interval;
} 

还有什么我应该考虑的,还是有比这更好的方法?

13 个答案:

答案 0 :(得分:34)

这就是cronjobs的用途。 man crontab假设您正在运行Linux服务器。如果您没有shell访问权限或无法设置cronjobs,则可以使用免费服务在外部服务器上设置cronjobs并ping您的某个URL。

答案 1 :(得分:17)

我现在正在回答这个问题,因为似乎没有人提到这个确切的解决方案。

在我正在处理的网站上,我们使用cPanel设置了一个cron作业,但是没有直接运行PHP解释器(因为我们使用CodeIgniter并且我们的代码被映射到控制器函数,这个可能不是一个好主意)我们正在使用wget

wget -q -O cron_job.log http://somehost/controller/method

-q是因为wget不会生成任何输出(因此您不会继续收到电子邮件)。 -O cron_job.log会将控制器生成的内容保存到日志文件中(每次都会覆盖,因此不会继续增长)。

我发现这是让'正确'的cron工作的最简单方法。

答案 2 :(得分:12)

如果您有cPanel主机,则可以通过Web界面添加cron作业。转到高级 - > Cron Jobs并使用非高级表单来设置cron频率。你想要一个像这样的命令:

/usr/bin/php /path/to/your/php/script.php

答案 3 :(得分:5)

如果您想知道如何从cron实际运行PHP脚本,有两个选项:直接调用PHP解释器(即“php /foo/myscript.php”),或使用lynx(lynx {{3 }})。您选择哪一个主要取决于您的脚本如何配置其环境 - 路径和文件访问权限将根据您是通过shell还是Web浏览器调用而不同。我推荐使用lynx。

一个副作用是每次运行时都会收到一封电子邮件。为了解决这个问题,我让我的cron PHP脚本输出什么(如果它们成功完成则不得输入任何内容,甚至不是空格),如果失败则输出错误消息。然后我使用cron的一个小PHP脚本调用它们。这样,如果失败,我只收到一封电子邮件。这与lynx方法基本相同,除了我的shell脚本发出HTTP请求而不是lynx。

将此脚本称为“docron”或其他内容(记住chmod + x),然后使用crontab中的命令:“docron http://mywebsite.com/myscript.php”。如果页面返回某些内容,它会将页面输出作为HTML电子邮件发送给您。

#!/usr/bin/php
<?php

$h = @file_get_contents($_SERVER['argv'][1]);

if ($h === false)
{
        $h = "<b>Failed to open file</b>: " . $_SERVER['argv'][1];
}

if ($h != '')
{
        @mail("cron@mydomain.com", $_SERVER['argv']['1'], $h, "From: cron@mydomain.com\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
}

?>

答案 4 :(得分:5)

你看过ATrigger吗? PHP library也可用于开始创建计划任务而无需任何开销。

免责声明:我是他们的团队之一。

答案 5 :(得分:4)

如果你想避免设置cron作业等等(虽然我建议这是一种更好的方法),你提供的解决方案非常好。在许多项目中,我已经让PHP脚本自行检查是否有时间运行更新。

如果没有人在某段时间内使用该应用程序,那么下方(好的,一个的下方)就是脚本无法运行。

最重要的是,如果在某段时间内没有人使用该应用程序,则该脚本将无法运行。我设置的任务是“更新缓存文件”,“每日备份”以及诸如此类的东西。如果有人没有使用该应用程序,那么您不需要更新缓存文件,也不会对备份进行任何数据库更改。

我建议您对方法的唯一修改是,只有在有人成功登录时才会运行这些检查。您无需检查每个页面加载。

答案 6 :(得分:4)

Cron是一种用于调度问题的通用解决方案。但是当你走得很大并且时间表的频率很高时,可能存在可靠性/重叠问题。如果您发现此类问题,请考虑supervise或更复杂的monit

答案 7 :(得分:3)

如果你使用cpanel你应该添加如下:

/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php

答案 8 :(得分:1)

如果您不想使用cronjobs或外部任何东西,那么您使用的方法很好,但每次加载页面时都要检查这些方法。

起初,一些cronjobs可能会被替换。例如,如果您有一个计数器,表明您的网站上已注册了多少用户,则只需在用户注册时更新此编号,这样您就不必使用cronjob或任何计划任务。

如果您想使用预定任务,我建议您立即使用您正在使用的方法,但稍作修改。如果你的网站一天有足够的点击量,你可以简单地让任务运行(或任务检查功能运行)只有1%或0.01%的命中而不是全部,你应该使用的百分比取决于在页面上点击你有你想要运行任务的次数。因此,只需添加随机函数即可实现此功能。

你可以简单地使用这样的函数;

if(rand (1, 100) <= 1) { // 1, 100 is used to generate a number between 1 and 100. 1 is for one percent.
    // Run the tasks system
}

希望这有帮助,

答案 9 :(得分:1)

我会用www.guardiano.pm外包cronjobs并每隔X分钟拨打一个网址。调用您的URL(即www.yoursite.com/dothis.php)时,执行某些代码。如果你不想让网页在你想要的时候请求页面,你只能在POST中允许请求并发送一些只有你知道的参数guardiano.pm

多数民众赞成我会做什么,因为我在我的宠物项目上这样做。玩得开心!

答案 10 :(得分:0)

命令行PHP + cron将是我的方式。它很简单,应该符合要求。它通常与PHP一起安装。

答案 11 :(得分:0)

如果您没有设置cronjob的选项,可以使用cUrl调用脚本(作为wget的替代 - 相同的功能)。只需在执行cUrl函数的本地计算机上执行计划任务。

答案 12 :(得分:0)

如果你想要更抽象的东西,你可以考虑使用类似PHP调度程序的东西。 例如:

而且,要解析cron表达式,您可以使用现有的库,例如https://github.com/mtdowling/cron-expression。它提供了许多有用的方法来帮助您找出cron作业的信息。

希望有所帮助。