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. 1941. Scary Martian Word

    1941. Scary Martian Word 这道题 一个长度为3的字符串视为 一个 火星文 字母(ASCII 33-122) ,给出一个火星人认为恐怖的单词(由火星字母组成) 然后 给你一篇文章 ...

  2. Server-side Sessions with Redis | Flask (A Python Microframework)

    Server-side Sessions with Redis | Flask (A Python Microframework) Server-side Sessions with Redis By ...

  3. 从M个数中随机选出N个数的所有组合,有序,(二)

    这就是数学中的 A m n 的选取. 共有   m!/n!种可能.. 同样举一个例子吧.. 从12345这五个数字中随机选取3个数字,要求选出来的这三个数字是有序,也就是说从12345中选出来的是12 ...

  4. NodeJS会是昙花一现吗?

    在用了一年以后,我感觉node.js有一点不正确劲.它非常有意思,可是我认为我应该用另外一个视角去审视它. 网络编程真的能够更easy吗? node.js无疑有一些设计很好的地方.前段时间我写了一个性 ...

  5. mac下brew install 报错

    mac下brew install 报错 错误提示: 原因:是这个brew的权限不正确 修改一下这个brew的权限 chown root:wheel /usr/local/bin/brew

  6. 学习了LINUX下用C语言遍历文件夹,一些心得

    struct dirent中的几个成员: d_type:4表示为目录,8表示为文件 d_reclen:16表示子目录或文件,24表示非子目录 d_name:目录或文件的名称 具体代码如下,仅供参考 # ...

  7. JDBC操作数据库的学习(1)

    单单对数据库的操作,比如说MySQL,我们可以在命令行窗口中执行,但是一般是应用程序要操作数据库,因此我们应该在程序中的代码上体现对数据库的操作,那么使用程序应用如何操作数据库呢?那就要使用到数据库的 ...

  8. Appium TestNg Maven Android Eclipse java简单启动实例

    环境准备 Eclipse + maven + appium + TestNg 确保已经在Eclipse 上面安装maven TestNg的插件 打开Eclipse,新建一个java项目,把项目转换成m ...

  9. WPF的消息机制

    前言 谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际 ...

  10. 使用commons-daemon启动、关闭java程序

    系统环境: CentOS 7 X64 JDK1.8 一: 安装jsvc 下载 commons-daemon的源代码包 http://apache.fayea.com//commons/daemon/s ...