小米技术社区
小米技术社区管理员 关于小米

27岁,山西运城人,职业电商经理人,前端开发工作者,从事过网站建设、网络推广、SEO、SEM、信息流推广、二类电商、网络运维、软件开发,等相关电商工作,经验较为丰富,小米技术社区致力于为广大从事Web前端开发的人员提供一些力所能及的引导和帮助 ...[更多]

E-mail:mzze@163.com

Q Q:32362389

W X:xiaomi168527

小米技术社区大牛王飞 关于王飞

27岁,山西运城人,职业电商经理人,网络工程师兼运维,从事过运营商网络建设,企业网络建设、优化。数据中心网络维护等通过,经验丰富,座右铭:当自己休息的时候,别忘了别人还在奔跑。 ...[更多]

E-mail:wf_live@126.com

Q Q:3940019

微博:王小贱ss

小米技术社区设计小艳 关于小艳

大于花一样的年龄,河南郑州是我家,2010年在北京接触团购网,2011年进入天猫淘宝一待就是四年,如今已经将设计走向国际化(ps:误打误撞开始进入阿里巴巴国际站的设计,嘿嘿)五年电商设计,丰富经验,从事过天猫淘宝阿里各项设计,店铺运营,产品拍摄;我将我的经历与您分享是我的快乐!座右铭:越努力越幸运! ...[更多]

E-mail:97157726@qq.com

Q Q:97157726

标签云
精品推荐
您的位置:首页 > 后端编程 > PHP > PHP基础

PHP的迭代器;它的工作原理,流程,作用和使用场景,以及什么是iterator接口?

分类: PHP基础48个赞

迭代器介绍

迭代器是PHP内置的接口,是类继承PHP的Iterator接口,使你能够通过循环来得到或删除集合的元素。以允许双向遍历列表和修改元素。

foreach遍历的本质就是使用iterator迭代器遍历。


那么什么是Iterator接口?

Iterator是一种接口,为各种不同的数据结构提供统一的访问机制

任何数据结构只要部署Iterator接口,就称这种数据结构是可遍历的

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性上


Iterator接口的作用?

为各种数据结构提供一个统一的,简便的访问接口

使得数据结构的成员能够按照某种次序排列

ES6创造了一种新的遍历命令for...of 循环,Iterator接口主要提供for...of消费


为什么会出现迭代器?迭代器使用场景和作用是什么?

一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口。


迭代器遍历对象,获取的是对象中属性保存的数组

允许对象以自己的方式迭代内部的数据,从而使它可以被循环访问


相比传统的编程模式,Iterator迭代器模式可以隐藏遍历元素的所需操作。


迭代器工作流程和原理

创建一个指针对象,指向当前数据结构的起始位置;也就是说,遍历器对象本质上就是一个指针对象

第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员

第二次调用指针对象的next方法,指针就指向数据结构的第二个成员

不断调用指针对象next方法,直到他指向数据结构的结束位置


1、复位数组指针        reset()

2、检查指针是否合法  获取当前指针,如果不为null就是合法的

3、获取当前值         current()

4、获取当前键         key()

5、指针下移              next()

其他:

6、rewind() 返回到迭代器的第一个元素

7、hasNext() :该方法会判断集合对象是否还有下一个元素,如果已经是最后一个元素则返回false。

迭代器案例:

<?php
$stu=['tom','berry','ketty','rose'];
reset($stu);    //复位指针
while(key($stu)!==null){//键合法
    echo key($stu),'-',current($stu),'<br>';//获取键、值
    next($stu);     //指针下移
}
/*
0-tom
1-berry
2-ketty
3-rose
*/


迭代器优缺点分析:

优点:

1.支持多种遍历方式。比如有序列表,我们根据需要提供正序遍历、倒序遍历两种迭代器。用户只需要得到我们的迭代器,就可以对集合执行遍历操作

2.简化了聚合类。由于引入了迭代器,原有的集合对象不需要自行遍历集合元素了

3.增加新的聚合类和迭代器类很方便,两个维度上可各自独立变化

4.为不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上操作


缺点:

迭代器模式将存储数据和遍历数据的职责分离增加新的集合对象时需要增加对应的迭代器类,类的个数成对增加,在一定程度上增加系统复杂度。


迭代器使用场景:遍历对象,获取的是对象中属性保存的数组

<?php
//定义类实现迭代器接口
class MyClass implements Iterator{
	//$list属性用来保存学生数组
	private $list=array();
	//添加学生
	public function addStu($name) {
		$this->list[]=$name;
	}
	//实现接口中的复位方法
	public function rewind() {
		reset($this->list);
	}
	//验证当前指针是否合法
	public function valid() {
		return key($this->list)!==null;
	}
	//获取值
	public function current() {
		return current($this->list);
	}
	//获取键
	public function key() {
		return key($this->list);
	}
	//指针下移
	public function next() {
		next($this->list);
	}
}

//创建班级
$class=new MyClass();
//添加学生
$class->addStu('tom');
$class->addStu('berry');
$class->addStu('ketty');
//遍历班级
foreach($class as $k=>$v){
	echo "{$k}-{$v}<br>";
}
/*
0-tom
1-berry
2-ketty
*/



迭代器进阶案例:

PHP的面向对象引擎提供了一个非常聪明的特性,就是,可以使用foreach()方法通过循环方式取出一个对象的所有属性,就像数组方式一样,代码如下:

class Myclass{
  public $a = 'php';
  public $b = 'onethink';
  public $c = 'thinkphp';
}
$myclass = new Myclass();

//用foreach()将对象的属性循环出来
foreach($myclass as $key.'=>'.$val){
  echo '$'.$key.' = '.$val."<br/>";
}
/*返回
  $a = php
  $b = onethink
  $c = thinkphp
*/

如果需要实现更加复杂的行为,可以通过一个iterator(迭代器)来实现

//迭代器接口
interface MyIterator{
  //函数将内部指针设置回数据开始处
  function rewind();
  //函数将判断数据指针的当前位置是否还存在更多数据
  function valid();
  //函数将返回数据指针的值
  function key();
  //函数将返回将返回当前数据指针的值
  function value();
  //函数在数据中移动数据指针的位置
  function next();
}
//迭代器类
class ObjectIterator implements MyIterator{
  private $obj;//对象
  private $count;//数据元素的数量
  private $current;//当前指针
  function __construct($obj){
    $this->obj = $obj;
    $this->count = count($this->obj->data);
  }
  function rewind(){
    $this->current = 0;
  }
  function valid(){
    return $this->current < $this->count;
  }
  function key(){
    return $this->current;
  }
  function value(){
    return $this->obj->data[$this->current];
  }
  function next(){
    $this->current++;
  }
}
interface MyAggregate{
  //获取迭代器
  function getIterator();
}
class MyObject implements MyAggregate{
  public $data = array();
  function __construct($in){
    $this->data = $in;
  }
  function getIterator(){
    return new ObjectIterator($this);
  }
}
//迭代器的用法
$arr = array(2,4,6,8,10);
$myobject = new MyObject($arr);
$myiterator = $myobject->getIterator();
for($myiterator->rewind();$myiterator->valid();$myiterator->next()){
  $key = $myiterator->key();
  $value = $myiterator->value();
  echo $key.'=>'.$value;
  echo "<br/>";
}
/*返回
  0=>2
  1=>4
  2=>6
  3=>8
  4=>10
*/


小米技术社区