← All posts

Tutorial Backend

How to Write a PHP Cron Job and Schedule It with crontab

Write a PHP cron job script and schedule it with crontab to automate tasks like backups, emails, and data cleanup.

Difficulty Beginner Time 20 min
PHP cron job script scheduled with crontab for automated task execution on a schedule

Cron jobs automate repetitive tasks by running scripts at scheduled intervals. In this tutorial, I will write a simple PHP script designed to run as a cron job, test it manually, schedule it with crontab to run automatically, and configure logging so you can monitor execution. By the end, you will have a working PHP cron job that runs on a schedule without manual intervention.

Prerequisites

  • A LAMP server with PHP installed
  • SSH access to the server
  • Basic familiarity with the command line
  • A text editor like nano or vim

Step 1 - Write a Simple PHP Cron Script

Create a directory for your cron scripts:

mkdir -p /var/www/cron cd /var/www/cron

Create a new PHP file:

nano cleanup.php

Add this basic script that logs a timestamp and performs a simple task:

<?php // Set timezone date_default_timezone_set('America/New_York'); // Log file path $logFile = '/var/www/cron/cleanup.log'; // Current timestamp $timestamp = date('Y-m-d H:i:s'); // Write to log file_put_contents($logFile, "[$timestamp] Cleanup job started\n", FILE_APPEND); // Example task: delete old temporary files $tmpDir = '/tmp/myapp'; if (is_dir($tmpDir)) { $files = glob($tmpDir . '/*'); $deleted = 0; foreach ($files as $file) { if (is_file($file) && time() - filemtime($file) > 86400) { unlink($file); $deleted++; } } file_put_contents($logFile, "[$timestamp] Deleted $deleted old files\n", FILE_APPEND); } else { file_put_contents($logFile, "[$timestamp] Directory not found\n", FILE_APPEND); } file_put_contents($logFile, "[$timestamp] Cleanup job finished\n", FILE_APPEND); ?>

This script deletes files older than 24 hours from a temporary directory and logs its activity. Adjust the timezone and paths to match your environment.

Save and close the file.

Step 2 - Make the Script Executable

Set proper permissions on the script:

chmod +x /var/www/cron/cleanup.php

Ensure the script is owned by the web server user or the user that will run the cron job:

sudo chown www-data:www-data /var/www/cron/cleanup.php

On CentOS or RHEL, the user is typically apache instead of www-data.

Step 3 - Test the Script Manually

Before scheduling, run the script manually to ensure it works:

php /var/www/cron/cleanup.php

Check the log file to verify output:

cat /var/www/cron/cleanup.log

You should see timestamped log entries showing the script ran successfully. If you see errors, fix them before proceeding.

If the log file was not created, check that the directory is writable:

ls -la /var/www/cron/

Step 4 - Understand Crontab Syntax

Crontab uses five time fields followed by the command to run:

* * * * * command │ │ │ │ │ │ │ │ │ └── Day of week (0-7, where 0 and 7 are Sunday) │ │ │ └──── Month (1-12) │ │ └────── Day of month (1-31) │ └──────── Hour (0-23) └────────── Minute (0-59)

Common schedule examples:

  • Every minute: * * * * *
  • Every hour at minute 0: 0 * * * *
  • Every day at 2:30 AM: 30 2 * * *
  • Every Monday at 9:00 AM: 0 9 * * 1
  • First day of every month: 0 0 1 * *

Step 5 - Open Your Crontab

Edit the crontab for the current user:

crontab -e

If this is your first time, you may be asked to choose an editor. Select nano for simplicity.

To edit the crontab for a specific user like www-data:

sudo crontab -u www-data -e

This is useful if your PHP script needs to run as the web server user.

Step 6 - Add the Cron Job

Add a line to schedule your PHP script. To run it every day at 3:00 AM:

0 3 * * * /usr/bin/php /var/www/cron/cleanup.php

Always use absolute paths for both the PHP binary and the script. Find your PHP binary location:

which php

For testing, schedule it to run every minute:

* * * * * /usr/bin/php /var/www/cron/cleanup.php

Save and close the file. Crontab will confirm the installation with a message like crontab: installing new crontab.

Step 7 - Verify the Cron Job Is Scheduled

List all cron jobs for the current user:

crontab -l

You should see your scheduled job in the output. To list cron jobs for www-data:

sudo crontab -u www-data -l

Step 8 - Monitor Cron Job Execution

Wait a minute or two, then check your log file:

tail -f /var/www/cron/cleanup.log

You should see new entries appearing every minute if you scheduled it that frequently. Press Ctrl+C to stop watching the log.

Also check the system cron log to see when jobs execute:

sudo tail -f /var/log/syslog | grep CRON

On CentOS or RHEL, use:

sudo tail -f /var/log/cron

You will see entries like CRON[12345]: (www-data) CMD (/usr/bin/php /var/www/cron/cleanup.php) each time the job runs.

Step 9 - Redirect Output and Errors

By default, cron emails output and errors to the user. To log them to a file instead, redirect output in your crontab:

0 3 * * * /usr/bin/php /var/www/cron/cleanup.php >> /var/www/cron/cron_output.log 2>&1

This appends both stdout and stderr to cron_output.log. To discard all output:

0 3 * * * /usr/bin/php /var/www/cron/cleanup.php > /dev/null 2>&1

To log errors only:

0 3 * * * /usr/bin/php /var/www/cron/cleanup.php > /dev/null 2>> /var/www/cron/errors.log

Step 10 - Handle Environment Variables

Cron jobs run with a limited environment. If your script relies on environment variables, set them in the crontab. Add these lines at the top of your crontab file:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin SHELL=/bin/bash

You can also set custom variables:

APP_ENV=production DB_HOST=localhost

Then your scheduled jobs appear below these declarations.

Step 11 - Disable or Remove a Cron Job

To temporarily disable a cron job, comment it out with a hash symbol:

# 0 3 * * * /usr/bin/php /var/www/cron/cleanup.php

Save the crontab. The job will no longer run.

To permanently remove all cron jobs for the current user:

crontab -r

Use this with caution as it deletes the entire crontab without confirmation.

Step 12 - Common Pitfalls and Solutions

If your cron job does not run, check these common issues:

  • Use absolute paths for the PHP binary and script file
  • Ensure the script has execute permissions
  • Check that the cron daemon is running: systemctl status cron
  • Verify file paths exist and are accessible by the cron user
  • Look for errors in /var/log/syslog or /var/log/cron
  • Test the script manually with the same user: sudo -u www-data php script.php

Note: Cron does not source your bash profile, so aliases and custom PATH entries may not be available. Always use absolute paths.

Wrap-up

You have written a PHP cron job script, scheduled it with crontab, and configured logging to monitor execution. Cron jobs are essential for automating maintenance tasks, sending scheduled emails, generating reports, cleaning up old data, and running backups. Always test scripts manually before scheduling, use absolute paths, log output for debugging, and monitor the first few executions to ensure everything works as expected. For complex workflows, consider using a job queue system like Laravel Scheduler or a dedicated task runner instead of raw cron.