php面向对象高级-魔术方法与迭代器

1,魔术方法__set与__get, __call

>这些魔术方法,将在相关的属性或者方法不存在时调用

>函数原型

  .function __set( $property, $value ):传递属性的名字和新的值

  .function __get( $property ):传递属性的名字,并且返回属性的值

  .function __call( $methods, $args ):传递方法的名字和一个数字索引的数组,数组包含传递的参数,第一个参数的索引是0

 1 class Coordinate {
 2         private $arr = array( 'x' => null, 'y' => null );
 3         function __get( $property ) {
 4             if( array_key_exists( $property, $this->arr ) ){
 5                 return $this->arr[$property];
 6             }else {
 7                 print "不能访问一个不存在的键名" . PHP_EOL;
 8             }
 9         }
10         function __set( $property, $value ) {
11             if( array_key_exists( $property, $this->arr ) ) {
12                 $this->arr[$property] = $value;
13             }else {
14                 print "不能设置一个不存在的键名" . PHP_EOL;
15             }
16         }
17     }
18     
19     $obj = new Coordinate();
20     $obj->x = 10;
21     echo $obj->x . PHP_EOL;
22     $obj->n = 20;
23     echo $obj->n . PHP_EOL;

2,__call的应用

>通过__call可以使HelloWorldDelegator的实例调用HelloWorld的任意存在的方法

 1 class HelloWorld {
 2         function display( $count ){
 3             for( $i = 0 ; $i < $count; $i++ ) {
 4                 echo "Hello World $i " . PHP_EOL;
 5             }
 6             return $count;
 7         }
 8     }
 9 
10     
11     class HelloWorldDelegator {
12         private $obj;
13         function __construct(){
14             $this->obj = new HelloWorld();
15         }
16         function __call( $method, $args ) {
17             return call_user_func_array( array( $this->obj, $method ), $args );
18         }
19     }
20 
21     $obj = new HelloWorldDelegator();
22     print $obj->display( 3 );
23     print PHP_EOL;
24     
25     $obj->show();

3,迭代

>实现一个自己的迭代器,可以通过实现Iterator接口

Iterator接口原型:

Iterator extends Traversable {
/* Methods */
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public bool valid ( void )
}
 1 class NumberSquared implements Iterator {
 2     private $start;
 3     private $end;
 4     private $cur;
 5 
 6     function __construct ( $start, $end ){
 7         $this->start = $start;
 8         $this->end = $end;
 9     }
10     function rewind(){ 
11         $this->cur = $this->start;
12     }
13     function key(){
14         return $this->cur;
15     }
16     function current(){
17         return pow( $this->cur, 2 );
18     }
19     function next(){
20         $this->cur++;
21     }
22     function valid(){
23         return $this->cur <= $this->end;
24     }
25 }    
26 
27 $obj = new NumberSquared( 3, 9 );
28 foreach( $obj as $key => $value ){
29     print "the square of $key is $value" . PHP_EOL;
30 }

类本身一般用来表示数据和拥有与这些数据的交互方法,所以一般不需要一个纯粹的类迭代器,我们可以实现另一个接口:IteratorAggregate,接口摘要如下:

IteratorAggregate extends Traversable {
/* Methods */
abstract public Traversable getIterator ( void )
}

这个接口只有一个方法,作用是创建一个外部的迭代器接口

改造后的迭代,实现了迭代器与数据处理的分离:

 1 class NumberSquared implements IteratorAggregate {
 2     private $start;
 3     private $end;
 4 
 5     function __construct( $start, $end ) {
 6         $this->start = $start;
 7         $this->end = $end;
 8     }
 9 
10     function getIterator(){
11         return new NumberSquaredIterator( $this );
12     }    
13 
14     function getStart(){
15         return $this->start;
16     }
17 
18     function getEnd(){ 
19         return $this->end;
20     }
21 }
22 
23 class NumberSquaredIterator implements Iterator {
24     private $cur;
25     private $obj;
26     function __construct( $obj ) {
27         $this->obj = $obj;
28     }
29     function rewind(){ 
30         $this->cur = $this->obj->getStart();
31     }
32     function key(){
33         return $this->cur;
34     }
35     function next(){
36         $this->cur++;
37     }
38     function current(){
39         return pow( $this->cur, 2 );
40     }
41     function valid(){
42         return $this->cur <= $this->obj->getEnd();
43     }
44 }
45 
46 $obj = new NumberSquared( 3, 9 );
47 foreach( $obj as $key => $value ) {
48     print "the $key is $value " . PHP_EOL;
49 }

 

posted @ 2018-02-22 17:33 ghostwu 阅读(...) 评论(...) 编辑 收藏
Copyright ©2017 ghostwu