[SPL]让一个类拥有数组的操作!ArrayAccess与IteratorAggregate

什么是SPL?

SPL是Standard PHP Library的缩写,属于PHP标准库的一支,是PHP5最新增加的功能,用来解决一些PHP语言本身不支持的问题以及实现更有效的数据的操作。据说是由某个很牛的大师因为不满于传统的PHP的对象的操作,而自己开发的一套库,后来被引入到PHP标准库当中。SPL能做很多事,以下就是一个很好的例子。

让对象像数组一样赋值、读取、删除

我想你一定听过PHP5中的魔术方法,那么数组方式的对象操作肯定不会陌生了。如果一个对象通过实现一个接口(也可以说是继承),那么它也会具有数组的操作方式,当然,你需要定义自己的魔术方法了。

<?php /** * 测试接口的使用 * * @author monkee * @since 2011-08-15 */ class arrayTest implements ArrayAccess { private $d = array(); function offsetExists($offset){ echo __METHOD__."\n"; return array_key_exists($offset, $this->d); } function offsetGet($offset){ echo __METHOD__."\n"; return $this->d[$offset]; } function offsetSet($offset, $value){ echo __METHOD__."\n"; $this->d[$offset] = $value; } function offsetUnset($offset){ echo __METHOD__."\n"; unset($this->d[$offset]); return true; } } $t = new arrayTest(); isset($t['m']); $t['m'] = 123456; $m = $t['m']; unset($t['m']); ?>
看看上面的代码能够让你得到什么?是不是很惊讶,对象arrayTest竟然可以拥有像对数组一样的操作方式。那么现在,如果你需要设计出能够使程序员方便使用的框架来,那么我想这样的方式也是你会考虑的一种选择之一。

Interface ArrayAccess

这个接口是SPL中的一个接口,它定义如下:

interface ArrayAccess { function offsetExists($key); //被isset调用时 function offsetGet($key); //被当作数组读时 function offsetSet($key, $value); //被当作数组赋值时 function offsetUnset($key); //被当作数组unset时 }
需要拥有数组操作方式的类,需要对其进行继承(我喜欢这么来描述)

class arrayTest implements ArrayAccess
那么你就拥有了类的数组方式的操作。

Interface Iterator

现在我们只是拥有了对数组类的赋值和取值,然而我们对foreach这样的对于数组很方便的操作还没有使用。如果要支持指针类的操作,那么:

<?php /** * 测试接口的使用 * * @author monkee * @since 2011-08-15 */ class arrayTest implements Iterator { protected $d = array('1', '2', '3'); protected $currIndex = 0; protected $all = 0; protected $more = false; function __construct($array){ if(!is_array($array)){ //do some error thing trigger_error('Error params' , E_USER_WARNING); } $this->d = $array; $this->currIndex = 0; $this->all = count($this->d); $this->more = ($this->all > 0); } function rewind(){ echo __METHOD__."\n"; } function valid(){ echo __METHOD__."\n"; return $this->more; } function key(){ echo __METHOD__."\n"; return key($this->d); } function current(){ echo __METHOD__."\n"; return current($this->d); } function next(){ echo __METHOD__."\n"; $v = next($this->d); $this->currIndex++; $this->more = ($this->currIndex < $this->all); } } $t = new arrayTest(array('a' => 'A', 'b' => 'B', 'c' => 'C')); foreach($t as $key => $item){ echo "{$key} => {$item} \n"; } ?>
上面的例子可以通过,也可以正常使用。

其中,Iterator的定义如下:

Iterator implements Traversable { abstract public mixed current ( void ); //返回当前的数据 abstract public scalar key ( void ); //返回当前的KEY值 abstract public void next ( void ); //下一个指针 abstract public void rewind ( void ); //建立指针时触发,在foreach的开始部分 abstract public boolean valid ( void ); //当前指针是否有效 }
完美的数组类

如果集合了如上两条功能,那么我们的类便更接近于数组的操作了。

<?php /** * 测试接口的使用 * * @author monkee * @since 2011-08-15 */ class arrayTest implements ArrayAccess, Iterator { protected $d = array('1', '2', '3'); protected $currIndex = 0; protected $all = 0; protected $more = false; function __construct($array){ if(!is_array($array)){ //do some error thing trigger_error('Error params' , E_USER_WARNING); } $this->d = $array; $this->currIndex = 0; $this->all = count($this->d); $this->more = ($this->all > 0); } function offsetExists($offset){ echo __METHOD__."\n"; return array_key_exists($offset, $this->d); } function offsetGet($offset){ echo __METHOD__."\n"; return $this->d[$offset]; } function offsetSet($offset, $value){ echo __METHOD__."\n"; $this->d[$offset] = $value; } function offsetUnset($offset){ echo __METHOD__."\n"; unset($this->d[$offset]); return true; } function rewind(){ echo __METHOD__."\n"; } function valid(){ echo __METHOD__."\n"; return $this->more; } function key(){ echo __METHOD__."\n"; return key($this->d); } function current(){ echo __METHOD__."\n"; return current($this->d); } function next(){ echo __METHOD__."\n"; $v = next($this->d); $this->currIndex++; $this->more = ($this->currIndex < $this->all); } } $t = new arrayTest(array('a' => 'A', 'b' => 'B', 'c' => 'C')); echo $t['a']; foreach($t as $key => $item){ echo "{$key} => {$item} \n"; } ?>
总结

这些功能在平常的开发中可能用不到,因为它不符合PHP标准。然而,如果在我们需要设计的框架中,希望用到类似的功能的话,那么以上的技巧便是可以考虑使用的。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值