检测一个类是否可以使用foreach进行遍历的接口
无法被单独实现的基本抽象接口。相反它必须由 IteratorAggregate 或 Iterator 接口实现
Note:
实现此接口的内建类可以使用 foreach 进行遍历而无需实现 IteratorAggregate 或 Iterator 接口。
Note:
这是一个无法在 PHP 脚本中实现的内部引擎接口。IteratorAggregate 或 Iterator 接口可以用来代替它。
接口摘要
接口摘要
Traversable {
}
这个接口没有任何方法,它的作用仅仅是作为所有可遍历类的基本接口。
判断一个类是否可以使用foreach
if( !is_array( $items ) && !$items instanceof Traversable )
//Throw exception here
if( is_array( $items ) || ( $items instanceof Traversable ) )
foreach...
?>
Iterator extends Traversable{
/*方法*/
abstract public mixed current( void );
abstract public scalar key( void );
abstract public void next( void );
abstract public void rewind( void );
abstract public boolean volid ( void );
}
Table of Contents
Iterator::current — 返回当前元素
Iterator::key — 返回当前元素的键
Iterator::next — 向前移动到下一个元素
Iterator::rewind — 返回到迭代器的第一个元素
Iterator::valid — 检查当前位置是否有效
PHP 已经提供了一些用于日常任务的迭代器。 详细列表参见 SPL 迭代器。
class myIterator implements Iterator {
private $position = 0;
private $array = arrray(
'firstelement',
'secondelement',
'lastelement',
);
public function __construct(){
$this->position = 0;
}
function rewind() {
var_dump(__METHOD__);
$this->position = 0;
}
function current() {
var_dump(__METHOD__);
return $this->array[$this->position];
}
function key(){
var_dump(__METHOD__);
return $this->position;
}
function next(){
var_dump(__METHOD__);
++$this->position;
}
function valid(){
var_dump(__METHOD__);
return isset($this->array[$this->position]);
}
}
$it = new myIterator;
foreach($it as $key => $value){
var_dump($key,$value);
echo '\n';
}
?>
以上例程的输出类似于:
string(18) "myIterator::rewind"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(0)
string(12) "firstelement"
string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(1)
string(13) "secondelement"
string(16) "myIterator::next"
string(17) "myIterator::valid"
string(19) "myIterator::current"
string(15) "myIterator::key"
int(2)
string(11) "lastelement"
string(16) "myIterator::next"
string(17) "myIterator::valid"
foreach 执行时迭代器的调用顺序
首先
rewind->valid->current->key
第二次
->next->valid->current->key
…
…
最后一次
->next->valid end
创建外部迭代器的接口。
IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator(void);
}
Table of Contents
IteratorAggregate::getIterator — 获取一个外部迭代器
class myData implements IteratorAggregate{
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three";
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three";
public function getIterator(){
return new ArrayIterator($this);
}
}
$obj = new myData;
foreach( $obj as $key => $value ){
var_dump($key,$value);
echo "\n";
}
//OUTPUT:
string(9) "property1"
string(19) "Public property one"
string(9) "property2"
string(19) "Public property two"
string(9) "property3"
string(21) "Public property three"
string(9) "property4"
string(13) "last property"
提供像访问数组一样访问对象的能力的接口。
ArrayAccess{
/** 方法 **/
abstract public boolean offsetExists ( mixed $offset );
abstract pbulic mixed offsetGet ( mixed $offset );
abstract public void offsetSet ( mixed $offset, mixed $value);
abstract public void offsetUnset ( mixed $offset );
}
Table of Contents ¶
ArrayAccess::offsetExists — 检查一个偏移位置是否存在
ArrayAccess::offsetGet — 获取一个偏移位置的值
ArrayAccess::offsetSet — 设置一个偏移位置的值
ArrayAccess::offsetUnset — 复位一个偏移位置的值
以下描述更好理解
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 ) #删除数据
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);
?>
以上例程的输出类似于:
bool(true)
int(2)
bool(false)
string(7) "A value"
obj Object
(
[container:obj:private] => Array
(
[one] => 1
[three] => 3
[two] => A value
[0] => Append 1
[1] => Append 2
[2] => Append 3
)
)
自定义序列化的接口。
实现此接口的类将不再支持 __sleep() 和 __wakeup()。不论何时,只要有实例需要被序列化,serialize 方法都将被调用。它将不会调用 __destruct() 或有其他影响,除非程序化地调用此方法。当数据被反序列化时,类将被感知并且调用合适的 unserialize() 方法而不是调用 __construct()。如果需要执行标准的构造器,你应该在这个方法中进行处理。
Serializable {
/* 方法 */
abstract public string serialize( void );
abstract public mixed unserialize ( string $serialized );
Table of Contents
Serializable::serialize — 对象的字符串表示
Serializable::unserialize — 构造对象
}
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());
?>
output:
string(15) "My private data"
Closure {
/* 方法 */
__construct( void );
public static Closure bind( Closure $closure, object $newthis [,mixed $newscope = 'static']);
public Closure bindTo (object $newthis [, mixed $newscpe = 'static']);
}
Table of Contents
Closure::__construct — 用于禁止实例化的构造函数
Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。
除了此处列出的方法,还有一个 __invoke 方法。这是为了与其他实现了 __invoke()魔术方法 的对象保持一致性,但调用闭包对象的过程与它无关。
下面将介绍Closure::bind和Closure::bindTo。
Closure::bind是Closure::bindTo的静态版本,其说明如下:
[php] view plain copy
public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
closure表示需要绑定的闭包对象。
newthis表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。
newscope表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是 ‘static’, 表示不改变。
该方法成功时返回一个新的 Closure 对象,失败时返回FALSE。
例子说明:
[php] view plain copy
dog;
};
/*
* 获取Animal实例公有成员属性
*/
$pig = function() {
return $this->pig;
};
$bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
echo $bindCat(),'
';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
echo $bindDog(),'
';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
echo $bindPig(),'
';// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性
?>
输出:
cat
dog
pig
Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域,其说明如下:
[php] view plain copy
public Closure Closure::bindTo (object $newthis [, mixed $newscope = 'static' ])
newthis表示绑定给闭包对象的一个对象,或者NULL来取消绑定。
newscope表示关联到闭包对象的类作用域,可以传入类名或类的示例,默认值是 ‘static’, 表示不改变。
该方法创建并返回一个闭包对象,它与当前对象绑定了同样变量,但可以绑定不同的对象,也可以绑定新的类作用域。绑定的对象决定了返回的闭包对象中的 this的取值,类作用域决定返回的闭包对象能够调用哪些方法,也就是说,此时 this可以调用的方法,与newscope类作用域相同。
例子1:
render(new Article, 'tpl.php');
?>
Template.php 模板类
bindTo($context, $context);
$closure($tpl);
}
}
Article.php 信息类
tpl.php 模板文件
title;?>
content;?>
运行时确保以上文件位于同级目录。
输出:
这是文章标题
这是文章内容
/**
* 给类动态添加新方法
*
* @author 疯狂老司机
*/
trait DynamicTrait {
/**
* 自动调用类中存在的方法
*/
public function __call($name, $args) {
if(is_callable($this->$name)){
return call_user_func($this->$name, $args);
}else{
throw new \RuntimeException("Method {$name} does not exist");
}
}
/**
* 添加方法
*/
public function __set($name, $value) {
$this->$name = is_callable($value)?
$value->bindTo($this, $this):
$value;
}
}
/**
* 只带属性不带方法动物类
*
* @author 疯狂老司机
*/
class Animal {
use DynamicTrait;
private $dog = 'dog';
}
$animal = new Animal;
// 往动物类实例中添加一个方法获取实例的私有属性$dog
$animal->getdog = function() {
return $this->dog;
};
echo $animal->getdog();
?>
输出:
dog
Generator 对象是从 generators返回的.
Caution Generator 对象不能通过 new 实例化.
Generator implements Iteraotr {
/* 方法 */
public mixed current( void );
public mixed key( void );
public void next( void );
public void rewind ( void )
public mixed send ( mixed $value )
public void throw ( Exception $exception )
public bool valid ( void )
public void __wakeup ( void )
}
Table of Contents
Generator::current — 返回当前产生的值
Generator::key — 返回当前产生的键
Generator::next — 生成器继续执行
Generator::rewind — 重置迭代器
Generator::send — 向生成器中传入一个值
Generator::throw — 向生成器中抛入一个异常
Generator::valid — 检查迭代器是否被关闭
Generator::__wakeup — 序列化回调