您好,欢迎访问一九零五行业门户网

PHP标准库 (SPL) 笔记

简介 spl是standard php library(php标准库)的缩写。
the standard php library (spl) is a collection of interfaces and classes that are meant to solve common problems.
官网说,spl是用来解决典型问题(common problems)的一组接口与类的集合。
那么,什么是common problems呢?
- 数据结构 解决数据怎么存储问题- 元素遍历 数据怎么查看- 常用方法的统一调用 数组、集合大小 自定义遍历- 类自动加载 spl_autoload_register
包含哪些内容?
数据结构 基础接口 基础函数 迭代器 异常 其它 spl接口 iterator 迭代器接口 spl规定,所有实现了iterator接口的class,都可以用在foreach loop中。iterator接口中包含5个必须实现的方法:
interface iterator extends traversable{ //返回当前元素 public mixed current ( void ); //返回当前元素的键 public scalar key ( void ); //向前移动到下一个元素 public void next ( void ); //返回到迭代器的第一个元素 public void rewind ( void ); //检查当前位置是否有效 public boolean valid ( void );}
arrayaccess 数组式访问接口 实现arrayaccess接口,可以使得object像array那样操作。arrayaccess接口包含四个必须实现的方法:
interface arrayaccess { //检查一个偏移位置是否存在 public mixed offsetexists ( mixed $offset ); //获取一个偏移位置的值 public mixed offsetget( mixed $offset ); //设置一个偏移位置的值 public mixed offsetset ( mixed $offset ); //复位一个偏移位置的值 public mixed offsetunset ( mixed $offset );}
iteratoraggregate 聚合式迭代器接口 假设对象a实现了上面的arrayaccess接口,这时候虽然可以像数组那样操作,却无法使用foreach遍历,除非实现了前面提到的iterator接口。
另一个解决方法是,有时会需要将数据和遍历部分分开,这时就可以实现iteratoraggregate接口。它规定了一个getiterator()方法,返回一个使用iterator接口的object。
iteratoraggregate extends traversable { /* 获取一个外部迭代器 */ abstract public traversable getiterator ( void )}
示例:
property4 = last property; } public function getiterator() { return new arrayiterator($this); }}$obj = new mydata;foreach($obj as $key => $value) { var_dump($key, $value); echo \n;}?>
注意:
虽然都继承自traversable,但这是一个无法在 php 脚本中实现的内部引擎接口。我们直接使用iteratoraggregate 或 iterator 接口来代替它。
recursiveiterator 这个接口用于遍历多层数据,它继承了iterator接口,因而也具有标准的current()、key()、next()、 rewind()和valid()方法。同时,它自己还规定了getchildren()和haschildren()方法。the getchildren() method must return an object that implements recursiveiterator。
seekableiterator seekableiterator接口也是iterator接口的延伸,除了iterator的5个方法以外,还规定了seek()方法,参数是元素的位置,返回该元素。如果该位置不存在,则抛出outofboundsexception。
countable 这个接口规定了一个count()方法,返回结果集的数量。
spl数据结构 数据结构是计算机存储、组织数据的方式。
spl提供了双向链表、堆栈、队列、堆、降序堆、升序堆、优先级队列、定长数组、对象容器。
基本概念
bottom:节点,第一个节点称bottom;
top:最后添加的链表的节点称top;
当前节点(current):链表指针指向的节点称为当前节点;
spldoublylinkedlist 双向链表 spldoublylinkedlist 实现了iterator , arrayaccess , countable接口。
类摘要
spldoublylinkedlist implements iterator , arrayaccess , countable {/* 方法 */public __construct ( void )public void add ( mixed $index , mixed $newval )public mixed bottom ( void )public int count ( void )public mixed current ( void )public int getiteratormode ( void )public bool isempty ( void )public mixed key ( void )public void next ( void )public bool offsetexists ( mixed $index )public mixed offsetget ( mixed $index )public void offsetset ( mixed $index , mixed $newval )public void offsetunset ( mixed $index )public mixed pop ( void )public void prev ( void )public void push ( mixed $value )public void rewind ( void )public string serialize ( void )public void setiteratormode ( int $mode )public mixed shift ( void )public mixed top ( void )public void unserialize ( string $serialized )public void unshift ( mixed $value )public bool valid ( void )}
注意:
spldoublylinkedlist::setiteratormode用来设置链表模式:
迭代方向:
spldoublylinkedlist::it_mode_lifo (stack style)spldoublylinkedlist::it_mode_fifo (queue style)
迭代器行为:
spldoublylinkedlist::it_mode_delete (elements are deleted by the iterator)spldoublylinkedlist::it_mode_keep (elements are traversed by the iterator)
默认模式: spldoublylinkedlist::it_mode_fifo | spldoublylinkedlist::it_mode_keep
当前节点操作:
rewind:将链表的当前指针指向第一个元素
current:链表当前指针,当节点被删除后,会指向空节点
prev:上一个
next:下一个
增加节点操作:
push 在双向链表的结尾处将元素压入
unshift 前置双链表元素,预备值在双链表的开始
删除节点操作:
pop 从双向链表的结尾弹出一个节点,不会改变指针位置
shift从双向链表的开头弹出一个节点,不会改变指针位置
定位操作:
bottom 返回当前双向链表的第一个节点的值,当前指针不变
top返回当前双向链表的最后一个节点的值,当前指针不变
特定节点操作:
offsetexists 理解为key是否存在
offsetget将key节点拿出来
offsetset把数据刷新
offsetunset删除
示例:spldoublylinkedlist.php
push(1);//把新的节点添加到链表的顶部top$obj -> push(2);$obj -> push(3);$obj -> unshift(10);//把新节点添加到链表底部bottomprint_r($obj);$obj ->rewind();//rewind操作用于把节点指针指向bottom所在节点$obj -> prev();//使指针指向上一个节点,靠近bottom方向echo 'next node :'.$obj->current().php_eol;$obj -> next();$obj -> next();echo 'next node :'.$obj->current().php_eol;$obj -> next();if($obj -> current()) echo 'current node valid'.php_eol;else echo 'current node invalid'.php_eol;$obj ->rewind();//如果当前节点是有效节点,valid返回trueif($obj->valid()) echo 'valid list'.php_eol;else echo 'invalid list'.php_eol;print_r($obj);echo 'pop value :'.$obj -> pop().php_eol;print_r($obj);echo 'next node :'.$obj ->current().php_eol;$obj ->next();//1$obj ->next();//2$obj -> pop();//把top位置的节点从链表中删除,并返回,如果current正好指>向top位置,那么调用pop之后current()会失效echo 'next node:'.$obj -> current().php_eol;print_r($obj);$obj ->shift();//把bottom位置的节点从链表中删除,并返回print_r($obj);
splstack 栈 栈(stack)是一种特殊的线性表,因为它只能在线性表的一端进行插入或删除元素(即进栈和出栈)。
栈是一种后进先出(lifo)的数据结构。
splstack 继承自 双向链表 spldoublylinkedlist。
示例:
push(1);$stack->push(2);$stack->push(3);echo 'bottom:'.$stack -> bottom().php_eol;echo top:.$stack->top().php_eol;//堆栈的offset=0,是top所在位置(即栈的末尾)$stack -> offsetset(0, 10);echo top:.$stack->top().'
';//堆栈的rewind和双向链表的rewind相反,堆栈的rewind使得当前指针指向top所在位置,而双向链表调用之后指向bottom所在位置$stack -> rewind();echo 'current:'.$stack->current().'
';$stack ->next();//堆栈的next操作使指针指向靠近bottom位置的下一个节点,而双向链表是靠近top的下一个节点echo 'current:'.$stack ->current().'
';//遍历堆栈$stack -> rewind();while ($stack->valid()) { echo $stack->key().'=>'.$stack->current().php_eol; $stack->next();//不从链表中删除元素}echo '
';echo $stack->pop() .'--';echo $stack->pop() .'--';echo $stack->pop() .'--';
输出:
bottom:1 top:3 top:10current:10current:22=>10 1=>2 0=>1 10--2--1--
splqueue 队列 队列是一种先进先出(fifo)的数据结构。使用队列时插入在一端进行而删除在另一端进行。
splqueue 也是继承自 双向链表 spldoublylinkedlist,并有自己的方法:
/* 方法 */__construct ( void )mixed dequeue ( void )void enqueue ( mixed $value )void setiteratormode ( int $mode )
示例1:
enqueue(1);$queue->enqueue(2);echo $queue->dequeue() .'--';echo $queue->dequeue() .'--';//1--2--
示例2:
enqueue('a');$obj -> enqueue('b');$obj -> enqueue('c');echo 'bottom:'.$obj -> bottom().php_eol;echo 'top:'.$obj -> top();echo '
';//队列里的offset=0是指向bottom位置$obj -> offsetset(0,'a');echo 'bottom:'.$obj -> bottom();echo '
';//队列里的rewind使得指针指向bottom所在位置的节点$obj -> rewind();echo 'current:'.$obj->current();echo '
';while ($obj ->valid()) { echo $obj ->key().'=>'.$obj->current().php_eol; $obj->next();//}echo '
';//dequeue操作从队列中提取bottom位置的节点,并返回,同时从队列里面删除该元素echo 'dequeue obj:'.$obj->dequeue();echo '
';echo 'bottom:'.$obj -> bottom().php_eol;
输出:
bottom:a top:cbottom:acurrent:a0=>a 1=>b 2=>c dequeue obj:abottom:b
splheap 堆 堆(heap)就是为了实现优先队列而设计的一种数据结构,它是通过构造二叉堆(二叉树的一种)实现。
根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。二叉堆还常用于排序(堆排序)。
splheap 是一个抽象类,实现了iterator , countable接口。最大堆(splmaxheap)和最小堆(splminheap)就是继承它实现的。最大堆和最小堆并没有额外的方法。
如皋要使用splheap类,需要实现其抽象方法int compare ( mixed $value1 , mixed $value2 )。
类摘要:
abstract splheap implements iterator , countable { /* 方法 */ public __construct ( void ) abstract protected int compare ( mixed $value1 , mixed $value2 ) public int count ( void ) public mixed current ( void ) public mixed extract ( void ) public void insert ( mixed $value ) public bool isempty ( void ) public mixed key ( void ) public void next ( void ) public void recoverfromcorruption ( void ) public void rewind ( void ) public mixed top ( void ) public bool valid ( void )}
示例:
insert( 4 );$obj->insert( 8 );$obj->insert( 1 );$obj->insert( 0 ); echo $obj->top(); //8echo $obj->count(); //4echo '
'; foreach( $obj as $number ) { echo $number.php_eol;}
输出:
848 4 1 0
splmaxheap 最大堆 最大堆(splmaxheap)继承自抽象类splheap实现的。最大堆并没有额外的方法。
splminheap 最小堆 最小堆(splminxheap)继承自抽象类splheap实现的。最小堆并没有额外的方法。
如下:最小堆(任意节点的优先级不小于它的子节点)
示例:
insert(4);$obj->insert(8);//提取echo $obj->extract(). php_eol;echo $obj->extract();//4 8
splpriorityqueue 优先级队列 优先级队列splpriorityqueue是基于堆实现的。和堆一样,也有int compare ( mixed $priority1 , mixed $priority2 )方法。
splpriorityqueue 实现了iterator , countable 接口。
示例:
$pq = new splpriorityqueue(); $pq->insert('a', 10);$pq->insert('b', 1);$pq->insert('c', 8); echo $pq->count() .php_eol; //3echo $pq->current() . php_eol; //a /** * 设置元素出队模式 * splpriorityqueue::extr_data 仅提取值 * splpriorityqueue::extr_priority 仅提取优先级 * splpriorityqueue::extr_both 提取数组包含值和优先级 */$pq->setextractflags(splpriorityqueue::extr_data); while($pq->valid()) { print_r($pq->current()); //a c b $pq->next();}
splfixedarray 定长数组 splfixedarray 实现了iterator , arrayaccess , countable 接口。
和普通数组不一样,定长数组规定了数组的长度。优势就是比普通的数组处理更快。
1 [1] => 2 [2] => 3 [3] => [4] => )
splobjectstorage 对象容器 splobjectstorage是用来存储一组对象的,特别是当你需要唯一标识对象的时候。该类实现了countable ,iterator ,serializable ,arrayaccess四个接口。可实现统计、迭代、序列化、数组式访问等功能。
示例:
class a { public $i; public function __construct($i) { $this->i = $i; }} $a1 = new a(1);$a2 = new a(2);$a3 = new a(3);$a4 = new a(4); $container = new splobjectstorage(); //splobjectstorage::attach 添加对象到storage中$container->attach($a1);$container->attach($a2);$container->attach($a3); //splobjectstorage::detach 将对象从storage中移除$container->detach($a2); //splobjectstorage::contains用于检查对象是否存在storage中var_dump($container->contains($a1)); //truevar_dump($container->contains($a4)); //false //遍历$container->rewind();while($container->valid()) { var_dump($container->current()); $container->next();}
spl类 spl的内置类 spl除了定义一系列interfaces以外,还提供一系列的内置类,它们对应不同的任务,大大简化了编程。
查看所有的内置类,可以使用下面的代码:
$value) { echo $key.' -> '.$value.'
'; }?>
splfileinfo php spl中提供了splfileinfo和splfileobject两个类来处理文件操作。
splfileinfo用来获取文件详细信息:
$file = new splfileinfo('foo-bar.txt'); print_r(array( 'getatime' => $file->getatime(), //最后访问时间 'getbasename' => $file->getbasename(), //获取无路径的basename 'getctime' => $file->getctime(), //获取inode修改时间 'getextension' => $file->getextension(), //文件扩展名 'getfilename' => $file->getfilename(), //获取文件名 'getgroup' => $file->getgroup(), //获取文件组 'getinode' => $file->getinode(), //获取文件inode 'getlinktarget' => $file->getlinktarget(), //获取文件链接目标文件 'getmtime' => $file->getmtime(), //获取最后修改时间 'getowner' => $file->getowner(), //文件拥有者 'getpath' => $file->getpath(), //不带文件名的文件路径 'getpathinfo' => $file->getpathinfo(), //上级路径的splfileinfo对象 'getpathname' => $file->getpathname(), //全路径 'getperms' => $file->getperms(), //文件权限 'getrealpath' => $file->getrealpath(), //文件绝对路径 'getsize' => $file->getsize(),//文件大小,单位字节 'gettype' => $file->gettype(),//文件类型 file dir link 'isdir' => $file->isdir(), //是否是目录 'isfile' => $file->isfile(), //是否是文件 'islink' => $file->islink(), //是否是快捷链接 'isexecutable' => $file->isexecutable(), //是否可执行 'isreadable' => $file->isreadable(), //是否可读 'iswritable' => $file->iswritable(), //是否可写));
splfileobject splfileobject继承splfileinfo并实现recursiveiterator、 seekableiterator接口 ,用于对文件遍历、查找、操作遍历:
try { foreach(new splfileobject('foo-bar.txt') as $line) { echo $line; }} catch (exception $e) { echo $e->getmessage();}
查找指定行:
try { $file = new splfileobject('foo-bar.txt'); $file->seek(2); echo $file->current();} catch (exception $e) { echo $e->getmessage();}
写入csv文件:
$list = array ( array( 'aaa' , 'bbb' , 'ccc' , 'dddd' ), array( '123' , '456' , '7891' )); $file = new splfileobject ( 'file.csv' , 'w' ); foreach ( $list as $fields ) { $file -> fputcsv ( $fields );}
directoryiterator 该类继承自splfileinfo并实现seekableiterator接口。
这个类用来查看一个目录中的所有文件和子目录:

arrayobject 该类实现了arrayaccess ,countable, iteratoraggregate, serializable接口。
这个类可以将array转化为object。
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() . '
'; }?>
arrayiterator 该类实现了arrayaccess, countable , seekableiterator , serializable 接口。
这个类实际上是对arrayobject类的补充,为后者提供遍历功能。
$value) { echo $key.' => '.$value.'
'; } }catch (exception $e) { echo $e->getmessage(); }?>
参考
1、php: spl - manual
http://php.net/manual/zh/book.spl.php
2、php: 预定义接口 - manual
http://php.net/manual/zh/reserved.interfaces.php
3、php spl笔记 - 阮一峰的网络日志
http://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html
4、php spl标准库之文件操作(splfileinfo和splfileobject) - php点点通
http://www.phpddt.com/php/splfileobject.html
其它类似信息

推荐信息