PHP array_replace_recursive if scalar array array_merge_recursive if

I have some default configurations and some specific configurations that could be customized. I need to combine specific configurations in the default configuration.

  • In case a specific configuration parameter does not exist, the default option will be used.
  • In the case where value is a scalar, a special configuration should be used.
  • In the case where value is a scalar array, the arrays must be concatenated and array_unique is applied.
  • In the case where value is an associative array, we need to apply the above rules of scalar and scalar_array .

Example:

 $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' => [ ... ] ], ]; 

Expected Result:

 $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' => [ ... ] ], ]; 

Is there a good clean way to achieve this?

+6
source share
2 answers

My case was a little different, but it could help. I needed to replace scalars and array_merge_recursive with arrays.

 class ArrayUtil { public static function mergeRecursive(array $array1, $array2) { if($array2 && is_array($array2)) { foreach($array2 as $key => $val2) { if (is_array($val2) && (null!==($val1 = isset($array1[$key]) ? $array1[$key] : null)) && is_array($val1)) { $array1[$key] = self::mergeRecursive($val1,$val2); } else { $array1[$key] = $val2; } } } return $array1; } } 
+1
source

This function gets the desired result. Specific types are assumed to be coherent with default types, so consistency checking is not performed. The function iterates over a specific configuration array and checks the corresponding default value 1 : if it is scalar, replace the default value; if it is an enumerated array 2, it combines unique values; otherwise, the function calls itself with the current values ​​as arguments.

 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; } 

The function call is as follows:

 $result = fillConfig( $defaultConfigs, $specificConfigs ); 

$result applied to your sample arrays is as follows:

 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 ( ) ) ) 

With this array of steam:

 $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 ( ) ) ) 

Notes:

1 Yes, this is a little incoherent: I felt that it was better to iterate over a specific array (non-existing elements remain untouched), but they perform a check of the default value, that is, a breakpoint.

2 Enum / associative array validation is based on this answer .

+1
source

All Articles