十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
迭代器是一种更高级的工具。foreach是简单的循环语法。虽然功能上看起来相似。但迭代器是工具,这是二者性质上的不同,所以迭代器有更丰富的功能特性,还可以自定义具体的实现。特别是在内存占用上,迭代器是按需读取数据,foreach是一次性载入数据。PHP里面PDO,SimpleXML里面都有迭代器的具体实现,更完整的全部在SPL扩展部分。
创新互联服务紧随时代发展步伐,进行技术革新和技术进步,经过十多年的发展和积累,已经汇集了一批资深网站策划师、设计师、专业的网站实施团队以及高素质售后服务人员,并且完全形成了一套成熟的业务流程,能够完全依照客户要求对网站进行成都网站制作、做网站、外贸营销网站建设、建设、维护、更新和改版,实现客户网站对外宣传展示的首要目的,并为客户企业品牌互联网化提供全面的解决方案。
《PHP设计模式介绍》第八章 迭代器模式
类中的面向对象编程封装应用逻辑 类 就是实例化的对象 每个单独的对象都有一个特定的身份和状态 单独的对象是一种组织代码的有用方法 但通常你会处理一组对象或者集合
属性来自 SQL 查询的一组数据就是一个集合 就像本书前面章节介绍的 Monopoly 游戏示例的对象列表
集合不一定是均一的 图形用户界面框架中的 Window 对象可以收集任意数量的控制对象 - Menu Slider 和 Button 并且 集合的实现可以有多种方式 PHP 数字是一个集合 但也是一个散列表 一个链接列表 一个堆栈以及队列
问题
如何操纵任意的对象集合?
解决方案
使用迭代器模式来提供对集合内容的统一存取
你可能没有意识到这一点 但你每天都在使用迭代器模式 - 它潜藏在 PHP 的数组类型和各种数组操作函数中 (其实 给你一些固有类的数组的组合和一群用这些固有类工作的可变函数 你将不得不使用这些数组来处理对象集合 这是在 PHP 中的本地数组迭代
$test = array( one o three );$output = ; reset($test); do {$output = current($test);} while (next($test));echo $output; // produces oneothree
reset() 函数将迭代重新转到数组的开始 current() 返回当前元素的值 next() 则前进至数组中的下一个元素并返回新的 current() 值 当你超出数组的最后一个元素时 next() 返回 false 使用这些迭代方法 PHP 数组的内部实现就与你不相关了 迭代器结合了封装和多态的面向对象程序设计原理 使用迭代器 你可以对集合中的对象进行操作 而无需专门了解集合如何显现或者集合包含什么(对象的种类) 迭代器提供了不同固定迭代实现的统一接口 它完全包含了如何操纵特定集合的详细信息 包括显示哪些项(过滤)及其显示顺序(排序)
让我们创建一个简单的对象 在数组中对它进行操作 (尽管该示例在 PHP 环境下 但迭代器并不特定于 PHP 虽然添加了较多的引用操作符 本章节中的大多数示例在 PHP 下也能够运行) 对象 Lendable 表示诸如电影 相册等媒体 它作为 Web 站点的一部分或服务 允许用户浏览或将他们的媒体集合分享给其他用户 (对 于该示例 请无需考虑其他方面 )让我们开始下面对 Lendable 基础设计的测试
// PHP class LendableTestCase extends UnitTestCase {function TestCheckout() {$item = new Lendable;$this assertFalse($item borrower);$item checkout( John );$this assertEqual( borrowed $item status);$this assertEqual( John $item borrower);}function TestCheckin() {$item = new Lendable;$item checkout( John );$item checkin();$this assertEqual( library $item status);$this assertFalse($item borrower);}}
要实现这一最初测试的需求 我们来创建一个带有若干公共属性和一些方法的类 来触发这些属性的值
class Lendable {public $status = library ;public $borrower = ;public function checkout($borrower) {$this status = borrowed ;$this borrower = $borrower;}public function checkin() {$this status = library ;$this borrower = ;}}
Lendable 是一个好的 普通的开端 让我们将它扩展到诸如 DVD 或 CD 的磁道项 媒体扩展了 Lendable 并且磁道详细记录了特定媒体的详细信息 包括项目的名称 发布的年份以及项本身的类型
class Media extends Lendable {public $name; public $type; public $year;public function __construct($name $year $type= dvd ) {$this name = $name;$this type = $type;$this year = (int)$year;}}
要使事情更加简单 媒体有三个公共的实例变量 Media::name Media::year 和Media::type 构造函数采用了两个参数 将第一个存储在 $name 中 第二个存储在 $year 中 构造函数还允许可选的第三个参数来指定类型(缺省为dvd)
给定单独的对象来操作 你现在可以创建一个容器来包含他们 Library 类似于常用的库 Library 应该能够添加 删除和计算集合中的项 甚至 Library 还应该允许访问集合(本章中的样本代码部分可看到示例)中的单一的项(对象)
我们开始构建 Library 的测试用例
class LibraryTestCase extends UnitTestCase {function TestCount() {$lib = new Library;$this assertEqual( $lib count());}}
它是满足这一测试的简单类
class Library {function count() {return ;}}
继续将一些有趣的功能添加到测试中
class LibraryTestCase extends UnitTestCase {function TestCount() { /* */ }function TestAdd() {$lib = new Library;$lib add( one );$this assertEqual( $lib count());}}
实现 add() 的简单方法是建立在 PHP 灵活数组函数的基础上 你可以将项添加到实例变量并使用 count() 来返回集合众项的数量
class Library {protected $collection = array();function count() {return count($this collection);}function add($item) {$this collection[] = $item;}}
lishixinzhi/Article/program/net/201311/13092
本文介绍下,php编程中SPL中的用法,SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,有需要的朋友参考下。
PHP SPL的用法
SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,并且从 PHP5.3 已逐渐的成熟。SPL 其实在所有的 PHP5 开发环境中被内置,同时无需任何设置。
似乎众多的 PHP 开发人员基本没有使用它,甚至闻所未闻。究其原因,可以追述到它那阳春白雪般的说明文档,使你忽略了「它的存在」。SPL 这块宝石犹如铁达尼的「海洋之心」般,被沉入海底。而现在它应该被我们捞起,并将它穿戴在应有的位置 ,而这也是这篇文章所要表述的观点。
SPL 提供了什么?
SPL 对 PHP 引擎进行了扩展,例如 ArrayAccess、Countable 和 SeekableIterator 等接口,它们用于以数组形式操作对象。同时,你还可以使用 RecursiveIterator、ArrayObejcts 等其他迭代器进行数据的迭代操作。
它还内置几个的对象例如 Exceptions、SplObserver、Spltorage 以及 splautoloadregister、splclasses、iteratorapply 等的帮助函数(helper functions),用于重载对应的功能。
这些工具聚合在一起就好比是把多功能的瑞士军刀,善用它们可以从质上提升 PHP 的代码效率。那么,如何发挥它的威力?
重载 autoloader
如果你是位「教科书式的程序员」,那么你保证了解如何使用 __autoload 去代替 includes/requires 操作惰性载入对应的类,对不?
但久之,你会发现你已经陷入了困境,首先是你要保证你的类文件必须在指定的文件路径中,例如在 Zend 框架中你必须使用「_」来分割类、方法名称(你如何解决这一问题?)。
另外的问题:
当项目变得越来越复杂, __autoload 内的逻辑也会变得相应的`复杂。到最后,甚至你会加入异常判断,以及将所有的载入类的逻辑如数写到其中。
大家都知道「鸡蛋不能放到一个篮子中」,利用 SPL 可以分离 __autoload 的载入逻辑。只需要写个你自己的 autoload 函数,然后利用 SPL 提供的函数重载它。
例如,上述 Zend 框架的问题,你可以重载 Zend loader 对应的方法,如果它没有找到对应的类,那么就使用先前定义的函数。
复制代码 代码示例:
?php
class MyLoader {
public static function doAutoload($class) {
// 本模块对应的 autoload 操作
}
}
spl_autoload_register( array('MyLoader', 'doAutoload') );
?
spl autoload register 还能以数组的形式加入多个载入逻辑。同时,你还可以利用spl autoload unregister 移除已经不再需要的载入逻辑,这功能总会用到的。
迭代器
迭代是常见设计模式之一,普遍应用于一组数据中的统一的遍历操作。可以毫不夸张的说,SPL 提供了所有你需要的对应数据类型的迭代器。
有个非常好的案例就是遍历目录。常规的做法就是使用 scandir ,然后跳过「.「 和 「..」,以及其它未满足条件的文件。例如你需要遍历个某个目录抽取其中的图片文件,就需要判断是否是 jpg、gif 结尾。
使用 SPL 的迭代器执行上述递归寻找指定目录中的图片文件的例子:
复制代码 代码示例:
?php
class RecursiveFileFilterIterator extends FilterIterator {
// 满足条件的扩展名
protected $ext = array('jpg','gif');
/**
* 提供 $path 并生成对应的目录迭代器
*/
public function __construct($path) {
parent::__construct(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)));
}
/**
* 检查文件扩展名是否满足条件
* //
*/
public function accept() {
$item = $this-getInnerIterator();
if ($item-isFile()
in_array(pathinfo($item-getFilename(), PATHINFO_EXTENSION), $this-ext)) {
return TRUE;
}
}
}
// 实例化
foreach (new RecursiveFileFilterIterator('/path/to/something') as $item) {
echo $item . PHP_EOL;
}
?
使用foreach 与使用迭代器,并不冲突
迭代器可以使用在:
1、使用返回迭代器的包或库时(如PHP5中的SPL迭代器)
2、无法在一次的调用获取容器的所有元素时
3、要处理数量巨大的无素时(数据库中的表以GB计的数据)
迭代器还可以用来构造一些数据结构。
你可以去后盾人平台看看,里面的东西不错