php如何使得你的对象可以像数组一样可以被访问(ArrayAccess 的作用)?

PHP预定义接口之 ArrayAccess

  最近这段时间回家过年了,博客也没有更新,感觉少学习了好多东西,也错失了好多的学习机会,就像大家在春节抢红包时常说的一句话:一不留神错过了好几亿。废话少说,这篇博客给大家说说关于PHP预定义接口中常用到的重量级人物: ArrayAccess。大家也许会问,最基本、最常用的预定义接口有6个呢,为啥非得说这个。从日常的使用情况来看:这个出现的频率非常高,特别是在框架中,比如Laravel、Slim等都会用到,并且用得非常经典,让人佩服啊。从技术上说:说实话其他的我用的少啊!只是知道简单的用法,对他的理解比较浅显,不敢在这里误导大家,哈哈!今天我要写的内容也不一定都正确,不对之处还请指正。

ArrayAccess

  先说 ArrayAccess 吧!ArrayAccess 的作用是使得你的对象可以像数组一样可以被访问。应该说 ArrayAccess 在PHP5中才开始有的,PHP5中加入了很多新的特性,当然也使类的重载也加强了,PHP5 中添加了一系列接口,这些接口和实现的 Class 统称为 SPL。

ArrayAccess 这个接口定义了4个必须要实现的方法:

1 {
2    abstract public offsetExists ($offset)  //检查偏移位置是否存在
3    abstract public offsetGet ($offset)     //获取一个偏移位置的值
4    abstract public void offsetSet ($offset ,$value) //设置一个偏移位置的值
5    abstract public void offsetUnset ($offset)       //复位一个偏移位置的值
6 }

所以我们要使用ArrayAccess这个接口,就要实现相应的方法,这几个方法不是随便写的,我们可以看一下 ArrayAccess 的原型:

