先看这么一段代码。
$a = new C();
foreach($a as $k=>$v){
echo $k.$v.'<br>';
}
$b = new B();
$b['a']='Hello array!';
echo $b['a'];
应该有一部分人,会奇怪了。PHP中的类也可以这么访问吗?你这段代码会不会是错的啊?
当然没有错,这么做是可以的,而且是正确的。不过你在定义类C和类B的时候,需要动一点儿手脚,不然直接写自然是不正确的。
第一部分,PHP官方为了让用户的类可以实现像数组一样支持foreach语句,定义了Iterator接口,凡是实现了该接口的类,都可以通过foreach的语法来调用。以上定义的类C就实现了该接口。
该接口中包含这么几个方法:
public function current (){} 返回当前元素
public function next () {} 返回下一个元素
public function key () {} 获得当前项的键值
public function valid () {} 是否已经越界
public function rewind (){} 将顺序反转
由此可以看到foreach的原理,每次循环都调用一下valid判断一下是否越界,然后取出建key和值current。然后进行下一次循环。
第二部分,那个东西在C#中叫做所引器,在PHP中是定义在一个ArrayAccess接口中的。该接口包含了这么几个方法:
public function offsetExists ($offset) 是否存在某个下标、索引或者键值都是一个东西
public function offsetGet ($offset) 通过索引获取数据对象
public function offsetSet($k ,$v) 通过索引设置对象
public function offsetUnset ($offset) 释放掉某个索引的对象
如此可见我们在设置数组值的时候的调用方法,分别是调用了如上的几个方法。
有人又要问了,不是数组不是还有个count么?你的应该不支持吧?确实,不过不要着急。PHP又定义了一个接口叫做Countable。其中只有一个方法:
public function count () 通过该方法可以实现获得数组中的个数。
如果Countable和ArrayAccess组合同时实现掉不就是一个活生生的数组了。 |