php 的 ArrayAccess 接口可以实现以数组下标的方式访问类的成员属性,我们只需要实现此接口的四个抽象方法即可
public function offsetSet($index, $val);
public function offsetGet($index);
public function offsetExists($index);
public function offsetUnset($index);
不过看了不少博文都是直接让类变成了彻底的数组下标访问模式,有种忘本逐末的赶脚,其并不烦,我们在实现此接口的同时用几个魔术函数就能完美实现。
/**
* 实现使用数组键值的方式访问对象属性
*/
class Foo implements ArrayAccess
{
private static $_instance;
//成员属性数组
private $_members;
private function __construct()
{
//not allow to call construct operation from outer
}
/**
* 单例模式
* @return instance of Foo Class
*/
public static function getInstance()
{
if ( isset(static::$_instance) ) {
return static::$_instance;
}
return static::$_instance = new static();
}
//对应 offsetSet
public function __set($index, $val)
{
$this->_members[$index] = $val;
}
//对应 offsetGet
public function __get($index)
{
return isset($this->_members[$index]) ? $this->_members[$index] : null;
}
//对应 offsetExists
public function __isset($index)
{
return isset($this->_members[$index]);
}
//对应 offsetUnset
public function __unset($index)
{
if ( isset($this->_members[$index]) ) {
unset($this->_members[$index]);
} else { // 属性不存在
trigger_error($index . " not exits!", E_USER_WARNING);
}
}
public function offsetSet($index, $val)
{
$this->_members[$index] = $val;
}
public function offsetGet($index)
{
return isset($this->_members[$index]) ? $this->_members[$index] : null;
}
public function offsetExists($index)
{
return isset($this->_members[$index]);
}
public function offsetUnset($index)
{
if ( isset($this->_members[$index]) ) {
unset($this->_members[$index]);
} else {
trigger_error($index . " not exits!", E_USER_WARNING);
}
}
}
$bar = Foo::getInstance();
$bar->name = "sallency";
echo $bar['name'] . PHP_EOL;
$bar['name'] = "big_cat";
echo $bar->name . PHP_EOL;
其实就是利用魔术方法和接口的方法将他们对应的操作都定向到存放属性的成员数组中去