如果在未做任何處理的情況下, 以數組的方式訪問對象,會拋給你一個大大的錯誤。
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);
}