60

If I have an array full of information, is there any way I can a default for values to be returned if the key doesn't exist?

function items() {
    return array(
        'one' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'two' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'three' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
    );
}

And in my code

$items = items();
echo $items['one']['a']; // 1

But can I have a default value to be returned if I give a key that doesn't exist like,

$items = items();
echo $items['four']['a']; // DOESN'T EXIST RETURN DEFAULT OF 99
3
  • 1
    php.net/array_key_exists. The manual can be quite useful. Commented Mar 4, 2012 at 14:45
  • 3
    Although array_key_exists would work, it may lead to performance issues with big arrays or lots of checks. It iterates over the entire array to make sure that key exists. Alternatively, isset() does one check and moves on. Commented Mar 4, 2012 at 14:56
  • 4
    What php needs is an array coalescing funcion, something that checks presence and gets the value or a default value if empty. Commented Mar 8, 2013 at 16:49

11 Answers 11

91

I know this is an old question, but my Google search for "php array default values" took me here, and I thought I would post the solution I was looking for, chances are it might help someone else.

I wanted an array with default option values that could be overridden by custom values. I ended up using array_merge.

Example:

<?php
    $defaultOptions = array("color" => "red", "size" => 5, "text" => "Default text");
    $customOptions = array("color" => "blue", "text" => "Custom text");
    $options = array_merge($defaultOptions, $customOptions);
    print_r($options);
?>

Outputs:

Array
(
    [color] => blue
    [size] => 5
    [text] => Custom text
)
Sign up to request clarification or add additional context in comments.

Comments

90

As of PHP 7, there is a new operator specifically designed for these cases, called Null Coalesce Operator.

So now you can do:

echo $items['four']['a'] ?? 99;

instead of

echo isset($items['four']['a']) ? $items['four']['a'] : 99;

There is another way to do this prior the PHP 7:

function get(&$value, $default = null)
{
    return isset($value) ? $value : $default;
}

And the following will work without an issue:

echo get($item['four']['a'], 99);
echo get($item['five'], ['a' => 1]);

But note, that using this way, calling an array property on a non-array value, will throw an error. E.g.

echo get($item['one']['a']['b'], 99);
// Throws: PHP warning:  Cannot use a scalar value as an array on line 1

Also, there is a case where a fatal error will be thrown:

$a = "a";
echo get($a[0], "b");
// Throws: PHP Fatal error:  Only variables can be passed by reference

At final, there is an ugly workaround, but works almost well (issues in some cases as described below):

function get($value, $default = null)
{
    return isset($value) ? $value : $default;
}
$a = [
    'a' => 'b',
    'b' => 2
];
echo get(@$a['a'], 'c');      // prints 'c'  -- OK
echo get(@$a['c'], 'd');      // prints 'd'  -- OK
echo get(@$a['a'][0], 'c');   // prints 'b'  -- OK (but also maybe wrong - it depends)
echo get(@$a['a'][1], 'c');   // prints NULL -- NOT OK
echo get(@$a['a']['f'], 'c'); // prints 'b'  -- NOT OK
echo get(@$a['c'], 'd');      // prints 'd'  -- OK
echo get(@$a['c']['a'], 'd'); // prints 'd'  -- OK
echo get(@$a['b'][0], 'c');   // prints 'c'  -- OK
echo get(@$a['b']['f'], 'c'); // prints 'c'  -- OK
echo get(@$b, 'c');           // prints 'c'  -- OK

2 Comments

In your example function you are disgarding the default value!
In your function, it should be return isset($value) ? $value : $default;
22

This should do the trick:

$value =  isset($items['four']['a']) ? $items['four']['a'] : 99;

A helper function would be useful, if you have to write these a lot:

function arr_get($array, $key, $default = null){
    return isset($array[$key]) ? $array[$key] : $default;
}

8 Comments

I can't believe it's 2013 and there is no native funcion for this. What's the point of typing a whole expression twice?
Kohana has an Array helper, you can do this by calling Arr::get('key', $array, $default) really handy.
I wish I could downvote PHP itself for not having a nicer way to deal with this.
Yep, it's hard to believe that PHP doesn't have something like : $array->get($key, $default)
I think you should rather test with array_key_exists than with isset, since a key set to a null value should still be considered set.
|
11

As of PHP7.0

You may use the null coalescing operator: ??

$value = $items['four']['a'] ?? 99;
echo $value;

# or simply
echo $items['four']['a'] ?? 99;

As of PHP7.4