复制代码
 1 /**
 2  * Interface to provide accessing objects as arrays.
 3  * @link http://php.net/manual/en/class.arrayaccess.php
 4  */
 5 interface ArrayAccess {
 6 
 7     /**
 8      * (PHP 5 &gt;= 5.0.0)<br/>
 9      * Whether a offset exists
10      * @link http://php.net/manual/en/arrayaccess.offsetexists.php
11      * @param mixed $offset <p>
12      * An offset to check for.
13      * </p>
14      * @return boolean true on success or false on failure.
15      * </p>
16      * <p>
17      * The return value will be casted to boolean if non-boolean was returned.
18      */
19     public function offsetExists($offset);
20 
21     /**
22      * (PHP 5 &gt;= 5.0.0)<br/>
23      * Offset to retrieve
24      * @link http://php.net/manual/en/arrayaccess.offsetget.php
25      * @param mixed $offset <p>
26      * The offset to retrieve.
27      * </p>
28      * @return mixed Can return all value types.
29      */
30     public function offsetGet($offset);
31 
32     /**
33      * (PHP 5 &gt;= 5.0.0)<br/>
34      * Offset to set
35      * @link http://php.net/manual/en/arrayaccess.offsetset.php
36      * @param mixed $offset <p>
37      * The offset to assign the value to.
38      * </p>
39      * @param mixed $value <p>
40      * The value to set.
41      * </p>
42      * @return void
43      */
44     public function offsetSet($offset, $value);
45 
46     /**
47      * (PHP 5 &gt;= 5.0.0)<br/>
48      * Offset to unset
49      * @link http://php.net/manual/en/arrayaccess.offsetunset.php
50      * @param mixed $offset <p>
51      * The offset to unset.
52      * </p>
53      * @return void
54      */
55     public function offsetUnset($offset);
56 }
复制代码

 下面我们可以写一个例子,非常简单:

 1 <?php
 2 class Test implements ArrayAccess
 3 {
 4     private $testData;
 5 
 6     public function offsetExists($key)
 7     {
 8         return isset($this->testData[$key]);
 9     }
10 
11     public function offsetSet($key, $value)
12     {
13         $this->testData[$key] = $value;
14     }
15 
16     public function offsetGet($key)
17     {
18         return $this->testData[$key];
19     }
20 
21     public function offsetUnset($key)
22     {
23         unset($this->testData[$key]);
24     }
25 }
26 
27   $obj = new Test();
28 
29   //自动调用offsetSet方法
30   $obj['data'] = 'data';
31 
32   //自动调用offsetExists
33   if(isset($obj['data'])){
34     echo 'has setting!';
35   }
36   //自动调用offsetGet
37   var_dump($obj['data']);
38 
39   //自动调用offsetUnset
40   unset($obj['data']);
41   var_dump($test['data']);
42 
43   //输出:
44   //has setting!
45   //data  
46   //null
复制代码
  1. <?php  
  2. /** 
  3. * ArrayAndObjectAccess 
  4. * 该类允许以数组或对象的方式进行访问 
  5. * 
  6. * @author 疯狂老司机 
  7. */  
  8. class ArrayAndObjectAccess implements ArrayAccess {  
  9.   
  10.     /** 
  11.      * 定义一个数组用于保存数据 
  12.      * 
  13.      * @access private 
  14.      * @var array 
  15.      */  
  16.     private $data = [];  
  17.   
  18.     /** 
  19.      * 以对象方式访问数组中的数据 
  20.      * 
  21.      * @access public 
  22.      * @param string 数组元素键名 
  23.      */  
  24.     public function __get($key) {  
  25.         return $this->data[$key];  
  26.     }  
  27.   
  28.     /** 
  29.      * 以对象方式添加一个数组元素 
  30.      * 
  31.      * @access public  
  32.      * @param string 数组元素键名 
  33.      * @param mixed  数组元素值 
  34.      * @return mixed 
  35.      */  
  36.     public function __set($key,$value) {  
  37.         $this->data[$key] = $value;  
  38.     }  
  39.   
  40.     /** 
  41.      * 以对象方式判断数组元素是否设置 
  42.      * 
  43.      * @access public 
  44.      * @param 数组元素键名 
  45.      * @return boolean 
  46.      */  
  47.     public function __isset($key) {  
  48.         return isset($this->data[$key]);  
  49.     }  
  50.   
  51.     /** 
  52.      * 以对象方式删除一个数组元素 
  53.      * 
  54.      * @access public 
  55.      * @param 数组元素键名 
  56.      */  
  57.     public function __unset($key) {  
  58.         unset($this->data[$key]);  
  59.     }  
  60.   
  61.     /** 
  62.      * 以数组方式向data数组添加一个元素 
  63.      * 
  64.      * @access public 
  65.      * @abstracting ArrayAccess 
  66.      * @param string 偏移位置 
  67.      * @param mixed  元素值 
  68.      */  
  69.     public function offsetSet($offset,$value) {  
  70.         if (is_null($offset)) {  
  71.             $this->data[] = $value;  
  72.         } else {  
  73.             $this->data[$offset] = $value;  
  74.         }  
  75.     }  
  76.   
  77.     /** 
  78.      * 以数组方式获取data数组指定位置元素 
  79.      * 
  80.      * @access public    
  81.      * @abstracting ArrayAccess        
  82.      * @param 偏移位置 
  83.      * @return mixed 
  84.      */  
  85.     public function offsetGet($offset) {  
  86.         return $this->offsetExists($offset) ? $this->data[$offset] : null;  
  87.     }  
  88.   
  89.     /** 
  90.      * 以数组方式判断偏移位置元素是否设置 
  91.      * 
  92.      * @access public 
  93.      * @abstracting ArrayAccess 
  94.      * @param 偏移位置 
  95.      * @return boolean 
  96.      */  
  97.     public function offsetExists($offset) {  
  98.         return isset($this->data[$offset]);  
  99.     }  
  100.   
  101.     /** 
  102.      * 以数组方式删除data数组指定位置元素 
  103.      * 
  104.      * @access public 
  105.      * @abstracting ArrayAccess      
  106.      * @param 偏移位置 
  107.      */  
  108.     public function offsetUnset($offset) {  
  109.         if ($this->offsetExists($offset)) {  
  110.             unset($this->data[$offset]);  
  111.         }  
  112.     }  
  113.   
  114. }  
  115.   
  116. $animal = new ArrayAndObjectAccess();  
  117.   
  118. $animal->dog = 'dog'// 调用ArrayAndObjectAccess::__set  
  119. $animal['pig'] = 'pig'// 调用ArrayAndObjectAccess::offsetSet  
  120. var_dump(isset($animal->dog)); // 调用ArrayAndObjectAccess::__isset  
  121. var_dump(isset($animal['pig'])); // 调用ArrayAndObjectAccess::offsetExists  
  122. var_dump($animal->pig); // 调用ArrayAndObjectAccess::__get  
  123. var_dump($animal['dog']); // 调用ArrayAndObjectAccess::offsetGet  
  124. unset($animal['dog']); // 调用ArrayAndObjectAccess::offsetUnset  
  125. unset($animal->pig); // 调用ArrayAndObjectAccess::__unset  
  126. var_dump($animal['pig']); // 调用ArrayAndObjectAccess::offsetGet  
  127. var_dump($animal->dog); // 调用ArrayAndObjectAccess::__get  
  128.   
  129. ?>  
以上输出:

boolean true
boolean true
string 'pig' (length=3)
string 'dog' (length=3)
null
null

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值