首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 命令行腳本開發完全指南:CLI 模式、參數處理、守護進程與定時任務

     編輯:PHP 相關知識

PHP 三大運行模式對比

模式典型場景SAPI 名稱特點
Web 模組網站、APIapache2handler, fpm-fcgi請求-響應、無狀態、超時限制
CLI腳本、佇列、定時任務cli長運行、標準輸入輸出、無超時、進程控制
嵌入式桌面應用embedPHP-GTK、PHP-JS 等

CLI 基礎操作

# 版本信息
php -v

# 語法檢查
php -l script.php

# 交互模式 (REPL)
php -a

# 直接執行代碼
php -r 'echo "Hello " . $argv[1];' World

# 內建 Web 服務器 (開發測試)
php -S localhost:8000 -t public/

# 顯示配置
php -i | grep memory_limit
php --ini

參數處理:$argv / $argc 與 getopt()

<?php
// script.php
// 執行:php script.php -u admin -p secret --env=prod arg1 arg2

echo "argc: $argc\n"; // 參數個數(含腳本名)
print_r($argv);
/*
Array
(
    [0] => script.php
    [1] => -u
    [2] => admin
    [3] => -p
    [4] => secret
    [5] => --env=prod
    [6] => arg1
    [7] => arg2
)
*/

// 解析短選項/長選項
$options = getopt('u:p::', ['env:', 'debug::']);
/*
Array
(
    [u] => admin
    [p] => secret
    [env] => prod
    [debug] => false  // 無值時為 false
)
*/

// 位置參數(非選項)
$positional = array_diff_key($argv, array_flip(array_keys($options)));
// 需手動過濾 -- 之後的參數

標準輸入/輸出/錯誤流

<?php
// 讀取 STDIN (管道/重定向)
$stdin = fopen('php://stdin', 'r');
while (($line = fgets($stdin)) !== false) {
    echo strtoupper($line);
}
fclose($stdin);

// 寫入 STDOUT / STDERR
fwrite(STDOUT, "Normal output\n");
fwrite(STDERR, "Error message\n");

// 管道組合:cat data.txt | php process.php > result.txt 2> error.log

常見 CLI 腳本模式

1. 批量處理/數據遷移

<?php
declare(ticks=1); // 信號處理

$pdo = new PDO('mysql:host=localhost;dbname=app', 'user', 'pass');
$stmt = $pdo->query('SELECT id, data FROM large_table');

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // 處理邏輯
    $result = transform($row['data']);
    $pdo->prepare('UPDATE large_table SET result=? WHERE id=?')
        ->execute([$result, $row['id']]);
    
    // 進度顯示
    if ($row['id'] % 1000 === 0) {
        fwrite(STDERR, "Processed {$row['id']} rows\n");
    }
}

2. 守護進程/佇列消費者

<?php
// worker.php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

pcntl_signal(SIGTERM, fn() => $shutdown = true);
pcntl_signal(SIGINT, fn() => $shutdown = true);

while (!$shutdown) {
    $job = $redis->lpop('queue:jobs');
    if ($job) {
        processJob(json_decode($job, true));
    } else {
        sleep(1); // 空閒休眠
    }
    pcntl_signal_dispatch(); // 處理信號
}

3. 定時任務

# crontab -e
# 每分鐘執行
* * * * * /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1

# Laravel 任務調度 (app/Console/Kernel.php)
protected function schedule(Schedule $schedule)
{
    $schedule->command('emails:send')->hourly();
    $schedule->job(new CleanupJob)->dailyAt('02:00');
    $schedule->exec('bash /scripts/backup.sh')->weekly();
}

進階技巧

  • 顏色輸出:echo "\033[32mSuccess\033[0m\n"; 或用 symfony/console 的 OutputInterface
  • 進度條:symfony/console ProgressBar
  • 異步並發:amphp/parallel、revolt/php-parallel、spatie/async
  • 內存監控:memory_get_peak_usage(true) 定期檢查
  • 單例鎖:flock(fopen('/tmp/script.lock', 'w'), LOCK_EX | LOCK_NB) 防重複運行
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved