当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP SPL标准库之接口(Interface)详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-26 15:13:35 浏览: 评论:0 

这篇文章主要介绍了PHP SPL标准库之接口(Interface)详解,本文分别讲解了Coutable接口、OuterIterator接口、RecursiveIterator接口、SeekableIterator接口、SplObserver和SplSubject接口等内容,需要的朋友可以参考下

PHP SPL标准库总共有6个接口,如下:

1.Countable

2.OuterIterator

3.RecursiveIterator

4.SeekableIterator

5.SplObserver

6.SplSubject

其中OuterIterator、RecursiveIterator、SeekableIterator都是继承Iterator类的,下面会对每种接口作用和使用进行详细说明。

Coutable接口:

实现Countable接口的对象可用于count()函数计数,代码如下:

  1. class Mycount implements Countable 
  2.     public function count() 
  3.     { 
  4.         static $count = 0; 
  5.         $count++; 
  6.         return $count
  7.     } 
  8.  
  9. $count = new Mycount(); 
  10. $count->count(); 
  11. $count->count(); 
  12.  
  13. echo count($count); //3 
  14. echo count($count); //4 

说明:调用count()函数时,Mycount::count()方法被调用

count()函数的第二个参数将不会产生影响

OuterIterator接口:

自定义或修改迭代过程,代码如下:

  1. //IteratorIterator是OuterIterator的一个实现类 
  2. class MyOuterIterator extends  IteratorIterator { 
  3.  
  4.     public function current() 
  5.     { 
  6.         return parent::current() . 'TEST'
  7.     } 
  8.  
  9. foreach(new MyOuterIterator(new ArrayIterator(['b','a','c'])) as $key => $value) { 
  10.     echo "$key->$value".PHP_EOL; 
  11. /* 
  12. 结果: 
  13. 0->bTEST 
  14. 1->aTEST 
  15. 2->cTEST 
  16. */ 

在实际运用中,OuterIterator极其有用:

  1. $db = new PDO('mysql:host=localhost;dbname=test''root''mckee'); 
  2. $db->query('set names utf8'); 
  3. $pdoStatement = $db->query('SELECT * FROM test1', PDO::FETCH_ASSOC); 
  4. $iterator = new IteratorIterator($pdoStatement); 
  5. $tenRecordArray = iterator_to_array($iterator); 
  6. print_r($tenRecordArray); 

RecursiveIterator接口:

用于循环迭代多层结构的数据,RecursiveIterator另外提供了两个方法:

RecursiveIterator::getChildren 获取当前元素下子迭代器

RecursiveIterator::hasChildren 判断当前元素下是否有迭代器,代码如下:

  1. class MyRecursiveIterator implements RecursiveIterator 
  2.     private $_data
  3.     private $_position = 0; 
  4.  
  5.     public function __construct(array $data) { 
  6.         $this->_data = $data
  7.     } 
  8.  
  9.     public function valid() { 
  10.         return isset($this->_data[$this->_position]); 
  11.     } 
  12.  
  13.     public function hasChildren() { 
  14.         return is_array($this->_data[$this->_position]); 
  15.     } 
  16.  
  17.     public function next() { 
  18.         $this->_position++; 
  19.     } 
  20.  
  21.     public function current() { 
  22.         return $this->_data[$this->_position]; 
  23.     } 
  24.  
  25.     public function getChildren() { 
  26.         print_r($this->_data[$this->_position]); 
  27.     } 
  28.  
  29.     public function rewind() { 
  30.         $this->_position = 0; 
  31.     } 
  32.  
  33.     public function key() { 
  34.         return $this->_position; 
  35.     } 
  36.  
  37. $arr = array(0, 1=> array(10, 20), 2, 3 => array(1, 2)); 
  38. $mri = new MyRecursiveIterator($arr); 
  39.  
  40. foreach ($mri as $c => $v) { 
  41.     if ($mri->hasChildren()) { 
  42.         echo "$c has children: " .PHP_EOL; 
  43.         $mri->getChildren(); 
  44.     } else { 
  45.         echo "$v" .PHP_EOL; 
  46.     } 
  47.  
  48. /* 

结果:

  1.  
  2. 1 has children: 
  3.  
  4. Array 
  5.     [0] => 10 
  6.     [1] => 20 
  7. 3 has children: 
  8. Array 
  9.     [0] => 1 
  10.     [1] => 2 
  11. */ 

SeekableIterator接口:

通过seek()方法实现可搜索的迭代器,用于搜索某个位置下的元素,代码如下:

  1. class  MySeekableIterator  implements  SeekableIterator  { 
  2.  
  3.     private  $position = 0; 
  4.  
  5.     private  $array  = array
  6.         "first element" , 
  7.         "second element" , 
  8.         "third element" , 
  9.         "fourth element" 
  10.     ); 
  11.  
  12.     public function  seek ( $position ) { 
  13.         if (!isset( $this -> array [ $position ])) { 
  14.             throw new  OutOfBoundsException ( "invalid seek position ( $position )" ); 
  15.         } 
  16.  
  17.        $this -> position  =  $position ; 
  18.     } 
  19.  
  20.     public function  rewind () { 
  21.         $this -> position  =  0 ; 
  22.     } 
  23.  
  24.     public function  current () { 
  25.         return  $this -> array [ $this -> position ]; 
  26.     } 
  27.  
  28.     public function  key () { 
  29.         return  $this -> position ; 
  30.     } 
  31.  
  32.     public function  next () { 
  33.         ++ $this -> position ; 
  34.     } 
  35.  
  36.     public function  valid () { 
  37.         return isset( $this -> array [ $this -> position ]); 
  38.     } 
  39.  
  40. try { 
  41.  
  42.     $it  = new  MySeekableIterator ; 
  43.     echo  $it -> current (),  "\n" ; 
  44.  
  45.     $it -> seek ( 2 ); 
  46.     echo  $it -> current (),  "\n" ; 
  47.  
  48.     $it -> seek ( 1 ); 
  49.     echo  $it -> current (),  "\n" ; 
  50.  
  51.     $it -> seek ( 10 ); 
  52.  
  53. } catch ( OutOfBoundsException $e ) { 
  54.     echo  $e -> getMessage (); 
  55. /* 
  56. 结果: 
  57. first element 
  58. third element 
  59. second element 
  60. invalid seek position ( 10 ) 
  61. */ 

SplObserver和SplSubject接口:

SplObserver和SplSubject接口用来实现观察者设计模式,观察者设计模式是指当一个类的状态发生变化时,依赖它的对象都会收到通知并更新。使用场景非常广泛,比如说当一个事件发生后,需要更新多个逻辑操作,传统方式是在事件添加后编写逻辑,这种代码耦合并难以维护,观察者模式可实现低耦合的通知和更新机制。

看看SplObserver和SplSubject的接口结构:

  1. //SplSubject结构 被观察的对象 
  2. interface SplSubject{ 
  3.     public function attach(SplObserver $observer); //添加观察者 
  4.     public function detach(SplObserver $observer); //剔除观察者 
  5.     public function notify(); //通知观察者 
  6.  
  7. //SplObserver结构 代表观察者 
  8. interface SplObserver{ 
  9.     public function update(SplSubject $subject); //更新操作 

看下面一个实现观察者的例子:

  1. class Subject implements SplSubject 
  2.     private $observers = array(); 
  3.  
  4.     public function attach(SplObserver  $observer
  5.     { 
  6.         $this->observers[] = $observer
  7.     } 
  8.  
  9.     public function detach(SplObserver  $observer
  10.     { 
  11.         if($index = array_search($observer$this->observers, true)) { 
  12.             unset($this->observers[$index]); 
  13.         } 
  14.     } 
  15.  
  16.     public function notify() 
  17.     { 
  18.         foreach($this->observers as $observer) { 
  19.             $observer->update($this); 
  20.         } 
  21.     } 
  22.  
  23.  
  24.  
  25. class Observer1 implements  SplObserver 
  26.     public function update(SplSubject  $subject
  27.     { 
  28.         echo "逻辑1代码".PHP_EOL; 
  29.     } 
  30.  
  31. class Observer2 implements  SplObserver 
  32.     public function update(SplSubject  $subject
  33.     { 
  34.         echo "逻辑2代码".PHP_EOL; 
  35.     } 
  36.  
  37.  
  38. $subject = new Subject(); 
  39. $subject->attach(new Observer1()); 
  40. $subject->attach(new Observer2()); 
  41.  
  42. $subject->notify(); 
  43. /* 
  44. 结果: 
  45. 逻辑1代码 
  46. 逻辑2代码 
  47. */

Tags: SPL标准库 Interface

分享到: