正確配置 PHP 錯誤日誌是生產環境穩定運行的基礎。本文詳細說明 php.ini (PHP 核心) 與 php-fpm.conf (進程管理器) 兩層配置的差異、關鍵指令、權限陷阱與最佳實踐,幫助你建立完整的錯誤監控體系。
; ===== 錯誤報告層級 ===== ; 開發環境: E_ALL ; 生產環境: E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT error_reporting = E_ALL & ~E_NOTICE ; ===== 顯示錯誤 (生產環境必須關閉) ===== display_errors = Off display_startup_errors = Off ; ===== 記錄錯誤到日誌 ===== log_errors = On ; ===== 日誌檔案路徑 (需確保寫入權限) ===== error_log = "/usr/local/lnmp/php/var/log/error_log" ; ===== 最大日誌長度 (0 = 無限制) ===== log_errors_max_len = 1024 ; ===== 忽略重複錯誤 ===== ignore_repeated_errors = Off ignore_repeated_source = Off ; ===== 記錄記憶體洩漏 (開發用) ===== ; report_memleaks = On
| 指令 | 推薦值 (生產) | 說明 |
|---|---|---|
| error_reporting | E_ALL & ~E_NOTICE | 報告所有錯誤但忽略通知 |
| display_errors | Off | 絕不向用戶顯示錯誤細節 (洩露路徑、SQL、堆疊) |
| log_errors | On | 啟用錯誤日誌記錄 |
| error_log | 絕對路徑 | 日誌檔案路徑,需 php-fpm 進程用戶可寫 |
| html_errors | Off | 不輸出 HTML 格式錯誤 (乾淨純文字) |
[global] ; pid 檔案 pid = /usr/local/php/var/run/php-fpm.pid ; php-fpm 自身錯誤日誌 (主進程錯誤、啟動失敗等) error_log = /usr/local/php/var/log/php-fpm.log ; 日誌等級: debug, notice, warning, error, alert log_level = notice [www] ; ===== 關鍵: 捕捉 Worker 輸出到 php-fpm 錯誤日誌 ===== ; 預設 Off,開啟後 worker 的 stdout/stderr 會導向 php-fpm.log catch_workers_output = yes ; ===== 慢日誌: 記錄執行超時的請求 ===== slowlog = /usr/local/php/var/log/slow.log ; 請求超過 5 秒記錄慢日誌 (需配合 request_slowlog_timeout) request_slowlog_timeout = 5 ; ===== 覆蓋 php.ini 設定 (池層級) ===== ; 關閉錯誤顯示 php_flag[display_errors] = off ; 指定此池的錯誤日誌 (分離不同站點日誌) php_admin_value[error_log] = /usr/local/php/var/log/www.log ; 強制啟用錯誤記錄 (不可被 ini_set 覆蓋) php_admin_flag[log_errors] = on ; 記憶體限制 php_admin_value[memory_limit] = 256M ; 安全相關 php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen php_admin_value[open_basedir] = /www/wwwroot/:/tmp/:/proc/
| 指令前綴 | 可被 ini_set 覆蓋 | 適用類型 | 說明 |
|---|---|---|---|
| php_flag | 是 | Boolean (on/off) | 對應 php.ini 中的 On/Off 設定 |
| php_value | 是 | Value (字串/數字) | 對應 php.ini 中的數值設定 |
| php_admin_flag | 否 | Boolean | 強制設定,腳本無法修改 (安全關鍵項) |
| php_admin_value | 否 | Value | 強制設定,腳本無法修改 |
最佳實踐:安全相關 (error_log, log_errors, disable_functions, open_basedir, memory_limit) 使用 php_admin_*;一般調優參數用 php_*。
# 1. 檢查 php-fpm 運行用戶
ps aux | grep php-fpm
# 輸出範例: www-data php-fpm: pool www
# 2. 檢查日誌目錄權限
ls -ld /usr/local/php/var/log/
# 需確保 www-data 有寫入權限
# 3. 修正權限
chown -R www-data:www-data /usr/local/php/var/log/
chmod 755 /usr/local/php/var/log/
# 4. 若使用 logrotate,確保建立新檔案後權限正確
# /etc/logrotate.d/php-fpm
/usr/local/php/var/log/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 www-data www-data
sharedscripts
postrotate
/bin/kill -USR1 `cat /usr/local/php/var/run/php-fpm.pid 2>/dev/null` 2>/dev/null || true
endscript
}
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT display_errors = Off display_startup_errors = Off log_errors = On log_errors_max_len = 4096 ignore_repeated_errors = On ignore_repeated_source = On error_log = /var/log/php/error.log html_errors = Off docref_root = "" docref_ext = ""
[www] user = www-data group = www-data listen = /run/php/php8.1-fpm.sock listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 ; 日誌 catch_workers_output = yes php_admin_flag[log_errors] = on php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_value[memory_limit] = 256M ; 慢日誌 slowlog = /var/log/php-fpm/www-slow.log request_slowlog_timeout = 10 request_terminate_timeout = 30 ; 安全 php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source php_admin_value[open_basedir] = /var/www/:/tmp/:/var/lib/php/sessions/
tail -f /var/log/php-fpm/www-error.log | grep -i "fatal\|error\|exception\"更多 PHP 相關內容可參考本站專題:《PHP 錯誤與異常處理方法總結》、《PHP 字符串用法總結》、《PHP 陣列操作技巧大全》、《PHP 運算與運算符用法總結》、《PHP 網絡編程技巧總結》、《PHP 基本語法入門教程》、《PHP 面向對象程序設計入門教程》、《PHP+MySQL 數據庫操作入門教程》及《PHP 常見數據庫操作技巧匯總》。