Home > PHP, Releases, Web Programming > PHPCron: Running scheduled tasks from PHP on a web server

PHPCron: Running scheduled tasks from PHP on a web server

October 17, 2006 Leave a comment Go to comments

PHPCron is a simple PHP script which lets you run multiple tasks on a schedule or timer. It can be run either from the command-line or via a web browser. Its behaviour is very similar to the popular cron program for UNIX.

Downloads for the software described here are available on the downloads page.

This software is a work in progress and should not be considered complete or secure.

Why?

Running scheduled tasks is a frequent requirement for web sites. For example, we use PHPCron at Deviant Audio (the radio station is now defunct) to monitor our radio streams’ availability, send out invoices automatically when payments are due and so on.

Some web hosts provide you with access to cron services, but many don’t. With this simple script, you can run scheduled tasks even without cron access, and that is its primary purpose.

How it works

PHPCron reads a list of scheduled tasks you define and runs continuously in the background, sleeping until it is time for the next task to execute. The task is run and PHPCron goes back to sleep again.

PHPCron can be called with parameters to make it start, stop or restart. In general it will not stop running unless you stop it or the machine is rebooted.

From a web server environment, PHPCron returns a status report to the browser when you call it but continues running on the server after the web browser has finished fetching the report, so you are free to close the browser window immediately.

Installation

PHPCron has been tested on PHP 5.1 and above but may work on earlier versions of PHP 5.

  1. Download the file from the downloads page and decompress it into a folder.
  2. Open cron.config.php and set the location of your crontabfile and the other files listed, as well as your email address for administrative reports.
    • The pidFile and exitFile must be in a folder that is writable by PHP and/or your web server (eg. Apache, IIS). Depending on the security configuration of your server, this may mean that you must give the folder “world” write permissions. You can set this with most FTP clients, or if you have shell access you can type chmod 777 cron where cron is the folder you extracted PHPCron into. If you set the file permissions incorrectly, PHPCron will give unexpected behaviour when you try to start, stop or restart it. To reset PHPCron after you make corrections to the file permissions, delete cron.lock and cron.exit if they exist, and call PHPCron with the kill parameter (see below).
  3. The crontab file must be writable by your web server if you are planning to use the web-based interface to edit your scheduled tasks. Use the same technique as in the previous step to make the file world writable if necessary.
  4. The crontab file should not be readable from a web browser, for security reasons. You can protect the file from being read either by moving it to a folder on the server that is not accessible via the web, or by using the web server’s access control features. With Apache in its default configuration, you can create an .htaccessfile in the same folder you extracted PHPCron into, with the following contents:
    Order Deny,Allow
    Deny from All

    This will prevent the folder contents from being read by a web browser.

  5. Unauthorised users should not be able to use PHPCron over the web. For this reason it is strongly recommended that you use an access control technique like HTTP Authentication on the folder you extracted PHPCron into, to require users to enter a valid username and password before they are able to access PHPCron. If you don’t restrict access to PHPCron, anybody can open the URL in their web browser and start or stop PHPCron, or edit your scheduled tasks. A hacker can create a simple task like:

    * * * * * rm -rf *

    to delete your entire web site or user account contents on a poorly secured web server.

Setting up your scheduled tasks

Scheduled tasks are called cronjobs in technical parlance. You can set up cronjobs in PHPCron in one of two ways:

  1. Edit the crontab file directly (either by editing it locally and uploading it to your web server via FTP, or by using a shell editor like vi on your web server).
  2. Use the web interface to edit it. If you installed PHPCron at http://www.yourdomain.com/cron, open http://www.yourdomain.com/cron/cron.php?edit in your web browser to display the editing interface. Full instructions on the available syntax in the crontab file are given in the interface.

The crontab file format is identical to that used by UNIX’s cron utility; full documentation can be found at Wikipedia’s Cron page.

PHPCron must be restarted for changes to the crontab to take effect. The web interface contains a link that will cause PHPCron to restart if it is already running, after you commit changes.

Usage from a web browser

PHPCron is called by opening the URL:

http://www.yourdomain.com/path/to/cron/cron.php?param

where param is a parameter to supply. If no parameter is supplied, PHPCron will attempt to start up if it is not already running.

Usage from the command-line

PHPCron is called by running the following command:

php cron.php --param

where param is a parameter to supply. If no parameter is supplied, PHPCron will attempt to start up if it is not already running.

Parameters

  • status – gets the running state of PHPCron
  • edit – edits the crontab file (web browser only)
  • kill – kills any running instances of PHPCron (execution of scheduled tasks will stop)
  • force – kills any running instances of PHPCron and starts one new instance (equivalent to restarting; causes changes to the crontab file to take effect). Restarting in this way may result in a delay of upto 60 seconds when called from a web browser. Be sure to wait until the browser finishes fetching the page before closing the browser window.

System tasks vs PHP tasks

The cronjobs specified in the crontab file are shell commands just as with UNIX’s cron utility. This means that you can execute any shell command available on your server under the web server’s user privileges (or under your own user privileges when running from the command-line). You can also run shell scripts you have written or uploaded to the server.

If you want to retrieve/cache a web page every half an hour, for example, you might create an entry like:

0,30 * * * * wget -O /path/to/save/location http://somedomain.com/page/to/retrieve

If you want to create a backup of your web site once a day at 9am, you might create an entry like:

0 9 * * * tar -czf /path/to/save/location/backup.tar.gz /path/to/web/site

What if you want to run PHP scripts on a timer? It’s simple! To run a PHP script from a shell command you just type php name_of_script.php where name_of_script.php is the script you want to run.

To run DoSomething.php every 2 hours on the first 7 days of each month, create an entry like:

0 */2 1-7 * * php DoSomething.php

What if you want to run a small snippet of PHP that’s not worth storing in a .php file? You can run embedded code using PHP’s -r switch. To send yourself an email on Monday mornings at 8am using PHP:

0 8 * * 1 php -r "mail('myemail@address.com', 'Subject line', 'Body of email');"

When writing embedded PHP code it’s important to bear a couple of things in mind:

  • The code must appear on one line, with each statement separated by semi-colons (;).
  • The last statement must also be terminated by a semi-colon.
  • The entire code snippet must be quoted ("...").
  • The dollar sign ($) is interpreted specially by the shell; to ensure it is processed properly by PHP as a variable identifier, you must put a backslash (\) before each dollar sign or the code will not run properly.

Supplied examples

The download includes two simple cronjobs.

The first runs test.php every minute, which simply appends a line to a text file stating when the script was executed (the target file must be writable by your web server).

The second runs on the last minute of each hour (xx:59), and uses embedded PHP to email you a status report on PHPCron’s health. It demonstrates the correct syntax for multi-statement embedded PHP code using variables.

Limitations and caveats

Due to restrictions imposed by the Windows security model, PHPCron cannot be run in an Apache web server environment on Windows (command-line operation works normally).

PHPCron keeps a process running continuously on the web server. While the process spends most of its time sleeping, some web hosts may not be happy about having long-running user processes on their machines.

Some technical details of the code itself

The information in this section is not important for using PHPCron, it is only relevant for those interested to know how it works.

Some interesting tricks are used to make PHPCron run in the background after the web browser has returned, to keep it running, and to ensure there is only one instance.

  • set_time_limit(0) ensures the PHP script will not auto-terminate after a certain length of time. By default, PHP scripts are killed if they run for more than 30 seconds to prevent badly behaved scripts from disrupting the server.
  • The function is_web_environment in PHPCron uses argc and argv to auto-detect whether a web browser or command-line instance has been started.
  • ignore_user_abort() is used to allow the PHP script to continue running after the web browser has finished fetching its output.
  • Pragma, Cache-Control and Connection: close headers are used to ensure PHPCron’s output isn’t cached, and to close the connection to the browser as soon as the output has been sent.
  • pid and exit files are used to track PHPCron. The pidFile exists if an instance is already running, and is checked for existence when subsequent instances are started to prevent multiple instances. The exitFile exists if running instances should be terminated, and PHPCron checks for the presence of this file every minute, quitting and deleting it if it exists.
  • register_shutdown_function() is used to make sure the pidFile and exitFile are deleted when the script ends even if it is aborted, crashes or is killed by an administrator (for example, with kill -9 at the shell prompt). This ensures correct behaviour of PHPCron on subsequent calls.
  • On UNIX/Linux, cronjob output is redirected to /dev/null so that each cronjob runs in the background and control is returned to PHPCron before the job has finished (no stalling). This redirection requirement is a quirk of PHP’s exec() function.
  • When using PHPCron from a web browser, Content-Length is used to tell the browser how many bytes of output there will be from PHPCron in advance. PHPCron buffers all of its output using PHP’s ob_*() functions and uses ob_get_length() when the output is completely formed to determine the number of bytes to specify in Content-Length. As soon as the specified number of bytes have been received by the browser, it closes the connection. This prevents the browser from hanging permanently when PHPCron goes into its main sleep/cronjob cycle.
  • The web-based crontab editor negates magic_quotes_gpc and magic_quotes_sybase php.ini settings.

Conclusion

I hope you find PHPCron a useful utility. Please be careful with your security settings, PHPCron is dangerous in the wrong hands! If you have any feedback, please feel free to leave comments below or email me via the contact page!

Advertisements
Categories: PHP, Releases, Web Programming Tags: , ,
  1. November 13, 2012 at 09:33

    there doesn’t seem to be anything related in the download section. looks like an interesting project would be nice to check it out. Let me know if it’s still around somewhere!
    Thanks

  2. January 18, 2013 at 19:12

    Does your blog have a contact page? I’m having a tough time locating it but, I’d like to send
    you an email. I’ve got some suggestions for your blog you might be interested in hearing. Either way, great blog and I look forward to seeing it develop over time.

  3. August 12, 2013 at 12:18

    Your style is so unique in comparison to other people I’ve read stuff from. I appreciate you for posting when you’ve got the opportunity, Guess I’ll just book mark this page.

  4. asmamaw
    October 15, 2013 at 17:07

    I have got nothing related on the download page

  5. April 8, 2014 at 10:57

    i’m having problems using it on a local environment, i’ve implemented phpdesktop (https://code.google.com/p/phpdesktop/) and i can’t find a way to invoke the script to start on run. i’ve tried an invisible iframe with a shell_exec to call wget on NUL of the url, even a bat (which is made an .exe) nothing. from the browser it starts and the ?status reports as running, with all other means it says not running.. i’m in a dead end her.

    just to be noted, we don’t want any kind of mysql solution, we need it as light as possible and phpcron script offers portability that the IT dept. likes. but can’t seem to be able to make it work for me..

    phpdesktop uses only portable mongoose and php, some unix binaries for windows are used but that’s it..

  6. ishita
    July 7, 2016 at 09:00

    plz tell me which field should i update in “corp.config.php” .

  1. July 22, 2013 at 14:45

Share your thoughts! Note: to post source code, enclose it in [code lang=...] [/code] tags. Valid values for 'lang' are cpp, csharp, xml, javascript, php etc. To post compiler errors or other text that is best read monospaced, use 'text' as the value for lang.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: