Running PHP Scripts with Cron

Lots of programmers like PHP for its ability to code and develop web applications fast. Well, this programming language was built for web. We have recently did post on caching with php to make your web sites faster. Today we want to cover another topic many developers are puzzled about, “How to run PHP Scripts with crontab?”

Cron is normally available on all Unix and Linux distributions; if you cannot access it, contact your root or server administrator. It is a daemon which allows you to schedule a program or script for a specific time of execution. If you want to learn more about cron, click here or type “man crontab” at your command prompt.

I have found myself in the need to run PHP scripts at specific times. For example, to update the content of a website, to remove expired articles, to send out e-mails on a given date and a lot more. While some may think that this is were PHP is doomed, I will show you how it’s done.

A Manual crontab?

The first solution that came to my mind was to run the script directly from my browser (e.g. entering www.mydomain.com/script.php into the web browser).

Since I need to run my script on a regular basis, I squashed that idea. My goodness, all the extra hassle is ridiculous.

An include?

Another possible solution is to include the script in one of the pages of the site, for example the very first index.php file.

<? include "cron.php"; ?>

The drawbacks to this solution are, that it works but when someone accesses the index.php. This could cause a lot of extra overhead produced by the script. If you get a lot of traffic, the script is executed 1000 times a day and adds a lot of usage on the database and the server.

On the other hand, if you do not get a lot of traffic, or people tend to access your site over another file, this will not work out as well. If you need to run the script on a regular intervals, this is not a solution.

Crontab!

Let’s suppose you either know what cron is or have read about it using the link above. We want to run our script once a minute. So where do we go from here? Here is how you can accomplish this task.

Your PHP setup

You will need to find out the answer to the following question, Is my PHP installed as CGI or as an Apache module?
To find out do the following: Create a new file, name it info.php (just an example), and put in the following code:

<? phpinfo(); ?>

Upload to your web server and go to it with your browser. Now check for Server API (4th item from the top), if it says CGI, you have PHP compiled as CGI, if it reads Apache, you have it running as an Apache module. These days most PHP installations are done as a Apache web server modules.

Compiled CGI

If the answer to the question above is “CGI” then you need to add a line to your PHP script. It has to be the first line of your script and must contain your server’s PHP executable location:

#!/usr/local/bin/php -q

That looks a lot like PERL now, doesn’t it? After that let’s add the necessary command to our crontab. Edit /etc/crontab and add the following line:

* * * * * php /path/to/your/cron.php

Execute the following from the command line:

Shell> crontab crontab

Be sure your script.php has the necessary permissions to be executable. If not, the shell command to do it is:

Shell> chmod 755 script.php

Now you are all set!

Apache module

If your PHP is installed using the Apache module, the approach is a little different. First, you need access to Lynx (Lynx Browser for more information). Lynx is a small web browser, generally available on Unix and Linux.

Running your PHP script will not require you to add any additional lines. You simply have to edit your /etc/crontab file and add the following line:

* * * * * lynx -dump http://www.somedomain.com/cron.php

