ホームページ  >  記事  >  バックエンド開発  >  PHP 高度なプログラミング SPL

PHP 高度なプログラミング SPL

WBOY
WBOYオリジナル
2016-06-23 13:57:00853ブラウズ

最近はPHP言語のSPLを勉強しています。

これは、PHP の高度なコンテンツに属するはずです。複雑に見えますが、非常に便利なので、長めのメモを作成しました。そうしないと覚えられず、将来使いたいときに最初から学ばなければなりません。

チュートリアルではなく自分用のメモなので、あまり説明せずに簡単に書いています。ただし、熟練した PHP5 プログラマーであれば、次の内容を理解して役立つはずだと思います。それを除けば、オンラインで SPL を中国語で詳しく紹介するものはまったくありません。

================

PHP SPL ノート

目次

第 1 部の概要

1. SPL とは何ですか?

2. イテレーターとは何ですか?

パート 2 SPL インターフェイス

3. Iterator インターフェイス

4. ArrayAccess インターフェイス

5. IteratorAggregate インターフェイス

6. RecursiveIterator インターフェイス

7. SeekableIterator インターフェイス

8. 可算インターフェイス

パート 3 SPL クラス

9. SPL の組み込みクラス

10. DirectoryIterator クラス

11. ArrayObject クラス

12. ArrayIterator クラス

13. RecursiveArrayIterator クラスと RecursiveIteratorIterator クラス

14. FilterIterator クラス

15. SimpleXMLIterator クラス

16 . CachingIteratorクラス

17. LimitIteratorクラス

18. SplFileObjectクラス

その1 はじめに

1. SPLとは?

SPL は Standard PHP Library の略です。

公式の定義によれば、「標準的な問題を解決することを目的としたインターフェイスとクラスのコレクション」です。ただし、現在の使用では、SPL はオブジェクトが配列の動作を模倣できるようにするインターフェイスおよびクラスとして見なされています。

2. イテレーターとは何ですか?

SPL の中核となる概念はイテレーターです。これは、「デザイン パターン」という本の定義によれば、イテレータの機能は「ある集合構造を横断し、その構造の実装に関する仮定を抽象化すること」であるとウィキペディアには書かれています。 , 「イテレータとは、プログラマがその特定の実装に関係なく、コレクションのすべての要素をトラバースできるようにするオブジェクトです。」....「イテレータ パターンは、イテレータを使用してコレクションの要素にアクセスする設計パターンです。

平たく言えば、Iterator を使用すると、データベースの結果セット、同じディレクトリ内のファイル セット、行のコレクションなど、さまざまなデータ構造に統一された操作インターフェイスを持たせることができます。テキストの。

通常の状況に従って MySQL 結果セットをトラバースする場合、プログラムは次のように記述する必要があります:

// Fetch the "aggregate structure"$result = mysql_query("SELECT * FROM users");// Iterate over the structurewhile ( $row = mysql_fetch_array($result) ) {   // do stuff with the row here}

ディレクトリの内容を読み取るには、次のように記述する必要があります:

// Fetch the "aggregate structure"$dh = opendir('/home/harryf/files');// Iterate over the structurewhile ( $file = readdir($dh) ) {   // do stuff with the file here}

Toテキスト ファイルの内容を読み取るには、次のように記述する必要があります:

// Fetch the "aggregate structure"$fh = fopen("/home/hfuecks/files/results.txt", "r");// Iterate over the structurewhile (!feof($fh)) {   $line = fgets($fh);   // do stuff with the line here}

上記の 3 つのコードは異なるリソースを処理しますが、それらの機能は結果セットを走査する (内容をループする) ことであるため、基本的な考え方はIterator はこれら 3 つの異なる操作を組み合わせることにより、操作が統一され、同じコマンド インターフェイスを使用して異なるリソースを処理します。

パート 2 SPL インターフェイス

3. Iterator インターフェイス

