PHP以數組的方式訪問對象

如果在未做任何處理的情況下, 以數組的方式訪問對象,會拋給你一個大大的錯誤。

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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章