如果在未做任何处理的情况下, 以数组的方式访问对象,会抛给你一个大大的错误。
Fatal error: Uncaught Error: Cannot use object of type Test as array
当然如果你对类进行一些改造的话,还是可以像数组一样访问。
如何访问受保护的对象属性
在正式改造之前,先看另一个问题。当我们试图访问一个受保护的属性的时候,也会抛出一个大大的错误。
Fatal error: Uncaught Error: Cannot access private property Test::$container
是不是受保护属性就不能获取?当然不是,如果我们想要获取受保护的属性,我们可以借助魔术方法__get。
DEMO1
获取私有属性
<?php
class Test
{
private $container = [];
public function __construct()
{
$this->container = ['one'=>1, 'two'=>2, 'three'=>3];
}
public function __get($name)
{
return property_exists($this, $name) ? $this->$name : null;
}
}
$test = new Test();
var_dump($test->container);
DEMO2
获取私有属性下对应键名的键值。
<?php
class Test
{
private $container = [];
public function __construct()
{
$this->container = ['one'=>1, 'two'=>2, 'three'=>3];
}
public function __get($name)
{
return array_key_exists($name, $this->container) ? $this->container[$name] : null;
}
}
$test = new Test();
var_dump($test->one);
如何以数组的方式访问对象
我们需要借助预定义接口中的ArrayAccess接口来实现。接口中有4个抽象方法,需要我们实现。
<?php
class Test implements ArrayAccess
{
private $container = [];
public function __construct()
{
$this->container = ['one'=>1, 'two'=>2, 'three'=>3];
}
public function offsetExists($offset)
{
return isset($this->container[$offset]);
}
public function offsetGet($offset){
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
public function offsetSet($offset, $value)
{
if(is_null($offset)){
$this->container[] = $value;
}else{
$this->container[$offset] = $value;
}
}
public function offsetUnset($offset){
unset($this->container[$offset]);
}
}
$test = new Test();
var_dump($test['one']);
如何遍历对象
其实对象在不做任何处理的情况下,也可以被遍历,但是只能遍历可见属性,也就是定义为public的属性。我们可以借助另一个预定义接口IteratorAggregate,来实现更为可控的对象遍历。
<?php
class Test implements IteratorAggregate
{
private $container = [];
public function __construct()
{
$this->container = ['one'=>1, 'two'=>2, 'three'=>3];
}
public function getIterator() {
return new ArrayIterator($this->container);
}
}
$test = new Test();
foreach ($test as $k => $v) {
var_dump($k, $v);
}