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

PHP 呼叫 Shell 指令完整教學:system、exec、passthru 函數詳解與安全模式設定

     編輯:PHP 綜合知識

前言

在 PHP 開發中,有時需要執行系統層級的指令,例如備份資料庫、處理圖片、呼叫外部程式等。PHP 提供了三個核心函數 system()、exec()、passthru() 來達成這個需求。本文將詳細說明如何設定 PHP 環境以允許執行外部指令,並深入解析這三個函數的差異與適用場景。

一、PHP 安全模式與環境設定

PHP 預設啟用安全模式來限制腳本執行外部程式,保護伺服器安全。若需呼叫 Shell,必須先檢查 php.ini 中的三項關鍵設定:

  • safe_mode:設為 Off 才能執行外部指令(若為 On,下列兩項無效)。
  • disable_functions:確保 system、exec、passthru、shell_exec 等未被列入禁用清單。
  • safe_mode_exec_dir:安全模式下允許執行外部程式的目錄,預設為 /usr/local/php/bin。

若執行指令無輸出且無錯誤,多半是因為安全模式阻擋,請聯繫主機商或調整上述設定。

二、三大核心函數詳細比較

1. system() — 直接輸出並回傳最後一行

string system ( string $command [, int &$return_var ] )
  • 執行指令並直接輸出結果到標準輸出。
  • 回傳指令輸出的最後一行字串。
  • 可選參數 $return_var 可取得指令結束狀態碼(0 表成功)。

範例:

<?php
system("/usr/local/bin/webalizer/webalizer");
?>

2. exec() — 靈活取得完整輸出陣列

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
?>

3. passthru() — 原始二進位輸出,適合圖片/檔案串流

void passthru ( string $command [, int &$return_var ] )
  • 執行指令並將原始輸出直接送至標準輸出,不回傳任何值。
  • 常用於輸出二進位資料,如圖片轉換工具(pbmplus)、PDF 產生等。
  • 可取得狀態碼。

範例:

<?php
header("Content-type: image/gif");
passthru("./ppmtogif hunte.ppm");
?>

三、函數選擇指南

需求建議函數理由
只需顯示指令結果、不需後處理system()最簡單,直接輸出
需在 PHP 中分析、過濾、儲存指令輸出exec()可取得完整陣列,彈性最高
輸出二進位檔案(圖片、PDF、壓縮檔)passthru()不經過 PHP 緩衝,直接串流輸出

四、安全性最佳實務

  1. 絕不直接信任使用者輸入:所有傳入指令的參數必須經過 escapeshellarg() 或 escapeshellcmd() 轉義。
  2. 最小權限原則:僅開放必要的指令與目錄,避免使用 root 權限執行 PHP。
  3. 記錄稽核:將所有外部指令呼叫寫入日誌,包含呼叫時間、參數、回傳碼。
  4. 考慮替代方案:純 PHP 函式庫(如 GD、Imagick、ZipArchive)通常比呼叫外部程式更安全、效能更好。

五、常見問題排查

  • 輸出為空白:檢查 safe_mode、disable_functions、指令路徑是否正確、權限是否足夠。
  • 中文亂碼:指令環境編碼與 PHP 不一致,可在指令前加 export LANG=zh_TW.UTF-8 或使用 iconv 轉碼。
  • 逾時:長時間運行的指令需調整 max_execution_time 或改用非同步背景執行(> /dev/null 2>&1 &)。

結語

掌握 system()、exec()、passthru() 三者差異,並嚴格遵循安全設定,才能在 PHP 專案中安全、高效地整合系統層功能。建議優先使用原生 PHP 擴展替代外部指令,若確有必要呼叫 Shell,務必做好輸入驗證與權限控管。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved