在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)

 

 

    

posted on 2016-09-09 09:38  睡着的糖葫芦  阅读(777)  评论(0编辑  收藏  举报