| PHP 檔案儲存編碼 | fwrite 寫入中文 | 輸出檔案編碼 |
| UTF-8 (無 BOM) ✅ 推薦 | 直接寫入中文 | UTF-8 (無 BOM) |
| UTF-8 (含 BOM) ⚠️ 可能干擾 | 直接寫入中文 | UTF-8 (含 BOM) |
| GBK/ANSI | 直接寫入中文 | GBK/ANSI |
| UTF-8 (無 BOM) | iconv('UTF-8', 'GBK', $str) | GBK |
方法一:最簡單 — 確保腳本為 UTF-8 無 BOM
<?php
// 1. 編輯器將本檔案存為 UTF-8 無 BOM
// 2. 直接寫入中文變數
$filename = 'test_utf8.txt';
$content = 'PHP學習網【www.jb51.net】';
$fp = fopen($filename, 'w');
if (!$fp) die('無法開啟檔案');
if (fwrite($fp, $content) === false) {
fclose($fp);
die('寫入失敗');
}
fclose($fp);
echo "成功建立 UTF-8 檔案:$filename";
?>
方法二:強制加入 UTF-8 BOM (某些 Windows 軟體需求)
<?php
$filename = 'test_utf8_bom.txt';
$content = '含 BOM 的 UTF-8 檔案';
$fp = fopen($filename, 'wb'); // 二進位模式
if (!$fp) die('開啟失敗');
// 寫入 BOM: EF BB BF
fwrite($fp, "\xEF\xBB\xBF");
// 寫入實際內容 (腳本需為 UTF-8)
fwrite($fp, $content);
fclose($fp);
echo "建立完成 (含 BOM)";
?>
方法三:腳本非 UTF-8 時,執行期轉碼寫入 UTF-8
<?php
// 假設本檔案為 GBK 編碼儲存
$filename = 'convert_to_utf8.txt';
$content = '這是 GBK 腳本轉 UTF-8 輸出'; // 實際為 GBK 位元組
$fp = fopen($filename, 'wb');
if (!$fp) die('開啟失敗');
// 1. 寫入 BOM (可選)
fwrite($fp, "\xEF\xBB\xBF");
// 2. 將內容從 GBK 轉 UTF-8
$utf8Content = iconv('GBK', 'UTF-8', $content);
fwrite($fp, $utf8Content);
fclose($fp);
echo "轉碼輸出完成";
?>
常見亂碼原因與解決對照表
| 現象 | 原因 | 解決 |
| 瀏覽器顯示亂碼 | HTTP 標頭無 charset 或 charset 錯誤 | header('Content-Type: text/html; charset=utf-8'); 在輸出前送出 |
| 檔案用記事本開啟顯示亂碼 | 檔案為 UTF-8 無 BOM,記事本誤判為 ANSI | 加入 BOM、或用 Notepad++/VS Code 開啟 |
| 中文變成 或 | 雙重編碼 (UTF-8 → UTF-8) 或編碼轉換錯誤 | 檢查 iconv 來源編碼參數、確保腳本編碼一致 |
| fwrite 寫入後檔案大小為 0 | 權限不足、磁碟滿、路徑錯誤 | 檢查 is_writable()、目錄權限、絕對路徑 |
三大編碼控制層級總結
- HTTP 回應層:
header('Content-Type: text/html; charset=utf-8'); 或 Apache AddDefaultCharset utf-8。
- PHP 腳本層:檔案儲存為 UTF-8 無 BOM (最推薦);或執行期
iconv() 轉碼。
- 檔案系統層:實際位元組序列;可加 BOM 協助編輯器辨識。
完整健壯範本:建立 UTF-8 檔案 (含目錄自建、錯誤處理、鎖定)
<?php
/**
* 安全建立 UTF-8 檔案
* @param string $path 完整檔案路徑
* @param string $content 內容 (預期為 UTF-8 字串)
* @param bool $bom 是否加入 BOM
* @return bool
*/
function createUtf8File($path, $content, $bom = false) {
// 1. 確保目錄存在
$dir = dirname($path);
if (!is_dir($dir) && !mkdir($dir, 0755, true)) {
trigger_error("建立目錄失敗: $dir", E_USER_WARNING);
return false;
}
// 2. 獨佔鎖定開啟 (避免並發寫入損毀)
$fp = fopen($path, 'wb');
if (!$fp) {
trigger_error("開啟檔案失敗: $path", E_USER_WARNING);
return false;
}
if (!flock($fp, LOCK_EX)) {
fclose($fp);
trigger_error("檔案鎖定失敗: $path", E_USER_WARNING);
return false;
}
// 3. 寫入 BOM (可選)
if ($bom) {
fwrite($fp, "\xEF\xBB\xBF");
}
// 4. 寫入內容 (假設 $content 已為 UTF-8)
$bytes = fwrite($fp, $content);
if ($bytes === false || $bytes !== strlen($content)) {
flock($fp, LOCK_UN);
fclose($fp);
trigger_error("寫入不完整: $path", E_USER_WARNING);
return false;
}
// 5. 釋放並關閉
flock($fp, LOCK_UN);
fclose($fp);
return true;
}
// 使用範例
createUtf8File(__DIR__ . '/data/log_' . date('Ymd') . '.txt', "測試內容\n", true);
?>
結語
PHP 建立 UTF-8 檔案的關鍵在於**「腳本檔案本身儲存為 UTF-8 無 BOM」**。若需相容 Windows 記事本等老舊工具,可選擇性加入 BOM (EF BB BF)。實務上建議統一專案編碼為 UTF-8 無 BOM、HTTP 標頭宣告 charset、資料庫連線設定 SET NAMES utf8mb4,三位一體徹底杜絕亂碼。
- 上一篇文章: PHP set_exception_handler 自訂異常處理在 ThinkPHP 中的應用詳解
- 下一篇文章: PHP 結合 JavaScript 實現超連結點擊確認刪除資料完整範例
Copyright ©
程式碼之家 All Rights Reserved