(TL;DR the answer to the last line is "Yes, it's possible - see Scuzzy's answer")
No. PHP arrays don't work that way.
If you need defaults for known keys, then you can assign them:
$defaults = [
'foo' => 'foo',
'bar' => 'bar',
];
$a = [ 'bar' => 'baz' ];
$a = array_merge($defaults, $a);
Now $a['bar]
will be 'baz' (not the default 'bar'), but $a['foo']
will yield 'foo'.
I think the only way to achieve a similar lexical simplicity with not-yet-defined keys is use a class and have $a
return a default value of your choice using a magic getter. Different defaults for different keys, even.
Then you can write,
class FakeArray {
private array $values;
private array $defaults;
private $default = null;
public function __get($key) {
if (array_key_exists($key, $this->values)) {
return $this->values[$key];
}
if (array_key_exists($key, $this->defaults)) {
return $this->defaults[$key];
}
return $this->default;
}
public function __construct(array $values = [ ]) {
$this->values = $values;
}
public function setDefault($default) {
$this->default = $default;
}
public function setDefaults(array $default = []) {
$this->defaults = $defaults;
}
};
$a = new FakeArray([ 'foo' => '123' ]);
$a->setDefaults([ 'joe' => 'jim' ]);
$a->setDefault('baz');
$c = $a->foo; // $c is now '123'.
$b = $a->bar; // $b is now 'baz' (no error).
$d = $a->joe; // $d is now 'jim' (not 'baz').
I would have thought that extending ArrayObject
would have come very close to what you wanted, allowing to replace $a['key']
for $a->key
, but that is not the case:
class FakeArray extends ArrayObject {
...
public function __get($key) {
return $this->default;
}
}
but while $a['foo'] = 'bar'
does store the value, actually not just accessing a nonexistent index, but even accessing a nonexistent property (which would otherwise work in other classes) 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.
This might mean that there's some magic goodness in ArrayObject that could yet be accessed and exploited, but I don't know for sure how and if this is true, or possible.