百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

PHP的SPL扩展库(五)文件及设计模式

liebian365 2024-11-21 17:35 3 浏览 0 评论

对于 SPL 来说,除了我们之前学习到的各种 数据结构 以及 迭代器 之外,还有一类非常好用的功能就是对于文件的操作。今天我们就来学习这方面的内容,同时,这也是 SPL 系列文章中最后要学习的内容。

文件操作

对于 PHP 的文件操作来说,在默认情况下我们都是使用面向过程的那些函数来进行操作,比如 fopen() 、 fwrite() 、 fread() 、 fgets() 这些。而 SPL 中提供的则是以面向对象的方式来进行这些文件相关的操作。

文件信息类

首先我们要学习的是 SplFileInfo 这个类。

$file = new SplFileInfo('./6.PHP的SPL扩展库(四)函数.php');

实例化它的时候,就需要传递一个文件路径参数。比如这里我们就直接打开上一篇文章的测试代码。然后,我们的 $file 变量就会得到一个 SplFileInfo 对象,在这个对象中,有许多和文件函数类似的方法可以供我们使用。

var_dump($file->getBasename());
// string(39) "6.PHP的SPL扩展库(四)函数.php"

var_dump($file->getPathname());
// string(41) "./6.PHP的SPL扩展库(四)函数.php"

var_dump($file->getFilename());
// string(39) "6.PHP的SPL扩展库(四)函数.php"

var_dump($file->getRealPath());
// string(102) "/Users/zhangyue/MyDoc/博客文章/dev-blog/php/2021/01/source/6.PHP的SPL扩展库(四)函数.php"

var_dump($file->getPathInfo());
// object(SplFileInfo)#2 (2) {
//     ["pathName":"SplFileInfo":private]=>
//     string(1) "."
//     ["fileName":"SplFileInfo":private]=>
//     string(1) "."
//   }

var_dump($file->getFileInfo());
// object(SplFileInfo)#2 (2) {
//     ["pathName":"SplFileInfo":private]=>
//     string(41) "./6.PHP的SPL扩展库(四)函数.php"
//     ["fileName":"SplFileInfo":private]=>
//     string(39) "6.PHP的SPL扩展库(四)函数.php"
//   }

我们可以通过上面的这些测试代码来获得文件相关的一些路径信息。是不是和普通的那些文件操作函数非常类似,或者说是完全一样的命名和使用方式。

var_dump($file->getExtension());
// string(3) "php"

var_dump($file->getType());
// string(4) "file"

var_dump($file->getCTime());
// int(1611017967)

var_dump($file->getOwner());
// int(501)

var_dump($file->getGroup());
// int(20)

var_dump($file->getSize());
// int(3543)

当然,文件的这些属性信息也都是可以正常获取到的,比如文件的 扩展名、类型、各种文件相关的时间、拥有者、属组、大小 之类的信息。

var_dump($file->isReadable());
// bool(true)

var_dump($file->isWritable());
// bool(true)

var_dump($file->isDir());
// bool(false)

var_dump($file->isFile());
// bool(true)

var_dump($file->isLink());
// bool(false)

当然,判断文件是否可写、可读,是否是目录或文件或连接的方法都有。总体来说,普通的文件操作函数所拥有的功能这边都是存在的,在这里我们也只是列出了一部分,更多的方法大家可以在官方文件中查阅。

文件操作类

上面的 SplFileInfo 中,我们好像没有对文件进行读写操作之类的功能,只能看到文件的一些属性信息。别急,对于文件的其它操作,我们使用另外一个类 SplFileObject 。它是继承自 SplFileInfo 的,并且另外又多实现了两个迭代器的接口。关于这两个多实现的接口的功能我们在后面会讲到。而相对于 SplFileInfo 来说,它扩展了文件的一些读写方法,能够让我们方便地进行文件的各种读写操作。

$txt1 = new SplFileObject('7.1.txt', 'a+');
$txt1->fwrite(date('Y-m-d H:i:s' . PHP_EOL));
// 71.txt
// 2021-01-20 09:03:15
// ……
// ……

