Rafael Dohms 上面的篇文章 让我为之惊艳,忍不住就翻译了下来,同一时候补充了部分内容。

SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,而且从 PHP5.3 已逐渐的成熟。SPL 事实上在全部的 PHP5 开发环境中被内置,同一时候无需不论什么设置。

似乎众多的 PHP 开发者基本没有使用它,甚至闻所未闻。究其原因,能够追述到它那阳春白雪般的说明文档,使你忽略了「它的存在」。

SPL 这块宝石宛如铁达尼的「海洋之心」般,被沉入海底。而如今它应该被我们捞起。并将它穿戴在应有的位置 ,而这也是这篇文章所要表述的观点。

那么。SPL 提供了什么?

SPL 对 PHP 引擎进行了扩展,比如 ArrayAccess、Countable 和 SeekableIterator 等接口,它们用于以数组形式操作对象。同一时候,你还能够使用 RecursiveIterator、ArrayObejcts 等其它迭代器进行数据的迭代操作。

它还内置几个的对象比如 Exceptions、SplObserver、Spltorage 以及 splautoloadregister、splclasses、iteratorapply 等的帮助函数(helper functions),用于重载相应的功能。

这些工具聚合在一起就好比是把多功能的瑞士军刀,善用它们能够从质上提升 PHP 的代码效率。那么,我们怎样发挥它的威力?

重载 autoloader

假设你是位「教科书式的程序猿」,那么你保证了解怎样使用 __autoload 去取代 includes/requires 操作惰性加载相应的类,对不?

但久之,你会发现你已经陷入了困境,首先是你要保证你的类文件必须在指定的文件路径中,比如在 Zend 框架中你必须使用「_」来切割类、方法名称(你怎样解决这一问题?)。

另外的一个问题。就是当项目变得越来越复杂, __autoload 内的逻辑也会变得对应的复杂。到最后,甚至你会增加异常推断。以及将全部的加载类的逻辑如数写到当中。

大家都知道「鸡蛋不能放到一个篮子中」,利用 SPL 能够分离 __autoload 的加载逻辑。仅仅须要写个你自己的 autoload 函数,然后利用 SPL 提供的函数重载它。

比如上述 Zend 框架的问题。你能够重载 Zend loader 相应的方法。假设它没有找到相应的类。那么就使用你先前定义的函数。

<?php
class MyLoader {
public static function doAutoload($class) {
// 本模块相应的 autoload 操作
}
} spl_autoload_register( array('MyLoader', 'doAutoload') );
?>

正如你所见, spl autoload register 还能以数组的形式增加多个加载逻辑。

同一时候,你还能够利用spl autoload unregister 移除已经不再须要的加载逻辑。这功能总会用到的。

迭代器

迭代是常见设计模式之中的一个,普遍应用于一组数据中的统一的遍历操作。

能够毫不夸张的说,SPL 提供了全部你须要的相应数据类型的迭代器。

有个很好的案例就是遍历文件夹。常规的做法就是使用 scandir 。然后跳过「.「 和 「..」。以及其他未满足条件的文件。

比如你须要遍历个某个文件夹抽取当中的图片文件,就须要推断是否是 jpg、gif 结尾。

以下的代码就是使用 SPL 的迭代器运行上述递归寻找指定文件夹中的图片文件的样例:

<?php
class RecursiveFileFilterIterator extends FilterIterator {
// 满足条件的扩展名
protected $ext = array('jpg','gif'); /**
* 提供 $path 并生成相应的文件夹迭代器
*/
public function __construct($path) {
parent::__construct(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)));
} /**
* 检查文件扩展名是否满足条件
*/
public function accept() {
$item = $this->getInnerIterator();
if ($item->isFile() &&
in_array(pathinfo($item->getFilename(), PATHINFO_EXTENSION), $this->ext)) {
return TRUE;
}
}
} // 实例化
foreach (new RecursiveFileFilterIterator('/path/to/something') as $item) {
echo $item . PHP_EOL;
}
?>

你可能会说,这不是花了很多其它的代码去办同一件事情吗?那么,查看上面的代码,你不是拥有了具有高度重用并且能够測试的代码了吗 :)

以下是 SPL 提供的其它的迭代器:

  • RecursiveIterator
  • RecursiveIteratorIterator
  • OuterIterator
  • IteratorIterator
  • FilterIterator
  • RecursiveFilterIterator
  • ParentIterator
  • SeekableIterator
  • LimitIterator
  • GlobIterator
  • CachingIterator
  • RecursiveCachingIterator
  • NoRewindIterator
  • AppendIterator
  • RecursiveIteratorIterator
  • InfiniteIterator
  • RegexIterator
  • RecursiveRegexIterator
  • EmptyIterator
  • RecursiveTreeIterator
  • ArrayIterator

自 PHP5.3 開始。会内置其它很多其它的迭代器,我想你都能够尝试下。也许它能改变你编写传统代码的习惯。

SplFixedArray

SPL 还内置了一系列的数组操作工具。比如能够使用 SplFixedArray 实例化一个固定长度的数组。那么为什么要使用它?由于它更快。甚至它关系着你的工资问题 :)

我们知道 PHP 常规的数组包括不同类型的键。比如数字、字符串等,而且长度是可变的。

正是由于这些「高级功能」,PHP 以散列(hash)的方式通过键得到相应的值 -- 事实上这在特定情况这会造成性能问题。

而 SplFixedArray 由于是使用固定的数字键。所以它并没有使用散列存储方式。不确切的说,甚至你能够觉得它就是个 C 数组。这就是为什么 SplFixedArray 会比通常数组要快的原因(仅在 PHP5.3 中)。

那究竟有多快呢。以下的组数据能够让你窥其究竟。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGhwZmVuZ2h1bw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

假设你须要大量的数组操作,那么你能够尝试下,相信它是值得信赖的。

数据结构

同一时候 SPL 还提供了些数据结构基本类型的实现 。尽管我们能够使用传统的变量类型来描写叙述数据结构。比如用数组来描写叙述堆栈(Strack)-- 然后使用相应的方式 pop 和 push(arraypop()、arraypush())。但你得时刻小心。·由于毕竟它们不是专门用于描写叙述数据结构的 -- 一次误操作就有可能破坏该堆栈。

而 SPL 的 SplStack 对象则严格以堆栈的形式描写叙述数据,并提供相应的方法。同一时候,这种代码应该也能理解它在操作堆栈而非某个数组,从而能让你的同伴更好的理解相应的代码,而且它更快。

最后,可能上述那些慘白的样例还不足矣「诱惑你」去使用 SPL。

实践出真知,SPL 很多其它、更强大的功能须要你自我们不得不挖。它慢慢宝石般掉漆。散发着灿烂的能力。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

PHP SPL他们留下的宝石的更多相关文章

  1. [Python] Codecombat 攻略 Sarven 沙漠 (1-43关)截止至30关

    首页:https://cn.codecombat.com/play语言:Python 第二界面:Sarven沙漠(43关)时间:4-11小时内容:算术运算,计数器,while循环,break(跳出循环 ...

  2. BZOJ4976 宝石镶嵌(动态规划)

    显然被留下的宝石应该贡献至少一位,否则就可以扔掉.所以如果n-k>=logw,直接输出所有数的or.现在n变得和k同阶了.于是设f[i][j]为前i个数or为j时至少选几个数,转移显然.当然可以 ...

  3. python 调试大法-大笨蛋的笔记

    说在前面 我觉得没有什么错误是调试器无法解决的,如果没有,那我再说一遍,如果有,那当我没说 一.抛出异常 可以通过 raise 语句抛出异常,使程序在我们已经知道的缺陷处停下,并进入到 except  ...

  4. python 调试大法

    说在前面 我觉得没有什么错误是调试器无法解决的,如果没有,那我再说一遍,如果有,那当我没说 一.抛出异常 可以通过 raise 语句抛出异常,使程序在我们已经知道的缺陷处停下,并进入到 except ...

  5. [Python] Codecombat 攻略 Sarven 沙漠 (1-43关)截止至36关

    首页:https://cn.codecombat.com/play语言:Python 第二界面:Sarven沙漠(43关)时间:4-11小时内容:算术运算,计数器,while循环,break(跳出循环 ...

  6. SPL学习 迭代器

    主要学习内容: 慕课网的spl视频教程 阮一峰SPL学习笔记 http://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html SPL类详解 http ...

  7. PHP SPL使用

    转载文章:php遗落的宝石 Rafael Dohms 上面的篇文章 让我惊艳了下,忍不住就翻译了下来,同时补充了部分内容. SPL,PHP 标准库(Standard PHP Library) ,此从 ...

  8. PHP SPL使用方法 自动加载和迭代器

    SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,并且从 PHP5.3 已逐渐的成熟.SPL 其实在所有的 PHP5 开发环境中被内置,同 ...

  9. PHP SPL使用方法和他的威力

    什么是SPL,如何使用,他有什么作用,下面我我们就讲讲PHP SPL的用法 SPL,PHP 标准库(Standard PHP Library) ,此从 PHP 5.0 起内置的组件和接口,并且从 PH ...

随机推荐

  1. 好消息:8月25日广州嵌入式Linux开发免费项目约定你

    8月18日,粤嵌深圳分校举行了盛大的免费嵌入式项目体验,众多嵌入式爱好者排队参加项目体验的火爆场景仿佛还在眼前,体验效果得到学员一致好评.时隔一周,粤嵌广州总部也不容落后,在粤嵌广州总部举办<嵌 ...

  2. <转载>Div+Css布局教程(-)CSS必备知识

    目录: 1.Div+Css布局教程(-)CSS必备知识 注:本教程要求对html和css有基础了解. 一.CSS布局属性 Width:设置对象的宽度(width:45px). Height:设置对象的 ...

  3. 关于ARM开发板与PC主机的网络设置问题

    直观来讲,ARM开发板多数情况下会有条网线与主机相连,所以最重要的一步是保证PC主机与ARM开发板能互通. 互通的意思进一步来讲就是互相能ping通.也就是说在瘟都死的dos下(假设主机是瘟都死系统) ...

  4. winform基础——实现简易赈灾物资发放登记系统

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  5. VS关闭Browser Link

    原文:VS关闭Browser Link 这是VS2013的一个新功能,叫Browser Link,基于SignalR. 它可以实现VS IDE和你的程序的双向通讯,在IDE编辑代码即刻将修改发送到浏览 ...

  6. 在springmvc中配置jedis(转)

    主要学习https://github.com/thinkgem/jeesite.一下代码均参考于此并稍作修改. 1.jedis 首先,需要添加jedis: <!--jedis--> < ...

  7. VC++ WIN32 sdk实现按钮自绘详解 之二.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  8. 14.5.7 Storing InnoDB Undo Logs in Separate Tablespaces 存储InnoDB Undo logs 到单独的表空间

    14.5.7 Storing InnoDB Undo Logs in Separate Tablespaces 存储InnoDB Undo logs 到单独的表空间 在MySQL 5.6.3,你可以存 ...

  9. tsunami:一种基于UDP协议的高速传输

    一. 需求 近期在做数据库迁移.常常须要打包实例传输.传统scp感觉非常慢. 二. 软件信息 1. 软件主页:http://tsunami-udp.sf.net/ 2. 软件安装:直接源代码make ...

  10. [Java][Android][Process] ProcessBuilder与Runtime差别

    在Android中想要进行Ping,在不Root机器的情况下似乎还仅仅能进行底层命调用才干实现. 由于在Java中要进行ICMP包发送须要Root权限. 于是仅仅能通过创建进程来攻克了.创建进程在Ja ...