PHP: running scheduled jobs (cron jobs) - php

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 (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.
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.

If you using cpanel u should add this like:
/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php

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
Thats what I would do because I do that on my pet projects. Have fun!

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
}

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 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.

If you want something more abstract, you might consider using something like a PHP scheduler.
For example:
https://github.com/lavary/crunz
https://github.com/peppeocchi/php-cron-scheduler
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.

Related

what is the best practice to create a scheduled task to access a URL? [duplicate]

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 (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.
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.
If you using cpanel u should add this like:
/usr/local/bin/php -q /home/yoursite/public_html/yourfile.php
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
Thats what I would do because I do that on my pet projects. Have fun!
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
}
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 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.
If you want something more abstract, you might consider using something like a PHP scheduler.
For example:
https://github.com/lavary/crunz
https://github.com/peppeocchi/php-cron-scheduler
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.

What is the best way to run a PHP script at a particular time?

I have a site where auctions end a varying times. I need to send an automated email to the seller and the buyer after the auction is finished to notify them of the auction ending and the results. Obviously I can't really wait for someone to load the page to run the script so is there a good way to automate this by checking the current time and comparing that to the time of the auction end and running that script?
The site is on a UNIX server so a cron job is an option, but I'm concerned that running a cron job like that will put quite a load on the server.
A cron job runs at most once per minute.
Whatever load it generates on the server really depends on the kind of script you're going to run. Btw, I'm assuming that you're using cli to run the script (rather than just doing a curl http://mysite.com.
If your script takes longer than one minute (you should monitor this), simply either:
Increase the interval time between runs or,
Use a lock file to make sure no two instances of your script can run at the same time.
if (($fp = fopen('/tmp/mylockfile', "r+")) === false) {
die("Could not open lock file");
}
if (!flock($fp, LOCK_EX | LOCK_NB)) {
die("Could not obtain lock");
}
// run your code here
// release the lock and close file
fclose($fp);
OTOH If the script needs to run more than once per minute, you would need a different mechanism entirely.
Q: What is the best way to run a PHP script at a particular time, or interval?
A: Use cron
Q: Does a cronjob create a big load on the server?
A: Depends off course off your script. But checking if an auction should be closed, close it and send two emails shouldn't be to difficult. Be sure to create some kind of lockfile to make sure that if your script runs longer than the interval set, it isn't run twice.
Q: running a script with shorter intervals than 1 minute
A: Can't answer this one for you. Sorry :)
Use Cron. It allows you to run any command at most once per minute: http://clickmojo.com/code/cron-tutorial.html
As far as server load goes, it generally won't be a concern unless you are running a massive number of database calls very often on a very low-end server. I speak in generalities, but the idea is sound.
If you are using something else (besides PHP) to run your auction timer mechanism, I recommend you attach some code to that timer mechanism that also executes a mail-sending script when the timer runs down to zero and determines a winner.
Run the PHP script as a command line script. This will not put a load on the webserver - just a load on the server and you can easily run it via CRON.
If you add #!/usr/bin/php to the top of the script and change the execute bit on the file with chmod +x scriptname.php you can directly execute the script without passing it through php
http://php.net/manual/en/features.commandline.php
A couple of things you need to do this:
Store something in your auction information indicating whether you've sent this e-mail yet or not (could be a boolean or a date for when it was sent which might be null). Although I have to assume you need to do something besides send this e-mail? Like mark the auction as closed so no more bidding can take place?
A bit of code that finds auctions which need this e-mail sent: e.g. they've ended and have not yet been reminded.
Something to repeatedly execute the bit of code in 2. You could use cron. Alternatively you can write a pretty simple daemon for unix that runs constantly in a loop of (wait at least a few ms or more; do some stuff). The latter is a lot more work but in my opinion scales much better. See http://pear.php.net/package/System_Daemon for some useful tools if you're interested in this approach.
One thing to consider is how much you want to be careful about accidentally double-sending this e-mail. If you're only running this code in a single thread it's pretty easy but if you ever want to build out to the point where you have several different distributed machines that create and send these e-mails you have to be a bit more careful. If you're running it out of cron can you guarantee one run of it will always be finished before another one starts?

Schedule and execute a PHP script automatically

I have written a PHP script which generates an SQL file containing all tables in my database.
What I want to do is execute this script daily or every n days. I have read about cron jobs but I am using Windows. How can I automate the script execution on the server?
You'll need to add a scheduled task to call the URL.
First of all, read up here:
MS KB - this is for Windows XP.
Second, you'll need some way to call the URL - i'd recommend using something like wget - this way you can call the URL and save the output to a file, so you can see what the debug output is. You can get hold of wget on this page.
Final step is, as Gabriel says, write a batch file to tie all this up, then away you go.
e: wget is pretty simple to use, but if you have any issues, leave a comment and I'll help out.
ee: thinking about it, you don't even really need a batch file, and could just call wget directly..
add a scheduled task to request the url. either using a batch file or a script file (WSH).
http://blog.netnerds.net/2007/01/vbscript-download-and-save-a-binary-file/
this script will allow you to download binary data from a web source. Modify it to work for you particular case. This vbs file can either be run directly or executed from within a script. Alternately you do not have to save the file using the script, you can just output the contents (WScript.Echo objXMLHTTP.ResponseBody) and utilize the CMD out to file argument:
cscript download.vbs > logfile.log
save that bad boy in a .bat file somewhere useful and call it in the scheduler: http://lifehacker.com/153089/hack-attack-using-windows-scheduled-tasks
Cron is not always available on many hosting accounts.
But try this:
http://www.phpjobscheduler.co.uk/
its free, has a useful interface so you can see all the scheduled tasks and will run on any host that provides php and mysql.
You can use ATrigger scheduling service. A PHP library is also available to create scheduled tasks without overhead. Reporting, Analytics, Error Handling and more benefits.
Disclaimer: I was among the ATrigger team. It's a freeware and I have not any commercial purpose.
Windows doesn't have cron, but it does come with the 'at' command. It's not as flexible as cron, but it will allow you to schedule arbitrary tasks for execution from the command line.
Yes, You can schedule and execute your php script on windows to run automatically. In linux like os u will have cron but on windows u can schedule task using task scheduler.
If your code is in remote hosted server then create a cron-job for the same.
Else if in local then use a scheduled task in windows.Its easy to implement.I am having servers with so many scheduled tasks running.

