PHP 不僅是 Web 開發語言,編譯為 CLI SAPI 後,同樣能勝任 Shell Script 自動化任務:系統管理、資料處理、定時任務、守護進程。本文說明 CLI 版本安裝、特性差異、實戰範例與最佳實踐。
# 1. 下載原始碼
wget https://www.php.net/distributions/php-8.2.10.tar.gz
tar xzf php-8.2.10.tar.gz
cd php-8.2.10
# 2. 僅編譯 CLI (無 Apache 模組、無 Web 擴充)
./configure \
--disable-all \
--enable-cli \
--enable-phar \
--enable-mbstring \
--enable-json \
--enable-pdo \
--with-pdo-mysql \
--with-openssl \
--with-curl \
--with-zlib \
--with-readline \
--without-pear
# 3. 編譯安裝
make -j$(nproc)
sudo make install
# 4. 驗證
php -v
# PHP 8.2.10 (cli) (built: ...)
php -m | grep -E 'cli|pdo|mbstring|json|phar'
Windows:下載官網 Non Thread Safe (NTS) ZIP 版,解壓至 C:\php,將目錄加入 PATH,重命名 php.ini-development 為 php.ini 並調整擴充套件。
| 特性 | CLI (php) | Web (mod_php/php-fpm) |
|---|---|---|
| 啟動方式 | 命令列 php script.php | HTTP 請求觸發 |
| 預設 php.ini | php.ini (cli 專用) | php.ini (fpm/apache 專用) |
| 輸出緩衝 | 預設關閉 (output_buffering=0) | 預設開啟 (4096) |
| 執行時間限制 | 無限制 (max_execution_time=0) | 通常 30-60 秒 |
| 當前工作目錄 | Shell 當前目錄 | 腳本所在目錄 |
| $_SERVER 變數 | 無 REQUEST_URI、HTTP_* 等 | 完整 HTTP 環境 |
| stdin/stdout/stderr | 標準串流可互動 | 輸出導向 HTTP 回應 |
| 錯誤顯示 | 直接輸出終端 | 依 display_errors/log_errors |
<?php
// import_csv.php
$file = $argv[1] ?? 'data.csv';
$pdo = new PDO("mysql:host=localhost;dbname=app;charset=utf8mb4", "user", "pass");
$stmt = $pdo->prepare("INSERT INTO products (sku, name, price) VALUES (?, ?, ?)");
$handle = fopen($file, 'r');
fgetcsv($handle); // 跳過標題
$count = 0;
while (($row = fgetcsv($handle)) !== false) {
$stmt->execute([$row[0], $row[1], $row[2]]);
$count++;
if ($count % 1000 === 0) echo "已匯入 {$count} 筆\n";
}
fclose($handle);
echo "完成,共匯入 {$count} 筆。\n";
# 執行
php import_csv.php products.csv > import.log 2>&1
<?php
// monitor.php
declare(ticks=1);
pcntl_signal(SIGTERM, fn() => exit(0));
pcntl_signal(SIGINT, fn() => exit(0));
while (true) {
$load = sys_getloadavg()[0];
$mem = memory_get_usage(true);
$disk = disk_free_space('/');
if ($load > 8.0) {
error_log("高負載警告: {$load}");
// 發送通知...
}
if ($disk < 1024*1024*1024) { // < 1GB
error_log("磁碟空間不足");
}
echo "[" . date('H:i:s') . "] Load: {$load} Mem: " . round($mem/1024/1024,1) . "MB\n";
sleep(60);
}
# 背景執行
nohup php monitor.php > monitor.log 2>&1 &
# 或使用 systemd 服務管理
<?php
// worker.php
$jobs = range(1, 20);
$maxWorkers = 4;
$running = 0;
$pidList = [];
foreach ($jobs as $job) {
if ($running >= $maxWorkers) {
$pid = pcntl_wait($status); // 等待任一子進程結束
$running--;
unset($pidList[$pid]);
}
$pid = pcntl_fork();
if ($pid === -1) { die("fork 失敗"); }
if ($pid === 0) {
// 子進程
doJob($job);
exit(0);
}
$pidList[$pid] = $job;
$running++;
}
// 等待剩餘子進程
while ($running > 0) {
pcntl_wait($status);
$running--;
}
function doJob($id) {
sleep(rand(1,3));
echo "Job {$id} 完成\n";
}
#!/usr/bin/env php,加 chmod +x 直接執行。$argv、$argc 或 getopt()、Symfony Console 組件。set_exception_handler()、register_shutdown_function() 記錄致命錯誤。echo (stdout)、錯誤 fwrite(STDERR, ...),配合 systemd / supervisor 管理。flock(fopen('/tmp/mylock','w'), LOCK_EX|LOCK_NB)。gc_collect_cycles()、分批處理大資料集、unset 大變數。composer require php ^8.2、Docker 基礎鏡像固定版本。PHP CLI 將 PHP 的生態 (資料庫、快取、隊列、加密、HTTP 客戶端) 直接帶入命令列自動化領域。配合 pcntl 多進程、posix 訊號、readline 互動,足以替代 Bash/Python/Perl 完成大多數系統級任務。現代專案常見模式:**Web 處理請求 → 推入隊列 → CLI Worker 異步消費** ,充分發揮 PHP 同步阻塞特性與生態優勢。