← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

PHP CLI & Command-Line Scripts

php PHP 5.0+ Beginner

Also Known As

PHP command line php cli CLI scripts

TL;DR

Running PHP from the command line for scripts, queue workers, cron jobs, and interactive tools — a distinct execution context from web requests.

Explanation

PHP CLI runs without a web server, with no request timeout, unlimited execution time by default, and access to stdin/stdout/stderr via STDIN, STDOUT, and STDERR constants. Arguments are available via $argv/$argc. Key differences from web PHP: no $_GET/$_POST/$_SERVER HTTP keys, different error output (stderr), and no output buffering by default. Use PHP CLI for: queue workers (long-running), scheduled tasks (cron), database migrations, and build scripts. Symfony Console and Laravel Artisan provide command frameworks with argument parsing, progress bars, and table output. Always handle signals (pcntl_signal) in long-running workers for graceful shutdown. Long-running CLI processes must actively manage memory — objects and references persist across iterations unlike web requests.

Common Misconception

PHP CLI scripts share the same configuration as the web server PHP process. PHP CLI uses a separate php.ini — memory_limit, max_execution_time, and extension settings often differ. CLI also does not reset state between iterations like web requests, which means memory usage and static variables persist in long-running scripts.

Why It Matters

PHP CLI enables running scripts, cron jobs, and build tools without a web server — it has different php.ini defaults, no request timeout, and access to stdin/stdout/stderr making it ideal for automation. Misunderstanding CLI behaviour leads to memory leaks, silent failures in CI, and unstable workers.

Common Mistakes

  • Not setting the correct shebang (#!/usr/bin/env php) for executable PHP scripts.
  • Using $_SERVER['REQUEST_URI'] or other HTTP superglobals in CLI scripts — they are not populated.
  • Not handling exit codes — a CLI script that exits with 0 on error confuses CI pipelines.
  • Ignoring that CLI has no memory or time limits by default — add them explicitly for long-running tasks.
  • Running long loops without freeing memory (e.g. ORM entities, large arrays) — leads to memory leaks and crashes.

Code Examples

✗ Vulnerable
// CLI script with no exit code handling — CI can't detect failure:
<?php
try {
    runImport();
} catch (Exception $e) {
    echo $e->getMessage(); // Prints error but exits with 0 — CI thinks success
}
// Fix: exit(1) on failure
✓ Fixed
#!/usr/bin/env php
<?php
// Guard: must not run via web
if (php_sapi_name() !== 'cli') {
    fwrite(STDERR, "CLI only.\n"); exit(1);
}

// Parse arguments
\$opts   = getopt('u:v', ['user:', 'verbose']);
\$userId = \$opts['u'] ?? \$opts['user'] ?? null;
\$verbose = isset(\$opts['v']) || isset(\$opts['verbose']);

if (!\$userId) {
    fwrite(STDERR, "Usage: php script.php -u <user_id>\n"); exit(1);
}

fwrite(STDOUT, "Processing user \$userId\n");

// Exit codes: 0 = success, non-zero = error
exit(0);

Added 15 Mar 2026
Edited 16 Apr 2026
Views 26
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 2 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S
Amazonbot 1 Perplexity 1
No pings yesterday
Amazonbot 8 Perplexity 7 Google 4 Unknown AI 2 Ahrefs 2
crawler 20 crawler_json 3
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use STDIN/STDOUT/STDERR for IO, always return proper exit codes (0 success, non-zero error), explicitly set memory_limit and time limits for long-running scripts, and handle SIGTERM/SIGINT with pcntl_signal() to allow graceful shutdown
📦 Applies To
PHP 5.0+ cli queue-worker laravel symfony
🔗 Prerequisites
🔍 Detection Hints
CLI script without SIGTERM handler; memory_limit not managed for long-running tasks; missing exit codes
Auto-detectable: ✗ No phpstan symfony-console
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: File

✓ schema.org compliant