欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-26 16:01:47
1,魔术方法__set与__get, __call >这些魔术方法,将在相关的属性或者方法不存在时调用 >函数原型 .function __set( $property, $value ):传递属性的名字和新的值 .function __get( $property ):传递属性的名字,并且返回属性 ......

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 }