简体   繁体   中英

PHP: running scheduled jobs (cron jobs)

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

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?

That's what cronjobs are made for. man crontab assuming 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.

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 .

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

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

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

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:

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

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

Disclaimer: I'm among their team.

if you're wondering how to actually run your PHP script from cron, there are two options: Call the PHP interpreter directly (ie, "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.

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.

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.

#!/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");
}

?>

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.

The down-side (okay, one of 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.

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 supervise or more sophisticated monit .

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

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

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.

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.

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.

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
}

I would outsource the cronjobs with www.guardiano.pm and call a url every X minute. When your url (ie 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

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

If you do not have the option to setup a cronjob you can call the script with cUrl (as alternative to wget - same functionality). Just do a scheduled task on your local machine that executes the cUrl function.

Command line PHP + cron would be the way I would go. It's simple and should fit the bill. It is usually installed with PHP as a matter of course.

If you want something more abstract, you might consider using something like a PHP scheduler. For example:

And also, to parse the cron expression, you could use an existing library such as https://github.com/mtdowling/cron-expression . It provides a lot of useful methods to help you figure out information of a cron job.

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM