关于 SPL 的日常学习笔记
一听到SPL这个词,第一反应就是项目中经常用的函数spl_autoload_register,这个函数在composer 底层autoload目录文件中的用法很巧妙,实际在我们项目中包括引入第三方SDK,封装类库等方面也是都能实现类的自动装载
SPL:Standard PHP Library
主要包括: 数据结构、迭代器 、基础接口 、基础接口 、SPL函数 、文件处理
说说比较熟悉的SPL函数
同级目录下有index.php
、src
文件夹(第三方SDK),src
下都是以.php
结尾的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// index.php
spl_autoload_extensions('.php');//注册搜索后缀
set_include_path(get_include_path().PATH_SEPARATOR.'src/');//注册搜索路径
spl_autoload_register();//注册spl_autoload自动装方式
new Start();
// src/Start.php
class Start
{
public function __construct()
{
echo 'autoload complete!';
}
}
// localhost$: php index.php
// localhost$: autoload complete!
|
自动加载指定目录下的指定类型文件,Include any files you want!
少用文件处理
SplFileInfo
用户获取文件的基本信息,比如修改时间,拥有者
SplFileObject
用户操作文件,比如文件的读取,写入
1
2
3
4
5
6
7
8
9
10
11
|
// 1.获取文件的基本属性信息
$file = new SplFileInfo('demo.php);
echo $file->getCTime();//获取文件创建时间
echo $file->getMTime();//获取文件修改时间
// 2.操作文件信息
$file = new SplFileObject('demo.php');
//读取
while ($file->valid()){
echo $file->fgets();
}
|
谈谈数据结构
- 对于数组的
pop
以及push
可以很好的描述Stack
模型,关于SPL
的数据结构之前也没怎么深入了解,借此机会,总结一波
- 双向链表的
rewind
和堆栈里的rewind
相反,堆栈里的rewind
指向当前指针指向top
的所在的位置,而双向链表调用之后指向bottom
所在的位置,Queue
的rewind
和双向链表的指向一样
Stack
的next
指向下一个靠近bottom
的节点,而双向链表是靠近top
的节点
SplDoublyLinkedList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
$obj = new SplDoublyLinkedList();
$obj->push('top_num_1');//插入到顶部
$obj->unshift('bottom_num_1');//插入到底部
$obj->shift(); //删除bottom(头部)所在位置的值
$obj->pop(); // 弹出top的值
$obj->rewind();//把指针指向底部 移动到bottom(头部)位置
echo $obj->current(); //取出当前元素 bottom_num_1
$obj->next(); //把指针指向下一个节点
echo $obj->current(); // top_num_1
$obj->prev();//把指针指向上一个节点
echo $obj->current(); //bottom_num_1
$obj->top(); //获取顶部(尾部)的元素
$obj->count(); //节点的个数
$obj->isEmpty(); // 当前是否为空,为空返回true
$obj->current(); // 获取当前节点的值
$obj->next(); //向下移动节点
$obj->prev(); //返回上一个节点
//循环遍历链表
$obj->rewind();
while($name=$obj->current()){
echo $name."\n";
$obj->next();
}
for ($obj->rewind(); $obj->valid(); $obj->next()) {
echo $obj->current()."\n";
}
var_dump($obj->valid()); //如果节点是有效节点返回true,否则返回false
//当$obj->current(), $obj->valid()之前必须$obj->rewind(); 否则指向空节点
|
Stack
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$obj = new SplStack();
$obj->push(0); //进栈 等同于$obj[] = 0
$obj->push(1); //进栈 等同于$obj[] = 1
$stack->bottom(); // 底部 0
echo $obj->pop(); //出栈 ,输出1
//循环遍历
//判断节点是否有效
while ($stack->valid()) {
echo $stack->key().'=>'.$stack->current().'****';
$stack->next();
}
|
queue
1
2
3
4
5
6
|
$obj = new SplQueue();
$obj->enqueue(0);//对队列
$obj->enqueue(1);//进队列
$queue->offsetSet(1,'demo_1'); //修改第二个数据
$queue->rewind(); //指向bottom(头部),和双向链表指向相同,和栈相反
echo $obj->dequeue();//出队列 输出0
|
SPL迭代器用法
- php中一想到遍历数组,莫名的会浮现
foreach
、array_walk
、each-list
等方式,现在开始可以尝试一下ArrayIterator
- php中关于文件处理的方法很多,递归查找居多,现在同样可以尝试一下
FilesystemIterator
AppendIterator
(遍历多个迭代器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
//example 1
$arr = [
'name' => 'reallyli',
'sex' => 0;
]
//获取数组迭代器$it
$obj = new ArrayObject( $arr );
$it = $obj->getIterator();
//使用迭代器遍历
$it->rewind();
while ($it->valid()){
echo $it->key()."=".$it->current()."<br>";
$it->next();
}
//example 2
//获取文件系统的迭代器
$it = new FilesystemIterator('.');
//遍历当前文件
foreach ($it as $fileInfo){
$fileName = $fileInfo->getFilename();
$lastModifyTime = date("Y-m-d H:i:s", $fileInfo->getMTime());
$isDir = $fileInfo->isDir() ? "DIR" : '';
$size = $fileInfo->getSize();
echo $fileName . ' '. $lastModifyTime. " ". $isDir . " ". $size ."<br>";
}
//example 3
// AppendIterator 迭代器 一次性遍历出多个数组迭代器
$arr1= new ArrayIterator([0=>'a',1=>'b',2=>'c']);
$array2=new ArrayIterator([1=>'z','2'=>'k','sdf'=>'y']);
$obj=new AppendIterator();
$obj->append($array_a);
$obj->append($array_b);
// var_dump($obj->getArrayIterator()); 获取append的迭代器详细
$obj->next();
echo $obj->key(); //1
echo $obj->current(); //b
foreach ($obj as $key => $value) {
echo $key.'----->'.$value.'<br/>';
}
|