Reputation: 7556
I just came across something weird. I have a class that is similar to this:
class Test {
public $id;
public $name;
public $details;
private $hidden;
private $otherhidden;
public function __construct() {
$this->id = 1;
$this->name = 'test';
$this->details = 'test';
$this->hidden = 1;
$this->otherhidden = 1;
}
public function toArray() {
$array = (array) $this;
print_r($array);
$array['Testhidden'] = 2;
$array['Testotherhidden'] = 2;
unset($array['details']);
unset($array['Testhidden']);
unset($array['Testotherhidden']);
print_r($array);
return $array;
}
}
If I create an instance of a Test, $test = new Test;
and then run $array = $test->toArray();
the two array's printed out are:
Array
(
[id] => 1
[name] => test
[details] => test
[Testhidden] => 1
[Testotherhidden] => 1
)
Array
(
[id] => 1
[name] => test
[Testhidden] => 1
[Testotherhidden] => 1
)
So it lets me unset the details
keyed item in the array, but it won't let me modify the values or the unset the values in the elements that were private in the object. Any ideas for why it won't let me modify the values of the array? Obviously there is some type of inheritance being passed from the object to the array.
EDIT
If I use get_object_vars()
instead of (array)
I am able to modify the private elements. So I have a work around, but it would still be nice to know why this happens.
Upvotes: 0
Views: 2022
Reputation: 24645
var_dump will show you the answer. The Array keys for protected properties are turning into
"\0Test\0otherhidden"
and "\0Test\0hidden"
. print_r is masking this fact from you.
Upvotes: 0
Reputation: 437336
The behavior you see is because when casting an object to an array like that the keys of the arrays that correspond to non-public properties are prefixed with unprintable "magic" strings.
The real keys inside $array
are not Testhidden
and Testotherhidden
. You can easily see that with
print_r(array_map('urlencode', array_keys($array)));
I randomly picked urlencode
as a very convenient way of transforming unprintable characters to printable representations, but of course any other function with that property would serve as well.
Upvotes: 2
Reputation: 16297
This post will answer your questions.
http://www.vancelucas.com/blog/get-only-public-class-properties-for-current-class-in-php/
But basically you get the properties because of the scope in which get_object_vars()
is called. But if you change the scope as outlined in the post you should get the results you are looking for.
public function toArray()
{
$getFields = function($obj) { return get_object_vars($obj); };
return $getFields($this);
}
Upvotes: 0