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

PHP 使用 fopen 建立 UTF-8 編碼檔案完整指南:BOM、編碼轉換與亂碼解決

     編輯:PHP 綜合知識

前言

PHP fopen() 建立檔案時,輸出檔案編碼**完全取決於 PHP 腳本檔案本身的儲存編碼**。若腳本為 UTF-8 (無 BOM),寫入的中文內容即為 UTF-8;若腳本為 ANSI/GBK,輸出即為對應編碼。本文詳細說明如何確保輸出 UTF-8 (含 BOM/不含 BOM)、解決亂碼、並提供實用範本。

核心原則:腳本編碼 = 輸出編碼

方法一:最簡單 — 確保腳本為 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 "轉碼輸出完成";
?>

常見亂碼原因與解決對照表

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

三大編碼控制層級總結

  1. HTTP 回應層:header('Content-Type: text/html; charset=utf-8'); 或 Apache AddDefaultCharset utf-8。
  2. PHP 腳本層:檔案儲存為 UTF-8 無 BOM (最推薦);或執行期 iconv() 轉碼。
  3. 檔案系統層:實際位元組序列;可加 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,三位一體徹底杜絕亂碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
現象原因解決
瀏覽器顯示亂碼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()、目錄權限、絕對路徑