PHP中数组转XML的三种实现方式对比与使用

小满
小满
发布时间:2026-10-15 | 4人浏览过
原创

在PHP开发中,将数据结构序列化为XML是常见的后端需求。由于PHP标准库提供了多种XML处理扩展,开发者通常会遇到不同的实现思路。本文将梳理并修正几段经典的数组转XML代码,涵盖SimpleXML面向对象操作、DOMDocument节点构建以及基础递归逻辑,帮助理解不同写法在处理嵌套数组和非法标签名时的策略。

方法一:基于SimpleXML的面向对象封装

这种方法利用 SimpleXMLElement 构建对象树,最后转换为字符串。其特点在于自动处理XML头,并通过正则表达式清洗Key以确保符合XML命名规范。

第1步:定义ArrayToXML类

该实现包含一个静态方法 toXml,支持递归遍历多维数组。需要注意以下几点逻辑:

  1. 兼容性设置:关闭Zend兼容模式,避免旧版PHP抛出警告。
  2. 根节点初始化:当传入 $xml 为null时,创建根节点对象。
  3. 键名清洗:若Key为数字,则替换为 unknownNode_ 前缀;若包含非字母数字字符,通过正则去除,以保证生成的XML合法。
  4. 值处理:子元素仍为数组时递归调用;否则使用 htmlentities 转义后添加为文本节点。
class ArrayToXML
{
    public static function toXml($data, $rootNodeName = 'data', $xml=null)
    {
        // 确保 SimpleXML 正常工作
        if (ini_get('zend.ze1_compatibility_mode') == 1) {
            ini_set ('zend.ze1_compatibility_mode', 0);
        }
        
        if ($xml == null) {
            $xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
        }
        
        foreach($data as $key => $value) {
            // 处理数字键
            if (is_numeric($key)) {
                $key = "unknownNode_". (string) $key;
            }
            // 清洗非法字符
            $key = preg_replace('/[^a-z]/i', '', $key);
            
            if (is_array($value)) {
                $node = $xml->addChild($key);
                // 递归处理子数组
                ArrayToXML::toXml($value, $rootNodeName, $node);
            } else {
                // 转义特殊字符并添加节点
                $value = htmlentities($value);
                $xml->addChild($key,$value);
            }
        }
        
        return $xml->asXML();
    }
}

方法二:基于DOMDocument的标准API操作

相比SimpleXML,DOMDocument 提供了更底层的节点控制能力。此函数采用默认参数设计,使其可以独立运行,也可作为部分DOM结构的一部分。

第2步:编写arrtoxml递归函数

逻辑核心在于判断 $dom 和 $item 是否存在,不存在则初始化为新的文档对象和根节点。对于每个数组元素,生成对应的Element节点:

  1. 如果Value不是数组,则创建Text节点并附加到Element节点。
  2. 如果Value是数组,则将当前Element作为父节点继续递归调用。
function arrtoxml($arr,$dom=0,$item=0){
    if (!$dom){
        $dom = new DOMDocument("1.0");
    }
    if(!$item){
        $item = $dom->createElement("root");
        $dom->appendChild($item);
    }
    
    foreach ($arr as $key=>$val){
        // 如果key是数字,统一命名为 item
        $tagName = is_string($key)?$key:"item";
        $itemx = $dom->createElement($tagName);
        $item->appendChild($itemx);
        
        if (!is_array($val)){
            $text = $dom->createTextNode($val);
            $itemx->appendChild($text);
        }else { 
            // 递归处理子节点
            arrtoxml($val,$dom,$itemx);
        }
    }
    return $dom->saveXML();
}

方法三:自定义递归字符串拼接

第三种方式不依赖特定的XML扩展对象,而是直接通过字符串拼接生成XML结构。这种方式轻量,但缺乏严格的DOM校验,且需手动管理全局变量控制层级缩进或结构标记。

第3步:配置array_Xml处理逻辑

使用 $elementLevel 全局变量跟踪深度。当Key为数字时,复用上一级Key名(这在某些特定JSON转XML场景下有用,但需注意语义准确性)。通过 startElement 和 endElement 包裹内容,递归生成闭合标签。

$elementLevel = 0 ;
function array_Xml($array, $keys = '')
{
    global $elementLevel;
    if(!is_array($array))
    {
        if($keys == ''){
            return $array;
        }else{
            return "\n<$keys>" . $array . "</$keys>";
        }
    }else{
        foreach ($array as $key => $value)
        {
            $haveTag = true;
            if (is_numeric($key))
            {
                $key = $keys;
                $haveTag = false;
            }
            
            /** * 根层级处理 */
            if($elementLevel == 0 ) 
            {
                $startElement = "<$key>";
                $endElement = "</$key>";
            }
            
            $text .= $startElement."\n";
            
            /** * 子层级处理 */
            if(!$haveTag)
            {
                $elementLevel++;
                $text .= "<$key>" . array_Xml($value, $key). "</$key>\n";
            }else{
                $elementLevel++;
                $text .= array_Xml($value, $key);
            }
            
            $text .= $endElement."\n";
        }
    }
    return $text;
}

应用示例:转换测试数组

以下是一个典型的员工信息多维数组结构,可用于验证上述方法的输出结果。注意观察嵌套的 employees 和重复的子键 employee。

<?php
$array = array(
    "employees" => array(
        "employee" => array(
            array(
                "name" => "name one",
                "position" => "position one"
            ),
            array(
                "name" => "name two",
                "position" => "position two"
            ),
            array(
                "name" => "name three",
                "position" => "position three"
            )
        )
    )
);

// 使用方法三进行转换测试
echo array_Xml($array);
?

总结与选择建议

以上三种代码片段均实现了从PHP数组到XML的转换,但在实际生产环境中请注意:

  • 方法一(SimpleXML) 适合大多数常规场景,API简洁且自带编码处理,但对非法标签名的清洗力度较大(仅保留字母)。
  • 方法二(DOMDocument) 是最稳健的选择,符合W3C标准,便于处理复杂的XML属性和名称空间(Namespace),推荐用于接口交互。
  • 方法三(字符串拼接) 代码较长且依赖全局状态,易出错,除非有极特殊的格式要求,否则不建议直接使用,建议优先使用内置扩展。

以上就是PHP中将数组转成XML格式的实现代码的详细分析与比较,更多关于PHP数据处理技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表