1

Could anyone explain why the following works in PHP?

$xml = \simplexml_load_string('<root></root>');
$xml->a->b->c = 123;

(And any depth will work.)

But when trying to inspect the item directly, it will, as I would expect, throw a reference error.

$xml = \simplexml_load_string('<root></root>');
var_dump($xml->a->b->c);

Because, $xml->a is a SimpleXMLElement, and $x->a-b is null, and then you can't reference properties of non-objects.

Even in the first situation of the assignment, I would expect the dereferencing to happen before the assignment and fail. But it looks like there's something working differently there.

Alin Purcaru
  • 43,655
  • 12
  • 77
  • 90
  • 1
    PHP creates absent levels when you set a value on a deep level - http://sandbox.onlinephpfunctions.com/code/dfe4eb72e5899c39c3b9bfcb0d87041060c2f4fb – splash58 Jan 04 '19 at 11:19
  • @splash58 it works, but it does give a warning: `Creating default object from empty value in php shell code on line 1` – Bart Friederichs Jan 04 '19 at 11:26
  • simple xml object has own methods to modify it. And structure of it is not the same than stdClass object. But in both cases the result value is set – splash58 Jan 04 '19 at 11:31
  • @splash58 yes, the behaviour is the same, except in SimpleXML there is no warning. – Bart Friederichs Jan 04 '19 at 11:32

1 Answers1

2

PHP creates a default object from an empty value when you dereference it. Consider this code, where $foo is not assigned yet:

php > $foo->bar = 'baz';
PHP Warning:  Creating default object from empty value in php shell code on line 1
php > var_dump($foo);
object(stdClass)#4 (1) {
  ["bar"]=>
  string(3) "baz"
}

So, it is expected behaviour on stdClass object, so I reckon the people from SimpleXML copied that. With stdClass though, it gives you a warning if it does.

See also Creating default object from empty value in PHP?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • Thanks for the answer Bart. I somehow forgot about this PHP behavior, or maybe I did not expect it to apply this way for SimpleXML. Do you maybe have some more info, if this is designed behavior, or it just works by accident? I'd assume it's by design, since the error is not thrown, but I couldn't find it somewhere documented. – Alin Purcaru Jan 04 '19 at 12:21
  • @AlinPurcaru I tried looking for documentation on this behaviour (also on the default `stdClass` behaviour) but I haven't found any. I don't think it works by accident though, because of the warning. – Bart Friederichs Jan 04 '19 at 12:24