12

I have an array with default settings, and one array with user-specified settings. I want to merge these two arrays so that the default settings gets overwritten with the user-specified ones.

I have tried to use array_merge, which does the overwriting like I want, but it also adds new settings if the user has specified settings that doesn't exist in the default ones. Is there a better function I can use for this than array_merge? Or is there a function I can use to filter the user-specified array so that it only contains keys that also exist in the default settings array?

Example of what I want

$default = array('a' => 1, 'b' => 2);
$user = array('b' => 3, 'c' => 4);

// Somehow merge $user into $default so we end up with this:
Array
(
    [a] => 1
    [b] => 3
)
2
  • 2
    +1 for editing an example of what you want... Commented May 15, 2010 at 1:49
  • 1
    @gnarf: Thank you, hehe. Got so many answers with what I didn't want so figured I should clearify it a bit :) Commented May 15, 2010 at 10:06

4 Answers 4

22

You can actually just add two arrays together ($user+$default) instead of using array_merge.

If you want to stop any user settings that don't exist in the defaults you can use array_intersect_key:

Returns an associative array containing all the entries of array1 which have keys that are present in all arguments

Example:

$default = array('a' => 1, 'b' => 2);
$user = array('b' => 3, 'c' => 4);

// add any settings from $default to $user, then select only the keys in both arrays
$settings = array_intersect_key($user + $default, $default);

print_r($settings);

Results:

Array
(
    [b] => 3
    [a] => 1
)

The keys/values (and order) are selected first from $user in the addition, which is why b comes before a in the array, there is no a in $user. Any keys not defined in $user that are defined in $default will then be added to the end of $user. Then you remove any keys in $user + $default that aren't defined in $default.

Sign up to request clarification or add additional context in comments.

4 Comments

If a key exists in the $userSettings but not in $defaultSettings, you would copy it over to $settings. He doesn't want that to happen.
This has the same problem as far as I can see from my tests. If there are any settings in $userSettings that are not defined in $defaultSettings, then they will be taken also. I want all keys not defined in $defaultSettings to be ignored and not present in my final $settings array.
@chad & @svish - Sorry, didn't read that caveat until I had posted already, updated with the solution (and wow, quick commenting ;) )
Hm... missed the + $defaultSettings at first, but when I added that this totally works :) Awesome!
1

It's probably simplest to just loop over the keys in the default-settings array, if you only want to consider those. So you can do something like this:

foreach ($default_settings AS $key => $default_value)
{
    if (array_key_exists($key, $user_settings))
    {
        $combined_settings[$key] = $user_settings[$key];
    }
    else
    {
        $combined_settings[$key] = $default_value;
    }
}

3 Comments

Yeah, seems like something along these lines will be the way to go. Was just hoping PHP had something more clever up it's sleeve and that I could get to know a new and interesting php function, hehe.
Well, if you want "clever" I'd go with gnarf's answer. But honestly, if I came across that line of code somewhere, I'd have no clue at all what it was doing. So please add an explanation in a comment if you do use that, for the sanity of future maintainers (including yourself).
I've seen the pattern I used in Zend Framework stuff, and the first time I said "wtf is this doing", but luckily with PHP is easy enough to go to php.net/array_intersect_key and figure it out.
1
foreach($default as $key=>$val){   
  if (isset($user[$key]))
  {
    $settings[$key] = $user[$key];
  } else {
    $settings[$key] = $default[$key];
  } 
}

I think this is what you want.

1 Comment

Wouldn't this fail if a key was not set in the $user_settings array?
0
foreach($user_settings as $key=>$val){   
    $global_settings[$key] = $val; 
}

?

3 Comments

That does exactly what he said he didn't want it to do.
Yup, hehe. I don't want anything that doesn't exist in the default array to be added.
I suppose that could work if I add an if(isset), but I was curious to see if there are any php function that can do it out of the box for me. Especially since there are quite a bit of array related functions that I don't quite understand...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.