The PHP command-line interface allows you to invoke PHP programs (scripts) from Linux or Windows terminal, as well as have them scheduled via cron.
Command-line PHP scripts
Usually, command-line PHP scripts are the ones which provide additional functions for your website and targeted towards running tasks which require more resources (memory, CPU). Or where it is desired to offload execution to background, for performance reasons.
Command-line PHP scripts can also serve utility purpose when it is simply more efficient and fast to run arbitrary website management tasks.
- A PHP script to send out newsletter to all website subscribers (example with big memory or CPU requirement)
- A PHP script script to send transactional emails (example of offloading execution “to the background”)
- A PHP script to compress, or otherwise optimize newly uploaded images (CPU heavy task)
- PHP CLI tools like WP-CLI or n98-magerun2 for managing WordPress or Magento 2 websites, respectively (utility purpose)
Those scripts are typically not exposed for the web access, to ensure malicious users are not able to invoke them.
Run a PHP script via CLI
To run a PHP script via command-line interface, simply invoke the PHP interpreter program and pass the path to PHP script as the first argument, like so:
You can also make the PHP script directly executable by placing proper shebang at the beginning of the script and making it executable. At the top of your PHP script, add shebang:
And make it executable:
chmod +x /path/to/script.php
Now you can run your script by simply specifying its filename:
After we’ve learnt some basics, let’s move on to specifics of PHP CLI in different operating systems.
Debian (Ubuntu) specifics
Debian makes things somewhat easier on multiple fronts. One of those fronts is how you work with PHP CLI.
The PHP is built and packaged in a way that CLI and PHP-FPM use different set of configuration
The PHP CLI is invoked without memory limit in Debian based systems. As we learnt earlier, PHP CLI scripts are often used for heavy tasks. Provided that you know your scripts are coded in efficient manner, it is desired to specify
-d memory_limit=-1 option while running most of PHP CLI scripts.
So Debian way of no memory limit for CLI scripts is a sane choice for most of use cases.
CentOS (RedHat) specifics
Most of PHP distributions in CentOS do not have separate .ini configuration between PHP-FPM and CLI. However you can easily implement the desired difference, which is unlimited memory for CLI calls. This can be done through a shell alias.
~/.bashrc, you can add:
alias php='php -d memory_limit=-1'
Note that this change will apply only after logout.
And it is important gotcha that cron service will not make use of your
.bashrc file. It is a best practice to specify complete path and options in the cron task definitions.
And yet, it is still useful to keep the shell alias around, to save some keystrokes when working with the server manually.
Run a PHP script via cron
The primary feature of Linux cron service is running some tasks on a regular basis.
When you run PHP scripts via cron, PHP command-line interface is still being used. The difference is that the PHP script is run for you by the operating system on a specific schedule.
To schedule a PHP script for running, fire up
crontab -e and add your task’s definition, specifying schedule for running the script:
* * * * * /usr/bin/php -d memory_limit=-1 /path/to/script.php
The above will run
/path/to/script.php every minute. You can adjust the schedule to run it every five minutes instead:
*/5 * * * * /usr/bin/php -d memory_limit=-1 /path/to/script.php
Get notified of failures
A supplementary feature of cron is notifications upon errors:
- If the scheduled program runs without any output, no notification is being sent to the cron task’s owner.
- If the scheduled program produces any output, notification is being sent to cron task’s owner every time
You can find various sources online suggesting to “drop” the use of the notification feature by silencing any output from tasks, e.g. appending
> /dev/null 2>&1.
The command line PHP scripts which are meant for running via cron, are no different to other cron tasks – they should be coded in a way to be “cron-friendly”. So instead of “silence everything” approach, adjust the code in a way that it outputs something (
echo) only when an error happens.
This way you will know when there’s a problem that needs fixing in the script.
Aside from some logical failure in your PHP script, it may simply fail due to PHP Parse Error. This is another case where you would like to receive notifications of failure.
So the most correct way to run a well coded PHP CLI script using cron, goes down to:
<schedule definition> /usr/bin/php -d memory_limit=-1 /path/to/script.php 2>&1
It takes output from
stderr and puts it into
stdout, making it consumable by the cron service. Thus, when fatal PHP errors occurs in the script, the cron service will “see it” and send notification.
For more examples of proper cron setup of PHP CLI scripts, you may refer to: