SPL提供了6个迭代器接口:
Traversable |
遍历接口(检测一个类是否可以使用 foreach 进行遍历的接口) |
Iterator |
迭代器接口(可在内部迭代自己的外部迭代器或类的接口) |
IteratorAggregate |
聚合式迭代器接口(创建外部迭代器的接口) |
OuterIterator |
迭代器嵌套接口(将一个或多个迭代器包裹在另一个迭代器中) |
RecursiveIterator |
递归迭代访问接口(提供递归访问功能) |
SeekableIterator |
可索引迭代访问接口(实现查找功能) |
下面对各种迭代器接口简单介绍一下:
1. Traversable
Traversable接口实际上不是一个接口,在实际写php代码中不能用。因为只有内部的PHP类(用C写的类)才可以直接实现Traversable接口。可以说这是个特性级别的东西。实际的PHP编程中我们使用Iterator接口或者IteratorAggregate接口来实现遍历。
Traversable 接口不能直接实现(implements).Traversable 重要的一个用处就是判断一个类是否可以遍历:
1 |
if ( $class instanceof Traversable)
|
下面是官方例子:
2 |
if ( ! is_array ( $items ) && ! $items instanceof Traversable )
|
2. Iterator
Iterator接口的主要用途是允许一个类实现一个基本的迭代功能,从而使它可以被循环访问,根据键值访问以及回滚。Iterator接口摘要如下:
01 |
Iterator extends Traversable
|
04 |
abstract public mixed current(void)
|
06 |
abstract public scalar key(void)
|
08 |
abstract public void next(void)
|
10 |
abstract public void rewind (void)
|
11 |
//判断当前索引游标指向的是否是一个元素,常常在调用 rewind()或 next()使用
|
12 |
abstract public boolean valid(void)
|
外部迭代器接口,实现该接口的对象可以迭代自己内部的数据。
Iterator 的例子这里就不再列举了,本专题前面部分以后后续有很多例子,具体请自行查看。
3. IteratorAggregate
又叫聚合式迭代器。创建外部迭代器的接口,其摘要如下:
1 |
IteratorAggregate extends Traversable {
|
2 |
//实现该方法时,必须返回一个实现了Iterator接口的类的实例
|
3 |
abstract public Traversable getIterator ( void )
|
其中getIterator 方法返回值必须是能遍历或实现Iterator接口(must be traversable or implement interface Iterator)。SPL还提供了一些专门用来与IteratorAggregate接口一起使用的内置迭代器。使用这些迭代器意味着只需要实现一个方法并实例化一个类就可以使对象可以迭代访问了。
实例:
04 |
class myData implements IteratorAggregate
|
06 |
public $property1 = "公共属性1" ;
|
07 |
public $property2 = "公共属性2" ;
|
08 |
public $property3 = "公共属性3" ;
|
10 |
public function __construct()
|
12 |
$this ->property4 = "最后一个公共属性" ;
|
15 |
public function getIterator()
|
17 |
return new ArrayIterator( $this );
|
22 |
foreach ( $obj as $key => $value ) {
|
23 |
echo "键名:{$key} 值:{$value}\n" ;
|
程序输出:
4 |
键名:property4 值:最后一个公共属性 |
4. ArrayAccess
数组式访问接口。实现该接口的对象能像数组一样使用:
3 |
abstract public boolean offsetExists ( mixed $offset )
|
4 |
abstract public mixed offsetGet ( mixed $offset )
|
5 |
abstract public void offsetSet ( mixed $offset , mixed $value )
|
6 |
abstract public void offsetUnset ( mixed $offset )
|
- ArrayAccess::offsetExists — 检查一个偏移位置是否存在
- ArrayAccess::offsetGet — 获取一个偏移位置的值
- ArrayAccess::offsetSet — 设置一个偏移位置的值
- ArrayAccess::offsetUnset — 复位一个偏移位置的值
举个栗子:
04 |
class obj implements arrayaccess {
|
05 |
private $container = array ();
|
06 |
public function __construct() {
|
07 |
$this ->container = array (
|
13 |
public function offsetSet( $offset , $value ) {
|
14 |
if ( is_null ( $offset )) {
|
15 |
$this ->container[] = $value ;
|
17 |
$this ->container[ $offset ] = $value ;
|
20 |
public function offsetExists( $offset ) {
|
21 |
return isset( $this ->container[ $offset ]);
|
23 |
public function offsetUnset( $offset ) {
|
24 |
unset( $this ->container[ $offset ]);
|
26 |
public function offsetGet( $offset ) {
|
27 |
return isset( $this ->container[ $offset ]) ? $this ->container[ $offset ] : null;
|
33 |
var_dump(isset( $obj [ "two" ]));
|
34 |
var_dump( $obj [ "two" ]);
|
36 |
var_dump(isset( $obj [ "two" ]));
|
37 |
$obj [ "two" ] = "A value" ;
|
38 |
var_dump( $obj [ "two" ]);
|
5. Serializable
序列化接口。实现该接口的类不能使用__sleep() 和__wakeup().在serialize时不执行__destruct(),在unserialize不执行__construct()。
3 |
abstract public string serialize ( void )
|
4 |
abstract public mixed unserialize ( string $serialized )
|
实现此接口的类将不再支持 __sleep() 和 __wakeup()。不论何时,只要有实例需要被序列化,serialize 方法都将被调用。它将不会调用 __destruct() 或有其他影响,除非程序化地调用此方法。当数据被反序列化时,类将被感知并且调用合适的 unserialize() 方法而不是调用 __construct()。如果需要执行标准的构造器,你应该在这个方法中进行处理。
- Serializable::serialize — 对象的字符串表示
- Serializable::unserialize — 构造对象
3 |
abstract public string serialize ( void )
|
4 |
abstract public mixed unserialize ( string $serialized )
|
例子:
01 |
class obj implements Serializable {
|
03 |
public function __construct() {
|
04 |
$this ->data = "My private data" ;
|
06 |
public function serialize() {
|
07 |
return serialize( $this ->data);
|
09 |
public function unserialize( $data ) {
|
10 |
$this ->data = unserialize( $data );
|
12 |
public function getData() {
|
18 |
$ser = serialize( $obj );
|
20 |
$newobj = unserialize( $ser );
|
22 |
var_dump( $newobj ->getData());
|
6. Closure
4 |
public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
|
5 |
public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
|
这个具体还没研究,具体可以去看官方文档:http://www.php.net/manual/en/reserved.interfaces.php
-
PHP Predefined Interfaces 预定义接口
SPL提供了6个迭代器接口: Traversable 遍历接口(检测一个类是否可以使用 foreach 进行遍历的接口) Iterator 迭代器接口(可在内部迭代自己的外部迭代器或类的接口) Ite ...
-
PHP预定义接口之 ArrayAccess
最近这段时间回家过年了,博客也没有更新,感觉少学习了好多东西,也错失了好多的学习机会,就像大家在春节抢红包时常说的一句话:一不留神错过了好几亿.废话少说,这篇博客给大家说说关于PHP预定义接口中常用到 ...
-
深入理解PHP数组函数和预定义接口
一. PHP对数组的过滤 函数: array_filter(p1[,p2]) 参数p1是要过滤的数组,参数p2是自定义过滤会掉函数(可以是匿名函数) 例子: <?php $arr = ['',n ...
-
深入理解 PHP 的 7 个预定义接口
深入理解预定义接口 场景:平常工作中写的都是业务模块,很少会去实现这样的接口,但是在框架里面用的倒是很多. 1. Traversable(遍历)接口 该接口不能被类直接实现,如果直接写了一个普通类 ...
-
PHP预定义接口
目录 引言 IteratorAggregate(聚合式aggregate迭代器Iterator) Countable ArrayAccess Iterator 总结 引言 在PHP中有好几个预定义的接 ...
-
php 预定义接口
Traversable Traversable { } 作用:检测一个类是否可以使用 foreach 进行遍历的接口. php代码中不能用.只有内部的PHP类(用C写的类)才可以直接实现Travers ...
-
预定义接口-迭代器Iterator
<?php /* 可在内部迭代自己的外部迭代器或类的接口. Iterator extends Traversable { abstract public mixed current ( void ...
-
Flink Pre-defined Timestamp Extractors / Watermark Emitters(预定义的时间戳提取/水位线发射器)
https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/event_timestamp_extractors.html 根据官网 ...
-
oracle有三种类型的异常错误: 预定义 ( Predefined )错误里面的常见错误
oracle有三种类型的异常错误: 预定义 ( Predefined )错误, 非预定义 ( Predefined )错误, 用户定义(User_define) 错误 预定义 ( Predefined ...
随机推荐
-
给你的应用“一只”智慧的眼睛 —— Barcode常识普及以及识别信息处理
在“如何用MediaCapture解决二维码扫描问题”这篇文章中,我们通过“成像”.“截图”与“识别”三个步骤介绍了使用MediaCapture扫码的主要过程及注意事项.本文主要针对“识别”的过程,对 ...
-
css3之currentColor
一个css3的高效变量currentColor,能够继承(父级)当前字体的颜色属性(代表当前的标签所继承的文字颜色). 参考demo:http://www.zhangxinxu.com/study/2 ...
-
Xamarin.Android开发实践(十六)
Xamarin.Android之Fragment Walkthrough 利用Fragment设计能够兼容不同屏幕的应用 这里我们先围观下最后的成果图,给读者打打气: 普通手机上显示的结果: 在平板上 ...
-
UI 公钥加密
RSA算法是一种非对称加密算法,常被用于加密数据传输.如果配合上数字摘要算法, 也可以用于文件签名. 本文将讨论如何在iOS中使用RSA传输加密数据. RSA基本原理 RSA使用"秘匙对&q ...
-
Heartbeat高可用解决方案
Heartbeat高可用 Heartbeat作用: 通过heartbeat,可以将资源(ip以及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用服务 ...
-
自动化测试基础篇--Selenium中JS处理浏览器弹窗
摘自https://www.cnblogs.com/sanzangTst/p/7692454.html 浏览器弹窗: 现在大多数网站都会使用自定义弹窗,使用Selenium自带的方法暂时处理不了,这时 ...
-
关于第一次在IED(MyEclipse)部署Maven时,pom.xml头部报这样的错---org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration)
rg.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache ...
-
宝塔Linux常用命令
https://www.bt.cn/bbs/thread-1186-1-1.html 2017年3月8日发布全新架构的宝塔Linux 面板3.1Beta版,到现在的5.2.0正式版,历经100多天打磨 ...
-
RxJava 和 RxAndroid (生命周期控制和内存优化)
RxJava使我们很方便的使用链式编程,代码看起来既简洁又优雅.但是RxJava使用起来也是有副作用的,使用越来越多的订阅,内存开销也会变得很大,稍不留神就会出现内存溢出的情况,这篇文章就是介绍Rxj ...
-
人生苦短之我用Python篇(列表list、字典dict、元组tuple、字符串str)
列表 创建列表 sample_list = ['a',1,('a','b')] Python 列表操作 sample_list = ['a','b',0,1,3] 得到列表中的某一个值 value_s ...