在PHP开发过程中,处理XML格式数据是常见需求,很多时候我们需要把获取到的XML对象转换为数组,方便后续的数据读取、遍历和存储操作。PHP本身提供了多种XML解析扩展,结合合理的转换逻辑就能实现XML对象到数组的平稳转换。

基础转换思路
首先我们需要先获取XML对象,PHP中常用的simplexml_load_string函数可以把XML字符串转换为SimpleXMLElement对象,之后再对这个对象做处理转换成数组。基础的转换逻辑是先处理对象的属性,再处理子节点,最后处理节点的文本内容。
简单XML对象转换示例
如果XML结构比较简单,没有多层嵌套,我们可以用基础的循环遍历实现转换,以下是示例代码:
<?php
// 定义XML字符串
$xmlStr = '<?xml version="1.0" encoding="UTF-8"?>
<user>
<name>张三</name>
<age>25</age>
<email>test@ipipp.com</email>
</user>';
// 将XML字符串转换为SimpleXMLElement对象
$xmlObj = simplexml_load_string($xmlStr);
// 基础转换函数
function simpleXmlToArray($xmlObj) {
$result = [];
// 处理对象属性
foreach ($xmlObj->attributes() as $key => $val) {
$result['@attributes'][$key] = (string)$val;
}
// 处理子节点
foreach ($xmlObj->children() as $key => $val) {
// 如果子节点只有一个同名的,直接赋值
if (count($xmlObj->$key) == 1) {
$result[$key] = (string)$val;
} else {
// 多个同名子节点则转为数组
$result[$key][] = (string)$val;
}
}
// 如果没有子节点,直接取文本内容
if (empty($result)) {
$result = (string)$xmlObj;
}
return $result;
}
$array = simpleXmlToArray($xmlObj);
print_r($array);
?>
上面的代码运行后会输出数组,包含name、age、email三个字段的对应值,适合处理结构简单的XML数据。
递归处理嵌套XML对象
实际开发中的XML往往存在多层嵌套结构,这时候就需要用递归的方式处理所有层级的节点,确保转换后不会丢失嵌套数据,以下是通用递归转换函数:
<?php
// 通用XML对象转数组函数,支持嵌套结构
function xmlObjectToArray($xmlObj) {
$result = [];
// 处理当前节点的属性
$attributes = $xmlObj->attributes();
if (count($attributes) > 0) {
foreach ($attributes as $key => $val) {
$result['@attributes'][$key] = (string)$val;
}
}
// 处理子节点
$children = $xmlObj->children();
if (count($children) > 0) {
// 记录同名子节点的数量
$childCount = [];
foreach ($children as $key => $val) {
if (!isset($childCount[$key])) {
$childCount[$key] = 0;
}
$childCount[$key]++;
}
foreach ($children as $key => $val) {
// 同名子节点超过1个,转为数组存储
if ($childCount[$key] > 1) {
$result[$key][] = xmlObjectToArray($val);
} else {
$result[$key] = xmlObjectToArray($val);
}
}
} else {
// 没有子节点时,取当前节点的文本内容
$result = (string)$xmlObj;
}
return $result;
}
// 测试嵌套XML
$nestedXmlStr = '<?xml version="1.0" encoding="UTF-8"?>
<order>
<order_id>1001</order_id>
<user_info>
<name>李四</name>
<phone>13800138000</phone>
</user_info>
<goods>
<item>
<goods_name>手机</goods_name>
<price>2999</price>
</item>
<item>
<goods_name>耳机</goods_name>
<price>199</price>
</item>
</goods>
</order>';
$xmlObj = simplexml_load_string($nestedXmlStr);
$orderArray = xmlObjectToArray($xmlObj);
print_r($orderArray);
?>
这个函数可以处理任意层级的嵌套XML,同时会自动把同名的多个子节点整理为数组,避免数据覆盖的问题。
转换注意事项
- 转换时要把SimpleXMLElement对象的值用
(string)强制转换为字符串,否则得到的还是对象类型,后续使用可能出现问题。 - 如果XML节点存在属性,建议在转换结果中用
@attributes键来单独存储属性值,避免和子节点键名冲突。 - 如果XML中包含命名空间,需要先处理命名空间再转换,否则可能获取不到对应节点的数据。
- 转换前需要确保XML字符串格式正确,否则
simplexml_load_string会返回false,需要做容错处理。
常见问题解答
转换后数组值是空是怎么回事
通常是没有对节点值做字符串强制转换,直接把SimpleXMLElement对象赋值给了数组,需要添加(string)转换。
如何处理带命名空间的XML
可以用getNamespaces方法获取命名空间,再用children方法传入命名空间参数获取对应节点,之后再调用转换函数即可。
PHPXML对象数组转换simplexml_load_string修改时间:2026-06-25 02:45:33