在实例化的时候,我们就可以通过 SplFileObject 的第二个参数来指定文件打开的形式,这个参数和 fopen() 函数中的相关参数的作用是一样的。这里我们使用的是 a+ ,也就是追加读写的能力。因为我们要不断地测试,所以使用的就是这样的一个读写属性。在实例化之后,我们使用对象的 fwrite() 方法就可以正常的向文件中进行写入了。

$txt1->seek(0);
var_dump($txt1->fread($txt1->getSize()));
// string(80) "2021-01-20 09:03:15
// "

对于读取来说,我们要先将文件对象内部的句柄指针指回开头处。这里使用的 seek() 方法是不是很眼熟。没错,它的出现正是 SplFileObject 实现了 Seekable 接口的最好证明。接着,我们使用 fread() 就可以读取文件中的全部内容了。

当然,像是在普通的文件函数中最经典的 eof + fgets 这种遍历方式在 SplFileObject 中也是支持的,同样,它也支持 fgetc 、fgetss 这些方法。

$txt1->seek(0);
while(!$txt1->eof()){
    var_dump($txt1->fgets());
}
// string(20) "2021-01-20 09:03:15
// "
// string(20) "2021-01-20 09:03:16
// "
// ……
// ……

前面说过,SplFileObject 是继承了一些迭代器接口的,也就是说,我们可以直接遍历这个对象来获得文件里面的内容。

foreach($txt1 as $t){
    var_dump($t);
}
// string(20) "2021-01-20 09:03:15
// "
// string(20) "2021-01-20 09:03:16
// "
// ……
// ……

是不是很神奇?这确实是 SplFileObject 中非常神奇的一个地方。通过这种方式我们直接就可以通过 foreach() 来实现对文件内容的遍历,而且可以看出,这种遍历形式也是按行来进行遍历的,完全可以替代上面的 eof+fgets 的方式。

关于普通的面向过程的文件操作函数的学习我们在之前的文章中已经学习过了,当中大部分的函数在 SplFileInfo 和 SplFileObject 中都可以找到对应的实现,这里就不进行更多的演示了。如果对文件操作相关函数还有什么疑问的同学,可以移步之前的文章再温习一下:

  • PHP中的文件系统函数(一):https://mp.weixin.qq.com/s/T7771zfScS1clCIg_AoLQg
  • PHP中的文件系统函数(二):https://mp.weixin.qq.com/s/8THIW4du-Y5HMefRNIV2RA
  • PHP中的文件系统函数(三):https://mp.weixin.qq.com/s/DU8ImuVYCmN2a83JAMU5CQ

临时文件类

关于文件相关操作我们最后再学习一个对于临时文件的操作。还记得之前我们学习过的 《在PHP中操作临时文件》https://mp.weixin.qq.com/s/bktuy1XSQ0TLOyGtMWe42g 吧,同样地,在 SPL 库中也有对应的操作临时文件的类。

$tmp = new SplTempFileObject(0);

$tmp->fwrite("tmp:" . date('Y-m-d H:i:s'));

$tmp->rewind();
foreach ($tmp as $line) {
    var_dump($line);
}
// string(23) "tmp:2021-01-20 09:14:34"

sleep(10);
// vim /tmp/phpRhgsVZ
// tmp:2021-01-20 09:14:34

怎么样,是不是也和 tmpfile() 一样通过在 /tmp 目录来保存临时文件,并且在程序运行结束后直接删除了文件。不过这里需要注意的是,我们的 SplTempFileObject 类在实例化的时候传递了一个 0 作为参数,表示的是不使用内存作为临时文件目录,而是真实地存放在临时文件目录中。如果这个参数不填或者是填大于 0 的数字,则表示是将这个临时文件存放在内存中,而大于 0 的数字则表示所使用的内存大小,不填的话默认值是 2MB 。

目录遍历迭代器

目录迭代器就是我们在之前讲迭代器中没有讲到的部分,也是我们说过要放在文件目录相关的文章中再讲到的内容。其实这方面的内容我们在之前也学习过,《PHP获取目录中的全部内容RecursiveDirectoryIterator》https://mp.weixin.qq.com/s/W8jE-AXZI18AhSMAPQlGYA 中使用的这个 RecursiveDirectoryIterator 就是 SPL 中的 递归目录迭代器 。今天,我们再学习一个比较简单的,也是这个 RecursiveDirectoryIterator 迭代器的上级迭代器,就是普通的目录迭代器的使用。

foreach (new DirectoryIterator('./') as $fileInfo) {
    if($fileInfo->isDot()) continue;
    if($fileInfo->isDir()){
        echo "dir: " . $fileInfo->getFilename() , PHP_EOL;
    }else{
        echo "file: " . $fileInfo->getFilename() , PHP_EOL;
    }
}
// file: 2.学习了解PHP中的SeasLog日志扩展.php
// dir: autoloadA
// file: 7.1.txt
// file: 6.PHP的SPL扩展库(四)函数.php
// file: 1.PHP中的一些杂项函数学习.php
// file: browscap.ini
// file: 7.PHP的SPL扩展库(四)文件及设计模式.php
// file: 3.PHP的SPL扩展库(一)数据结构.php
// file: 4.PHP的SPL扩展库(二)对象数组与数组迭代器.php
// file: 1.txt
// dir: autoloadB
// file: 5.PHP的SPL扩展库(三)迭代器.php

同样非常简单的代码,这里就不多解释了。而它和带 递归 功能的迭代器相关的区别和其它的迭代器都一样,也是在之前的文章都讲解过的,这里就不多赘述了。

设计模式

最后,我们再来复习一下 设计模式 。设计模式系列文章是较早之前写过的一系列文章了。当时就在两篇文章中讲到过 SPL 中为我们准备好并且已经实现了的一些设计模式。

迭代器

迭代器相信已经不用多说了,前面的文章 《PHP的SPL扩展库(三)迭代器》https://mp.weixin.qq.com/s/KevUTCbfmEPLuu5TvD0SSw 中已经详细说明了 SPL 中各种迭代器的实现。而对于迭代器这种设计模式,也可以参考我们之前的文章 《PHP设计模式之迭代器模式》https://mp.weixin.qq.com/s/uycac0OXYYjAG1BlzTUjsw 进行深入的学习了解。另外,Iterator 这个类不是 SPL 扩展中的哦!SPL 库中只是有几种不同的具体迭代器实现而已。

观察者

除了迭代器,另一个就是观察者模式,SPL 库中直接为我们准备好了 SplObserver 和 SplSubject 这两个类来专门用于实现观察者模式。具体的实现代码和这个设计模式的讲解我们也在之前的设计模式系列文章中有过详细的说明,大家可以再过去好好学习下 《PHP设计模式之观察者模式》https://mp.weixin.qq.com/s/SlSToMIGNBtU06BWNCwWvg 。

总结

从这篇文章中可以看出一个问题,那就是 SPL 扩展库现在已经非常常用了,要不这里也不会有这么多之前文章的链接。相信大家也会在将来的业务开发中更多地使用 SPL 中操作文件的类来进行文件操作,这也是一种趋势,毕竟面向对象的方法才是更主流的方法。好了,又是一个大扩展的完结,SPL 库作为一个已经默认集成到官方的扩展,确实是值得我们花更多的时间来学习掌握的,学习好这个扩展一定不会让你失望!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/2021/01/source/7.PHP的SPL扩展库(五)文件及设计模式.php

参考文档:

https://www.php.net/manual/zh/book.spl.php

相关推荐

快递查询教程,批量查询物流,一键管理快递

作为商家,每天需要查询许许多多的快递单号,面对不同的快递公司,有没有简单一点的物流查询方法呢?小编的回答当然是有的,下面随小编一起来试试这个新技巧。需要哪些工具?安装一个快递批量查询高手快递单号怎么快...

一键自动查询所有快递的物流信息 支持圆通、韵达等多家快递

对于各位商家来说拥有一个好的快递软件,能够有效的提高自己的工作效率,在管理快递单号的时候都需要对单号进行表格整理,那怎么样能够快速的查询所有单号信息,并自动生成表格呢?1、其实方法很简单,我们不需要一...

快递查询单号查询,怎么查物流到哪了

输入单号怎么查快递到哪里去了呢?今天小编给大家分享一个新的技巧,它支持多家快递,一次能查询多个单号物流,还可对查询到的物流进行分析、筛选以及导出,下面一起来试试。需要哪些工具?安装一个快递批量查询高手...

3分钟查询物流,教你一键批量查询全部物流信息

很多朋友在问,如何在短时间内把单号的物流信息查询出来,查询完成后筛选已签收件、筛选未签收件,今天小编就分享一款物流查询神器,感兴趣的朋友接着往下看。第一步,运行【快递批量查询高手】在主界面中点击【添...

快递单号查询,一次性查询全部物流信息

现在各种快递的查询方式,各有各的好,各有各的劣,总的来说,还是有比较方便的。今天小编就给大家分享一个新的技巧,支持多家快递,一次能查询多个单号的物流,还能对查询到的物流进行分析、筛选以及导出,下面一起...

快递查询工具,批量查询多个快递快递单号的物流状态、签收时间

最近有朋友在问,怎么快速查询单号的物流信息呢?除了官网,还有没有更简单的方法呢?小编的回答当然是有的,下面一起来看看。需要哪些工具?安装一个快递批量查询高手多个京东的快递单号怎么快速查询?进入快递批量...

快递查询软件,自动识别查询快递单号查询方法

当你拥有多个快递单号的时候,该如何快速查询物流信息?比如单号没有快递公司时,又该如何自动识别再去查询呢?不知道如何操作的宝贝们,下面随小编一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号若干...

教你怎样查询快递查询单号并保存物流信息

商家发货,快递揽收后,一般会直接手动复制到官网上一个个查询物流,那么久而久之,就会觉得查询变得特别繁琐,今天小编给大家分享一个新的技巧,下面一起来试试。教程之前,我们来预览一下用快递批量查询高手...

简单几步骤查询所有快递物流信息

在高峰期订单量大的时候,可能需要一双手当十双手去查询快递物流,但是由于逐一去查询,效率极低,追踪困难。那么今天小编给大家分享一个新的技巧,一次能查询多个快递单号的物流,下面一起来学习一下,希望能给大家...

物流单号查询,如何查询快递信息,按最后更新时间搜索需要的单号

最近有很多朋友在问,如何通过快递单号查询物流信息,并按最后更新时间搜索出需要的单号呢?下面随小编一起来试试吧。需要哪些工具?安装一个快递批量查询高手快递单号若干怎么快速查询?运行【快递批量查询高手】...

连续保存新单号功能解析,导入单号查询并自动识别批量查快递信息

快递查询已经成为我们日常生活中不可或缺的一部分。然而,面对海量的快递单号,如何高效、准确地查询每一个快递的物流信息,成为了许多人头疼的问题。幸运的是,随着科技的进步,一款名为“快递批量查询高手”的软件...

快递查询教程,快递单号查询,筛选更新量为1的单号

最近有很多朋友在问,怎么快速查询快递单号的物流,并筛选出更新量为1的单号呢?今天小编给大家分享一个新方法,一起来试试吧。需要哪些工具?安装一个快递批量查询高手多个快递单号怎么快速查询?运行【快递批量查...

掌握批量查询快递动态的技巧,一键查找无信息记录的两种方法解析

在快节奏的商业环境中,高效的物流查询是确保业务顺畅运行的关键。作为快递查询达人,我深知时间的宝贵,因此,今天我将向大家介绍一款强大的工具——快递批量查询高手软件。这款软件能够帮助你批量查询快递动态,一...

从复杂到简单的单号查询,一键清除单号中的符号并批量查快递信息

在繁忙的商务与日常生活中,快递查询已成为不可或缺的一环。然而,面对海量的单号,逐一查询不仅耗时费力,还容易出错。现在,有了快递批量查询高手软件,一切变得简单明了。只需一键,即可搞定单号查询,一键处理单...

物流单号查询,在哪里查询快递

如果在快递单号多的情况,你还在一个个复制粘贴到官网上手动查询,是一件非常麻烦的事情。于是乎今天小编给大家分享一个新的技巧,下面一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号怎么快速查询?...

取消回复欢迎 发表评论: