php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)

一、总结

直接看代码实例,特别方便易懂

thinkphp控制器利眠宁不支持(说明差文件引入么),但是view里面支持(也就是原生php支持),

二、php spl标准库简介

SPL简介

SPL是用于解决典型问题(standard problems)的一组接口与类的集合。

SPL是Standard PHP Library(PHP标准库)的缩写。
目前在使用中,SPL更多地被看作是一种使object(对象)模仿array(数组)行为的interfaces和classes

SPL的常用数据结构

什么是数据结构?

  • 数据结构是计算机存储、组织数据的方式。是指相互之间存在的一种或多种特定关系的数据元素的集合。
  • 解决的是软件开发过程中的数据如何存储的问题

数据结构之双向链表

双向链表简介

  • Bottom:节点,第一个节点称Bottom
  • Top:最后添加的链表的节点称Top
  • 链表指针:可以指向任意节点;
  • 当前节点:链表指针指向的节点称为当前节点;
  • 节点细化成节点名称,和节点数据;

数据结构之SplDoublyLinkedList

SplDoublyLinkedList类提供了一个双向链表的主要功能
当前节点操作:

  • rewind:将链表的当前指针指向第一个元素
  • current:链表当前指针,当节点被删除后,会指向空节点
  • prev:上一个
  • next:下一个

增加节点操作:

  • push 在双向链表的结尾处将元素压入
  • unshift 前置双链表元素,预备值在双链表的开始

删除节点操作:

  • pop 从双向链表的结尾弹出一个节点,不会改变指针位置
  • shift从双向链表的开头弹出一个节点,不会改变指针位置

定位操作:

  • bottom 返回当前双向链表的第一个节点的值,当前指针不变
  • top返回当前双向链表的最后一个节点的值,当前指针不变

特定节点操作:

  • offsetExists 理解为key是否存在
  • offsetGet将key节点拿出来
  • offsetSet把数据刷新
  • offsetUnset删除

代码实现双向链表
SplDoublyLinkedList.php

<?php
/**
*SplDoublyLinkedList 类学习
*/
$obj = new SplDoublyLinkedList();
$obj -> push(1);//把新的节点添加到链表的顶部top
$obj -> push(2);
$obj -> push(3);
$obj -> unshift(10);//把新节点添加到链表底部bottom
print_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返回true
if($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);

数据结构之堆栈

堆栈简介

先进后出 first in last out

继承自SplDoublyLinkedList类的SplStack类
操作:

  • push压入堆栈
  • pop弹出堆栈

    代码示例

<?php
$stack = new SplStack(); $stack -> push('a');
$stack -> push('b');
$stack -> push('c');//入栈 print_r($stack);
echo 'bottom:'.$stack -> bottom().PHP_EOL;
echo "top:".$stack->top().PHP_EOL;
//堆栈的offset=0,是TOP所在位置(即栈的末尾),offset=1是top位置节点靠近bottom位置的相连节点
$stack -> offsetSet(0,'C'); print_r($stack); //双向链表的rewind和堆栈的rewind,相反,堆栈的rewind使得当前指针指向top所在位置,而双向链表调用之后指向bottom所在位置
$stack -> rewind(); echo 'current:'.$stack->current().PHP_EOL; $stack ->next();//堆栈的next操作使指针指向靠近bottom位置的下一个节点,而双向链表是靠近top的下一个节点
echo 'current:'.$stack ->current().PHP_EOL; //遍历堆栈 $stack -> rewind();
while ($stack->valid()) {
echo $stack->key().'=>'.$stack->current().PHP_EOL;
$stack->next();//不从链表中删除元素
} //删除堆栈数据
$popObj = $stack -> pop();//弹出最后一个元素,并删除该节点
echo 'pop object:'.$popObj.PHP_EOL;
print_r($stack);

数据结构之队列

  • 队列和堆栈刚好相反,最先进入队列的元素会最新走出队列
  • 继承自SplDoublyLinkedList类的SplQueue类

    代码示例

<?php

$obj = new SplQueue();

$obj -> enqueue('a');
$obj -> enqueue('b');
$obj -> enqueue('c');
print_r($obj); echo 'bottom:'.$obj -> bottom().PHP_EOL; echo 'top:'.$obj -> top().PHP_EOL;
//队列里的offset=0是指向bottom位置,offset=1是top方向相连的节点
$obj -> offsetSet(0,'A');
valid()
print_r($obj);
//队列里的rewind使得指针指向bottom所在位置的节点
$obj -> rewind();
echo 'current:'.$obj->current().PHP_EOL; while ($obj ->valid()) { echo $obj ->key().'=>'.$obj->current().PHP_EOL;
$obj->next();//
}
//dequeue操作从队列中提取bottom位置的节点,并返回,同时从队列里面删除该元素
echo 'dequeue obj:'.$obj->dequeue().PHP_EOL; print_r($obj);

SPL的常用迭代器

迭代器概述

ArrayIterator

  • 熟悉使用seek()跳过元素
  • 熟悉使用asort,ksort排序
<?php

$fruits =  array(
'apple'=>'apple value',
'orange' => 'orange value',
'grape' => 'grape value',
'pear' => 'pear value'
); print_r($fruits);//打印数组
echo '*******user fruits directly'.PHP_EOL;
foreach ($fruits as $key => $value) {
# code...
echo $key.':'.$value.PHP_EOL;
}
//使用ArrayIterator遍历数组
$obj = new ArrayObject($fruits);
$it = $obj -> getIterator();//获得迭代器
echo '*******user ArrayIterator in for'.PHP_EOL;
foreach ($it as $key => $value) {
# code...
echo $key.':'.$value.PHP_EOL;
}
echo '*******user ArrayIterator in while'.PHP_EOL;
$it -> rewind();//调用current之前一定要先调用rewind
while ($it -> valid()) {
echo $it -> key().':'.$it->current().PHP_EOL;
$it -> next();//这个必须加上,要不然死循环
} //跳过某些元素进行打印
echo '*******user seek before while'.PHP_EOL;
$it ->rewind();
if($it->valid()){
$it->seek(1);//跳过第一个元素
while ($it -> valid()) {
echo $it -> key().':'.$it->current().PHP_EOL;
$it -> next();//这个必须加上,要不然死循环
}
}
echo '*******user ksort'.PHP_EOL;
$it->ksort();//对key字典排序
foreach ($it as $key => $value) {
# code...
echo $key.':'.$value.PHP_EOL;
}
echo '*******user asort'.PHP_EOL;
$it->asort();//对value字典排序
foreach ($it as $key => $value) {
# code...
echo $key.':'.$value.PHP_EOL;
}

AppendIterator

能陆续遍历几个迭代器

  • -按顺序迭代几个不同的迭代器,例如,希望在一次循环中迭代访问两个或多个组合
<?php

$array_a = new ArrayIterator(array('a','b','c','d'));

$array_b = new ArrayIterator(array('e','f','e','g'));

$it = new AppendIterator();
$it ->Append($array_a);
//通过append方法把迭代器对象添加到AppendIterator对象中
$it -> append($array_b);
foreach ($it as $key => $value) {
# code...
echo $value.PHP_EOL;
}

MultipleIterator

一个迭代器,依次遍历所有附加的迭代器

  • 用于把多个Iterator里面的数据组合成一个整体来访问
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);
$id_iter = new ArrayIterator(array('01','02','03')); $name_iter = new ArrayIterator(array('张三','李四','王五')); $age_iter = new ArrayIterator(array('21','22','23')); $mit = new MultipleIterator (MultipleIterator::MIT_KEYS_ASSOC); $mit -> attachIterator($id_iter,'ID'); $mit -> attachIterator($name_iter,'name');
$mit -> attachIterator($age_iter,'age'); foreach ($mit as $key => $value) {
# code...
print_r($value);
}

FilesystemIterator

遍历文件系统

<?php
//显示当前目录下的所有文件、大小、创建时间 $it = new FileSystemIterator('.');
date_default_timezone_set('PRC');
foreach ($it as $key => $file_info){
# code...
printf('%s\t%s\t%8s\t%s\n',
date('Y-m-d H:i:s',$file_info->getMTime()),
$file_info->isDir() ? "<dir>" : '',
number_format($file_info->getsize()),
$file_info->getFileName()
);
}

SPL基础接口

接口简介

  • 理解Countable、OuterIterator、RecursiveIterator和SeekableIterator接口的概念
  • 掌握Countable接口的使用
    SPL的基础接口里面定义了最常用的接口
  • Countable继承了该接口的类可以直接调用count()得到元素的个数
  • OuterIterator如果想对迭代器进行一定的处理之后再返回,可以用这个接口
  • RecursiveIterator可以对多层结构的迭代器进行迭代,比如遍历一棵树
  • SeekableIterator可以通过seek方法定位到集合里面的某个特定的元素

Countable接口

类实现 Countable 可被用于 count() 函数.

<?php
//Example One, BAD :( class CountMe
{ protected $_myCount = 3; public function count()
{
return $this->_myCount;
} } $countable = new CountMe();
echo count($countable); //result is "1", not as expected
echo $countable->count;//result is "3"
//Example Two, GOOD :) class CountMe implements Countable
{ protected $_myCount = 3; public function count()
{
return $this->_myCount;
} } $countable = new CountMe();
echo $countable->count();//result is "3"
echo count($countable); //result is "3" as expected
?>

OuterIterator接口

  • OuterIterator如果想对迭代器进行一定的处理之后再返回,可以用这个接口
  • IteratorIterator类是OuterIterator的实现,扩展的时候可以直接继承IteratorIterator
<?php

/**
*
*/
class outerImpl extends IteratorIterator
{ public function current()
{
# code...
return parent::current().'_tail';
}
public function key()
{
return 'pre_'.parent::key();
}
} $array = ['value1','value2','value3','value4']; $outerObj = new outerImpl(new ArrayIterator($array)); foreach ($outerObj as $key => $value) {
# code...
echo '++'.$key.'-'.$value.PHP_EOL;
}

RecursiveIterator接口

  • 可以对多层结构的迭代器进行迭代,比如遍历一棵树
  • 所有具有层次结构特点的数据都可以用这个接口遍历,如文件夹
  • 关键方法
    • hasChildren方法可以用于判断当前节点是否存在子节点
    • getChildren方法用于得到当前节点子节点的迭代器
  • SPL中实现该接口的类
  • RecursiveArrayIterator,RecuriveCachingIterator等以Recurive开头的类都可以进行多层次结构化遍历

SeekableIterator接口

  • SeekableIterator

    • 可以通过seek方法定位到集合里面的某个特定的元素
    • seek方法的参数是元素的位置,从0开始计算
  • SPL中实现该接口的类
    • ArrayIterator、DirectoryIterator、FilesystemIterator、GlobIterator、RecursiveArrayIterator、RecursiveDirectoryIterator

SPL函数的使用

使用spl_autoload_register装载类

<?php

/**
* libs/Test.class.php
*/
class Test
{ function __construct()
{
# code...
echo 'loading class libs/Test.class.php\n';
}
} /**
* autoload.php
*/
//设置autoload寻找php定义的类文件的扩展名,多个扩展名用逗号分隔,前面的扩展名优先匹配
spl_autoload_extensions('.class.php,.php');
//设置autoload寻找PHP定义的类文件的目录,多个目录用PATH_SEPARATOR进行分隔
set_include_path(get_include_path().PATH_SEPARATOR.'libs/');
//提示PHP使用autoload机制查找类定义
spl_autoload_register();
new Test();

__autoload装载类

<?php

function __autoload($class_name){
//定义autoload函数,可以在不调用spl_autoload_register函数的情况下完成类的装载
echo '__autoload class :'.$class_name.PHP_EOL;
require_once 'libs/'.$class_name.'.php';//装载类
}
//定义一个替换__autoload函数的类文件装载函数
function classLoader($class_name){
echo 'classloader() load class : '.$class_name.PHP_EOL;
require_once 'libs/'.$class_name.'.php';//装载类
}
//传入定义好的装载类的函数的名称替换__autoload函数
spl_autoload_register('classLoader'); new Test();

自定义__autoload函数装载类

<?php

//定义一个替换__autoload函数的类文件装载函数
function classLoader($class_name){
echo 'classloader() load class : '.$class_name.PHP_EOL; //当我们不用require_once或require载入类文件的时候,而想通过系统查找include_path来装载类时,必须显式调用spl_autoload函数,参数是类的名称来重启类文件的自动查找(装载)
set_include_path('libs/');
spl_autoload($class_name);
}
//传入定义好的装载类的函数的名称替换__autoload函数
spl_autoload_register('classLoader'); new Test();

SPL函数调用过程

SPL其他函数

SPL的文件处理类

<?php

date_default_timezone_set('PRC');

$file = new SplFileInfo('tmp.txt');

echo 'file is created at '.date('Y-m-d H:i:s',$file->getCTime()).PHP_EOL;

echo 'file is modifyed at '.date('Y-m-d H:i:s',$file->getMTime()).PHP_EOL;

echo 'file size is '.$file->getSize().'bytes'.PHP_EOL;

//读取文件里的内容
$fileObj = $file -> openFile('r'); while ($fileObj ->valid()) {
# code...
echo $fileObj->fgets();
}
//销毁对象
$fileObj = null;
$file = null;

php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)的更多相关文章

  1. JSTL的全称:JSP Standard Tag Library, jsp 标准标签库

    JSTL的全称:JSP Standard Tag Library, jsp 标准标签库 JSTL的作用     提供给Java web开发人员一个标准通过的标签函数库和EL来取代传统直接在页面上嵌入j ...

  2. JSP Standard Tag Library JSP标准标签库

    了解了基本的标签的底层实现,可以看系统定义的强大的标准标签 1.首先引入两个jar包 2.基本语法 <%@ taglib prefix="c" uri="http: ...

  3. C++ Standard Template Library STL(undone)

    目录 . C++标准模版库(Standard Template Library STL) . C++ STL容器 . C++ STL 顺序性容器 . C++ STL 关联式容器 . C++ STL 容 ...

  4. JSTL 标准标签库 (JavaServer Pages Standard Tag library, JSTL)

    JSP标准标签库(JavaServer Pages Standard Tag Library,JSTL)是一个定制标签库的集合,用来解决 像遍历Map或集合.条件测试.XML处理,甚至数据 库访问和数 ...

  5. Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  6. Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  7. Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  8. C++标准库简介、与STL的关系。

    转自http://www.cnblogs.com/xiongjiaji/archive/2011/06/22/2476490.html C++标准库的所有头文件都没有扩展名.C++标准库的内容总共在5 ...

  9. JSTL(JSP Standard Tag Library ,JSP标准标签库)

    JSTL标签之核心标签   JSTL(JSP Standard Tag Library ,JSP标准标签库)是一个实现 Web应用程序中常见的通用功能的定制标记库集,这些功能包括迭代和条件判断.数据管 ...

随机推荐

  1. Linux平台下Ntop流量监测安装,并实现Netflow全过程

    Linux平台下Ntop流量监测安装,并实现Netflow全过程 更多原创教学视频详见: http://you.video.sina.com.cn/m/1443650204 本文出自 "李晨 ...

  2. python 补0的方法

    # 方法一 z = 'bb' z.zfill(6) ----'0000bb' n = ' n.zfill(5) ----' # 方法二 ' " ---- '报错' # 方法的区别 方法二只能 ...

  3. Java中的继承和接口

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 这是个老话题,继承和接口是实现多态的两种方式,如果对象很多,其中一对一对的有共同点,建议用继承,如果 ...

  4. 洛谷 P2837 晚餐队列安排

    P2837 晚餐队列安排 题目背景 Usaco Feb08 Bronze 题目描述 为了避免餐厅过分拥挤,FJ要求奶牛们分2批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想,所有第2批就餐 ...

  5. [Angular & Unit Testing] Testing Component with Store

    When using Ngrx, we need to know how to test the component which has Router injected. Component: imp ...

  6. IAR FOR STM8 学习笔记 固件库 GPIO

    经过一番挣扎,还是决定使用官方的固件库了.. 从网上下一个STM8S的固件库,记得是FOR IAR的. 找到里面的IAR模板就可以开始用了. 这些都是直接写好的库函数,可以直接调用,但首先得先读懂,先 ...

  7. POJ 1320 Street Numbers Pell方程

    http://poj.org/problem?id=1320 题意很简单,有序列 1,2,3...(a-1),a,(a+1)...b  要使以a为分界的 前缀和 和 后缀和 相等 求a,b 因为序列很 ...

  8. C#之菜单控件、主窗体打开子窗体、GroupBox控件使用

    一.背景 一年前有学习过C#,但没有在项目中去实际做APP,重新捡起来应用到项目中.我同事本来做好一个CANOPEN设备管理的界面,由于近期搜索了别人的开发的界面,我觉得有很多东西要重新安排,以及我已 ...

  9. A glance on VDBI

    Just like other thing in data transfter, a resource should have themselves description. And the reso ...

  10. JavaScript---call()使用的一些疑问

    疑问:在使用.call()时,调用对象到底是否可以直接拥有了被调用者的方法和属性? 这里输出结果为:ReferenceError: o is not defined function Person(n ...