Home > Enterprise >  Default value for an associative array in PHP, if key not present
Default value for an associative array in PHP, if key not present

Time:12-01

Note: I have already read Function to set default value of associative array if the key is not present and Default values for Associative array in PHP.

Let's say:

$a = array('foo' => '123');
$b = $a['bar'];       // PHP Notice:  Undefined index: bar

I'd like to have an empty string by default "" if the key is not present, instead of a PHP Notice.

I know the solutions would be to do:

$b = isset($a['bar']) ? $a['bar'] : "";
// or, since PHP 5.3:
$b = $a['bar'] ?: "";      // but this still produces a "PHP Notice"!

Is there a way to avoid the ?: "" and directly have:

$b = $a['bar'];

get "" with no Notice?


Note: this exists in Python with:

import collections
d = collections.defaultdict(str)
print(d['bar'])   # empty string, no error

CodePudding user response:

No. PHP arrays don't work that way.

What you can do to achieve a similar simplicity is use a class. Then you can write,

$a = new FakeArray([ 'foo' => '123' ]);

$a->setDefault('baz');

$b = $a->bar; // $b is now 'baz'.
$c = $a->foo; // $c is now '123'.

and have $a return a default value of your choice using a magic getter.

I would have thought that extending ArrayObject would have come very close to what you wanted:

class FakeArray extends ArrayObject {
    ...
    public function __get($key) {
         return $this->default;
    }
}

but while $a['foo'] = 'bar' does store the value, actually even accessing a nonexistent property now triggers an Index notice:

$b = $a->baz;

PHP Notice:  Undefined index: baz in ./test.php ...

So, the ArrayObject actually behaves worse than a StdClass.

CodePudding user response:

I'd like to submit another solution using array ArrayObject as stated above

This extends the class and slightly tweaks the offsetGet behavior to always return an empty string

the parent:: statement here invokes the function of the extended class

class MyArrayObject extends ArrayObject
{
   function offsetGet( $key )
   {
     return parent::offsetExists( $key ) ? parent::offsetGet( $key ) : '';
   }
}

$myArray = new MyArrayObject( array( 'foo' => '123') );

var_dump( $myArray['foo'] ); // '123' provided string
var_dump( $myArray['bar'] ); // '' our new default
var_dump( isset( $myArray['foo'] ) ); // true
var_dump( isset( $myArray['bar'] ) ); // false

foreach( $myArray as $key )
{
    var_dump( $key ); // only one iteration of '123'
}

var_dump( is_array( $myArray ) ); // false unfortunately
var_dump( is_iterable( $myArray ) ); // true however

var_dump( array_merge( array(), $myArray ) ); // will fail
var_dump( array_merge( array(), (array) $myArray ) ); // will work

and finally

$myArray['bar'] = '456'; // now if we set bar
var_dump( $myArray['bar'] ); // '456' new value
var_dump( isset( $myArray['bar'] ) ); // now true

as a suggestion from @miken32 to set a default value

class MyArrayObject extends ArrayObject
{
    protected $default;
    public function __construct($array = [], $default = null, $flags = 0, $iteratorClass = "ArrayIterator")
    {
        parent::__construct( $array, $flags, $iteratorClass );
        $this->default = $default;
    }
    function offsetGet( $key )
    {
        return parent::offsetExists( $key ) ? parent::offsetGet( $key ) : $this->default;
    }
}

you can set a default value via

$myArray = new MyArrayObject( array( 'foo' => '123'), 'mydefault' );

CodePudding user response:

You'd have to pre-populate your array with your defaults or create a object class as stated to handle the default response.

$array = array('foo' => '123')   array('foo' => '', 'bar' => '');

var_dump( $array );

array(2) {
  ["foo"]=>string(3) "123"
  ["bar"]=> string(0) ""
}

CodePudding user response:

1 step - add this function:

function getIfIsset(array $array, string $key)
{
    return $array[$key] ?? '';
}

2 step - use this:

echo getIfIsset($mayArray, 'bar');

CodePudding user response:

You can use this method @ before variable with key:

echo @$a['bar'];

  • Related