Site icon GetPageSpeed

PHP CLI: Complete Guide to Running Scripts from Command Line

PHP CLI

PHP CLI

πŸ“… Updated: February 18, 2026 (Originally published: December 30, 2018)

PHP CLI (command-line interface) lets you run PHP scripts directly from the terminal without a web server. This makes it perfect for cron jobs, background tasks, database migrations, and administrative scripts that need more memory and CPU than typical web requests allow.

Whether you’re sending newsletters to thousands of subscribers, processing image uploads, or running WP-CLI commands for WordPress management, understanding command-line PHP execution is essential for any developer working on Linux servers.

Why Use Command-Line PHP Instead of Web Requests?

Running PHP from the command line offers several advantages over triggering scripts via HTTP:

No timeout limits: Web requests typically timeout after 30-60 seconds. Command-line scripts can run for hours if needed.

More memory available: You can allocate unlimited memory to CLI scripts, while web requests are constrained by memory_limit.

No web server overhead: Scripts execute directly without Apache or NGINX, reducing resource consumption.

Secure execution: CLI scripts aren’t exposed to the internet, eliminating attack vectors.

Better error output: Stack traces and errors display directly in the terminal rather than hiding in logs.

Common Use Cases for Command-Line PHP

Background Processing

Heavy tasks should run in the background rather than blocking web requests:

Administrative Tools

Command-line PHP powers essential tools that system administrators rely on daily:

Scheduled Tasks

Cron jobs rely on PHP CLI to run recurring tasks automatically. See our dedicated guide on Magento 2 cron jobs or WordPress cron optimization for framework-specific examples.

Running PHP Scripts from the Command Line

Basic Execution

The simplest way to run a PHP script is invoking the interpreter directly:

/usr/bin/php /path/to/script.php

You can also pass arguments to your script:

/usr/bin/php /path/to/script.php --verbose --config=/etc/myapp.ini

Access these arguments in PHP via $argv or use getopt() for proper option parsing:

<?php
$options = getopt('v', ['verbose', 'config:']);
$verbose = isset($options['v']) || isset($options['verbose']);
$config = $options['config'] ?? '/etc/default.ini';

Making Scripts Directly Executable

Add a shebang line at the top of your PHP script:

#!/usr/bin/env php
<?php
echo "Hello from the command line!\n";

Then make it executable:

chmod +x /path/to/script.php

Now run it directly:

/path/to/script.php

Using #!/usr/bin/env php is preferred over #!/usr/bin/php because it finds PHP in the user’s PATH, making scripts portable across different systems where PHP might be installed in different locations.

Checking PHP Version and Modules

Before running scripts, verify your PHP environment is properly configured.

Check PHP Version

php --version

Example output on Rocky Linux 10:

PHP 8.3.26 (cli) (built: Sep 23 2025 17:57:26) (NTS gcc aarch64)
Copyright (c) The PHP Group
Zend Engine v4.3.26, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.26, Copyright (c), by Zend Technologies

List Loaded Modules

See all loaded PHP extensions:

php -m

Check if a specific module is loaded:

php -m | grep -i mysql

View Configuration Values

Check a specific configuration value:

php -r "echo ini_get('memory_limit') . \"\n\";"

View all configuration settings:

php -i

Or filter for specific settings:

php -i | grep -i opcache

Configuration for Command-Line PHP

The CLI uses a separate php.ini configuration file from PHP-FPM. Find your configuration:

php --ini

On Rocky Linux and RHEL, this typically shows /etc/php.ini or /etc/php.d/ directory for modular configuration.

Memory Limits

The most common configuration change is removing memory limits. Heavy scripts like data imports or image processing need more memory than the default 128MB.

Temporary override (recommended for most cases):

php -d memory_limit=-1 /path/to/script.php

Permanent change in /etc/php.d/99-cli.ini:

; Remove memory limit for CLI scripts
memory_limit = -1

Execution Time

Unlike max_execution_time which only affects web requests, CLI scripts run until completion by default. The set_time_limit() function also has no effect in CLI mode, giving your scripts unlimited runtime.

Rocky Linux and RHEL Configuration

On Rocky Linux 9/10, AlmaLinux, and RHEL systems, command-line PHP configuration requires some attention.

OPcache for the CLI

Enable OPcache to speed up frequently-run scripts. In Rocky Linux 10 with PHP 8.3, this is enabled by default. Verify with:

php -r "echo 'opcache.enable_cli=' . ini_get('opcache.enable_cli') . \"\n\";"

If disabled, add to /etc/php.d/10-opcache.ini:

opcache.enable_cli=1

For scripts that run briefly, file-based OPcache provides better performance. See our detailed guide on Faster PHP CLI and Cron Jobs for optimal OPcache configuration.

Shell Alias for Convenience

Add a shell alias in ~/.bashrc to always run PHP with unlimited memory:

alias php='php -d memory_limit=-1'

Apply changes:

source ~/.bashrc

Note: This alias only works in interactive shells. Cron jobs and systemd services don’t load .bashrc, so always specify options explicitly in those contexts.

Running PHP Scripts via Cron

Cron executes scripts on a schedule. Edit your crontab:

crontab -e

Cron Syntax

* * * * * command
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ └─ Day of week (0-7, Sunday = 0 or 7)
β”‚ β”‚ β”‚ └─── Month (1-12)
β”‚ β”‚ └───── Day of month (1-31)
β”‚ └─────── Hour (0-23)
└───────── Minute (0-59)

Example Cron Jobs

Run every minute:

* * * * * /usr/bin/php -d memory_limit=-1 /var/www/html/cron.php

Run every 5 minutes:

*/5 * * * * /usr/bin/php -d memory_limit=-1 /var/www/html/process-queue.php

Run daily at 3 AM:

0 3 * * * /usr/bin/php -d memory_limit=-1 /var/www/html/cleanup.php

Error Notifications

Cron sends email notifications when scripts produce output. Configure this behavior:

Send all output via email (default):

*/5 * * * * /usr/bin/php /path/to/script.php 2>&1

The 2>&1 redirects stderr to stdout, ensuring PHP fatal errors and parse errors trigger notifications.

Silence everything (not recommended):

*/5 * * * * /usr/bin/php /path/to/script.php > /dev/null 2>&1

Best practice: Write β€œcron-friendly” scripts that only output on errors. This way you receive notifications only when intervention is needed, rather than silencing potentially important warnings.

Cron Environment Differences

Cron runs with a minimal environment:
– No .bashrc or shell aliases
– Limited PATH (usually /usr/bin:/bin)
– No TTY (terminal) attached
– Different working directory

Always use absolute paths in cron jobs:

# Good
*/5 * * * * /usr/bin/php /var/www/html/app/console cache:clear

# Bad - assumes current directory and PATH
*/5 * * * * php app/console cache:clear

Systemd Timers: Modern Alternative to Cron

Systemd timers offer advantages over cron: better logging via journalctl, dependency management, and resource controls like CPU/memory limits.

Create a service file /etc/systemd/system/myapp-cleanup.service:

[Unit]
Description=MyApp Cleanup Task

[Service]
Type=oneshot
User=nginx
ExecStart=/usr/bin/php -d memory_limit=-1 /var/www/html/cleanup.php

Create a timer /etc/systemd/system/myapp-cleanup.timer:

[Unit]
Description=Run MyApp cleanup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the timer:

systemctl enable --now myapp-cleanup.timer

View timer status and next scheduled run:

systemctl list-timers --all

View logs from previous runs:

journalctl -u myapp-cleanup.service

Debugging Command-Line PHP Scripts

Error Display

Enable error display for debugging:

php -d display_errors=1 -d error_reporting=E_ALL /path/to/script.php

Interactive Mode

Test PHP code interactively:

php -a

This opens a REPL (Read-Eval-Print Loop) where you can type PHP code and see immediate results. Useful for quick testing without creating files.

Xdebug for Step Debugging

Xdebug works with command-line scripts for step-debugging. Configure in /etc/php.d/xdebug.ini:

xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=127.0.0.1

Then run with the XDEBUG_SESSION environment variable:

XDEBUG_SESSION=1 php /path/to/script.php

Security Best Practices

File Permissions

CLI scripts shouldn’t be web-accessible. Store them outside the document root:

/var/www/
β”œβ”€β”€ html/          # Document root (public)
β”‚   └── index.php
└── scripts/       # CLI scripts (private)
    └── cron.php

Environment Variables

Don’t hardcode credentials in scripts. Use environment variables:

export DB_PASSWORD="secret"
/usr/bin/php /path/to/script.php

Access in PHP:

$password = getenv('DB_PASSWORD');

For systemd services, use Environment= or EnvironmentFile= directives to securely pass credentials without exposing them in command lines.

Running as Non-Root

Never run scripts as root unless absolutely necessary. Use a dedicated user:

sudo -u www-data /usr/bin/php /var/www/html/cron.php

In system crontab (/etc/cron.d/myapp), specify the user:

*/5 * * * * www-data /usr/bin/php /var/www/html/cron.php

Conclusion

PHP CLI is indispensable for running background tasks, scheduled jobs, and administrative scripts on Linux servers. Whether you’re managing WordPress with WP-CLI, running Magento cron jobs, or building custom automation scripts, command-line PHP provides the flexibility and power you need.

Key takeaways:

For advanced optimization, especially on Rocky Linux and RHEL systems, see our guide on Faster PHP CLI and Cron Jobs which covers OPcache tuning and performance best practices.

Exit mobile version