在PHP中有好几个预定义的接口,比较常用的四个接口(Countable、ArrayAccess、Iterator、IteratorAggregate(聚合式aggregate迭代器Iterator)).
1. Countable接口
从手册上看到,主要是 类实现 Countable 可被用于 count() 函数.
示例:
<?php class ConutMe { protected $_myCount = 3; public function count() { return $this->_myCount; } } $countable = new ConutMe(); echo count($countable); ///result is "1", not as expected //实现接口Countable class CountMe implements Countable { protected $_myc = 4; public function count() { return $this->_myc; } } $countable = new CountMe(); echo count($countable);//result is "4" as expected
总结:
Countable这个接口用于统计对象的数量,当对一个对象调用count的时候,如果类(如CountMe)没有继承Countable,将一直返回1,如果继承了Countable会返回所实现的count方法所返回的数字.
2. ArrayAccess接口
非常常用,各大框架都会实现这个接口. 主要功能: 提供像访问数组一样访问对象的能力的接口。(详细看已经写的 php使用数组语法访问对象 )
3.Iterator接口 (可在内部迭代自己的外部迭代器或类的接口。)
(自己水平比较low,暂时没发现什么好处).
记录下执行的流程
1 <?php 2 class myIterator implements Iterator { 3 4 private $position = 0; 5 private $array = array( 6 "firstelement", 7 "secondelement", 8 "lastelement", 9 ); 10 11 public function __construct() { 12 $this->position = 0; 13 } 14 15 //返回到迭代器的第一个元素 16 function rewind() { 17 var_dump(__METHOD__); 18 $this->position = 0; 19 } 20 21 //返回当前元素 22 function current() { 23 var_dump(__METHOD__); 24 return $this->array[$this->position]; 25 } 26 27 //返回当前元素的键 28 function key() { 29 var_dump(__METHOD__); 30 return $this->position; 31 } 32 33 //向前移动到下一个元素 34 function next() { 35 var_dump(__METHOD__); 36 ++$this->position; 37 } 38 39 //检查当前位置是否有效 40 function valid() { 41 var_dump(__METHOD__); 42 return isset($this->array[$this->position]); 43 } 44 } 45 46 $it = new myIterator; 47 48 //记录步骤 49 //1. 在第一次循环迭代之前, Iterator::rewind() is called 50 //2. 在每次循环迭代中, Iterator::valid() is called 51 //3. 如果Iterator::valid() 返回 false , 循环结束 52 // 如果Iterator::valid() 返回 true , Iterator::current() is called and Iterator::key() is called. 53 //4. 返回当前迭代器的值 echo 54 //5. 在每一次迭代后, Iterator::next() is called , 然后又从 步骤2开始执行. 55 56 foreach($it as $key => $value) { 57 echo $key,'-',$value; 58 echo "\n"; 59 } 60 /* 61 * 输出的结果 62 * myIterator::rewind 重置迭代器(返回到迭代器的第一个元素) 63 * 64 * myIterator::valid 检查当前位置是否有效 65 * myIterator::current 66 * myIterator::key 67 * 0-firstelement 68 * myIterator::next 69 * 70 * myIterator::valid 71 * myIterator::current 72 * myIterator::key 73 * 1-secondelement 74 * myIterator::next 75 * 76 * myIterator::valid 77 * myIterator::current 78 * myIterator::key 79 * 2-lastelement 80 * myIterator::next 81 * 82 * myIterator::valid 83 * 84 * 循环结束 85 * 86 */ 87 88 ?>
4.IteratorAggregate接口 (创建外部迭代器)
1 class my implements IteratorAggregate 2 { 3 private $arr = []; 4 const TYPE_INDEXED = 1; 5 const TYPE_ASSOCIATIVE = 2; 6 7 public function __construct(array $data,$type = self::TYPE_INDEXED) 8 { 9 reset($data); 10 //each 返回当前数组的键值,并且指针向前移动一步 11 while (list($k,$v) = each($data)){ 12 $type == self::TYPE_INDEXED ? $this->arr[] = $v : 13 $this->arr[$k] = $v; 14 } 15 /* 16 print_r($this->arr); 17 exit(); 18 */ 19 } 20 21 public function getIterator() 22 { 23 //对 属性arr迭代 24 return new ArrayIterator($this->arr); 25 } 26 } 27 28 //返回一个迭代器 29 $obj = new my(['one'=>'php','javascript','three'=>'c#','java',], 1 ); 30 31 //迭代 32 foreach ($obj as $key=>$value){ 33 var_dump($key,$value); 34 echo "<br/>"; 35 }
总结: 如果对一个普通对象循环,只是会输出此对象的 public属性, 如果对象实现了 IteratorAggregate 接口 ,是可以通过参数对 指定数据进行迭代.
(例如上例的私有属性arr)