Рекурсивное слияние php

Мне нужно объединить некоторые массивы по-другому, и я использую array_merge_recursive. Однако есть что-то, что мне нужно изменить, и я не знаю, как это сделать. Вот цитата из php.net

Если, однако, массивы имеют один и тот же числовой ключ, более позднее значение не будет перезаписывать исходное значение, но будет добавлено.

Я хочу это значение, НЕ добавляемое, я хочу не добавлять точные значения в новый массив. Надеюсь, вы это поняли.

Пример:

$array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other'] = 'key2'; 

Если я использую array_merge_recursive, это приведет к следующему:

 Array ( [some] => Array ( [other] => Array ( [0] => key [1] => key2 ) ) ) 

Я хочу, чтобы он совпал с тем же результатом, а не добавлял его. Да, я знаю, вы бы сказали, а затем используйте array_merge, но он тоже не работает. Если я использую это:

 $array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other2'] = 'key2'; print_r(array_merge($array, $array2)); 

Он удалит $ array [some] [other] из списка и оставит только $ array [some] [other2]. Я не знаю, что лучше, так как никто не делает это лучше.

попробуй это

 <?php function mymerge(&$a,$b){ //$a will be result. $a will be edited. It's to avoid a lot of copying in recursion foreach($b as $child=>$value){ if(isset($a[$child])){ if(is_array($a[$child]) && is_array($value)){ //merge if they are both arrays mymerge($a[$child],$value); } //else ignore, you can add your own logic, ie when 1 of them is array } else $a[$child]=$value; //add if not exists } //return $a; } 

Я написал для этого класс слияния:

 <?php class ArrayMerge { /** * @param array $a * @param array $b * * @return array */ public function merge ( $a, $b ) { foreach ( $b as $k => $v ) { if ( is_array( $v ) ) { if ( isset( $a[ $k ] ) ) { if ( $this->isDeep( $v ) ) { $a[ $k ] = $this->merge( $a[ $k ], $v ); } else { $a[ $k ] = array_merge( $a[ $k ], $v ); } } else { $a[ $k ] = $v; } } else { $a[ $k ] = $v; } } return $a; } /** * @param array $array * * @return bool */ private function isDeep ( $array ) { foreach ( $array as $elm ) { if ( is_array( $elm ) ) { return TRUE; } } return FALSE; } } 

Я начал с версии RiaD и добавил обработку объекта. Необходимость тестирования и обратной связи

 function recursiveMerge(&$a,$b){ //$a will be result. $a will be edited. It's to avoid a lot of copying in recursion if(is_array($b) || is_object($b)){ foreach($b as $child=>$value){ if(is_array($a)){ if(isset($a[$child])) recursiveMerge($a[$child],$value); else $a[$child]=$value; } elseif(is_object($a)){ if(isset($a->{$child})) recursiveMerge($a->{$child},$value); else $a->{$child}=$value; } } } else $a=$b; } 

Другой вариант: array_merge_deep из drupal:

 function array_merge_deep($arrays) { $result = array(); foreach ($arrays as $array) { foreach ($array as $key => $value) { // Renumber integer keys as array_merge_recursive() does. Note that PHP // automatically converts array keys that are integer strings (eg, '1') // to integers. if (is_integer($key)) { $result[] = $value; } // Recurse when both values are arrays. elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { $result[$key] = array_merge_deep(array($result[$key], $value)); } // Otherwise, use the latter value, overriding any previous value. else { $result[$key] = $value; } } } return $result; } 

Для PHP> = 5.3 просто используйте array_replace_recursive