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

ThinkPHP Session/Cookie 失效根因:BOM 頭破壞輸出緩衝區的鐵律

     編輯:PHP 綜合知識

故障現象

  • 本地 Windows 開發環境正常
  • 部署 Linux 服務器後 Session/Cookie 失效
  • 當前頁 `var_dump($_SESSION)` 有值,跳轉後丟失

根因:UTF-8 BOM (Byte Order Mark)

Windows 記事本等編輯器以 UTF-8 with BOM 保存,文件頭部包含 3 字節 `EF BB BF`。

PHP 不識別 BOM,將其作為輸出內容發送瀏覽器,導致:

  1. HTTP Header 發送前已有輸出 → `session_start()` / `setcookie()` 失敗
  2. 輸出緩衝區被污染,Cookie 設定失效

檢測方法

# Linux 命令檢測
hexdump -C yourfile.php | head -5
# 輸出開頭若見 ef bb bf 即有 BOM

# 或 PHP 檢測
$content = file_get_contents('yourfile.php');
var_dump(bin2hex(substr($content, 0, 3))); // efbbbf 表示有 BOM

去除 BOM 方案

編輯器設置(推薦)

編輯器操作路徑
EditPlus工具 → 首選項 → 文件 → UTF-8 標識 → 總是刪除簽名
UltraEdit另存為 → 編碼選擇 "UTF-8 無 BOM"
VS Code右下角編碼 → "Save with Encoding" → "UTF-8"
PhpStormFile → File Encoding → UTF-8 (無 BOM)
Notepad++編碼 → 轉為 UTF-8 (無 BOM)

批量清理腳本

# Linux 批量移除 BOM
find . -name "*.php" -exec sed -i '1s/^\xEF\xBB\xBF//' {} \;

# PHP 腳本遞歸清理
function removeBOM($dir) {
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
    foreach ($files as $file) {
        if ($file->isFile() && pathinfo($file, PATHINFO_EXTENSION) === 'php') {
            $content = file_get_contents($file);
            if (substr($content, 0, 3) === "\xEF\xBB\xBF") {
                file_put_contents($file, substr($content, 3));
                echo "Removed BOM: $file\n";
            }
        }
    }
}
removeBOM(__DIR__);

預防鐵律

  1. 團隊統一編輯器配置:項目 `.editorconfig` 指定 `charset = utf-8`, `insert_final_newline = true`
  2. Git 鉤子攔截:pre-commit 檢測 BOM,拒絕提交
  3. CI/CD 檢查:構建階段掃描 PHP 文件 BOM
  4. 新文件模板:IDE 配置無 BOM 模板

相關知識點

  • BOM 僅影響 UTF-8,UTF-16/32 必須有 BOM 指示字節序
  • `header("Content-Type: text/html; charset=utf-8")` 控制輸出編碼,不處理文件編碼
  • GD 圖片輸出若有 BOM 會導致「紅叉」無法顯示
  • Dreamweaver 可在偏好設置中關閉 BOM

「無 BOM」應成為 PHP 團隊的肌肉記憶,從源頭杜絕此類部署環境差異 Bug。

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