PHP Predefined Interfaces 预定义接口

系统 1927 0

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 预定义接口


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论