(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.