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 }