PHP Predefined Interfaces 预定义接口
SPL提供了6个迭代器接口:
| Traversable | 遍历接口(检测一个类是否可以使用 foreach 进行遍历的接口) |
| Iterator | 迭代器接口(可在内部迭代自己的外部迭代器或类的接口) |
| IteratorAggregate | 聚合式迭代器接口(创建外部迭代器的接口) |
| OuterIterator | 迭代器嵌套接口(将一个或多个迭代器包裹在另一个迭代器中) |
| RecursiveIterator | 递归迭代访问接口(提供递归访问功能) |
| SeekableIterator | 可索引迭代访问接口(实现查找功能) |
下面对各种迭代器接口简单介绍一下:
1. Traversable
Traversable接口实际上不是一个接口,在实际写php代码中不能用。因为只有内部的PHP类(用C写的类)才可以直接实现Traversable接口。可以说这是个特性级别的东西。实际的PHP编程中我们使用Iterator接口或者IteratorAggregate接口来实现遍历。
Traversable {
}
Traversable 接口不能直接实现(implements).Traversable 重要的一个用处就是判断一个类是否可以遍历:
if($class instanceof Traversable)
{
//foreach...
}
下面是官方例子:
<?php
if( !is_array( $items ) && !$items instanceof Traversable )
//Throw exception here
?>
2. Iterator
Iterator接口的主要用途是允许一个类实现一个基本的迭代功能,从而使它可以被循环访问,根据键值访问以及回滚。Iterator接口摘要如下:
Iterator extends Traversable
{
//返回当前索引游标指向的元素
abstract public mixed current(void)
//返回当前索引游标指向的元素的键名
abstract public scalar key(void)
//移动当前索引游标指向下一元素
abstract public void next(void)
//重置索引游标的指向第一个元素
abstract public void rewind(void)
//判断当前索引游标指向的是否是一个元素,常常在调用 rewind()或 next()使用
abstract public boolean valid(void)
}
外部迭代器接口,实现该接口的对象可以迭代自己内部的数据。
Iterator 的例子这里就不再列举了,本专题前面部分以后后续有很多例子,具体请自行查看。
3. IteratorAggregate
又叫聚合式迭代器。创建外部迭代器的接口,其摘要如下:
IteratorAggregate extends Traversable {
//实现该方法时,必须返回一个实现了Iterator接口的类的实例
abstract public Traversable getIterator ( void )
}
其中getIterator 方法返回值必须是能遍历或实现Iterator接口(must be traversable or implement interface Iterator)。SPL还提供了一些专门用来与IteratorAggregate接口一起使用的内置迭代器。使用这些迭代器意味着只需要实现一个方法并实例化一个类就可以使对象可以迭代访问了。托福答案
实例:
/**
* @author 简明现代魔法 http://www.nowamagic.net
*/
class myData implements IteratorAggregate
{
public $property1 = "公共属性1";
public $property2 = "公共属性2";
public $property3 = "公共属性3"; public function __construct()
{
$this->property4 = "最后一个公共属性";
} public function getIterator()
{
return new ArrayIterator($this);
}
} $obj = new myData;
foreach ($obj as $key => $value) {
echo "键名:{$key} 值:{$value}\n";
}
程序输出:
键名:property1 值:公共属性1
键名:property2 值:公共属性2
键名:property3 值:公共属性3
键名:property4 值:最后一个公共属性
4. ArrayAccess
数组式访问接口。实现该接口的对象能像数组一样使用:
ArrayAccess {
/* Methods */
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}
- ArrayAccess::offsetExists — 检查一个偏移位置是否存在
- ArrayAccess::offsetGet — 获取一个偏移位置的值
- ArrayAccess::offsetSet — 设置一个偏移位置的值
- ArrayAccess::offsetUnset — 复位一个偏移位置的值
举个栗子:
/**
* @author 简明现代魔法 http://www.nowamagic.net
*/
class obj implements arrayaccess {
private $container = array();
public function __construct() {
$this->container = array(
"one" => 1,
"two" => 2,
"three" => 3,
);
}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
} $obj = new obj; var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
5. Serializable
序列化接口。实现该接口的类不能使用__sleep() 和__wakeup().在serialize时不执行__destruct(),在unserialize不执行__construct()。
Serializable {
/* Methods */
abstract public string serialize ( void )
abstract public mixed unserialize ( string $serialized )
}
实现此接口的类将不再支持 __sleep() 和 __wakeup()。不论何时,只要有实例需要被序列化,serialize 方法都将被调用。它将不会调用 __destruct() 或有其他影响,除非程序化地调用此方法。当数据被反序列化时,类将被感知并且调用合适的 unserialize() 方法而不是调用 __construct()。如果需要执行标准的构造器,你应该在这个方法中进行处理。托福改分
- Serializable::serialize — 对象的字符串表示
- Serializable::unserialize — 构造对象
Serializable {
/* Methods */
abstract public string serialize ( void )
abstract public mixed unserialize ( string $serialized )
}
例子:
class obj implements Serializable {
private $data;
public function __construct() {
$this->data = "My private data";
}
public function serialize() {
return serialize($this->data);
}
public function unserialize($data) {
$this->data = unserialize($data);
}
public function getData() {
return $this->data;
}
}
$obj = new obj;
$ser = serialize($obj);
$newobj = unserialize($ser);
var_dump($newobj->getData());
6. Closure
Closure {
/* 方法 */
__construct ( void )
public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )
}
PHP Predefined Interfaces 预定义接口的更多相关文章
- 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 ...
随机推荐
- Pick-up sticks(判断两条线段是否相交)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8351 Accepted: 3068 Description Stan has ...
- COJ 2105 submatrix
submatrix 难度级别: A: 编程语言:不限:运行时间限制:2000ms: 运行空间限制:131072KB: 代码长度限制:102400B 试题描述 小A有一个N×M的矩阵,矩阵中1~N* ...
- Light OJ 1021 - Painful Bases(状态压缩DP)
题目大意: 给你一个base 进制的数字,把这个数字的每一位进行全排列,问有多少个数字是可以整除k的. 题目解析: #include<cstdio> #include<cstring ...
- HDU 5410 CRB and His Birthday
题目大意: 一个人要去买礼物,有M元.有N种礼物,每件礼物的价值是Wi, 你第i件礼物买k个 是可以得到 Ai * k + Bi 个糖果的. 问怎么才能使得你得到的糖果数目最多. 其实就是完全背包 ...
- [Locked] Meeting Room I && II
Meeting Room Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2 ...
- python多线程机制
Python中的线程从一开始就是操作系统的原生线程.而Python虚拟机也同样使用一个全局解释器锁(Global Interpreter Lock,GIL)来互斥线程多Python虚拟机的使用. GI ...
- “VICUTU威克多”高档男装
"VICUTU威克多"高档男装 北京威克多制衣中心是一家从事高档男装设计.制造和销售为一体的股份服装企业.主要经营品牌为"VICUTU"男装系列,主导产品为 ...
- Eclipse 在线汉化
1. 打开Eclipse , 进入菜单中 Help-->Install new Software.. 2. 到Eclipse 官网找到语言包地址,http://www.eclipse.org/ ...
- Linux下profile environment bashrc的区别
先将export LANG=zh_CN加入/etc/profile ,退出系统重新登录,登录提示显示英文.将/etc/profile 中的export LANG=zh_CN删除,将LNAG=z ...
- hive 模块