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

PHP 常見錯誤診斷與修正:白屏、語法錯誤、變數未定義、無限迴圈、編碼亂碼

     編輯:PHP 相關知識

錯誤分類與顯示設定

<?php
// 開發環境:顯示所有錯誤
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

// 生產環境:記錄不顯示
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php/error.log');
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);

原則: 開發全開、生產全記錄、永不對用戶顯示堆疊追蹤。

五大常見錯誤類型與修正

1. 白屏 (White Screen of Death)

現象: 瀏覽器完全空白、無回應、View Source 也是空。

原因排查步驟修正
致命錯誤 + display_errors=Off檢查 PHP 錯誤日誌 tail -f /var/log/php/error.log修正程式碼、開啟 display_errors 除錯
語法錯誤 (Parse Error)日誌會顯示行號:Parse error: syntax error, unexpected '}' in ...修正語法、檢查括號配對、分號遺漏
記憶體耗盡日誌:Allowed memory size of 134217728 bytes exhausted優化演算法、分批處理、調大 memory_limit
無限迴圈/遞迴爆棧CPU 100%、請求超時、日誌無輸出加入迴圈計數器、遞迴深度限制、Xdebug 追蹤
輸出緩衝區過大未 flushob_start() 但未 ob_end_flush()確保正確結束緩衝、或關閉輸出緩衝

2. 語法錯誤

method()           // 缺少分號
function foo($a, $b = 1, $c) {} // 有預設值參數必須在最後
class A { use T1, T2 { T1::foo insteadof T2; } } // Trait 衝突解決語法錯誤

// 工具:PHP lint 快速檢查
php -l your_file.php

3. 變數未定義 / 型別錯誤

現象原因修正
Notice: Undefined variable $x使用前未賦值$x = $x ?? 'default' 或 isset($x) 判斷
Notice: Undefined array key "name"陣列無此鍵$arr['name'] ?? '' 或 array_key_exists
Warning: Undefined property物件無此屬性檢查類別定義、用 property_exists
TypeError: Argument must be array, string given傳參型別不符加入型別宣告、驗證輸入、PHPStan 靜態分析
Fatal: Call to member function on null物件為 null 呼叫方法$obj?->method() (PHP 8) 或 if ($obj) 守衛

4. 編碼亂碼

exec("SET NAMES utf8mb4");

// 3. HTML 輸出
header('Content-Type: text/html; charset=utf-8');
echo '<meta charset="utf-8">';

// 4. 檔案編碼
// 編輯器存檔為 UTF-8 無 BOM

// 5. 表單提交
// <form accept-charset="utf-8">

// 偵測工具
mb_detect_encoding($str, ['UTF-8', 'GBK', 'Big5'], true);
bin2hex($str) // 查看原始位元組

5. SQL 錯誤與注入風險

prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$name]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 除錯:查看實際 SQL
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 或開啟 MySQL 一般查詢日誌
// SET GLOBAL general_log = 'ON';

除錯工具鏈

工具用途安裝/使用
Xdebug 3斷點、堆疊、變數檢查、程式碼覆蓋率pecl install xdebug + IDE 設定 (PhpStorm/VS Code)
PHPStan / Psalm靜態分析、型別錯誤、死碼偵測composer require --dev phpstan/phpstan
var_dump / dd()快速印出變數結構Laravel dump()、Symfony VarDumper
ErrorException將錯誤轉為例外統一捕獲set_error_handler(fn($s,$m,$f,$l) => throw new ErrorException($m,0,$s,$f,$l))
Monolog結構化日誌、多通道、Slack/Email 告警composer require monolog/monolog

生產環境錯誤處理模式

<?php
// bootstrap.php
set_error_handler(function($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) return; // 忽略被抑制的錯誤
    throw new ErrorException($message, 0, $severity, $file, $line);
});

set_exception_handler(function(Throwable $e) {
    // 記錄完整堆疊
    error_log(json_encode([
        'time' => date('c'),
        'type' => get_class($e),
        'message' => $e->getMessage(),
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString(),
    ], JSON_UNESCAPED_UNICODE));

    // 回傳友善頁面
    http_response_code(500);
    if (php_sapi_name() === 'cli') {
        echo "Error: {$e->getMessage()}\n";
    } else {
        // 區分 AJAX/一般請求
        if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
            header('Content-Type: application/json');
            echo json_encode(['error' => '伺服器內部錯誤,請稍後再試']);
        } else {
            include __DIR__ . '/templates/500.php';
        }
    }
    exit;
});

register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        // 捕獲致命錯誤
        $e = new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line']);
        // 交給 exception handler
        // (需自行實作或使用框架內建)
    }
});

總結

  • 錯誤報告層級:開發 E_ALL、生產記錄不顯示。
  • 白屏:看日誌、開 display_errors、檢查記憶體/迴圈。
  • 語法錯誤:php -l、IDE 即時提示、CI 整合 lint。
  • 變數未定義:??、isset、型別宣告、PHPStan。
  • 編碼亂碼:PHP/DB/HTML/檔案/表單全鏈路 UTF-8。
  • SQL 注入:永遠用預處理、ERRMODE_EXCEPTION 捕獲錯誤。
  • 建立全域例外處理器 + 結構化日誌,生產環境可觀測、可追蹤、可告警。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved