PHP內置接口ArrayAccess:像使用數組一樣使用類

class ab implements ArrayAccess{

    /**
     * Determine if the given attribute exists.
     *
     * @param  mixed  $offset
     * @return bool
     */
    public function offsetExists($offset)
    {
        return isset($this->$offset);
    }

    /**
     * Get the value for a given offset.
     *
     * @param  mixed  $offset
     * @return mixed
     */
    public function offsetGet($offset)
    {
        return $this->$offset;
    }

    /**
     * Set the value for a given offset.
     *
     * @param  mixed  $offset
     * @param  mixed  $value
     * @return void
     */
    public function offsetSet($offset, $value)
    {
        $this->$offset = $value;
    }

    /**
     * Unset the value for a given offset.
     *
     * @param  mixed  $offset
     * @return void
     */
    public function offsetUnset($offset)
    {
        unset($this->$offset);
    }

    /**
     * 獲取不存在屬性
     * @param $name
     * @return null
     */
    public function __get($name)
    {
        return null;
    }

}

$ab = new ab;
$ab->a = 'a';
$ab['b'] = 'b';

echo "類屬性方式獲取" . PHP_EOL;
var_dump($ab->a, $ab->b, $ab->c);
echo "數組子健方式獲取" . PHP_EOL;
var_dump($ab['a'], $ab['b'], $ab['c']);
echo "類" . PHP_EOL;
var_dump($ab);
/* 輸出:
類屬性方式獲取
string(1) "a"
string(1) "b"
NULL
數組子健方式獲取
string(1) "a"
string(1) "b"
NULL
類
object(ab)#3 (2) {
  ["a"]=>
  string(1) "a"
  ["b"]=>
  string(1) "b"
}
*/

更方便的寫法,封裝一個trait,然後類實現接口並使用統一的trait;如下:
下類支持數字鍵設置,上面的DEMO類不支持;

trait ArrayAccessTrait
{

    public $numOffset = 0;

    /**
     * Determine if the given attribute exists.
     *
     * @param  mixed $offset
     * @return bool
     */
    public function offsetExists($offset)
    {
        return isset($this->$offset);
    }

    /**
     * Get the value for a given offset.
     *
     * @param  mixed $offset
     * @return mixed
     */
    public function offsetGet($offset)
    {
        return $this->$offset;
    }

    /**
     * Set the value for a given offset.
     *
     * @param  mixed $offset
     * @param  mixed $value
     * @return void
     */
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            if(!isset($this->{$this->numOffset})) {
                $this->{$this->numOffset} = $value;
                $this->numOffset++;
            } else {
                $this->numOffset++;
                $this->offsetSet($offset, $value);
            }
        } else {
            $this->$offset = $value;
        }
    }

    /**
     * Unset the value for a given offset.
     *
     * @param  mixed $offset
     * @return void
     */
    public function offsetUnset($offset)
    {
        unset($this->$offset);
    }

    /**
     * 獲取不存在屬性
     * @param $name
     * @return null
     */
    public function __get($name)
    {
        return null;
    }

}

class ab implements ArrayAccess
{
    use ArrayAccessTrait;
}

$ab = new ab;
$ab->a = 'a';
$ab['b'] = 'b';
$ab[] = 'c';
$ab[] = 'd';
$ab[2] = 'de';
$ab[3] = 'ef';
$ab[] = 'e';
$ab[99] = 'f';

echo "類屬性方式獲取" . PHP_EOL;
var_dump($ab->a, $ab->b, $ab->c, $ab->{0}, $ab->{'0'}, $ab->{99}, $ab->{100});
echo "數組子健方式獲取" . PHP_EOL;
var_dump($ab['a'], $ab['b'], $ab['c'], $ab[0], $ab['0'], $ab[99], $ab[100]);
echo "類" . PHP_EOL;
var_dump($ab);

/* 輸出:
類屬性方式獲取
string(1) "a"
string(1) "b"
NULL
string(1) "c"
string(1) "c"
string(1) "f"
NULL
數組子健方式獲取
string(1) "a"
string(1) "b"
NULL
string(1) "c"
string(1) "c"
string(1) "f"
NULL
類
object(ab)#3 (9) {
  ["num"]=>
  int(5)
  ["a"]=>
  string(1) "a"
  ["b"]=>
  string(1) "b"
  ["0"]=>
  string(1) "c"
  ["1"]=>
  string(1) "d"
  ["2"]=>
  string(2) "de"
  ["3"]=>
  string(2) "ef"
  ["4"]=>
  string(1) "e"
  ["99"]=>
  string(1) "f"
}
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章