What options are there for executing a PHP script at a certain time every day?

I have a PHP script that needs to be run at certain times every weekday. Is cron or Windows task scheduler the only way to do this?
Is there a way to set this up from within another PHP script?
Depends how exact the timing needs to be. A technique I've seen used (dubbed "poor man's cron") is to have a frequently accessed script (a site's home page, for example) fire off a task on the first page load after a certain time (kept track of in the database).
If you need any sort of guaranteed accuracy, though, cron or a Windows scheduled task is really the best option. If your host doesn't support them, it's time to get a better one.
Apart from cron or Scheduled Tasks, you can have your PHP script to always run it. The process should sleep (within a loop) until the time has reached. Then, the process could execute the remaining functions/methods. Or, you can set up another script (which will act as a daemon) to check for the time and execute the other script.
Well since the web is a pull mechanism you have to have some sort of action that will trigger a PHP script to execute. cron is an option on *nix and task scheduler on windows. You could also write your own service that has a timer but only if needed, this is common on windows services for updaters, jobs etc.
One way you could do it is in the cron task just call a php script for each action needed. Or one php script that executes other tasks. The problem with web based tasks though such as PHP is timeouts. Make sure your tasks are under 60-90 seconds. If not you might look at using python , perl or ruby or even bash scripts to do the work rather than the PHP script.
cron seems like the best option for you though. You will have to call your script with wget. There are examples here: http://www.thesitewizard.com/general/set-cron-job.shtml
For instance this runs the script everyday at 11:
30 11 * * * /usr/bin/wget http://www.example.com/cron.php
Cron, of course, is by far the best way to schedule anything on *nix.
If this is in a remote server you do not have cron access to, you can setup cron/windows scheduler on your computer, to open a web browser to the page that contains the script you wish to run
You probably want to use cron (or windows scheduled tasks).
If you really wanted, you could set up another php script to run continuously with an infinite loop (with a sleep command inside the loop, say for 30 seconds or so) and then when you reach your desired day/time execute the other script via a shell command call. While possible, I can't think if a single good reason to use this method rather than cron/scheduled tasks
You can write a long running script that runs your main script in predefined times but it will be very unnecessary, error prone, and it will basically be a "cron rewrite in phph".
Using the real cron itself will be easier and a more robust solution. If you are packaging an application, you can put a file in /etc/cron.d which contains a single cron line running your application.
You'll need to use a cron job (under Linux/Unix) or a scheduled task under Windows. You could have another script running on a continuous basis which checks the time and executes a script at a specified interval, but using the OS-supplied mechanism is easier to manage and resilient to restarts, etc.
The Uniform Server project has some good suggestions on mimicking cron in environments where cron is unacceptable. Still though, if cron is at all an option, use it.

Resetting a MySQL Field value without user execution

I need to reset a MySQL Field value automatically at midnight. It is a specific column in a specific row in a table. I know how to do this in PHP but I do not know how to execute the PHP Script at midnight without someone having to do it themselves. Do you have any viable solutions?
Edit:--------------------
Preferably without using Cron Jobs.
If you are running on linux you would use a cronjob
On most distros there is a command called crontab that schedules tasks for you and a specific format you need:
0 0 * * * php /path/to/file.php
EDIT:
Wrote this before you edited yours :p I'm not sure there is any other way. Do you have a specific reason not to use a cronjob?
You may not even need to specify the php part if the php file is marked as executable i.e
0 0 * * * /path/to/file.php
Just do "chmod +x /path/to/file.php" form the linux command line
There are web based cron services too. Basically you set up an account and then they visit an URL of your choosing at a regular interval. On your server you set up a page that does what you need to get done. Preferably give it a unlikely-to-find-name like myjob789273634ahhh8s2nhw8sghusgf874wfu.php. You get the idea. (Remember that PHP-scripts timeout after like 30secs.)
Here's a google search:
**oops I'm new so I can't post URL apparently. Just search for "web based cron".
Good luck
/0
You could write a job scheduler into your program that runs jobs in a cron-like way. It would require a user to interact with the system to trigger, but it might be good enough depending on your needs. This is much more complicated than just running a cronjob, and does not ensure prefect timing (since it wont run until a user hits a page).
You'd probably need to add a table into you database that would list the job, the time you want them done, and a locking flag to avoid concurrent attempts to run the job. Each time your script runs, you'd check this table for overdue jobs and run them as needed.
Asking how to reliably set off a script at the same time every night without cron (or a scheduled task, on Windows) is like asking how to make a dynamic website without a server-side language.
If your app absolutely relies on a script running exactly at midnight, cron is a requirement. If your users have a hosting company that (stupidly) does not permit cron, they're going to be out of luck.

Categories