我有一些默认配置,以及一些可配置的特定配置。我需要将特定配置合并到默认配置中。
将使用默认选项。
value
的情况下是标量,具体配置应该应用value
的情况下是标量数组,应合并数组并应用 array_unique。 value
的情况下是一个关联数组,我们需要应用上面的scalar
和 scalar_array
规则。 例子:
$defaultConfigs = [
'scalar1' => 1,
'scalar2' => "Apple",
'array_scalar' => [3,4,5],
'array_associative' => [
'scalar' => 1,
'array_scalar' => [1,2,3],
'array_associative' => [
...
]
],
];
$specificConfigs = [
'scalar1' => "A",
'array_scalar' => [3,4,5],
'array_associative' => [
'scalar' => 1,
'array_scalar' => [1,2,3],
'array_associative' => [
...
]
],
];
预期输出:
$expectedConfigs = [
'scalar1' => "A", // Overridden
'scalar2' => "Apple", // Default used
'array_scalar' => [1,2,3,4,5], // Scalar merged and array_unique
'array_associative' => [
'scalar' => "B", // Overridden
'array_scalar' => [1,2,3,4,5], // Scalar merged and array_unique
'array_associative' => [
...
]
],
];
有没有一种很好的干净的方法来实现这一目标?
最佳答案
此功能获得您想要的结果。它假设特定类型与默认类型是一致的,因此不执行一致性检查。该函数迭代特定的配置数组并检查对应的默认值1:如果是标量,则替换默认值;如果是枚举的array2,则合并唯一值;否则函数以当前值作为参数调用自身。
function fillConfig( $default, $specific )
{
foreach( $specific as $key=> $val )
{
if( isset( $default[$key] ) )
{
if( ! is_array( $default[$key] ) )
{
$default[$key] = $val;
}
elseif( array_keys($default[$key]) === range(0, count($default[$key]) - 1) )
{
$default[$key] = array_unique( array_merge( $default[$key], $val ) );
}
else
{
$default[$key] = fillConfig( $default[$key], $val );
}
}
else
{
// This happens when a specific key doesn't exists in default configuration.
// I think that in this case the value must be omitted,
// otherwise you can un-comment following line:
// $default[$key] = $val;
}
}
return $default;
}
以这种方式调用函数:
$result = fillConfig( $defaultConfigs, $specificConfigs );
$result
,应用于您的阵列样本,是这样的:Array
(
[scalar1] => A
[scalar2] => Apple
[array_scalar] => Array
(
[0] => 3
[1] => 4
[2] => 5
)
[array_associative] => Array
(
[scalar] => 1
[array_scalar] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[array_associative] => Array
(
)
)
)
使用这对数组:
$defaultConfigs = [
'scalar1' => 1,
'scalar2' => "Apple",
'array_scalar' => [3,4,5],
'array_associative' => [
'scalar' => 1,
'array_scalar' => [1,2,3],
'array_associative' => [
]
],
];
$specificConfigs = [
'scalar1' => "A",
'array_scalar' => [3,4,5],
'array_associative' => [
'scalar' => B,
'array_scalar' => [3,4,5],
'array_associative' => [
]
],
];
$result
是:Array
(
[scalar1] => A
[scalar2] => Apple
[array_scalar] => Array
(
[0] => 3
[1] => 4
[2] => 5
)
[array_associative] => Array
(
[scalar] => B
[array_scalar] => Array
(
[0] => 1
[1] => 2
[2] => 3
[4] => 4
[5] => 5
)
[array_associative] => Array
(
)
)
)
笔记:
1 是的,这有点不连贯:我觉得最好遍历特定数组(不存在的项目保持不变),但对默认数组执行值检查,即引用点。
2 枚举/关联数组检查基于 this answer .
关于PHP array_replace_recursive 如果是标量,array_merge_recursive 如果是数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35552679/