只使用匹配的覆盖组合两个数组

时间:2016-03-18 08:13:18

标签: php arrays

我有两个数组:

原文:

array(2) {
  'app_name' =>
  string(15) "dropcat-default"
  'site' =>
  array(1) {
    'environment' =>
    array(7) {
      'drush_alias' =>
      NULL
      'backup_path' =>
      string(6) "backup"
      'config_name' =>
      NULL
      'original_path' =>
      string(33) "/var/www/webroot/shared/some_path"
      'symlink' =>
      string(43) "/var/www/webroot/mysite_latest/symlink_path"
      'url' =>
      string(17) "http://localhost"
      'name' =>
      string(11) "mystagesite"
    }
  }
}

有一个覆盖:

array(2) {
  'app_name' =>
  string(17) "dropcat-overrides"
  'site' =>
  array(1) {
    'environment' =>
    array(1) {
      'drush_alias' =>
      string(6) "foobar"
    }
  }
}

我想替换原始数组中的覆盖,但保留覆盖中不存在的密钥 - 使用array_replace只是写入现有的密钥,因为我在数组中有数组。有没有一种简单的方法可以解决这个问题?

4 个答案:

答案 0 :(得分:0)

function _merge_array_rec($arr, $arr2, $i = 0)
{ 
    foreach ($arr2 as $key => $value)
    {
        if (!isset($arr[$key]))
        {
            $arr[$key] = $value;
        }
        else
        {
            if (is_array($value))
            {
                $arr[$key] = _merge_array_rec($arr[$key], $arr2[$key], $i + 1);
            }
            else
            {
                $arr[$key] = $value;
            }
        }
    }        
    return $arr;
}

$merge_array = _merge_array_rec($array1, $array2);

答案 1 :(得分:0)

array_replace_recursive为多维数组完成了它。

对于单维数组,循环遍历原始数组,然后检查覆盖数组是否具有此值是足够有趣的。

类似的东西:

$original=array();
$overriding=array();
foreach($original as $key => $value){
  if(isset($overriding[$key]) && !empty($overriding[$key])){
      $original[$key]=$overriding[$key];
  }
}

希望这有帮助

答案 2 :(得分:0)

    应使用
  • array_key_exists代替isset,因为isset会忽略NULL
  • $overrides的结构应该验证,不应该验证吗?

尝试一下。

<?php

function array_replace_recursive_if_valid(array $defaults, array $overrides) {
    foreach ($overrides as $key => $value) {
        if (!array_key_exists($key, $defaults)) {
            continue;
        }
        if (is_array($defaults[$key]) && is_array($value)) {
            $defaults[$key] = array_replace_recursive_if_valid($defaults[$key], $value);
            continue;
        }
        if (!is_array($defaults[$key]) && !is_array($value)) {
            $defaults[$key] = $value;
            continue;
        }
    }
    return $defaults;
}

$defaults = [
    'app_name' => 'dropcat-default',
    'site' => [
        'environment' => [
            'drush_alias' => null,
            'back_path' => 'packup',
            'config_name' => null,
            'original_path' => '/var/www/webroot/shared/some_path',
            'symlink' => '/var/www/webroot/mysite_latest/symlink_path',
            'url' => 'http://localhost',
            'name' => 'mystagesite',
        ],
    ],
];

$overrides = [
    'app_name' => 'dropcat-overrides',
    'this is invalid' => 'foo',
    'site' => [
        'environment' => [
            'drush_alias' => 'foobar',
            'url' => ['this is invalid'],
        ],
    ],
];

var_export(array_replace_recursive_if_valid($defaults, $overrides));

答案 3 :(得分:0)

最后,我最终这样做了:

$configs = array_replace_recursive($default_config, $env_config);

它涵盖了我的用例。