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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/120228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:31:47  来源:igfitidea点击:

PHP: running scheduled jobs (cron jobs)

phpcronschedulingscheduled-tasks

提问by Eikern

I have a site on my webhotel I would like to run some scheduled tasks on. What methods of achieving this would you recommend?

我的 webhotel 上有一个站点,我想在其上运行一些计划任务。您会推荐哪些方法来实现这一目标?

What I've thought out so far is having a script included in the top of every page and then let this script check whether it's time to run this job or not.

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

This is just a quick example of what I was thinking about:

这只是我在想的一个简单的例子:

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

Anything else I should take into consideration or is there a better method than this?

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

回答by Armin Ronacher

That's what cronjobs are made for. man crontabassuming you are running a linux server. If you don't have shell access or no way to setup cronjobs, there are free services that setup cronjobs on external servers and ping one of your URLs.

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

回答by Armin Ronacher

I'm answering this now because no-one seems to have mentioned this exact solution.

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

On a site I'm currently working on, we've set up a cron job using cPanel, but instead of running the PHP Interpreter directly (because we're using CodeIgniter and our code is mapped to a controller function, this probably isn't a great idea) we're using wget.

在我目前正在开发的一个站点上,我们使用 cPanel 设置了一个 cron 作业,而不是直接运行 PHP 解释器(因为我们使用的是 CodeIgniter 并且我们的代码映射到控制器函数,这可能不是'这是个好主意)我们正在使用wget.

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

-qis so that wget won't generate any output (so you won't keep getting emails). -O cron_job.logwill save the contents of whatever your controller generates to a log file (overwritten each time so it won't keep growing).

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

I've found this to be the easiest way of getting 'proper' cron working.

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

回答by David McLaughlin

If you have a cPanel host, you can add cron jobs through the web interface.Go to Advanced -> Cron Jobs and use the non-advanced form to set up the cron frequency. You want a command like this:

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

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

回答by Kousha

Have you ever looked ATrigger? The PHP libraryis also available to start creating scheduled tasks without any overhead.

你有没有看过ATrigger?该PHP库也可以启动没有任何开销创建计划任务。

Disclaimer: I'm among their team.

免责声明:我在他们的团队中。

回答by MrZebra

if you're wondering how to actually run your PHP script from cron, there are two options: Call the PHP interpreter directly (i.e., "php /foo/myscript.php"), or use lynx (lynx http://mywebsite.com/myscript.php). Which one you choose depends mostly on how your script needs its environment configured - the paths and file access permissions will be different depending on whether you call it through the shell or the web browser. I'd recommend using lynx.

如果您想知道如何从 cron 实际运行 PHP 脚本,有两种选择:直接调用 PHP 解释器(即“php /foo/myscript.php”),或使用 lynx(lynx http://mywebsite.php)。 com/myscript.php)。您选择哪一个主要取决于您的脚本需要如何配置其环境 - 路径和文件访问权限会有所不同,具体取决于您是通过 shell 还是通过 Web 浏览器调用它。我建议使用lynx。

One side effect is that you get an e-mail every time it runs. To get around this, I make my cron PHP scripts output nothing (and it has to be nothing, not even whitespace) if they complete successfully, and an error message if they fail. I then call them using a small PHP script from cron. This way, I only get an e-mail if it fails. This is basically the same as the lynx method, except my shell script makes the HTTP request and not lynx.

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

Call this script "docron" or something (remember to chmod +x), and then use the command in your crontab: "docron http://mydomain.com/myscript.php". It e-mails you the output of the page as an HTML e-mail, if the page returns something.

将此脚本称为“docron”或其他名称(记住 chmod +x),然后在您的 crontab 中使用命令:“docron http://mydomain.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("[email protected]", $_SERVER['argv']['1'], $h, "From: [email protected]\nMIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1");
}

?>

回答by nickf

If you want to avoid setting up cron jobs and whatnot (though I'd suggest it's a better method), the solution you've provided is pretty good. On a number of projects, I've had the PHP script itself do the check to see whether it's time to run the update.

如果您想避免设置 cron 作业等(尽管我建议这是一种更好的方法),那么您提供的解决方案非常好。在许多项目中,我已经让 PHP 脚本本身进行检查以查看是否需要运行更新。

The down-side (okay, oneof the down sides) is that if no one is using the app during a certain period then the script won't run.

不利的一面(好吧,不利的一面之一)是,如果在特定时期内没有人使用该应用程序,则脚本将无法运行。

The up-side is that if no one is using the app during a certain period then the script won't run. The tasks I've got it set up to do are things like "update a cache file", "do a daily backup" and whatnot. If someone isn't using the app, then you aren't going to need updated cache files, nor are there going to be any database changes to backup.

好处是,如果在某个时期内没有人使用该应用程序,则脚本将不会运行。我设置它要做的任务是“更新缓存文件”、“进行每日备份”等等。如果有人没有使用该应用程序,那么您就不需要更新缓存文件,也不需要备份任何数据库更改。

The only modification to your method which I'd suggest is that you only run those checks when someone successfully logs in. You don't need to check on every page load.

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

回答by mixdev

Cron is a general purpose solution for scheduling problems. But when you go big and schedules go high in frequency, there can be reliability/overlapping issues. If you see such problems, consider something like superviseor more sophisticated monit.

Cron 是用于调度问题的通用解决方案。但是,当您变大并且日程安排频率很高时,可能会出现可靠性/重叠问题。如果您看到此类问题,请考虑使用诸如supervise或更复杂的monit 之类的东西。

回答by mokiSRB

If you using cpanel u should add this like:

如果您使用 cpanel,您应该添加如下内容:

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

回答by Lorenzo Sinisi

I would outsource the cronjobs with www.guardiano.pm and call a url every X minute. When your url (i.e www.yoursite.com/dothis.php) is called than you execute some code. If you don't want to let the web request the page when you want you can allow only request in POST and send some parameter that only you know with guardiano.pm

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

Thats what I would do because I do that on my pet projects. Have fun!

这就是我会做的,因为我在我的宠物项目中这样做。玩得开心!

回答by Tim Visée

The method you are using is fine, if you don't want to use cronjobs or anything external, but these can be heavy to check each time a page loads.

您使用的方法很好,如果您不想使用 cronjobs 或任何外部内容,但是每次加载页面时检查这些方法可能很繁重。

At first, some cronjobs can probably be replaced. For example if you have a counter for how many users have registered on your website, you can simply update this number when a user registers, so you don't have to use a cronjob or any scheduled task for this.

起初,一些 cronjobs 可能会被替换。例如,如果您有一个计数器来显示有多少用户在您的网站上注册,您可以在用户注册时简单地更新此数字,因此您不必为此使用 cronjob 或任何计划任务。

If you want to use scheduled tasks, I suggest you to use the method you are using right now, but with a little modification. If you're site has enough hits on a day, you can simply make the tasks run (or the tasks check function run) only for 1% or maybe 0.01% of the hits instead of all of them, the percentage you should use depends on the page hits you have and how many times you want to run the task. So, simply add a randomizer to achieve this feature.

如果你想使用计划任务,我建议你使用你现在正在使用的方法,但稍微修改一下。如果您的站点一天有足够的点击量,您可以简单地让任务运行(或任务检查功能运行)仅针对 1% 或 0.01% 的点击量而不是全部点击量,您应该使用的百分比取决于在您拥有的页面点击次数以及您想要运行该任务的次数。因此,只需添加一个随机发生器即可实现此功能。

You could simply use a function like this;

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

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
}