11

Lets say you are having a user provide information.

Array 1

But not all is required. So you have defaults.

Array 2

Does PHP have a function which will overwrite all array values of Array 2 based on if they are supplied in Array 1, and not empty?

Orangeman555
  • 1,179
  • 2
  • 21
  • 45
  • This question is too vague and is missing a [mcve]. We don't know what the input arrays look like. Answers are too varied and may only be circumstantially correct. – mickmackusa Oct 03 '22 at 20:37

5 Answers5

21

I think what you are looking for is array_replace_recursive, especially for the case when your "defualts" may be an associative array more than one level deep.

$finalArray = array_replace_recursive(array $defaults, array $inputOptions)

heres an example that takes an optional array of options to a function and does some processing based on the result of those options "opts" and the defaults which you specify:

function do_something() {
    $args = func_get_args();
            $opts = $args[0] ? $args[0] : array();

    $defaults = array(
        "second_level" => array(
                    "key1" => "val1",
                    "key2" => "val2"
                ),
        "key1" => "val1",
        "key2" =>  "val2",
        "key3" => "val3"
    );

    $params = array_replace_recursive($defaults, $opts);
    // do something with these merged parameters
}

The php.net reference document is here

Augie Gardner
  • 2,749
  • 3
  • 25
  • 36
3
$defaults = array(
    'some_key_1'=>'default_value_1',
    'some_key_2'=>'default_value_2',
);

$inputs = array_merge($defaults, $inputs)

Note that if the $inputs array contains keys not in the $defaults array they will be added in the result.

gagarine
  • 4,190
  • 2
  • 30
  • 39
Vladyslav Savchenko
  • 1,282
  • 13
  • 10
3

If you just want to keep the options that you expect and discard the rest you may use a combination of array_merge and array_intersect_key.

<?php

function foo($options) {
    $defaults = [
        'a' => 1,
        'b' => null,
    ];

    $mergedParams = array_merge(
        $defaults,
        array_intersect_key($options, $defaults)
    );

    return $mergedParams;
}


var_dump(foo([
    'a' => 'keep me',
    'c' => 'discard me'
]));

// => output
//
// array(2) {
//   ["a"]=>
//   string(7) "keep me"
//   ["b"]=>
//   NULL
// }

If you instead want to keep any extra key then array_merge($defaults, $options) will do just fine.

jave.web
  • 13,880
  • 12
  • 91
  • 125
Riccardo Galli
  • 12,419
  • 6
  • 64
  • 62
  • 1
    Yes this answer is of my liking :) Also I like the note you've added, that this is only if you want to remove the extra keys :) PS: I've added links to docs ;) – jave.web Feb 03 '17 at 12:54
1

array_merge() is exactly what you are looking for.

  • it's wrong, array_merge will add any key in the non-default array and you could end up with keys not available in the default array – Riccardo Galli Feb 04 '16 at 16:09
  • @RiccardoGalli the keys not available in default array are not used anyway, I don't see this as issue. – jave.web Feb 01 '17 at 21:47
  • This is meant more for 1-dimensional arrays or when rewriting array-like default value completely with provided value is the intended behaviour. Sidenote: performance speaking in PHP 5.6 it was faster to `foreach`, in PHP 7 there is almost no difference. – jave.web Feb 01 '17 at 21:48
  • @jave.web "keys not available in default array are not used anyway" you can't really know that, for example you may want to store the user's current configuration, and you would end up storing who knows what (just as example). I think you should really avoid to have to worry about that and just drop unexpected keys – Riccardo Galli Feb 01 '17 at 21:56
  • @RiccardoGalli my point is, when your design is right, this can not bother you :) Especially user's configuration that comes from user must be prepared anyway :) BTW: What would YOU suggest then? :) – jave.web Feb 01 '17 at 21:58
  • @jave.web I've added an answer, I hope it's of your liking – Riccardo Galli Feb 02 '17 at 06:33
0

You can just do something like

foreach($array1 as $key=>$value) $array2[$key]=$value;
javic
  • 823
  • 1
  • 6
  • 9
  • As this will work in most of the cases, it directly overrides `$array2` which is, in this use-case, the "defaults" array. This may or may not be intended behaviour. – jave.web Feb 01 '17 at 23:00