在 PHP 開發中,有時需要執行系統層級的指令,例如備份資料庫、處理圖片、呼叫外部程式等。PHP 提供了三個核心函數 system()、exec()、passthru() 來達成這個需求。本文將詳細說明如何設定 PHP 環境以允許執行外部指令,並深入解析這三個函數的差異與適用場景。
PHP 預設啟用安全模式來限制腳本執行外部程式,保護伺服器安全。若需呼叫 Shell,必須先檢查 php.ini 中的三項關鍵設定:
Off 才能執行外部指令(若為 On,下列兩項無效)。system、exec、passthru、shell_exec 等未被列入禁用清單。/usr/local/php/bin。若執行指令無輸出且無錯誤,多半是因為安全模式阻擋,請聯繫主機商或調整上述設定。
string system ( string $command [, int &$return_var ] )
$return_var 可取得指令結束狀態碼(0 表成功)。範例:
<?php
system("/usr/local/bin/webalizer/webalizer");
?>
string exec ( string $command [, array &$output [, int &$return_var ] ] )
$output 可將每一行輸出存入陣列,方便後續處理。$return_var 需搭配第二參數使用,取得狀態碼。範例:
<?php
exec("/bin/ls -l"); // 只取最後一行
exec("/bin/ls -l", $res); // $res 為陣列,每個元素為一行輸出
exec("/bin/ls -l", $res, $rc); // $rc 為狀態碼,成功通常為 0
?>
void passthru ( string $command [, int &$return_var ] )
範例:
<?php
header("Content-type: image/gif");
passthru("./ppmtogif hunte.ppm");
?>
| 需求 | 建議函數 | 理由 |
|---|---|---|
| 只需顯示指令結果、不需後處理 | system() | 最簡單,直接輸出 |
| 需在 PHP 中分析、過濾、儲存指令輸出 | exec() | 可取得完整陣列,彈性最高 |
| 輸出二進位檔案(圖片、PDF、壓縮檔) | passthru() | 不經過 PHP 緩衝,直接串流輸出 |
escapeshellarg() 或 escapeshellcmd() 轉義。safe_mode、disable_functions、指令路徑是否正確、權限是否足夠。export LANG=zh_TW.UTF-8 或使用 iconv 轉碼。max_execution_time 或改用非同步背景執行(> /dev/null 2>&1 &)。掌握 system()、exec()、passthru() 三者差異,並嚴格遵循安全設定,才能在 PHP 專案中安全、高效地整合系統層功能。建議優先使用原生 PHP 擴展替代外部指令,若確有必要呼叫 Shell,務必做好輸入驗證與權限控管。