Please note that in general, you have to specify the entire URL (with “http://” and so on). But depending on your Lynx’s configuration, the URL might be relative; I suggest always using the absolute reference as in my example above – it always works.

Again execute the following from the command line:

Shell> crontab crontab

That all it takes to get a cron job setup using PHP. Hope you have learned something new and will use it to save overhead time on the server and on the developer.

56 Responses

  • dave

    There is another way that seems to be independent of whether php is installed as a module or cgi…use curl or wget.

    * * * * * /usr/bin/curl -o http://www.yoursite.com/path/to/script.php

    or

    * * * * * /usr/bin/wget -q -O /dev/null http://www.yoursite.com/path/to/script.php

    Just wanted to throw that out there since it seems some jobs on certain webhosts just don’t work with either previous option.

  • @dave.

    Nice one, if like me you don’t have cgi version of PHP, or lynx installed wget does the business – thanks for throwing it out, caught with gratitude!

  • As for me it is very unusuall to use such script

  • Nice one., Yeah! This allows you to run your PHP scripts at command line similar to Perl or any other scripting language. No need to learn another scripting language such as Perl, Bash or Awk.

  • MrSato

    None of these work for me! :-(

    What’s up with that?

    If I bring up the “page” (php script) in my browser, from a different machine (windows) it runs and does its job. But if I try any of the 3 above methods, nothing appears to happen. No error messages, nothing.

    I’m running Ubuntu and the script was created by phpMyBackupPro.

  • @MrSato – Is your PHP installation running as a CGI module or an apache module?

    Do you know if you have any sort of GUI front-end installed to help you manage crontabs? On my personal server, we’re running Webmin, which allows you to easily add crontabs to your server.

    Are you able to run PHP from the command-line? If so, try running your PHP script from the command-line and see if it works. If so, then the cron job should run. If not, then you’re going to need to find a different way to run the cron job.

  • Mahesh Vanneldas

    @MrSato – Hi
    do you the lynx installed on your server, if not then installed it

    then to run the cron tab just
    lynx -dump “http://www.yoursite.com/path/to/script.php”

    Hope this will help.

    Regards
    Mahesh Vanneldas

    • Noel

      #10 solution worked perfectly for me after trying many many other methods. Although I sdidn’t use “” around the url

  • You need to add the run times at the beginning of each line e.g.

    5 * * * * wget etc…
    or
    1/ * * * wget will run every minute etc..

  • Check also my tutorial – maybe you’ll find it useful: http://www.lampdocs.com/blog/2008/09/18/how-to-run-a-php-file-using-crontab/

  • Shiki

    Thanks!

  • Hi
    I’m new to this “cron” thingi.
    Can you recommend where to learn more about it?

    Searching the net only confusing me more. :(

    Thanks,
    Amit.

  • Vanquish

    Hiya,

    is there any solution to runa .php via cron, which is NOT accessible through web?

    Cheers! :)

  • @Vanquish – If you have access to set up actual crontabs through your server, it is absolutely possible. You can place a PHP script anywhere on the server. As long as you have the command-line interface (CLI) extension for PHP installed, you can tell the crontab to execute the PHP script.

  • @MrSato – Is your PHP installation running as a CGI module or an apache module?

  • MarcG

    Thanks for the advice. The Apache module command was exactly right!

  • A thousand thank you’s. Great article, exactly what I was looking for to run a PHP script once a day.

  • Easy Daemons in PHP

    […] This class and script makes it easy to turn a one-shot php script into a daemon that runs in the background on a timer. This is good for things you want to happen infrequently. For example, your site may need to use curl to fetch several different rss feeds, combining them into one feed. You don’t want to fetch all the feeds every time someone asks for the combined one. It is better to generate the combined feed every 5 minutes or so. […]

  • Vince Cannon

    I need to run a cron for my auto-responder and the setting for the auto-responder are set to deliver the message every 10 minutes but when I set the cron it doesn’t seem to be working.

    This is the path /usr/bin/php -f /home/mysite/public_html/AR/admin/cron/cron.php

    This is the cron setting that was provided by the AR script and it’s supposed to run according to my settings in the AR Admin section.

    What is the purpose of the -f ?

    What would the wildcard settings be if I want the cron to run every 10 minutes?

  • If none of these work for you, you can use wget
    wget –output-document=temp http://yourname.com/file.php

    wget just downloads the file. It is requesting it over http, so the webserver executes the script first (which is what you want).
    “–output-document=temp” saves the file as “temp” and overwrites the old one each time, so you don’t end up with several copies. You could also just save it to the temp directory, then it is deleted automatically.

    This does require that the script be somewhere that is accessible by the public, but it should work no matter how php is setup, and whether or not lynx is installed

    You’ll still need to setup the crontab, but using this command will work

  • Jake

    I’m using this

    * * * * * /usr/bin/wget -q -O /dev/null http://www.yoursite.com/path/to/script.php

    and it works fine in command line, but not when i try to use it by cron. Does anyone know whats wrong? Looks like cron never does the job..

    • Jake

      I have solution.. Add one whitespace after the line in the crontab file

  • Hey Amit:

    Hoping you found the solution to your problem by now, but for other who are struggling with Cron, consider using an online cron replacement service to run your cron job PHP scripts. I personally recommend http://cronless.com because they’re reliable, easy to use, friendly and stable.

    They offer free cron jobs and site monitoring with a reasonably priced upgrade. Site monitoring too. Great service. Check them out.

  • Nitesh

    Iam customizing vtiger CRM. There are following users in the system based on the heirarchy:
    Technician – Territory Manager – Area Sales manager – MD

    Trouble ticket is created by Technician is assigned to Territory manager. Territory manager has 30 min to respond to the same. If he fails to, it automatically escalates to Area Sales Manager. The same time limit applies to him after which it gets escalated to the MD. the MD should be able to view all the details along with the date and time.

    a cron script that can scan all open trouble tickets should work . Based on the last-modified time and current time difference I have set the assigned_user_id to right user-id. But, it is not working. I would really appreciate your help.

    Regards,
    Nitesh

  • akou

    I want to create cronjobs for the 2 following files,

    include/CronStats.php
    include/AlexaThumbCronJob.php

    Plz reply if you have a idea how i can create this

    thanks a lot

  • terry

    @akou I use cronless.com to automate php scripts that validate links in my web directories, its been working perfectly well for the past 3 months.

  • Clark Burns

    @Vince Cannon

    using -f with the php command stands for file

    a quick ‘man php’ on the command line will give you lots of information ;)

  • If your cron jobs do important stuff for your business I suggest to look for some way to monitor their work.

    There are number of monitoring tools, but if you don’t want to install and configure ‘a big ones’ you can try service called AlertGrid (http://alert-grid.com)

    You can easily integrate it with your cron jobs and receive SMS/phone/email notifications if your jobs don’t respond for some time, or respond with some errors.

  • mani

    please anyone reply for this..
    i have installed php in my system using windows installer for php..
    but after installing that when i run my php files in web browser it shows my coding page.. why????

  • alex

    hey! trying to get the cron job to work, got 2 questions :

    1. what does the * -q * do ?

    2. the line :* #!/usr/local/bin/php -q * that needs to be put in the .php script as the first line, is it before or after the <?php … cause if I put it after it becomes a comment.. so not sure..

    Let me know! thx!

  • ige

    i am having difficulty with running a php script at the shell prompt for testing.
    can somebody enlighten me?
    or point me to sites which explain relevant things i need to understand.
    many thanks.

    i have these :
    a) ubuntu 8.04 LTS, apache, php, mysql, bash

    b) directory: ../webroot/
    -rwxr-xr– 1 root root 6.9K 2010-12-01 18:31 yy.php

    this is a php script that reads log files at /var/www/ylogs and
    converts contents to records into a mysql table.
    i hope to run this script in cron later after a successful testing.

    c) directory: /var/www/ylogs
    -rwxrwx— 1 www-data root 185 2010-12-03 15:08 tallyA
    -rwxrwx— 1 www-data root 185 2010-12-03 15:08 tallyB


    -rwxrwx— 1 www-data root 185 2010-12-03 15:08 tallyZ

    d) what happens :
    when i try entering http://localhost/webroot/yy.php at the URL field in Firefox,
    the script works.

    but when i am in a bash shell prompt and i try :
    sudo -i (i enter password of the default-sudoer-user, i am given this prompt)
    root@name-of-computer :~#
    and i issue
    lynx -dump http://localhost/webroot/x.php

    it gives me this error :
    Connection to 127.0.0.1 failed, (111) Connection refused

    but when i logout from root into
    default-sudoer-user@name-of-computer :~$
    and i issue
    lynx -dump http://localhost/webroot/yy.php
    it works

    when i log as a regular user (non-sudoer)
    regular-user@name-of-computer :~$
    and i issue
    lynx -dump http://localhost/webroot/yy.php
    it also works.

    when the tally logs are owned as root:root, i get permission denied when i run the script,
    but when the tally logs are chowned as www-data:root, the script runs.

    e) some questions :
    in bash (and later cron), what user should i run the script yy.php as?
    (and also in apache/php, my understanding is it should be www-data?)

    if several computers are to submit their respective tallies
    via a cronned scp into this /var/www/ylogs directory,
    should i give these computers login access as user www-data
    so that apache/php can run the script?
    is this secure?

    i am so confused, any help will be appreciated.
    and sorry for a very long post.

  • ige

    sorry, my typo error in comment #32

    in d) but when i am in a bash shell prompt …

    and i issue
    lynx -dump http://localhost/webroot/x.php

    should read
    lynx -dump http://localhost/webroot/yy.php

    thanks again for any leads

  • sanantone

    why not install php-cli?

    then write your php script with the shebang in the first line (path must be to your php executable, -q is optional now i believe)

    #!/usr/bin/php -q

    followed by typical php stuff, example

    <?php echo php_info();

    the resulting script file can be executed from the command line:
    php myphpinfoscript.php

    or if you chmod myphpinfoscript.php as executable, then simply run it as
    ./myphpinfoscript.php

    the .php is optional too

  • Randy

    Thanks… this was the info I needed to get my first PHP cron running.

  • I was having a problem setting up a cron job, but after reading your post I was able to fix it – thank you!

  • Vebh

    i want to start my automatic newsletter section through in queue sending, right now i am with proper setting from Magento panel for my site, please suggest me a best solution for newsletter queue.

  • Stefano

    I have php as apache module, lynx is not possible install.
    with wget not successful operation. with curl not successful operation

    my script php content:

    ThisPath = realpath( dirname(__FILE__) ); 
    include($ThisPath.'/../config_db.php');
    /** link al db */
    $link = mysql_connect($DB_host,$DB_login,$DB_password);
    if (!$link) {
        die("\r \n Impossibile connettersi: ".mysql_error());
    } else {
        echo "\r \n Connesione eseguita a: ".$DB_host;
    }
    /** Select DB */
    $db_selected = mysql_select_db($Application["dati"], $link);
    if (!$db_selected) {
        die ("\r \n Impossibile utilizzare: ".mysql_error());
    } else {
        echo "\r \n Selezione del DB: ";    
    }
    $backupFile= $ThisPath.'/'.$Application["dati"] . date("Y-m-d-H-i-s") . '.gz';
    echo $Application["dati"];
    $command='mysqldump --opt -h '.$DB_host.' -u'.$DB_login.' --password='.$DB_password.' -A | gzip > '.$backupFile;
    echo $command;
    system($command);
    
    string $command result:
    mysqldump --opt -h 127.0.0.1 -u root --password=password -A | gzip > /var/www/BK_db/db2011-02-02-13-15-36.gz
    

    why?

  • I use Dashboard, but this code does not work. What could be the reason?

    php -q /domains/sitename.com/public_html/phpfilename.php

  • Hi,

    I am going to run crontab job on php by using GET parameter. Does it work?.

    for e.g:
    1 * * * * c:\php.exe c:\test.php?action=fruits

    I tested and failed. Is there any way to run php file but using GET paramenter as I described above?.

    So, if it could works, will be easier for me to maintain function/ code only in a single php file.

    Thanks.
    Doya.

  • Todor Pavlov

    The best solution for me is to create only one cron job which runs every minute:
    * * * * * php /path/to/your/cron.php

    and then to make web interface to execute as many scripts as you want in what time you want. The names of the scripts and the time for execution can be written in the database and executed with system() php function

  • One thing to add: keep your php-output to a minimum. any output of a script run by a cronjob will be reported to the user. So set the error_reporting() to an appropiate level and remove all the echos if you don’t need the output.

  • We recently prepared a mini project (PHP>=5.3) to manage the cron files for private and individual tasks. This tool connects and manages the cron files so you can use them, for example per project. Unittests avialable :-)

    Sample from command line:

    bin/cronman –enable /var/www/myproject/.cronfile –user www-data

    Sample from API:

    use php\manager\crontab\CrontabManager;

    $crontab = new CrontabManager();
    $crontab->enableOrUpdate(‘/tmp/my/crontab.txt’);
    $crontab->save();

    Managing individual tasks from API:

    use php\manager\crontab\CrontabManager;

    $crontab = new CrontabManager();
    $job = $crontab->newJob();
    $job->on(‘* * * * *’);
    $job->onMinute(’20-30′)->doJob(“echo foo”);
    $crontab->add($job);
    $job->onMinute(’35-40′)->doJob(“echo bar”);
    $crontab->add($job);
    $crontab->save();

    github: https://github.com/MediovskiTechnology/php-crontab-manager

  • how to make cron setup for schedule back up in cpanel?

  • jason

    Hi, thank you for the insight.
    Just so I am clear, in the method you describe above, are we simply using CRON to call the php script via browser (WGET or Lynx as you mention)?

    In other words, is CRON calling the php script directly from the Linux shell or is it actually calling upon a browser to call the script just as a human might if they opened a browser to the php script URL every 5 minutes or whatever?

    If I am correct, can I assume then that theoretically the php script and the CRON job could actually live on two separate machines? Further, if I am understanding correctly, is there any downside to calling the script via WGET as opposed to directly from the shell (if that is possible… I’m kinda of a Linux novice)

    Thank you very much! J

    • Right, if you are using the option where cron is running Lynx, wget or curl, cron is executing these tools and pointing them to your php file on the web server. Lynx is a browser, wget or curl are command line tools but in this case the result is the same.

      Web server (which servers your php file) can be running on the same server as cron or can be completely remote.

      As for downsides. The only downside I see is that this php script is exposed to the public and this means that everyone can access it from any web browser. So theoretically someone can be continuously running your cron script without you having control over this process.

      As a solution to this you could add some security in your cron.php file to only if requested form specific IP address etc.

  • pramod

    I have set sh on crontab When it’s running it will take by default 3 red line which I have set on sh file.

    Below these format i have put on crontab

    /usr/bin/php /var/www/html/metro/script.php
    /usr/bin/php /var/www/html/metro/header.php

    sh /var/www/html/test.sh

    is it correct can u pls tell me

  • Jason U.

    Not sure why you would need to use an independent browser. You could just ssh into your server, open the file using nano, save, and your done. No more extra steps.

    • Well, the idea here is that one can run any PHP scripts by Cron on any independent box. In order for PHP script to be processed you just point browser or curl to that PHP file.

  • Salome

    I found something that looks like a good useful – easycron.com which will load a specific URL at a given time.

  • Fully Help

    Thanks for sharing your information article i love to read the A php tutorials that covers all the basics of php.

  • Backler

    Thanks for the article. I use a cron service called easycron.com to trigger the php script to run.

    • its a nice service, and it has a free account to try. but you have to pay for any reasonable use.
      the approach we are discussing in this post allows you to reduce this cost

  • meigie

    how about crontab in windows?

  • Siva Shankar

    how to retrieve this?

    System should have a functional web-based front-end.
    It should list all the cron jobs on the server or have the ability to configure jobs individually.
    It should be able to detect success and failure of jobs based on exit codes of scripts.
    Provide ability to look at scripts outputs (stdout/stderr).