56

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
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
cgwebprojects
  • 3,382
  • 6
  • 27
  • 40
  • 1
    http://php.net/array_key_exists. The manual can be quite useful. – vascowhite Mar 04 '12 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. – CaseySoftware Mar 04 '12 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. – Jens Mar 08 '13 at 16:49

11 Answers11

87

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
)
Hein Andre Grønnestad
  • 6,885
  • 2
  • 31
  • 43
83

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
Slavik Meltser
  • 9,712
  • 3
  • 47
  • 48
21

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;
}
Silas Parker
  • 8,017
  • 1
  • 28
  • 43
Mārtiņš Briedis
  • 17,396
  • 5
  • 54
  • 76
  • 43
    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? – Jens Mar 08 '13 at 16:47
  • 1
    Kohana has an Array helper, you can do this by calling `Arr::get('key', $array, $default)` really handy. – Mārtiņš Briedis Mar 09 '13 at 21:27
  • 31
    I wish I could downvote PHP itself for not having a nicer way to deal with this. – Tyler Collier Apr 15 '14 at 00:27
  • 4
    Yep, it's hard to believe that PHP doesn't have something like : ```$array->get($key, $default)``` – fe_lix_ Jun 18 '14 at 07:15
  • I made another helper function which is simpler and needs fewer arguments: http://stackoverflow.com/a/25205195/1890285 – stepmuel Aug 08 '14 at 13:59
  • 4
    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. – Elmar Zander Feb 24 '15 at 21:01
  • The helper function would not work for your example, as it will work for 1-dimensional arrays, only. – ESP32 Jan 23 '16 at 21:17
  • In Laravel you could use Arr::get($array, 'key') the default is null, and works with multidimensional arrays. – Luco Nov 14 '19 at 17:10
9

As of PHP7.0 you can use the null coalescing operator ??

$value = $items['one']['two'] ?? 'defaut';

For <5.6

You could also do this:

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

This equates to:

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

It saves the need to wrap the whole statement into a function!

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 false (either unset or a false value like 0).

Mārtiņš Briedis
  • 17,396
  • 5
  • 54
  • 76
Eric Keyte
  • 633
  • 5
  • 14
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);
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
ESP32
  • 8,089
  • 2
  • 40
  • 61
3

Not that I know of.

You'd have to check separately with isset

echo isset($items['four']['a']) ? $items['four']['a'] : 99;
J. Bruni
  • 20,322
  • 12
  • 75
  • 92
knittl
  • 246,190
  • 53
  • 318
  • 364
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
        )

)
rostamiani
  • 2,859
  • 7
  • 38
  • 74
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.

Ihor Burlachenko
  • 4,689
  • 1
  • 26
  • 25
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"
Bishal Udash
  • 142
  • 2
  • 8
  • 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. – gilliduck Mar 22 '20 at 16:46
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;
}
Ynhockey
  • 3,845
  • 5
  • 33
  • 51
-1

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

Link to the PHP docs.