萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP SPL標准庫之接口(Interface)詳解

PHP SPL標准庫之接口(Interface)詳解

   這篇文章主要介紹了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()函數計數。

  代碼如下:

  class Mycount implements Countable

  {

  public function count()

  {

  static $count = 0;

  $count++;

  return $count;

  }

  }

  $count = new Mycount();

  $count->count();

  $count->count();

  echo count($count); //3

  echo count($count); //4

  說明:

  調用count()函數時,Mycount::count()方法被調用

  count()函數的第二個參數將不會產生影響

  OuterIterator接口:

  自定義或修改迭代過程。

   代碼如下:

  //IteratorIterator是OuterIterator的一個實現類

  class MyOuterIterator extends IteratorIterator {

  public function current()

  {

  return parent::current() . 'TEST';

  }

  }

  foreach(new MyOuterIterator(new ArrayIterator(['b','a','c'])) as $key => $value) {

  echo "$key->$value".PHP_EOL;

  }

  /*

  結果:

  0->bTEST

  1->aTEST

  2->cTEST

  */

  在實際運用中,OuterIterator極其有用:

   代碼如下:

  $db = new PDO('mysql:host=localhost;dbname=test', 'root', 'mckee');

  $db->query('set names utf8');

  $pdoStatement = $db->query('SELECT * FROM test1', PDO::FETCH_ASSOC);

  $iterator = new IteratorIterator($pdoStatement);

  $tenRecordArray = iterator_to_array($iterator);

  print_r($tenRecordArray);

  RecursiveIterator接口:

  用於循環迭代多層結構的數據,RecursiveIterator另外提供了兩個方法:

  RecursiveIterator::getChildren 獲取當前元素下子迭代器

  RecursiveIterator::hasChildren 判斷當前元素下是否有迭代器

  代碼如下:

  class MyRecursiveIterator implements RecursiveIterator

  {

  private $_data;

  private $_position = 0;

  public function __construct(array $data) {

  $this->_data = $data;

  }

  public function valid() {

  return isset($this->_data[$this->_position]);

  }

  public function hasChildren() {

  return is_array($this->_data[$this->_position]);

  }

  public function next() {

  $this->_position++;

  }

  public function current() {

  return $this->_data[$this->_position];

  }

  public function getChildren() {

  print_r($this->_data[$this->_position]);

  }

  public function rewind() {

  $this->_position = 0;

  }

  public function key() {

  return $this->_position;

  }

  }

  $arr = array(0, 1=> array(10, 20), 2, 3 => array(1, 2));

  $mri = new MyRecursiveIterator($arr);

  foreach ($mri as $c => $v) {

  if ($mri->hasChildren()) {

  echo "$c has children: " .PHP_EOL;

  $mri->getChildren();

  } else {

  echo "$v" .PHP_EOL;

  }

  }

  /*

  結果:

  0

  1 has children:

  Array

  (

  [0] => 10

  [1] => 20

  )

  2

  3 has children:

  Array

  (

  [0] => 1

  [1] => 2

  )

  */

  SeekableIterator接口:

  通過seek()方法實現可搜索的迭代器,用於搜索某個位置下的元素。

   代碼如下:

  class MySeekableIterator implements SeekableIterator {

  private $position = 0;

  private $array = array(

  "first element" ,

  "second element" ,

  "third element" ,

  "fourth element"

  );

  public function seek ( $position ) {

  if (!isset( $this -> array [ $position ])) {

  throw new OutOfBoundsException ( "invalid seek position ( $position )" );

  }

  $this -> position = $position ;

  }

  public function rewind () {

  $this -> position = 0 ;

  }

  public function current () {

  return $this -> array [ $this -> position ];

  }

  public function key () {

  return $this -> position ;

  }

  public function next () {

  ++ $this -> position ;

  }

  public function valid () {

  return isset( $this -> array [ $this -> position ]);

  }

  }

  try {

  $it = new MySeekableIterator ;

  echo $it -> current (), "n" ;

  $it -> seek ( 2 );

  echo $it -> current (), "n" ;

  $it -> seek ( 1 );

  echo $it -> current (), "n" ;

  $it -> seek ( 10 );

  } catch ( OutOfBoundsException $e ) {

  echo $e -> getMessage ();

  }

  /*

  結果:

  first element

  third element

  second element

  invalid seek position ( 10 )

  */

  SplObserver和SplSubject接口:

  SplObserver和SplSubject接口用來實現觀察者設計模式,觀察者設計模式是指當一個類的狀態發生變化時,依賴它的對象都會收到通知並更新。使用場景非常廣泛,比如說當一個事件發生後,需要更新多個邏輯操作,傳統方式是在事件添加後編寫邏輯,這種代碼耦合並難以維護,觀察者模式可實現低耦合的通知和更新機制。

  看看SplObserver和SplSubject的接口結構:

   代碼如下:

  //SplSubject結構 被觀察的對象

  interface SplSubject{

  public function attach(SplObserver $observer); //添加觀察者

  public function detach(SplObserver $observer); //剔除觀察者

  public function notify(); //通知觀察者

  }

  //SplObserver結構 代表觀察者

  interface SplObserver{

  public function update(SplSubject $subject); //更新操作

  }

  看下面一個實現觀察者的例子:

  復制代碼 代碼如下:

  class Subject implements SplSubject

  {

  private $observers = array();

  public function attach(SplObserver $observer)

  {

  $this->observers[] = $observer;

  }

  public function detach(SplObserver $observer)

  {

  if($index = array_search($observer, $this->observers, true)) {

  unset($this->observers[$index]);

  }

  }

  public function notify()

  {

  foreach($this->observers as $observer) {

  $observer->update($this);

  }

  }

  }

  class Observer1 implements SplObserver

  {

  public function update(SplSubject $subject)

  {

  echo "邏輯1代碼".PHP_EOL;

  }

  }

  class Observer2 implements SplObserver

  {

  public function update(SplSubje

copyright © 萬盛學電腦網 all rights reserved