PHP设计模式之PHP迭代器模式讲解


Posted in PHP onMarch 22, 2019

迭代器有时又称光标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如list或vector)上遍访的接口,设计人员无需关心容器物件的内容。

各种语言实作Iterator的方式皆不尽同,有些面向对象语言像Java, C#, Python, Delphi都已将Iterator的特性内建语言当中,完美的跟语言整合,我们称之隐式迭代器(implicit iterator),但像是C++语言本身就没有Iterator的特色,但STL仍利用template实作了功能强大的iterator。

PHP5开始支持了接口, 并且内置了Iterator接口, 所以如果你定义了一个类,并实现了Iterator接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT.

对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach.

先来看下迭代器的定义,那就是提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部显示。它可帮助构造特定的对象,那些对象能够提供单一标准接口循环或迭代任何类型的可计数数据。来看下迭代器模式的结构图:

PHP设计模式之PHP迭代器模式讲解

再来看下迭代器需要用到的内部方法:

  • Iterator::current — Return the current element 返回当前元素
  • Iterator::key — Return the key of the current element 返回当前元素的键
  • Iterator::next — Move forward to next element 移向下一个元素
  • Iterator::rewind — Rewind the Iterator to the first element 重新回到第一个元素
  • Iterator::valid — Checks if current position is valid 检查当前位置的有效性

而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach。

<?php
/**
* Iterator模式的简单实现类
*/
class sample implements Iterator {
  private $_items ;
  public function __construct(&$data) {
    $this->_items = $data;
  }
  public function current() {
    return current($this->_items);
  }
  public function next() {
    next($this->_items);  
  }
  public function key() {
    return key($this->_items);
  }
  public function rewind() {
    reset($this->_items);
  }
  public function valid() {                                       
    return ($this->current() !== FALSE);
  }
}
/** DEMO */
$data = array(1, 2, 3, 4, 5);
$sa = new sample($data);
foreach ($sa AS $key => $row) {
  echo $key, ' ', $row, '<br />';
}
?>

举几个迭代器的使用范围:

使用返回迭代器的包或库时(如PHP5中的SPL迭代器)
无法在一次的调用获取容器的所有元素时
要处理数量巨大的无素时(数据库中的表以GB计的数据)
……

不同的迭代器有不同的接口,例如PHP SPL迭代器中包括Next()(移动到下一个元素),corrent()(返回当前元素),valid()(检查迭代结尾),rewind()(从头重新开始),key()(返回当前元素的索引)。当然你可以自己写适合自己用的迭代器,也可以用系统中的迭代器。

一般是使用foreach来使用迭代器,下面整理了一下代码:

<?php  
class sample implements Iterator
{
  private $_items = array(1,2,3,4,5,6,7);
  public function __construct() {
         ;//void
  }
  public function rewind() { reset($this->_items); }
  public function current() { return current($this->_items); }
  public function key() { return key($this->_items); }
  public function next() { return next($this->_items); }
  public function valid() { return ( $this->current() !== false ); }
}
$sa = new sample();
foreach($sa as $key => $val){
  print $key . "=>" .$val;
}
?>

while循环也可以:

<?php
while ($itertor->valid()){ //判断是不是最后元素
 $element=$itertor->current(); //获取当前元素
 $itertor->next(); //移动到下一个元素
}
?>

为什么要学习PHP的迭代器呢?有个很重要的原因:利用PHP的迭代器可以利用面向对象实现常见的数据结构,例如列表,堆栈,队列与图。后面会做一个专题,用PHP实现大部分的数据结构,而且以面向对象的形式。所以这里先预热了一下PHP的迭代器。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

PHP 相关文章推荐
在 PHP 中使用随机数的三个步骤
Oct 09 PHP
不用数据库的多用户文件自由上传投票系统(1)
Oct 09 PHP
利用static实现表格的颜色隔行显示的代码
Sep 02 PHP
ajax+php打造进度条 readyState各状态
Mar 20 PHP
PHP中的生成XML文件的4种方法分享
Oct 06 PHP
php获取通过http协议post提交过来xml数据及解析xml
Dec 16 PHP
php inc文件使用的风险和注意事项
Nov 12 PHP
php 解压rar文件及zip文件的方法
May 05 PHP
php中Y2K38的漏洞解决方法实例分析
Sep 22 PHP
PHP获取数组长度或某个值出现次数的方法
Feb 11 PHP
PHP编程 SSO详细介绍及简单实例
Jan 13 PHP
PHP实现活动人选抽奖功能
Apr 19 PHP
ThinkPHP5.1表单令牌Token失效问题的解决
Mar 22 #PHP
PHP iconv()函数字符编码转换的问题讲解
Mar 22 #PHP
PHP里的$_GET数组介绍
Mar 22 #PHP
PHP匿名函数(闭包函数)详解
Mar 22 #PHP
PHP利用递归函数实现无限级分类的方法
Mar 22 #PHP
用PHP的反射实现委托模式的讲解
Mar 22 #PHP
PHP读取目录树的实现方法分析
Mar 22 #PHP
You might like
PHP insert语法详解
2008/06/07 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
JavaScript对象模型-执行模型
2008/04/28 Javascript
Mootools 1.2教程 Fx.Morph、Fx选项和Fx事件
2009/09/15 Javascript
LazyForm jQuery plugin 定制您的CheckBox Radio和Select
2009/10/24 Javascript
jquery入门—数据删除与隔行变色以及图片预览
2013/01/07 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
JavaScript加强之自定义callback示例
2013/09/21 Javascript
jQuery实现平滑滚动的标签分栏切换效果
2015/08/28 Javascript
js创建对象的方法汇总
2016/01/07 Javascript
浅谈JS正则表达式的RegExp对象和括号的使用
2016/07/28 Javascript
JavaScript中windows.open()、windows.close()方法详解
2016/07/28 Javascript
jQuery Ajax 加载数据时异步显示加载动画
2016/08/01 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
2017/01/16 Javascript
svg动画之动态描边效果
2017/02/22 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
vue 2.x 中axios 封装的get 和post方法
2018/02/28 Javascript
vue自定义底部导航栏Tabbar的实现代码
2018/09/03 Javascript
微信小程序非swiper组件实现的自定义伪3D轮播图效果示例
2018/12/11 Javascript
Python实现Linux下守护进程的编写方法
2014/08/22 Python
Python使用turtule画五角星的方法
2015/07/09 Python
在unittest中使用 logging 模块记录测试数据的方法
2018/11/30 Python
实例教程 HTML5 Canvas 超炫酷烟花绽放动画实现代码
2014/11/05 HTML / CSS
浅谈移动端网页图片预加载方案
2018/11/05 HTML / CSS
Ado与Ado.net的相同与不同
2014/12/08 面试题
应聘编辑职位自荐信范文
2014/01/05 职场文书
2014教师个人自我评价范文
2014/09/13 职场文书
给老婆道歉的话
2015/01/20 职场文书
逃出克隆岛观后感
2015/06/09 职场文书
医学会议开幕词
2016/03/03 职场文书
详解CSS不受控制的position fixed
2021/05/25 HTML / CSS
开机音效回归! Windows 11重新引入开机铃声
2021/11/21 数码科技
Golang数据类型和相互转换
2022/04/12 Golang
Spring Cloud OpenFeign模版化客户端
2022/06/25 Java/Android
Python可视化神器pyecharts绘制水球图
2022/07/07 Python