PHP学习之预定义接口
2017-11-11 10:39
253 查看
Traversable(遍历)接口
检测一个类是否可以使用foreach进行遍历的接口无法被单独实现的基本抽象接口。相反它必须由 IteratorAggregate 或 Iterator 接口实现
Note: 实现此接口的内建类可以使用 foreach 进行遍历而无需实现 IteratorAggregate 或 Iterator 接口。 Note: 这是一个无法在 PHP 脚本中实现的内部引擎接口。IteratorAggregate 或 Iterator 接口可以用来代替它。
接口摘要
接口摘要
Traversable {
}
这个接口没有任何方法,它的作用仅仅是作为所有可遍历类的基本接口。
判断一个类是否可以使用foreach
<?php if( !is_array( $items ) && !$items instanceof Traversable ) //Throw exception here if( is_array( $items ) || ( $items instanceof Traversable ) ) foreach... ?>
Iterator(迭代器) 接口
简介 可在内部迭代自己的外部迭代器或类的接口
接口摘要
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 迭代器。Example #1 Basic usage
<?php 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 (聚合式迭代器)接口
简介
创建外部迭代器的接口。接口摘要
IteratorAggregate extends Traversable { /* 方法 */ abstract public Traversable getIterator(void); } Table of Contents IteratorAggregate::getIterator — 获取一个外部迭代器
Example #1 Basic usage
<?php 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(数组式访问)接口
简介
提供像访问数组一样访问对象的能力的接口。接口摘要
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 ) #删除数据
Example #1 Basic usage
<?php 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[ f601 "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 — 构造对象
}
Example #1 Basic usage
<?php 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 类
类摘要
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
<?php /** * 复制一个闭包,绑定指定的$this对象和类作用域。 * * @author 疯狂老司机 */ class Animal { private static $cat = "cat"; private $dog = "dog"; public $pig = "pig"; } /* * 获取Animal类静态私有成员属性 */ $cat = static function() { return Animal::$cat; }; /* * 获取Animal实例私有成员属性 */ $dog = function() { return $this->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(),'<br>';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性 echo $bindDog(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性 echo $bindPig(),'<br>';// 根据绑定规则,允许闭包通过绑定的$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:
<?php function __autoload($class) { require_once "$class.php"; } $template = new Template; $template->render(new Article, 'tpl.php'); ?>
Template.php 模板类
<?php /** * 模板类,用于渲染输出 * * @author 疯狂老司机 */ class Template{ /** * 渲染方法 * * @access public * @param obj 信息类 * @param string 模板文件名 */ public function render($context, $tpl){ $closure = function($tpl){ ob_start(); include $tpl; return ob_end_flush(); }; $closure = $closure->bindTo($context, $context); $closure($tpl); } }
Article.php 信息类
<?php /** * 文章信息类 * * @author 疯狂老司机 */ class Article{ private $title = "这是文章标题"; private $content = "这是文章内容"; }
tpl.php 模板文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> </head> <body> <h1><?php echo $this->title;?></h1> <p><?php echo $this->content;?></p> </body> </html>
运行时确保以上文件位于同级目录。
输出:
这是文章标题
这是文章内容
<?php /** * 给类动态添加新方法 * * @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 — 序列化回调
相关文章推荐
- php 接口类(interface,implements)的学习和使用
- PHP接口定义
- PHP学习笔记10. PHP中的预定义变量
- PHP与Spring之间的强势接口设计:学习案例
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
- 片上总线Wishbone 学习(四)接口信号定义
- php学习笔记--预定义常量
- PHP学习笔记--Php预定义超全局变量$_GET
- Effective C# 学习笔记(二十二)多用接口定义实现,少用继承
- php 多态与接口学习实现与实例代码
- PHP学习笔记——ThinkPHP开发指南-关联模型之关联定义
- PHP学习笔记——函数的定义和结构,自定义函数;
- PHP Predefined Interfaces 预定义接口
- EJB3.0学习笔记---Bean实现多个接口的情况下定义,访问方式:
- Android学习之跨进程通信安卓接口定义语言AIDL(二)
- php接口定义和具体说明
- [导入]关于PHP接口的学习
- php——学习笔记,预定义变量
- PHP接口学习
- PHP以接口方式实现多重继承(完全模拟)--学习笔记