About error "Attempt to modify property of non-object"
php
Solution
StdClass vs Array
Array
Arrays in PHP allow for the implicit creation of multidimensional arrays from the base. ie:
$a[] = "something"; //new array created, indexed at 0
$a[] = "yep"; //adds element to end of array (array_push);
The `var_dump` of the above gives:
array(2) {
[0]=>
string(9) "something"
[1]=>
string(3) "yep"
}
In PHP 5.4.x no notices are given either. You could also do:
$a[] = "something";
$a[1][2][3] = "yep";
And all levels of the array are implicitly created giving the `var_dump` of:
array(2) {
[0]=>
string(9) "something"
[1]=>
array(1) {
[2]=>
array(1) {
[3]=>
string(3) "yep"
}
}
}
PHP was designed to handle this type of array-creation with ease. For more information on how arrays are handled, please read the Array Type documentation. Because of this, if you access a key within an array for value assignment, if it doesn't already exist, it is implicitly created. When used in conjunction with `unset`, no errors are thrown because it can check up to the final array and see that it key doesn't exist.
StdClass
Because this is an `object`, properties must be explicitly created past what was cast in to it. For example:
$s = new StdClass;
$s->a = new stdClass;
$s->a->b = new stdClass;
$s->a->b->c = "test";
Will yield:
object(stdClass)#1 (1) {
["a"]=>
object(stdClass)#2 (1) {
["b"]=>
object(stdClass)#3 (1) {
["c"]=>
string(4) "test"
}
}
}
As we create the `object`'s required to reach that point. If, however, you try and use:
$s = new StdClass;
$s->a->b->c = "test";
You get the error:
Warning: Creating default object from empty value in file.php on line x
However, the object is then created giving the `var_dump` of:
object(stdClass)#1 (1) {
["a"]=>
object(stdClass)#2 (1) {
["b"]=>
object(stdClass)#3 (1) {
["c"]=>
string(4) "test"
}
}
}
Which is what you would 'expect' as it goes through the values `a` and creates a default object, then `b` and then assigns the object property `b->c` with the value of "test". When going to `unset` the values in an object, it won't go through casting all the properties to default objects for you. For example,
$s = new StdClass;
unset($s->a->b);
Won't give you an error because `a` can be a property of `$s`, and will do a default type cast to an object and then unset `b`. However, it won't go any further down the list.
unset($s->a->b->c);
Will go with the assumption that `b` is a created object within `a`, but it is not, so you are trying to access a property of a non-object by using `b->c`. A more explicit example:
$s = new stdclass;
$s->a->b->c = array();
unset($s->a->b->c->d);
the `unset` here won't throw any errors, because it will type-cast `c` to to an object and then `unset` the `d`. You do get the warning that it casts all the way up to `c` as `stdClass` though. What this shows, is that the last element/class will by type-cast to an object to access the property if it is not one already, but it won't type-cast all the elements to access the last property when using `unset`.
Conclusion
In all, the difference is between how PHP handles arrays and how it handles objects. Objects have a stricter standard and are not implicitly type-cast to multiple levels as they are accessed to be `unset`, whereas arrays are. With objects, you can implicitly create them to the levels needed (getting a warning as you do), but when being unset, the type-casting doesn't happen, and you are accessing properties that don't exist.
Problem
Can anyone tell me why the following code will have different results ? unset object property ``` $s = new StdClass; unset($s->a->b); //it is working fine unset($s->x->y->z); //it is got an error: Attempt to modify property of non-object ``` unset array index ``` $a = array(); unset($a[1][2]); //it is working fine unset($a[3][4][5]); //it is working fine ```