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

PHP 常見錯誤總結與除錯技巧大全 (新手必讀)

     編輯:PHP 相關知識

PHP 開發中 80% 的時間在除錯。本文系統整理 30+ 高頻錯誤類別、根因分析、解決方案與預防最佳實踐,涵蓋變數、Session、資料庫、編碼、上傳、效能、部署等面向,助你從「試誤修補」轉向「預防為主」。

一、核心原則

  1. 開啟完整錯誤報告:開發/測試環境 error_reporting = E_ALL,display_errors = On;生產環境 display_errors = Off、log_errors = On
  2. 規範程式碼風格:PSR-12、嚴格型別宣告 declare(strict_types=1)、靜態分析
  3. 善用除錯工具:Xdebug + IDE 斷點、var_dump 替代品 (symfony/var-dumper)、日誌記錄

二、高頻錯誤分類與解決

1. 變數/超全域陣列

錯誤原因解決
Undefined variable變數未初始化即使用宣告初始值:$var = null;isset()/?? 檢查
Undefined array key/index陣列鍵不存在$arr['key'] ?? 'default'、array_key_exists()、$_GET['id'] ?? 0
Trying to access array offset on value of type null/bool對非陣列用 [] 存取 (PHP 8.0+)確保變數為陣列:is_array($var) && $var['key']
無法取得 POST/GET 變數register_globals = Off (PHP 5.4+ 移除)**務必用超全域陣列**:$_POST['name']、$_GET['id']、$_REQUEST (不推薦)

2. Session 與 Cookie

錯誤原因解決
session_start(): headers already sentSession 前有輸出 (空白、BOM、echo)session_start() 放**最頂端**,檔案無 BOM、無前置空白
Session 變數跨頁遺失Cookie 被禁用、域名/路徑不匹配、session.save_path 無權限檢查 session.cookie_domain、session.save_path 權限、HTTPS 下 session.cookie_secure=1
session_start(): open(/tmp/sess_...) failed儲存目錄不存在/不可寫建立目錄並給權限:mkdir('/var/lib/php/sessions', 0777, true) 或設定 session.save_path

3. 資料庫 (PDO/MySQLi)

錯誤原因解決
SQLSTATE[HY000] [2002] Connection refusedMySQL 服務未啟動、Host/Port 錯誤、防火牆檢查服務狀態、netstat -tlnp | grep 3306、DSN 正確性
SQLSTATE[42000]: Syntax errorSQL 語法錯誤、保留字未跳脫**使用參數綁定** (Prepared Statements);識別字加反引號 `table`
PDOException: could not find driver缺少 pdo_mysql/mysqli 擴展docker-php-ext-install pdo_mysql 或 apt install php-mysql
中文亂碼連線編碼未設定DSN 加 charset=utf8mb4 或 $pdo->exec("SET NAMES utf8mb4")

4. 編碼與亂碼

  • 檔案儲存為 **UTF-8 無 BOM**
  • HTTP Header:header("Content-Type: text/html; charset=UTF-8")
  • HTML:<meta charset="UTF-8">
  • 資料庫:utf8mb4 + utf8mb4_unicode_ci
  • PHP 內部:mb_internal_encoding('UTF-8')

5. 檔案上傳

錯誤碼常數原因
1UPLOAD_ERR_INI_SIZE超過 upload_max_filesize
2UPLOAD_ERR_FORM_SIZE超過表單 MAX_FILE_SIZE
3UPLOAD_ERR_PARTIAL部分上傳 (網路中斷)
4UPLOAD_ERR_NO_FILE未選檔案
6UPLOAD_ERR_NO_TMP_DIR缺 upload_tmp_dir 或權限
7UPLOAD_ERR_CANT_WRITE寫入暫存失敗 (磁碟滿/權限)

解決:設定 upload_tmp_dir、目錄權限、post_max_size > upload_max_filesize、驗證 $_FILES['file']['error'] === UPLOAD_ERR_OK

6. 標頭與重導向

  • Cannot modify header information - headers already sent → 同 Session 錯誤,輸出前設定 Header
  • header("Location: ...") 後**必須** exit,否則腳本繼續執行

7. 記憶體與執行時間

  • Allowed memory size exhausted:ini_set('memory_limit', '256M')、分批處理、Generator、unset 大變數
  • Maximum execution time exceeded:set_time_limit(0) (CLI)、分批、佇列非同步

8. Composer 與自動載入

  • Class not found:composer dump-autoload、檢查 composer.json autoload 區塊、命名空間對應
  • 版本衝突:composer why-not pkg/name version 分析

三、除錯工具與技巧

1. 統一除錯輸出函式

function debug(mixed $var, string $label = '', bool $die = false): void {
    if (php_sapi_name() === 'cli') {
        fwrite(STDERR, ($label ? "[$label] " : '') . print_r($var, true) . "\n");
    } else {
        echo "
";
        echo ($label ? "[$label]\n" : '');
        var_dump($var);
        echo "
"; } if ($die) exit; }

2. Xdebug + IDE (VS Code / PhpStorm) 斷點除錯

  • 安裝 xdebug,設定 xdebug.mode=debug、xdebug.client_host=host.docker.internal
  • IDE 安裝 PHP Debug 擴展,設定 Listen Port 9003
  • 瀏覽器安裝 Xdebug Helper,點擊 Debug 模式重整

3. 錯誤日誌集中化

// php.ini
log_errors = On
error_log = /var/log/php/error.log
error_log = syslog (系統日誌)

生產環境接入 ELK / Loki / Datadog 等日誌平台。

4. 靜態分析 (CI/CD 整合)

  • PHPStan:vendor/bin/phpstan analyse src --level=5
  • Psalm:vendor/bin/psalm --show-info=false
  • Rector:自動修正程式碼風格、升級語法

四、預防性開發清單

  1. declare(strict_types=1) 每個檔案頂端
  2. 所有函式/方法加**完整型別宣告** (參數、回傳、屬性)
  3. 輸入驗證:filter_var、assert()、Value Object、DTO
  4. 資料庫**一律 Prepared Statements**,禁止字串拼接 SQL
  5. 例外處理:自訂例外類別、統一錯誤回應格式、記錄堆疊追蹤
  6. 單元測試覆蓋核心邏輯 (PHPUnit + Pest)
  7. 程式碼審查 (Code Review) 機制

五、總結

除錯心法:
1. **錯誤訊息是朋友**,完整閱讀堆疊追蹤
2. **最小複現**,隔離問題最小單元
3. **假設驗證**,用斷點/日誌證實/推翻假設
4. **修正根因**,而非掩蓋症狀 (如 @ 抑制錯誤)
5. **沉澱文檔**,將踩坑轉化為團隊規範與工具

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