对于SPL来说,除了我们之前学过的各种数据结构和迭代器之外,还有一个非常好用的功能就是对文件的操作。今天我们就来学习一下这方面的内容,同时这也是SPL系列文章最后要学习的内容。文件操作对于PHP的文件操作,我们默认使用面向过程的函数,如fopen()、fwrite()、fread()、fgets()等,SPL提供了一种面向对象的方式来执行这些与文件相关的操作操作。文件信息类我们首先要学习的是SplFileInfo类。$file=newSplFileInfo('./6.PHP的SPL扩展库(4)function.php');实例化的时候,需要传递一个文件路径参数。比如这里我们直接打开上一篇文章的测试代码。然后,我们的$file变量会得到一个SplFileInfo对象,在这个对象中,有很多类似file函数的方法可以使用。var_dump($file->getBasename());//string(39)"6.PHP的SPL扩展库(四)function.php"var_dump($file->getPathname());//string(41)"./6.PHPSPL扩展库(4)function.php"var_dump($file->getFilename());//string(39)"6.PHPSPL扩展库(4)function.php"var_dump($file->getRealPath());//string(102)"/Users/zhangyue/MyDoc/blogarticle/dev-blog/php/2021/01/source/6.PHP的SPL扩展库(4)函数.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.PHPSPL扩展库(4)function.php"//["fileName":"SplFileInfo":private]=>//string(39)"6.PHP的SPL扩展库(4)function.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并实现了两个迭代器接口。这两个multi-implemented接口的作用我们后面会讲到。与SplFileInfo相比,它扩展了一些读写文件的方法,可以方便我们对文件进行各种读写操作。$txt1=newSplFileObject('7.1.txt','a+');$txt1->fwrite(date('Y-m-dH:i:s'.PHP_EOL));//71.txt//2021-01-2009:03:15//...//...在实例化的时候,我们可以通过SplFileObject的第二个参数来指定打开文件的形式。该参数的作用与fopen()函数中的相关参数相同。这里我们使用a+,也就是附加读写能力。因为我们一直在测试,所以我们使用这样的读写属性。实例化后,我们就可以使用对象的fwrite()方法正常写入文件了。$txt1->seek(0);var_dump($txt1->fread($txt1->getSize()));//string(80)"2021-01-2009:03:15//"用于读取For例如,我们首先将文件对象内部的句柄指针指向开头。这里使用的seek()方法是不是很眼熟?没错,它的出现就是SplFileObject实现了Seekable接口的最好证明。然后,我们可以使用fread()读取文件的所有内容。当然,普通文件函数中最经典的eof+fgets遍历方式,在SplFileObject中也是支持的。同样,它也支持fgetc、fgetss等方法。$txt1->seek(0);while(!$txt1->eof()){var_dump($txt1->fgets());}//string(20)"2021-01-2009:03:15//"//string(20)"2021-01-2009:03:16//"//...//...前面说了SplFileObject继承了一些iterator接口,也就是说,我们你可以直接遍历这个对象来获取文件的内容。foreach($txt1as$t){var_dump($t);}//字符串(20)"2021-01-2009:03:15//"//字符串(20)"2021-01-2009:03:16//“//...//...是不是很神奇?这确实是SplFileObject非常神奇的地方。这样我们就可以直接通过foreach()遍历文件内容了,可以看出这种遍历形式也是按行遍历,完全可以替代上面的eof+fgets方法。我们在之前的文章中了解了普通的面向进程的文件操作函数。大部分功能都可以在SplFileInfo和SplFileObject中找到对应的实现,这里不再多做演示。对文件操作相关函数有疑问可以回顾上一篇:PHP中的文件系统函数(一):https://mp.weixin.qq.com/s/T7771zfScS1clCIg_AoLQgPHP中的文件系统函数(二):https://mp.weixin.qq.com/s/8THIW4du-Y5HMefRNIV2RAPHP文件系统函数(3):https://mp.weixin.qq.com/s/DU8ImuVYCmN2a83JAMU5CQ临时文件类关于文件相关操作最后我们学习对临时文件的操作。还记得我们之前学过的《在PHP中操作临时文件》https://mp.weixin.qq.com/s/bktuy1XSQ0TLOyGtMWe42g。同样,SPL库中也有相应的操作临时文件的类。$tmp=newSplTempFileObject(0);$tmp->fwrite("tmp:".date('Y-m-dH:i:s'));$tmp->倒带();foreach($tmpas$line){var_dump($line);}//字符串(23)"tmp:2021-01-2009:14:34"sleep(10);//vim/tmp/phpRhgsVZ//tmp:2021-01-2009:14:34怎么样,是不是像tmpfile()一样在/tmp目录下保存临时文件,程序运行完直接删除文件。不过这里需要注意的是,我们的SplTempFileObject类在实例化的时候传入了一个0作为参数,也就是说它并没有使用内存作为临时文件目录,而是实际存储在临时文件目录中。如果这个参数不填或者填一个大于0的数字,表示临时文件存放在内存中,大于0的数字表示使用的内存大小。如果不填,默认值为2MB。目录遍历迭代器目录迭代器是我们之前在迭代器中没有讲到的部分,也是我们说要放在文件目录相关文章中的。事实上,我们之前已经了解过这方面的知识。《PHP获取目录中的全部内容RecursiveDirectoryIterator》https://mp.weixin.qq.com/s/W8jE-AXZI18AhSMAPQlGYA中使用的RecursiveDirectoryIterator是SPL中的递归目录迭代器。今天我们来学习一个更简单的,也是这个RecursiveDirectoryIterator迭代器的上级迭代器,也就是普通目录迭代器的使用。foreach(newDirectoryIterator('./')as$fileInfo){if($fileInfo->isDot())继续;if($fileInfo->isDir()){echo"dir:".$fileInfo->getFilename(),PHP_EOL;}else{回声“文件:”。$fileInfo->getFilename(),PHP_EOL;}}//file:2.了解SeasLog日志扩展在PHP.php//dir:autoloadA//file:7.1.txt//file:6.PHPSPLextensionlibrary(4)functions.php//file:1.学习PHP.php中的一些杂项函数//文件:browscap.ini//文件:7.PHPSPL扩展库(4)文件和设计模式.php//文件:3.PHPSPL扩展库(1)数据structure.php//文件:4.PHPSPL扩展库(2)对象数组和数组迭代器.php//文件:1.txt//目录:autoloadB//文件:5.PHP的SPL扩展库(3)迭代器。php也是很简单的代码,这里就不多解释了。它和带递归函数的迭代器的区别和其他迭代器一样,在之前的文章中已经说明,这里不再赘述。设计模式最后,让我们再次回顾一下设计模式。设计模式系列文章是之前写的系列文章。当时我在两篇文章中讲了一些为我们准备和实现的SPL中的设计模式。IteratorIterator相信不用多说了吧。上一篇文章《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扩展库(5)文件和设计模式。php参考文档:https://www.php.net/manual/zh/book.spl.php
