PHP 開發 WebService 時,WSDL 文件包含中文導致 XML 解析錯誤或瀏覽器顯示亂碼。根因通常是文件編碼不一致或輸出未聲明 charset。本文給出標準化解決流程。
?wsdl 顯示「XML 解析錯誤:編碼聲明錯誤」或亂碼。SOAP-ERROR: Parsing WSDL。編碼 → 轉為 UTF-8 (無 BOM)UTF-8(預設無 BOM)File → File Encoding → UTF-8<?php
header('Content-Type: text/xml; charset=utf-8');
// 或 SOAP 服務端
$server = new SoapServer('service.wsdl', ['encoding' => 'UTF-8']);
<?xml version="1.0" encoding="UTF-8"?>
<definitions ...> ... </definitions>
$pdo->exec("SET NAMES utf8mb4");
| 誤區 | 後果 | 正確做法 |
|---|---|---|
| 用 ANSI/GBK 保存 WSDL | 中文在 UTF-8 環境下亂碼 | 全鏈路 UTF-8 |
| UTF-8 帶 BOM | XML 解析器報錯「處理指令外有內容」 | 無 BOM |
| 只設 header 不轉文件編碼 | 實際輸出字節流與聲明不符 | 文件編碼 + header 雙保險 |
| WSDL 中未寫 encoding="UTF-8" | 解析器回退預設編碼(通常 UTF-8,但不標準) | 明確聲明 |
[ ] 所有 .php/.wsdl/.xsd 文件均為 UTF-8 無 BOM
[ ] HTTP 響應頭 Content-Type: text/xml; charset=utf-8
[ ] XML 聲明 <?xml version="1.0" encoding="UTF-8"?>
[ ] SoapServer/SoapClient 構造參數 encoding='UTF-8'
[ ] 資料庫/外部服務編碼一致
[ ] 瀏覽器直接訪問 ?wsdl 正常顯示中文
[ ] SoapClient 消費無異常
<?php
// 動態輸出 WSDL
header('Content-Type: text/xml; charset=utf-8');
echo '' . "\n";
echo '';
// ... 確保所有動態插入字符串已是 UTF-8
echo ' ';
「全鏈路 UTF-8 無 BOM」是解決 PHP WebService 中文問題的黃金法則,一次配置,永久免疫編碼地雷。