Slim框架中如何便捷实现带属性的PHP数组转XML?
在Slim框架中适配CakePHP XML类或实现数组转带属性XML的方案
一、直接适配CakePHP的XML类
CakePHP的Xml类(原cake.libs中的XML类,现位于Cake\Utility\Xml)是独立组件,无需依赖整个CakePHP框架,可直接集成到Slim项目:
提取核心文件
从CakePHP源码中复制Xml.php(路径通常为vendor/cakephp/cakephp/src/Utility/Xml.php)和依赖的XmlException.php,放到你的Slim项目目录(比如src/Utility/)。调整命名空间
修改两个文件的命名空间,与你的Slim项目保持一致,例如改为App\Utility:// Xml.php 顶部 namespace App\Utility; // XmlException.php 顶部 namespace App\Utility;处理依赖Trait
若Xml类用到Cake\Core\InstanceConfigTrait,可直接提取该Trait文件到项目,或手动将Trait内的配置逻辑整合到Xml类中(核心的数组转XML逻辑集中在fromArray方法,配置部分代码量不大)。在Slim中调用
完成上述步骤后,即可在路由或控制器中直接使用:use App\Utility\Xml; // 符合CakePHP格式的数组(@标识属性,#text标识节点文本) $data = [ 'root' => [ '@id' => 1, 'product' => [ ['@sku' => 'SP001', '#text' => '无线耳机'], ['@sku' => 'SP002', '#text' => '蓝牙音箱'] ] ] ]; $xml = Xml::fromArray($data); echo $xml->asXML();
二、适配数据库结果数组的处理方案
针对数据库返回的普通数组,无需手动添加属性标识,可封装一层转换函数,自动生成符合Xml类要求的格式:
function dbDataToXmlFormat($dbResult, $rootNode = 'dataset', $itemNode = 'record') { $xmlData = [$rootNode => []]; foreach ($dbResult as $row) { $item = []; foreach ($row as $field => $value) { // 示例:将主键id设为节点属性,其他字段作为子节点 if ($field === 'id') { $item["@$field"] = $value; } else { $item[$field] = $value; } } $xmlData[$rootNode][$itemNode][] = $item; } return $xmlData; } // 数据库查询结果示例 $dbResult = [ ['id' => 1, 'username' => 'zhangsan', 'email' => 'zhangsan@example.com'], ['id' => 2, 'username' => 'lisi', 'email' => 'lisi@example.com'] ]; // 转换为Xml类兼容格式并生成XML $xmlFormatData = dbDataToXmlFormat($dbResult); $xml = Xml::fromArray($xmlFormatData); echo $xml->asXML();
三、实现轻量版数组转带属性XML
若不想引入CakePHP文件,可自行编写简易转换器,核心逻辑是识别数组中的属性标识(@前缀)并递归生成XML:
class SimpleXmlConverter { public static function arrayToXml($data, $rootNode = 'root') { $xml = new \SimpleXMLElement("<$rootNode/>"); self::buildNodes($xml, $data); return $xml->asXML(); } private static function buildNodes(\SimpleXMLElement $parent, $data) { foreach ($data as $key => $value) { if (is_array($value)) { // 处理属性 if (str_starts_with($key, '@')) { $parent->addAttribute(substr($key, 1), $value); continue; } // 处理节点文本 if ($key === '#text') { $parent[0] = $value; continue; } // 数字索引视为同节点的多个实例,默认节点名为item $nodeName = is_numeric($key) ? 'item' : $key; $child = $parent->addChild($nodeName); self::buildNodes($child, $value); } else { $parent->addChild($key, htmlspecialchars($value)); } } } } // 使用示例 $data = [ '@version' => '1.0', 'user' => [ ['@id' => 1, 'name' => '张三', 'age' => 25], ['@id' => 2, 'name' => '李四', 'age' => 30] ] ]; echo SimpleXmlConverter::arrayToXml($data, 'users');
内容的提问来源于stack exchange,提问作者devanshu decoded
相关产品推荐
相关产品推荐