You could instead use the null coalescing assignment operator if you want to additionally assign the default value to the array key if empty.

$items['four']['a'] ??= 99;
echo $items['four']['a'];

For PHP <=5.x

If you can guarantee that 'four' and 'a' keys always exist and is either a truthy or falsy value, then you may use the ternary operator with empty middle part: ?:

However, if the array keys are not guaranteed to exist, this may give you errors, so be careful to check with isset() or !empty() (see the long-form answer below).

$value = $items['four']['a'] ?: 99;
echo $value;

All versions of PHP support the long-form ternary operator:

$value = !empty($items['four']['a']) ? $items['four']['a'] : 99;
echo $value;

Note that this does not return 99 if and only if the key 'a' is not set in items['four']. Instead, it returns 99 if and only if the value $items['four']['a'] is either unset or a falsy value value like an empty string (''), empty array, NULL, 0, or FALSE.

6 Comments

Are you really sure that those both lines do the same?
This wouldn't return the value $items['four']['a'], but instead would return TRUE.
This would be checking the value of $items['four']['a'] not its existence. It is very different from checking with isset.
What if the value of $items['four']['a'] is 0 or FALSE.
in php7 you could do this. $value = $items['four']['a'] ?? 99;
|
4

The question is very old, but maybe my solution is still helpful. For projects where I need "if array_key_exists" very often, such as Json parsing, I have developed the following function:

function getArrayVal($arr, $path=null, $default=null) {
    if(is_null($path)) return $arr;
    $t=&$arr;
    foreach(explode('/', trim($path,'/')) As $p) {
        if(!array_key_exists($p,$t)) return $default;
        $t=&$t[$p];
    }
    return $t;
}

You can then simply "query" the array like:

$res = getArrayVal($myArray,'companies/128/address/street');

This is easier to read than the equivalent old fashioned way...

$res = (isset($myArray['companies'][128]['address']['street']) ? $myArray['companies'][128]['address']['street'] : null);

Comments

3

Not that I know of.

You'd have to check separately with isset

echo isset($items['four']['a']) ? $items['four']['a'] : 99;

Comments

2

Use Array_Fill() function

http://php.net/manual/en/function.array-fill.php

$default = array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         );
$arr = Array_Fill(1,3,$default);
print_r($arr);

This is the result:

Array
(
    [1] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

    [2] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

    [3] => Array
        (
            [a] => 1
            [b] => 2
            [c] => 3
            [d] => 4
        )

)

Comments

0

I don't know of a way to do it precisely with the code you provided, but you could work around it with a function that accepts any number of arguments and returns the parameter you're looking for or the default.

Usage:

echo arr_value($items, 'four', 'a');

or:

echo arr_value($items, 'four', 'a', '1', '5');

Function:

function arr_value($arr, $dimension1, $dimension2, ...)
{
    $default_value = 99;
    if (func_num_args() > 1)
    {
        $output = $arr;
        $args = func_gets_args();
        for($i = 1; $i < func_num_args(); $i++)
        {
            $outout = isset($output[$args[$i]]) ? $output[$args[$i]] : $default_value;
        }
    }
    else
    {
        return $default_value;
    }

    return $output;
}

Comments

0

You can use DefaultArray from Non-standard PHP library. You can create new DefaultArray from your items:

use function \nspl\ds\defaultarray;
$items = defaultarray(function() { return defaultarray(99); }, $items);

Or return DefaultArray from the items() function:

function items() {
    return defaultarray(function() { return defaultarray(99); }, array(
        'one' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'two' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
         'three' => array(
              'a' => 1,
              'b' => 2,
              'c' => 3,
              'd' => 4,
         ),
    ));
}

Note that we create nested default array with an anonymous function function() { return defaultarray(99); }. Otherwise, the same instance of default array object will be shared across all parent array fields.

Comments

0

Currently using of php 7.2

>>> $a = ["cat_name"=>"Beverage", "details"=>"coca cola"];
=> [
     "cat_name" => "Beverage",
     "details" => "coca cola",
   ]
>>> $a['price']
PHP Notice:  Undefined index: price in Psy Shell code on line 1
=> null
>>> $a['price'] ?? null ? "It has price key" : "It does not have price key"
=> "It does not have price key"

1 Comment

There are several detailed answers on this very old question. If you think your answer adds something that theirs lacks, please explain in more detail vs leaving what amounts to just a code snippet.
-1

In PHP7, as Slavik mentioned, you can use the null coalescing operator: ??

Link to the PHP docs.

Comments

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.