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
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' );