新版和旧版的ThinkPHP在处理XML方面差异较大,我们以XML数据转换成数组为例,两者都使用了递归实现,我们看看不同的版本下面的实现方法。
旧版处理XML转换成数组的方式是使用XML 语法解析函数,用到了xml_parser_create、xml_parser_set_option、xml_parse_into_struct等函数,写法比较复杂,好处是可以兼容PHP4。
- function xml_to_array($xml)
- {
-
$values = array();-
$index = array();-
$array = array();-
$parser = xml_parser_create();-
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);-
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);- if(
0===xml_parse_into_struct($parser, $xml, $values, $index)) {- return
false;- }
-
xml_parser_free($parser);-
$i = 0;-
$name = $values[$i]['tag'];-
$array[$name] = isset($values[$i]['attributes']) ? $values[$i]['attributes'] : '';-
$array[$name] = struct_to_array($values, $i);- return
$array[$name];- }
- function
struct_to_array($values, &$i)- {
-
$child = array();- if (isset(
$values[$i]['value'])) array_push($child, $values[$i]['value']);- while (
$i++ < count($values)) {- switch (
$values[$i]['type']) {- case
'cdata':-
array_push($child, $values[$i]['value']);- break;
- case
'complete':-
$name = $values[$i]['tag'];- if( !empty(
$name)){-
$child[$name]= isset($values[$i]['value'])?($values[$i]['value']):'';- if(isset(
$values[$i]['attributes'])) {-
$child[$name] = $values[$i]['attributes'];- }
- }
- break;
- case
'open':-
$name = $values[$i]['tag'];-
$size = isset($child[$name]) ? sizeof($child[$name]) : 0;-
$child[$name][$size] = struct_to_array($values, $i);- break;
- case
'close':- return
$child;- break;
- }
- }
- return
$child;- }
新版ThinkPHP采用了SimpleXML类库函数,仅仅使用了simplexml_load_string函数,除了写法简化不少,效率也有数量级的提高(对于大的XML数据解析尤其明显),不过只能用于PHP5以上版本。
- function xml_to_array($xml)
- {
-
$array = (array)(simplexml_load_string($xml));- foreach (
$array as $key=>$item){-
$array[$key] = struct_to_array((array)$item);- }
- return
$array;- }
- function
struct_to_array($item) {- if(!
is_string($item)) {-
$item = (array)$item;- foreach (
$item as $key=>$val){-
$item[$key] = struct_to_array($val);- }
- }
- return
$item;- }
PS:由于新版的XML解析机制变化,所以模板引擎的解析速度大幅度提升