某些舊系統或特定工具(如 Excel 開啟 CSV)要求 UTF-8 檔案開頭包含 BOM (Byte Order Mark),否則會誤判編碼導致亂碼。PHP 寫入帶 BOM 檔案的方法極簡單:在內容最前方寫入三個位元組 EF BB BF。
<?php
$content = "這是 UTF-8 內容\n包含中文測試";
// 方法一:直接串接 BOM 位元組(推薦,可讀性佳)
$bom = chr(239) . chr(187) . chr(191); // EF BB BF
file_put_contents('with_bom.txt', $bom . $content);
// 方法二:使用十六進位字串(等效)
// $bom = "\xEF\xBB\xBF";
// file_put_contents('with_bom.txt', $bom . $content);
// 驗證:十六進位檢視
echo bin2hex(file_get_contents('with_bom.txt'));
// 輸出開頭:efbbbf e98099 e698af20 ...
?>
| 場景 | 是否需要 BOM | 說明 |
|---|---|---|
| Excel 開啟 CSV | 建議加 BOM | 無 BOM 時 Excel 預設用系統編碼(如 Big5/GBK)導致中文亂碼 |
| Notepad++ 編輯 | 自動偵測 | 現代編輯器均能正確識別無 BOM UTF-8 |
| PHP include/require | 嚴禁 BOM | BOM 會輸出到瀏覽器,破壞 HTTP 標頭、JSON 格式、Session 啟動 |
| Web 瀏覽器請求 | 不需要 | HTTP 標頭已聲明 charset,BOM 屬多餘 |
<?php
function addBomToFile($filepath) {
$content = file_get_contents($filepath);
// 避免重複添加 BOM
if (substr($content, 0, 3) !== "\xEF\xBB\xBF") {
file_put_contents($filepath, "\xEF\xBB\xBF" . $content);
return true;
}
return false;
}
// 遞迴處理目錄下所有 .csv 檔案
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/path/to/csv'));
foreach ($iterator as $file) {
if ($file->isFile() && $file->getExtension() === 'csv') {
addBomToFile($file->getPathname());
echo "已添加 BOM: {$file->getPathname()}\n";
}
}
?>
掌握 BOM 控制技巧,能完美解決跨系統檔案交換的編碼相容性問題。