SPL は、Iterator インターフェイスを展開するすべてのクラスが foreach ループで使用できることを規定しています。 Iterator インターフェースには、デプロイする必要がある 5 つのメソッドが含まれています:

    * current()      This method returns the current index's value. You are solely      responsible for tracking what the current index is as the      interface does not do this for you.    * key()      This method returns the value of the current index's key. For       foreach loops this is extremely important so that the key       value can be populated.    * next()      This method moves the internal index forward one entry.    * rewind()      This method should reset the internal index to the first element.    * valid()      This method should return true or false if there is a current       element. It is called after rewind() or next().

以下は、Iterator インターフェースをデプロイするクラスの例です:

/*** An iterator for native PHP arrays, re-inventing the wheel** Notice the "implements Iterator" - important!*/class ArrayReloaded implements Iterator {   /**   * A native PHP array to iterate over   */ private $array = array();   /**   * A switch to keep track of the end of the array   */ private $valid = FALSE;   /**   * Constructor   * @param array native PHP array to iterate over   */ function __construct($array) {   $this->array = $array; }   /**   * Return the array "pointer" to the first element   * PHP's reset() returns false if the array has no elements   */ function rewind(){   $this->valid = (FALSE !== reset($this->array)); }   /**   * Return the current array element   */ function current(){   return current($this->array); }   /**   * Return the key of the current array element   */ function key(){   return key($this->array); }   /**   * Move forward by one   * PHP's next() returns false if there are no more elements   */ function next(){   $this->valid = (FALSE !== next($this->array)); }   /**   * Is the current element valid?   */ function valid(){   return $this->valid; }}

使用方法は次のとおりです:

// Create iterator object$colors = new ArrayReloaded(array ('red','green','blue',));// Iterate away!foreach ( $colors as $color ) { echo $color."<br>";}

foreach ループ () メソッドでキーを使用します:

// Display the keys as wellforeach ( $colors as $key => $color ) { echo "$key: $color<br>";}

foreach ループに加えて、while ループも使用できます。

// Reset the iterator - foreach does this automatically$colors->rewind();// Loop while validwhile ( $colors->valid() ) {   echo $colors->key().": ".$colors->current()."";   $colors->next();}

テストによると、while ループは foreach ループよりわずかに高速です。実行時の中間呼び出しが 1 つ少なくなるためです。

4. ArrayAccess インターフェイス

ArrayAccess インターフェイスを導入すると、オブジェクトを配列のように動作させることができます。 ArrayAccess インターフェイスには、展開する必要がある 4 つのメソッドが含まれています:

    * offsetExists($offset)      This method is used to tell php if there is a value      for the key specified by offset. It should return       true or false.    * offsetGet($offset)      This method is used to return the value specified       by the key offset.    * offsetSet($offset, $value)      This method is used to set a value within the object,       you can throw an exception from this function for a       read-only collection.    * offsetUnset($offset)      This method is used when a value is removed from       an array either through unset() or assigning the key       a value of null. In the case of numerical arrays, this       offset should not be deleted and the array should       not be reindexed unless that is specifically the       behavior you want.

以下は、ArrayAccess インターフェイスを展開する例です:

/*** A class that can be used like an array*/class Article implements ArrayAccess { public $title; public $author; public $category;   function __construct($title,$author,$category) {   $this->title = $title;   $this->author = $author;   $this->category = $category; } /** * Defined by ArrayAccess interface * Set a value given it's key e.g. $A['title'] = 'foo'; * @param mixed key (string or integer) * @param mixed value * @return void */ function offsetSet($key, $value) {   if ( array_key_exists($key,get_object_vars($this)) ) {     $this->{$key} = $value;   } } /** * Defined by ArrayAccess interface * Return a value given it's key e.g. echo $A['title']; * @param mixed key (string or integer) * @return mixed value */ function offsetGet($key) {   if ( array_key_exists($key,get_object_vars($this)) ) {     return $this->{$key};   } } /** * Defined by ArrayAccess interface * Unset a value by it's key e.g. unset($A['title']); * @param mixed key (string or integer) * @return void */ function offsetUnset($key) {   if ( array_key_exists($key,get_object_vars($this)) ) {     unset($this->{$key});   } } /** * Defined by ArrayAccess interface * Check value exists, given it's key e.g. isset($A['title']) * @param mixed key (string or integer) * @return boolean */ function offsetExists($offset) {   return array_key_exists($offset,get_object_vars($this)); }}

使用方法は次のとおりです:

// Create the object$A = new Article('SPL Rocks','Joe Bloggs', 'PHP');// Check what it looks likeecho 'Initial State:<div>';print_r($A);echo '</div>';// Change the title using array syntax$A['title'] = 'SPL _really_ rocks';// Try setting a non existent property (ignored)$A['not found'] = 1;// Unset the author fieldunset($A['author']);// Check what it looks like againecho 'Final State:<div>';print_r($A);echo '</div>';

実行結果は次のとおりです。 :

Initial State:Article Object(   [title] => SPL Rocks   [author] => Joe Bloggs   [category] => PHP)Final State:Article Object(   [title] => SPL _really_ rocks   [category] => PHP)

がわかります。 $A はオブジェクトですが、配列のように操作できます。

データを読み取るときにプログラム内にロジックを追加することもできます:

function offsetGet($key) {   if ( array_key_exists($key,get_object_vars($this)) ) {     return strtolower($this->{$key});   } }

5. IteratorAggregate インターフェイス

ただし、$A は配列のように操作できますが、前の前提がデプロイされていない限り、foreach トラバーサルは使用できません。イテレータインターフェイス。

別の解決策は、場合によってはデータ部分とトラバーサル部分を分離する必要がある場合に、IteratorAggregate インターフェイスをデプロイすることです。 Iterator インターフェイスを使用してオブジェクトを返す getIterator() メソッドを指定します。

还是以上一节的Article类为例:

class Article implements ArrayAccess, IteratorAggregate {/** * Defined by IteratorAggregate interface * Returns an iterator for for this object, for use with foreach * @return ArrayIterator */ function getIterator() {   return new ArrayIterator($this); }

使用方法如下:

$A = new Article('SPL Rocks','Joe Bloggs', 'PHP');// Loop (getIterator will be called automatically)echo 'Looping with foreach:<div>';foreach ( $A as $field => $value ) { echo "$field : $value<br>";}echo '</div>';// Get the size of the iterator (see how many properties are left)echo "Object has ".sizeof($A->getIterator())." elements";

显示结果如下:

Looping with foreach:title : SPL Rocksauthor : Joe Bloggscategory : PHPObject has 3 elements

6. RecursiveIterator界面

这个界面用于遍历多层数据,它继承了Iterator界面,因而也具有标准的current()、key()、next()、 rewind()和valid()方法。同时,它自己还规定了getChildren()和hasChildren()方法。The getChildren() method must return an object that implements RecursiveIterator.

7. SeekableIterator界面

SeekableIterator界面也是Iterator界面的延伸,除了Iterator的5个方法以外,还规定了seek()方法,参数是元素的位置,返回该元素。如果该位置不存在,则抛出OutOfBoundsException。

下面是一个是实例:

<?phpclass PartyMemberIterator implements SeekableIterator{    public function __construct(PartyMember $member)    {        // Store $member locally for iteration    }    public function seek($index)    {        $this->rewind();        $position = 0;        while ($position < $index && $this->valid()) {            $this->next();            $position++;        }        if (!$this->valid()) {            throw new OutOfBoundsException('Invalid position');        }    }    // Implement current(), key(), next(), rewind()    // and valid() to iterate over data in $member}?>

8. Countable界面

这个界面规定了一个count()方法,返回结果集的数量。

第三部分 SPL Classes

9. SPL的内置类

SPL除了定义一系列Interfaces以外,还提供一系列的内置类,它们对应不同的任务,大大简化了编程。

查看所有的内置类,可以使用下面的代码:

<?php// a simple foreach() to traverse the SPL class namesforeach(spl_classes() as $key=>$value)        {        echo $key.' -&gt; '.$value.'<br />';        }?>

10. DirectoryIterator类

这个类用来查看一个目录中的所有文件和子目录:

<?phptry{  /*** class create new DirectoryIterator Object ***/    foreach ( new DirectoryIterator('./') as $Item )        {        echo $Item.'<br />';        }    }/*** if an exception is thrown, catch it here ***/catch(Exception $e){    echo 'No files Found!<br />';}?>

查看文件的详细信息:

<table><?phpforeach(new DirectoryIterator('./' ) as $file )    {    if( $file->getFilename()  == 'foo.txt' )        {        echo '<tr><td>getFilename()</td><td> '; var_dump($file->getFilename()); echo '</td></tr>';    echo '<tr><td>getBasename()</td><td> '; var_dump($file->getBasename()); echo '</td></tr>';        echo '<tr><td>isDot()</td><td> '; var_dump($file->isDot()); echo '</td></tr>';        echo '<tr><td>__toString()</td><td> '; var_dump($file->__toString()); echo '</td></tr>';        echo '<tr><td>getPath()</td><td> '; var_dump($file->getPath()); echo '</td></tr>';        echo '<tr><td>getPathname()</td><td> '; var_dump($file->getPathname()); echo '</td></tr>';        echo '<tr><td>getPerms()</td><td> '; var_dump($file->getPerms()); echo '</td></tr>';        echo '<tr><td>getInode()</td><td> '; var_dump($file->getInode()); echo '</td></tr>';        echo '<tr><td>getSize()</td><td> '; var_dump($file->getSize()); echo '</td></tr>';        echo '<tr><td>getOwner()</td><td> '; var_dump($file->getOwner()); echo '</td></tr>';        echo '<tr><td>$file->getGroup()</td><td> '; var_dump($file->getGroup()); echo '</td></tr>';        echo '<tr><td>getATime()</td><td> '; var_dump($file->getATime()); echo '</td></tr>';        echo '<tr><td>getMTime()</td><td> '; var_dump($file->getMTime()); echo '</td></tr>';        echo '<tr><td>getCTime()</td><td> '; var_dump($file->getCTime()); echo '</td></tr>';        echo '<tr><td>getType()</td><td> '; var_dump($file->getType()); echo '</td></tr>';        echo '<tr><td>isWritable()</td><td> '; var_dump($file->isWritable()); echo '</td></tr>';        echo '<tr><td>isReadable()</td><td> '; var_dump($file->isReadable()); echo '</td></tr>';        echo '<tr><td>isExecutable(</td><td> '; var_dump($file->isExecutable()); echo '</td></tr>';        echo '<tr><td>isFile()</td><td> '; var_dump($file->isFile()); echo '</td></tr>';        echo '<tr><td>isDir()</td><td> '; var_dump($file->isDir()); echo '</td></tr>';        echo '<tr><td>isLink()</td><td> '; var_dump($file->isLink()); echo '</td></tr>';        echo '<tr><td>getFileInfo()</td><td> '; var_dump($file->getFileInfo()); echo '</td></tr>';        echo '<tr><td>getPathInfo()</td><td> '; var_dump($file->getPathInfo()); echo '</td></tr>';        echo '<tr><td>openFile()</td><td> '; var_dump($file->openFile()); echo '</td></tr>';        echo '<tr><td>setFileClass()</td><td> '; var_dump($file->setFileClass()); echo '</td></tr>';        echo '<tr><td>setInfoClass()</td><td> '; var_dump($file->setInfoClass()); echo '</td></tr>';        }}?></table>

除了foreach循环外,还可以使用while循环:

<?php/*** create a new iterator object ***/$it = new DirectoryIterator('./');/*** loop directly over the object ***/while($it->valid())    {    echo $it->key().' -- '.$it->current().'<br />';    /*** move to the next iteration ***/    $it->next();    }?>

如果要过滤所有子目录,可以在valid()方法中过滤:

<?php/*** create a new iterator object ***/$it = new DirectoryIterator('./');/*** loop directly over the object ***/while($it->valid())        {        /*** check if value is a directory ***/        if($it->isDir())                {                /*** echo the key and current value ***/                echo $it->key().' -- '.$it->current().'<br />';                }        /*** move to the next iteration ***/        $it->next();        }?>

11. ArrayObject类

这个类可以将Array转化为object。

<?php/*** a simple array ***/$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');/*** create the array object ***/$arrayObj = new ArrayObject($array);/*** iterate over the array ***/for($iterator = $arrayObj->getIterator();   /*** check if valid ***/   $iterator->valid();   /*** move to the next array member ***/   $iterator->next())    {    /*** output the key and current array value ***/    echo $iterator->key() . ' => ' . $iterator->current() . '<br />';    }?>

增加一个元素:

$arrayObj->append('dingo');

对元素排序:

$arrayObj->natcasesort();

显示元素的数量:

echo $arrayObj->count();

删除一个元素:

$arrayObj->offsetUnset(5);

某一个元素是否存在:

 if ($arrayObj->offsetExists(3))    {       echo 'Offset Exists<br />';    }

更改某个位置的元素值:

 $arrayObj->offsetSet(5, "galah");

显示某个位置的元素值:

echo $arrayObj->offsetGet(4);
12. ArrayIterator类

这个类实际上是对ArrayObject类的补充,为后者提供遍历功能。

示例如下:

<?php/*** a simple array ***/$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');try {    $object = new ArrayIterator($array);    foreach($object as $key=>$value)        {        echo $key.' => '.$value.'<br />';        }    }catch (Exception $e)    {    echo $e->getMessage();    }?>

ArrayIterator类也支持offset类方法和count()方法:

<ul><?php/*** a simple array ***/$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');try {    $object = new ArrayIterator($array);    /*** check for the existence of the offset 2 ***/    if($object->offSetExists(2))    {    /*** set the offset of 2 to a new value ***/    $object->offSetSet(2, 'Goanna');    }   /*** unset the kiwi ***/   foreach($object as $key=>$value)        {        /*** check the value of the key ***/        if($object->offSetGet($key) === 'kiwi')            {            /*** unset the current key ***/            $object->offSetUnset($key);            }        echo '<li>'.$key.' - '.$value.'</li>'."\n";        }    }catch (Exception $e)    {    echo $e->getMessage();    }?></ul>

13. RecursiveArrayIterator类和RecursiveIteratorIterator类

ArrayIterator类和ArrayObject类,只支持遍历一维数组。如果要遍历多维数组,必须先用RecursiveIteratorIterator生成一个Iterator,然后再对这个Iterator使用RecursiveIteratorIterator。

<?php$array = array(    array('name'=>'butch', 'sex'=>'m', 'breed'=>'boxer'),    array('name'=>'fido', 'sex'=>'m', 'breed'=>'doberman'),    array('name'=>'girly','sex'=>'f', 'breed'=>'poodle'));foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $key=>$value)    {    echo $key.' -- '.$value.'<br />';    }?>

14. FilterIterator类

FilterIterator类可以对元素进行过滤,只要在accept()方法中设置过滤条件就可以了。

示例如下:

<?php/*** a simple array ***/$animals = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'NZ'=>'kiwi', 'kookaburra', 'platypus');class CullingIterator extends FilterIterator{/*** The filteriterator takes  a iterator as param: ***/public function __construct( Iterator $it ){  parent::__construct( $it );}/*** check if key is numeric ***/function accept(){  return is_numeric($this->key());}}/*** end of class ***/$cull = new CullingIterator(new ArrayIterator($animals));foreach($cull as $key=>$value)    {    echo $key.' == '.$value.'<br />';    }?>

下面是另一个返回质数的例子:

<?phpclass PrimeFilter extends FilterIterator{/*** The filteriterator takes  a iterator as param: ***/public function __construct(Iterator $it){  parent::__construct($it);}/*** check if current value is prime ***/function accept(){if($this->current() % 2 != 1)    {    return false;    }$d = 3;$x = sqrt($this->current());while ($this->current() % $d != 0 && $d < $x)    {    $d += 2;    } return (($this->current() % $d == 0 && $this->current() != $d) * 1) == 0 ? true : false;}}/*** end of class ***//*** an array of numbers ***/$numbers = range(212345,212456);/*** create a new FilterIterator object ***/$primes = new primeFilter(new ArrayIterator($numbers));foreach($primes as $value)    {    echo $value.' is prime.<br />';    }?>

15. SimpleXMLIterator类

这个类用来遍历xml文件。

示例如下:

<?php/*** a simple xml tree ***/ $xmlstring = <<<XML<?xml version = "1.0" encoding="UTF-8" standalone="yes"?><document>  <animal>    <category id="26">      <species>Phascolarctidae</species>      <type>koala</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="27">      <species>macropod</species>      <type>kangaroo</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="28">      <species>diprotodon</species>      <type>wombat</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="31">      <species>macropod</species>      <type>wallaby</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="21">      <species>dromaius</species>      <type>emu</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="22">      <species>Apteryx</species>      <type>kiwi</type>      <name>Troy</name>    </category>  </animal>  <animal>    <category id="23">      <species>kingfisher</species>      <type>kookaburra</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="48">      <species>monotremes</species>      <type>platypus</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="4">      <species>arachnid</species>      <type>funnel web</type>      <name>Bruce</name>      <legs>8</legs>    </category>  </animal></document>XML;/*** a new simpleXML iterator object ***/try    {       /*** a new simple xml iterator ***/       $it = new SimpleXMLIterator($xmlstring);       /*** a new limitIterator object ***/       foreach(new RecursiveIteratorIterator($it,1) as $name => $data)          {          echo $name.' -- '.$data.'<br />';          }    }catch(Exception $e)    {    echo $e->getMessage();    }?>

new RecursiveIteratorIterator($it,1)表示显示所有包括父元素在内的子元素。

显示某一个特定的元素值,可以这样写:

<?phptry {    /*** a new simpleXML iterator object ***/    $sxi =  new SimpleXMLIterator($xmlstring);    foreach ( $sxi as $node )        {        foreach($node as $k=>$v)            {            echo $v->species.'<br />';            }        }    }catch(Exception $e)    {    echo $e->getMessage();    }?>

相对应的while循环写法为:

<?phptry {$sxe = simplexml_load_string($xmlstring, 'SimpleXMLIterator');for ($sxe->rewind(); $sxe->valid(); $sxe->next())    {    if($sxe->hasChildren())        {        foreach($sxe->getChildren() as $element=>$value)          {          echo $value->species.'<br />';          }        }     }   }catch(Exception $e)   {   echo $e->getMessage();   }?>

最方便的写法,还是使用xpath:

<?phptry {    /*** a new simpleXML iterator object ***/    $sxi =  new SimpleXMLIterator($xmlstring);    /*** set the xpath ***/    $foo = $sxi->xpath('animal/category/species');    /*** iterate over the xpath ***/    foreach ($foo as $k=>$v)        {        echo $v.'<br />';        }    }catch(Exception $e)    {    echo $e->getMessage();    }?>

下面的例子,显示有namespace的情况:

<?php/*** a simple xml tree ***/ $xmlstring = <<<XML<?xml version = "1.0" encoding="UTF-8" standalone="yes"?><document xmlns:spec="http://example.org/animal-species">  <animal>    <category id="26">      <species>Phascolarctidae</species>      <spec:name>Speed Hump</spec:name>      <type>koala</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="27">      <species>macropod</species>      <spec:name>Boonga</spec:name>      <type>kangaroo</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="28">      <species>diprotodon</species>      <spec:name>pot holer</spec:name>      <type>wombat</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="31">      <species>macropod</species>      <spec:name>Target</spec:name>      <type>wallaby</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="21">      <species>dromaius</species>      <spec:name>Road Runner</spec:name>      <type>emu</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="22">      <species>Apteryx</species>      <spec:name>Football</spec:name>      <type>kiwi</type>      <name>Troy</name>    </category>  </animal>  <animal>    <category id="23">      <species>kingfisher</species>      <spec:name>snaker</spec:name>      <type>kookaburra</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="48">      <species>monotremes</species>      <spec:name>Swamp Rat</spec:name>      <type>platypus</type>      <name>Bruce</name>    </category>  </animal>  <animal>    <category id="4">      <species>arachnid</species>      <spec:name>Killer</spec:name>      <type>funnel web</type>      <name>Bruce</name>      <legs>8</legs>    </category>  </animal></document>XML;/*** a new simpleXML iterator object ***/try {    /*** a new simpleXML iterator object ***/    $sxi =  new SimpleXMLIterator($xmlstring);    $sxi-> registerXPathNamespace('spec', 'http://www.exampe.org/species-title');    /*** set the xpath ***/    $result = $sxi->xpath('//spec:name');    /*** get all declared namespaces ***/   foreach($sxi->getDocNamespaces('animal') as $ns)        {        echo $ns.'<br />';        }    /*** iterate over the xpath ***/    foreach ($result as $k=>$v)        {        echo $v.'<br />';        }    }catch(Exception $e)    {    echo $e->getMessage();    }?>

增加一个节点:

<?php  $xmlstring = <<<XML<?xml version = "1.0" encoding="UTF-8" standalone="yes"?><document>  <animal>koala</animal>  <animal>kangaroo</animal>  <animal>wombat</animal>  <animal>wallaby</animal>  <animal>emu</animal>  <animal>kiwi</animal>  <animal>kookaburra</animal>  <animal>platypus</animal>  <animal>funnel web</animal></document>XML;try {    /*** a new simpleXML iterator object ***/    $sxi =  new SimpleXMLIterator($xmlstring);    /*** add a child ***/    $sxi->addChild('animal', 'Tiger');    /*** a new simpleXML iterator object ***/    $new = new SimpleXmlIterator($sxi->saveXML());    /*** iterate over the new tree ***/    foreach($new as $val)        {        echo $val.'<br />';        }    }catch(Exception $e)    {    echo $e->getMessage();    }?>

增加属性:

<?php $xmlstring =<<<XML<?xml version = "1.0" encoding="UTF-8" standalone="yes"?><document>  <animal>koala</animal>  <animal>kangaroo</animal>  <animal>wombat</animal>  <animal>wallaby</animal>  <animal>emu</animal>  <animal>kiwi</animal>  <animal>kookaburra</animal>  <animal>platypus</animal>  <animal>funnel web</animal></document>XML;try {    /*** a new simpleXML iterator object ***/    $sxi =  new SimpleXMLIterator($xmlstring);    /*** add an attribute with a namespace ***/    $sxi->addAttribute('id:att1', 'good things', 'urn::test-foo');    /*** add an attribute without a  namespace ***/    $sxi->addAttribute('att2', 'no-ns');    echo htmlentities($sxi->saveXML());    }catch(Exception $e)    {    echo $e->getMessage();    }?>

16. CachingIterator类

这个类有一个hasNext()方法,用来判断是否还有下一个元素。

示例如下:

<?php/*** a simple array ***/$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');try {    /*** create a new object ***/    $object = new CachingIterator(new ArrayIterator($array));    foreach($object as $value)        {        echo $value;        if($object->hasNext())            {            echo ',';            }        }    }catch (Exception $e)    {    echo $e->getMessage();    }?>

17. LimitIterator类

这个类用来限定返回结果集的数量和位置,必须提供offset和limit两个参数,与SQL命令中limit语句类似。

示例如下:

<?php/*** the offset value ***/$offset = 3;/*** the limit of records to show ***/$limit = 2;$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');$it = new LimitIterator(new ArrayIterator($array), $offset, $limit);foreach($it as $k=>$v)    {    echo $it->getPosition().'<br />';    }?>

另一个例子是:

<?php/*** a simple array ***/$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');$it = new LimitIterator(new ArrayIterator($array));try    {    $it->seek(5);    echo $it->current();    }catch(OutOfBoundsException $e)    {    echo $e->getMessage() . "<br />";    }?>

18. SplFileObject类

这个类用来对文本文件进行遍历。

示例如下:

<?phptry{    // iterate directly over the object    foreach( new SplFileObject(&quot;/usr/local/apache/logs/access_log&quot;) as $line)    // and echo each line of the file    echo $line.'<br />';}catch (Exception $e)    {    echo $e->getMessage();    }?>

返回文本文件的第三行,可以这样写:

<?phptry{    $file = new SplFileObject("/usr/local/apache/logs/access_log");    $file->seek(3);    echo $file->current();        }catch (Exception $e)    {    echo $e->getMessage();    }?>

[参考文献]

1. Introduction to Standard PHP Library (SPL), By Kevin Waterson

2. Introducing PHP 5's Standard Library, By Harry Fuecks

3. The Standard PHP Library (SPL), By Ben Ramsey

4. SPL - Standard PHP Library Documentation

(終了)

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。