关于 SPL 的日常学习笔记

  1. 一听到SPL这个词,第一反应就是项目中经常用的函数spl_autoload_register,这个函数在composer 底层autoload目录文件中的用法很巧妙,实际在我们项目中包括引入第三方SDK,封装类库等方面也是都能实现类的自动装载

  2. SPL:Standard PHP Library 主要包括: 数据结构、迭代器 、基础接口 、基础接口 、SPL函数 、文件处理

说说比较熟悉的SPL函数

同级目录下有index.phpsrc文件夹(第三方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!

少用文件处理

  1. SplFileInfo用户获取文件的基本信息,比如修改时间,拥有者
  2. 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();
}

谈谈数据结构

  1. 对于数组的pop以及push可以很好的描述Stack模型,关于SPL的数据结构之前也没怎么深入了解,借此机会,总结一波
  2. 双向链表的rewind和堆栈里的rewind相反,堆栈里的rewind指向当前指针指向top的所在的位置,而双向链表调用之后指向bottom所在的位置,Queuerewind和双向链表的指向一样
  3. Stacknext指向下一个靠近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迭代器用法

  1. php中一想到遍历数组,莫名的会浮现foreacharray_walkeach-list等方式,现在开始可以尝试一下ArrayIterator
  2. php中关于文件处理的方法很多,递归查找居多,现在同样可以尝试一下FilesystemIterator
  3. 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/>';  
}