PHP SPL 学习(一)

  • 话说真正作PHP程序员也将近三年了,感受仍是有老多东西不懂不了解,最近想学习ZF2 边看框架边想弄个博客出来,谁知道ZF框架里面各类设计模式啊,各类高深的东西啊,各类不理解啊。最关键的是它无处不在的SPL的东西啊,虽然知道这东西好久了,但只是只知其一;不知其二,因此决定好好整理整理SPL 的知识。看看手册 ,看看博客,决定整合翻译翻译前人的东西。
  • 原文:http://www.phpro.org/tutorials/Introduction-to-SPL.htm

主要内容:

什么是SPL?php

  通俗点讲SPL就是一套PHP 自带的标准的类与接口的集合,使用它来处理一些平常事务 如遍历文件目录,遍历数组,资源类型数据,效率上讲会快不少。html

咱们可使用程序员

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

来获得全部可使用的标准的 SPL类库:获得结果以下:数据库

Countable -> Countable
DirectoryIterator -> DirectoryIterator
DomainException -> DomainException
EmptyIterator -> EmptyIterator
FilesystemIterator -> FilesystemIterator
FilterIterator -> FilterIterator
GlobIterator -> GlobIterator
InfiniteIterator -> InfiniteIterator
InvalidArgumentException -> InvalidArgumentException
IteratorIterator -> IteratorIterator
LengthException -> LengthException
LimitIterator -> LimitIterator
LogicException -> LogicException
MultipleIterator -> MultipleIterator
NoRewindIterator -> NoRewindIterator
OuterIterator -> OuterIterator
OutOfBoundsException -> OutOfBoundsException
OutOfRangeException -> OutOfRangeException
OverflowException -> OverflowException
ParentIterator -> ParentIterator
RangeException -> RangeException
RecursiveArrayIterator -> RecursiveArrayIterator
RecursiveCachingIterator -> RecursiveCachingIterator
RecursiveCallbackFilterIterator -> RecursiveCallbackFilterIterator
RecursiveDirectoryIterator -> RecursiveDirectoryIterator
RecursiveFilterIterator -> RecursiveFilterIterator
RecursiveIterator -> RecursiveIterator
RecursiveIteratorIterator -> RecursiveIteratorIterator
RecursiveRegexIterator -> RecursiveRegexIterator
RecursiveTreeIterator -> RecursiveTreeIterator
RegexIterator -> RegexIterator
RuntimeException -> RuntimeException
SeekableIterator -> SeekableIterator
SplDoublyLinkedList -> SplDoublyLinkedList
SplFileInfo -> SplFileInfo
SplFileObject -> SplFileObject
SplFixedArray -> SplFixedArray
SplHeap -> SplHeap
SplMinHeap -> SplMinHeap
SplMaxHeap -> SplMaxHeap
SplObjectStorage -> SplObjectStorage
SplObserver -> SplObserver
SplPriorityQueue -> SplPriorityQueue
SplQueue -> SplQueue
SplStack -> SplStack
SplSubject -> SplSubject
SplTempFileObject -> SplTempFileObject
UnderflowException -> UnderflowException
UnexpectedValueException -> UnexpectedValueException

 

什么是Iterators(迭代器)?设计模式

   Iterator是专门用来遍历特定的数据集的,例如数组,文件目录结果,或者数据库查询出的结果集等等。这个描述其实不是十分的精确,具体信息后面会使用例子再讲解。Iterator也分为不少种,例如Array Iterator,Directory Iterator等等,咱们会先用DirectoryIterator 来了解它,可是在此以前有一点须要先明确,那就是不管哪一种的数据结构集 ,他们均可以经过标准的接口来访问,也就是说访问他们数据内容的方法都是一致的,这个但是PHP一个大大的进步哇~数组

将回调函数做用于Iterator上数据结构

 由于Iterator是只读的,因此回调函数不能直接做用于其值上,可是这并不影响Iterator使用回调函数,下面的例子使用了一个简单的数组来讲明这一点:app

<?php
    function addCaps( Iterator $it )
    {
        echo ucfirst( $it->current() ) . '<br />';
        return true;
    }

    /*** an array of aussies ***/
    $array = array( 'dingo', 'wombat', 'wallaby' );

    try
    {
        $it = new ArrayIterator( $array );
        iterator_apply( $it, 'addCaps', array($it) );//为迭代器中每一个元素调用一个用户自定义函数:iterator_apply( Traversable  , callback  [, array  ] )$iterator$function$args

    }
    catch(Exception $e)
    {
        /*** echo the error message ***/
        echo $e->getMessage();
    }
?>

 上面的例子中须要注意的是方法addCaps必须返回true,iterator_apply函数才会继续向下遍历执行,不然只会执行第一个元素就中止了。最终结果以下:框架

Dingo
Wombat
Wallaby

扩展DirectoryIterator:koa

<?php
    /*** class definition to extend Directory Iterator class ***/
    class DirectoryReader extends DirectoryIterator
    {
        // constructor.. duh!
        function __construct($path)
        {
            /*** pass the $path off to the parent class constructor ***/
            parent::__construct($path);
        }

        /*** return the current filename ***/
        function current()
        {
            return parent::getFileName();
        }

        /*** members are only valid if they are a directory ***/
        function valid()
        {
            if(parent::valid())
            {
                if (!parent::isDir())
                {
                    parent::next();
                    return $this->valid();
                }
            return TRUE;
            }
            return FALSE;
        }

    } // end class

    try
    {
        /*** a new iterator object ***/
        $it = new DirectoryReader('./');
        /*** loop over the object if valid ***/
        while($it->valid())
        {
            /*** echo the current object member ***/
            echo $it->current().'<br />';
            /*** advance the internal pointer ***/
            $it->next();
        }
    }
    catch(Exception $e)
    {
        echo 'No files Found!<br />';
    }

?>

  上面的例子给咱们展现了如何重载Iterator里的方法来减小代码中的逻辑部分,这给重复的且灵活的使用类提供了很好了机会,所以减小了用户代码并加快了开发效率,另外使用Exception告诉咱们能够很方便的捕获错误而且处理它们。咱们还可使用isfile()方法来替代isDir()以只展现出文件,能够作的事情是无穷尽的。

  让咱们来看看在上面的例子中咱们都作了些什么。首先咱们建立了一个类继承了内部的DirectoryIterator,在构造函数类咱们传递了 目录$path,而后调用了父类中的构造函数,而且传递了$path.

  $valid方法检查了文件是否合法,这个是基于父类中的valid()方法,检查当前Iterator是否有值,而后检查当前Iterator是不是目录,若是不是目录就调用$parant::next() 检查下一个值,咱们可使用filterIterator 来达到一样的目的,可是这个后面再讲。

ArrayObject

  Arrayobject容许遍历数组内部结构而且建立ArrayIterator的实例,像DirectoryIterator同样,咱们能够经过下面的代码片断看到ArrayObject的内部方法:

<?php
foreach(get_class_methods(new ArrayObject()) as $key=>$method)
{
echo $key.' -> '.$method.'<br />';
}
?>
内部方法以下:
0 -> __construct
1 -> offsetExists
2 -> offsetGet
3 -> offsetSet
4 -> offsetUnset
5 -> append
6 -> getArrayCopy
7 -> count
8 -> getFlags
9 -> setFlags
10 -> asort
11 -> ksort
12 -> uasort
13 -> uksort
14 -> natsort
15 -> natcasesort
16 -> getIterator
17 -> exchangeArray
18 -> setIteratorClass
19 -> getIteratorClass

咱们将会经过多种方式来展示ArrayIterator,先来一个简单点的:

<?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(); $iterator->valid();$iterator->next())
    {
    /*** output the key and current array value ***/
    echo $iterator->key() . ' => ' . $iterator->current() . '<br />';
    }
?>

上面的例子中咱们使用ArrayIterator遍历了数组的内部结构,咱们也可使用foreach来遍历上面的数组,那样的话getInstance()方法就会被隐式的调用,key()和current()方法也属于ArrayIterator 实例,从上面的代码中咱们获得了下面的结果:

    0 => koala
    1 => kangaroo
    2 => wombat
    3 => wallaby
    4 => emu
    5 => kiwi
    6 => kookaburra
    7 => platypus

  通过了上面,咱们如今应该能够去荡荡秋千了吧。为了简单起见,咱们仍是用上面的那个例子来讲明如何添加或者删除一个值经过iterator,值得注意的是ArrayObject::getIterator将会返回一个原始的Iterator实例给咱们。只有getIterator()方法是动态调用的

相关文章
相关标签/搜索