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

PHP 使用 DOMDocument 解析含中文 XML 文檔防亂碼方案

     編輯:PHP 相關知識

問題背景

DOMDocument 載入 XML 時默認按 UTF-8 解析,若 XML 聲明編碼為 UTF-8 但 PHP 內部處理或輸出編碼不一致,中文會出現亂碼。

完整解析代碼示例

<?php
// 1. 創建 DOMDocument
$xmlDoc = new DOMDocument();

// 2. 載入 XML 文件 (支持 URL)
$xmlDoc->load('https://127.0.0.1/holiday.xml');
// 或本地文件
// $xmlDoc->load(__DIR__ . '/holiday.xml');

// 3. 獲取所有年份節點
$years = $xmlDoc->getElementsByTagName('year');

foreach ($years as $year) {
    // 獲取年份值
    $yearNames = $year->getElementsByTagName('yearName');
    $yearName = $yearNames->item(0)->nodeValue;
    
    // 關鍵:輸出時轉碼 (若頁面非 UTF-8)
    echo iconv('UTF-8', 'GBK//IGNORE', $yearName) . '年
'; // 獲取假日列表 $holidays = $year->getElementsByTagName('holiday'); foreach ($holidays as $holiday) { // 假日名稱 $holidayNames = $holiday->getElementsByTagName('holidayName'); $holidayName = $holidayNames->item(0)->nodeValue; echo iconv('UTF-8', 'GBK//IGNORE', $holidayName) . ':
'; // 放假日期 $daysOffs = $holiday->getElementsByTagName('daysOff'); $daysOff = $daysOffs->item(0); $from = $daysOff->getElementsByTagName('from')->item(0)->nodeValue; $to = $daysOff->getElementsByTagName('to')->item(0)->nodeValue; echo "假期:$from 至 $to
"; // 調休日期 $overTimes = $holiday->getElementsByTagName('overTime'); $overTime = $overTimes->item(0); $days = $overTime->getElementsByTagName('day'); if ($days->length > 0) { echo '調休日:'; foreach ($days as $day) { echo $day->nodeValue . ' '; } echo '
'; } echo '
'; } } ?>

XML 文件示例 (holiday.xml)

<?xml version="1.0" encoding="UTF-8"?>
<daysOff-overTime>
    <year>
        <yearName>2012</yearName>
        <holiday>
            <holidayName>元旦</holidayName>
            <daysOff>
                <from>2012-1-1</from>
                <to>2012-1-3</to>
            </daysOff>
            <overTime>
                <day>2011-12-31</day>
            </overTime>
        </holiday>
        <holiday>
            <holidayName>春節</holidayName>
            <daysOff>
                <from>2012-1-22</from>
                <to>2012-1-28</to>
            </daysOff>
            <overTime>
                <day>2012-1-21</day>
                <day>2012-1-29</day>
            </overTime>
        </holiday>
    </year>
</daysOff-overTime>

關鍵技術點

1. 編碼轉換防亂碼

<?php
// XML 內容為 UTF-8,頁面輸出為 GBK
$value = $node->nodeValue; // 獲取的是 UTF-8 字符串
echo iconv('UTF-8', 'GBK//IGNORE', $value); // 轉碼輸出

// 若頁面也是 UTF-8,無需轉碼
// 但建議統一:header('Content-Type: text/html; charset=UTF-8');
?>

2. 保存 XML 時指定編碼

<?php
$dom = new DOMDocument('1.0', 'UTF-8');
// 構建文檔...
$dom->save('output.xml'); // 會寫入 
// 或
$dom->saveXML(); // 返回字符串
?>

3. 載入非 UTF-8 XML

<?php
// XML 聲明 encoding="GB2312"
$dom = new DOMDocument();
$dom->load('gbk.xml'); // 自動按聲明編碼解析,內部轉為 UTF-8
$value = $dom->getElementsByTagName('name')->item(0)->nodeValue;
// $value 現在是 UTF-8 編碼
?>

4. 錯誤處理與容錯

<?php
libxml_use_internal_errors(true); // 禁用默認錯誤輸出
$dom = new DOMDocument();
$loaded = @$dom->load('data.xml');
if (!$loaded) {
    $errors = libxml_get_errors();
    foreach ($errors as $error) {
        error_log("XML Error: {$error->message} at line {$error->line}");
    }
    libxml_clear_errors();
    die('XML 解析失敗');
}
// 成功解析...
?>

DOMDocument vs SimpleXML vs XMLReader

特性DOMDocumentSimpleXMLXMLReader
記憶體佔用高 (全樹載入)中極低 (流式)
寫入/修改完整支持有限支持不支持
XPath 支持完整基本無
大文件處理不適合不適合最適合
命名空間完整麻煩手動處理

最佳實踐建議

  1. 項目統一使用 UTF-8,避免轉碼麻煩
  2. 解析前調用 libxml_use_internal_errors(true)
  3. 大文件 (>10MB) 必須用 XMLReader
  4. 需修改 XML 結構用 DOMDocument
  5. 簡單讀取優先 SimpleXML (語法更簡潔)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved