XMLParser 封裝 simplexml_load_string,提供統一介面從 XML 檔案或字串轉換為 PHP 陣列,內含格式驗證與物件轉陣列遞歸。
<?php
class XMLParser {
public function loadXmlFile($xmlfile) {
$xmlstring = file_exists($xmlfile) ? file_get_contents($xmlfile) : '';
list($flag, $data) = $this->parser($xmlstring);
return $this->response($flag, $data);
}
public function loadXmlString($xmlstring) {
list($flag, $data) = $this->parser($xmlstring);
return $this->response($flag, $data);
}
private function parser($xmlstring) {
$flag = false; $data = [];
if ($this->checkXmlFormat($xmlstring)) {
$flag = true;
$obj = simplexml_load_string($xmlstring, 'SimpleXMLElement', LIBXML_NOCDATA);
$this->objectToArray($obj, $data);
}
return [$flag, $data];
}
private function checkXmlFormat($xmlstring) {
if ($xmlstring === '') return false;
$parser = xml_parser_create();
$result = xml_parse_into_struct($parser, $xmlstring, $vals, $indexs);
xml_parser_free($parser);
return $result === 1;
}
private function objectToArray($obj, &$arr) {
if (is_object($obj)) $obj = get_object_vars($obj);
if (is_array($obj)) {
foreach ($obj as $k => $v) {
$v = (is_object($v) || is_array($v)) ? [] : $v;
$this->objectToArray($v, $arr[$k] = []);
if (is_array($v) && $v) $arr[$k] = $v;
elseif (!is_array($v)) $arr[$k] = $v;
}
}
}
private function response($flag, $data) {
return ['success' => $flag, 'data' => $data];
}
}
$parser = new XMLParser();
// 從檔案
$result = $parser->loadXmlFile('data.xml');
// 從字串
$xml = '<root><item id="1">Apple</item><item id="2">Banana</item></root>';
$result = $parser->loadXmlString($xml);
if ($result['success']) {
print_r($result['data']);
} else {
echo "XML 格式錯誤或檔案不存在";
}
LIBXML_NOCDATA:將 CDATA 節點視為文字節點,避免產生 SimpleXMLElement 物件導致轉陣列異常。xml_parse_into_struct:輕量級驗證 XML 格式,不建構 DOM 樹,效能優於 DOMDocument::loadXML。objectToArray 遞歸處理巢狀物件/陣列,將 SimpleXMLElement 扁平化為純陣列。| 限制 | 改進方向 |
|---|---|
| 同名兄弟節點會被覆蓋 (陣列鍵值衝突) | 檢測重複鍵時自動轉為數字索引陣列 |
| 屬性與子節點同名無法區分 | 鍵名前綴區分:@attr、#text |
| 命名空間處理不完善 | 使用 DOMDocument + XPath 完整支援 |
| 大檔案記憶體佔用高 | 改用 XMLReader 流式解析 |
XMLParser 以 SimpleXML 為核心,提供檔案/字串雙入口、格式驗證、陣列輸出的便利封裝,適合中小型 XML 處理場景。複雜/大型 XML 請改用 DOMDocument 或 XMLReader 以獲得完整標準支援與記憶體效率。