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.