我正在运行一组数组和对象以进行进一步处理。如果它是一个对象,我使用get_object_vars($obj)
来获取它的问题。但是,如果该对象使用magic getters/ssetters,它将返回一个空数组。这里有一个问题的小演示:
class Foo {
protected
$fields = array(
'foo'=>1,
'bar'=>2
);
function __get($key) {
return $this->fields[$key];
}
function __isset($key) {
return array_key_exists($key,$this->fields);
}
}
$foo = new Foo();
var_dump(get_object_vars($foo));
我希望get_object_vars
返回$fields
键值对。有没有什么方法可以走,或者有什么方法可以在Foo
中实现以使其工作?
谢谢你的提示。
这与魔术方法无关,但与get_object_vars()返回指定对象相对于作用域的可访问非静态属性数组有关。如果调用来自对象内部,但仅来自对象外部的公共调用,则它将返回所有属性。但是,您可以使用IteratorAggregate接口和ArrayIdeator类,并将其与迭代器_to_array()函数相结合,以获得类似的行为和一些额外的好处,如本例所示。
class Foo implements IteratorAggregate {
protected
$fields = array(
'foo' => 1,
'bar' => 2
);
function __get( $name ) {
return array_key_exists( $name, $this->fields ) ? $this->fields[$name] : null;
}
public function __set( $name, $value )
{
$this->fields[$name] = $value;
}
function __isset( $name ) {
return isset( $this->fields[$name] );
}
public function getIterator() {
return new ArrayIterator( $this->fields );
}
}
$foo = new Foo();
$foo->baz = 3;
foreach( $foo as $key => $value ) {
echo "$key: $value "; // OUTPUT: foo: 1 bar: 2 baz: 3
}
array_walk( ( iterator_to_array( $foo ) ), function( $value, $key ) {
echo "$key: $value "; // OUTPUT: foo: 1 bar: 2 baz: 3
});
print_r( iterator_to_array( $foo ) ); // OUTPUT: Array ( [foo] => 1 [bar] => 2 [baz] => 3 )
get_object_vars
仅返回可见属性。当您从对象外部调用函数时,它对protected
字段不可见,因此不会返回。
相反,您可以将对象强制转换为数组:
var_dump((array) $foo);
这会稍微改变一下钥匙。请查看此处了解详细信息。
另一种选择是在对象中创建一个从内部返回get_object_vars
的方法,因为它可以查看所有内容。例如
class Foo {
...
public function get_object_vars() {
return get_object_vars($this);
}
}
$foo = new Foo();
var_dump($foo->get_object_vars());
另一种选择显然是简单地将属性更改为public
而不是protected
。