学习使用PHP怎么也有7年的时间了,竟然也没有注意到有个函数是array_replace_recursive,之前只知道array_merge_recursive,而且,这两个函数的返回结果,都非常地出人意料,不怎么符合直觉,而使用了Yii框架若干年,竟然也不知道有个CMap::mergeArray()方法,这个方法,如果跟前面两个函数混同起来看,竟然也显得有点离奇。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| [ 'apple', 'orange' ], 'nested' => [ 'A' => 'xx', 'B' => 'yy' ], 'single' => 1, ]; $b = [ 'fruite' => [ 'penapple', ], 'nested' => [ 'A' => 'zz', ], 'single' => [ 'string' ], ]; echo "array_merge_recursive: ", PHP_EOL; var_export(array_merge_recursive($a, $b)); echo PHP_EOL, "array_replace_recursive: ", PHP_EOL; var_export(array_replace_recursive($a, $b)); echo PHP_EOL, "CMap::mergeArray: ", PHP_EOL; var_export(CMap::mergeArray($a, $b));
|
然后,我们来看一下这个用例输出的结果,相当神奇哦~1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| array_merge_recursive: array ( 'fruite' => array ( 0 => 'apple', 1 => 'orange', 2 => 'penapple', ), 'nested' => array ( 'A' => array ( 0 => 'xx', 1 => 'zz', ), 'B' => 'yy', ), 'single' => array ( 0 => 1, 1 => 'string', ), ) array_replace_recursive: array ( 'fruite' => array ( 0 => 'penapple', 1 => 'orange', ), 'nested' => array ( 'A' => 'zz', 'B' => 'yy', ), 'single' => array ( 0 => 'string', ), ) CMap::mergeArray: array ( 'fruite' => array ( 0 => 'apple', 1 => 'orange', 2 => 'penapple', ), 'nested' => array ( 'A' => 'zz', 'B' => 'yy', ), 'single' => array ( 0 => 'string', ), )
|
实在是没有心力去把所有的用例想完整,只能随便写几个,从中可以看出来,这些函数的处理规则,不是简单可以说清楚的。
- 对于包含了字符串键的数组,是逐个键去做merge或者replace的
- merge:对于键的值都是纯数组的情况,单纯合并
- merge:对于键的值都是非数组的情况,创建数组添加两者作为元素
- merge:对于键的值一边是数组,另一边是非数组,结果就匪夷所思了,将数组降维后,按上一条规则处理
- 相比之下,replace的行为更具被一致性,就是纯替换
- CMap::mergeArray 则跟两者的行为都有所不同,我也是跪了
当然,问题绝不止这么几个,只是我懒得想全所有用例而已。