如何将含SimpleXML元素的封装数组转为Laravel缓存可存储格式
解决Laravel缓存存储含SimpleXMLElement数组的问题
这个问题我之前也碰到过,确实挺头疼的——既要保留XML的属性,又要能存入Laravel缓存。给你两个实用的解决方案,看你的需求选就行:
方法一:将SimpleXMLElement转换为保留属性的关联数组
如果你的需求只是获取XML里的数据(包括属性),不需要再用SimpleXMLElement的方法,那可以把每个SimpleXMLElement递归转换成带属性的关联数组。这样转换后的数组可以直接序列化存入缓存,完全不会有问题。
先写一个递归转换的函数,专门处理SimpleXMLElement:
function simplexml_to_array(SimpleXMLElement $xml): array { $array = (array)$xml; // 递归处理子节点 foreach ($array as $key => $value) { if ($value instanceof SimpleXMLElement) { $array[$key] = simplexml_to_array($value); } } // 把节点属性存入@attributes字段,避免和子节点冲突 if ($attributes = $xml->attributes()) { $array['@attributes'] = (array)$attributes; } return $array; }
然后用这个函数处理整个数组(包括多层嵌套的情况):
function convert_nested_array($data) { if (is_array($data)) { return array_map('convert_nested_array', $data); } elseif ($data instanceof SimpleXMLElement) { return simplexml_to_array($data); } return $data; } // 处理你的原始数组 $convertedArray = convert_nested_array($yourOriginalArray); // 存入Laravel缓存 Cache::put('xml_data_key', $convertedArray, now()->addHours(24)); // 取出使用 $cachedData = Cache::get('xml_data_key'); // 比如获取某个节点的属性:$cachedData['some_node']['@attributes']['id']
这种方式的好处是后续操作数据像普通数组一样方便,完全不需要再处理SimpleXML对象。
方法二:存储XML字符串,取出时还原为SimpleXMLElement
如果你后续还要用SimpleXMLElement的方法(比如xpath()、attributes()这些),那可以把每个SimpleXMLElement转换成XML字符串存储,取出时再还原成对象。
处理代码如下:
// 转换数组:把所有SimpleXMLElement转成XML字符串 function serialize_with_simplexml($data) { if (is_array($data)) { return array_map('serialize_with_simplexml', $data); } elseif ($data instanceof SimpleXMLElement) { return $data->asXML(); } return $data; } // 处理并存入缓存 $serializedArray = serialize_with_simplexml($yourOriginalArray); Cache::put('xml_data_key', $serializedArray, now()->addHours(24)); // 取出并还原成SimpleXMLElement function unserialize_to_simplexml($data) { if (is_array($data)) { return array_map('unserialize_to_simplexml', $data); } elseif (is_string($data) && str_starts_with($data, '<?xml')) { return simplexml_load_string($data); } return $data; } $restoredArray = unserialize_to_simplexml(Cache::get('xml_data_key')); // 现在$restoredArray里的对象还是SimpleXMLElement,可以正常调用它的方法
这个方法能完美还原原来的SimpleXMLElement对象,适合需要继续用XML操作方法的场景。
两种方法都能解决序列化的问题,你可以根据自己的实际需求选择~
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

