PHP学习之预定义接口

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["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 — 序列化回调
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值