今天我们将开启一个新的探索旅程,深入到 PHP 文件系统中,系统的学习和掌握 PHP 文件系统的基本使用。
相信大家在日常研发过程中,难免需要和各种文件纠缠不清。比如,打开.env文件并从中读取配置信息、把项目中的错误信息写入到日志文件中或者获取图片的创建时间等等。在处理这些功能时,我们都需要使用到 PHP 文件系统接口。
下面是本文所涉主题的提纲:
一 什么是文件系统
二 深入 PHP 文件系统
三 面向对象的目录遍历
四 PHP 文件系统思维导图
本文较长,耗时约 20 分钟,请做好战斗准备!
一 什么是文件系统
开始之前,我们首先需要厘清我们所研究的问题领域,理解什么是文件系统,还有我们所研究的对象。
在计算机中,文件系统(file system or filesystem)用于管理数据如何存储和如何被获取的。 - 维基百科
简单来说,就是我们应该如何管理我们的目录(文件夹)和文件。通常,我们将具有相似属性的文件,存储到同一个目录中以便后续查找,这个常见的操作就会涉及到目录和文件。
对于软件工程师来讲,一个非常典型的使用场景,就是在开发MVC项目时,将控制器、视图和模型等模块的文件,存储到不同的目录结构中方便管理。
无论如何,我们依据不同特性划分文件和目录都是为了解决文件存储和查找的问题。
有了这些认知后,应该自然而然的想到我们当前研究的 PHP 文件系统(或者说文件系统)其所研究的对象,简单概括起来就是:
目录(文件夹)
文件
也就是说,本文我们所讲解的 PHP 文件系统函数处理,基本都是围绕目录和文件展开的。
二 深入 PHP 文件系统
在 PHP 文件系统中内置提供了超过 80 个可用的 文件系统函数。由于数量繁多功能强大,自然本文无法将对所有的系统函数逐一讲解。一来,时间过于仓促;再者,短时间内我们也没有那么多的精力将它们全部掌握。
尽管如此,大家也不必气馁,本文会将有限的时间和精力,来研究以下几个在文件处理时的常见话题:
文件的元数据应该如何获取
文件的 MIME 类型如何获取
文件和目录的操作处理
文件和目录的权限管理
另外,补充说明一点,PHP 标准函数库不仅为我们提供了面向过程的文件系统处理函数。同时,还封装了常用目录及文件操作的面向对象接口和迭代器接口方便大家使用:
SplFileInfo
finfo
DirectoryIterator
RecursiveDirectoryIterator
文件系统的元数据什么是元数据
元数据(meta data):通俗一点讲就是「数据的数据」。拿一个 php 文件来说它的元数据可以是创建时间、文件名、文件大小或文件所有权限等,这类能够表明该文件基本特征的数据就是「元数据(meta data)」了。
常用元数据获取
在这一节,我们将学习一些经常需要获取的文件元数据函数,包括:
获取文件的最后修改时间
获取文件的上次访问时间
获取文件的路径信息
获取文件的绝对路径
获取文件类型
获取文件大小
获取文件权限
获取文件所属用户及用户组
话不多说,开干吧!
1、获取文件的最后修改时间
要获取文件的上次被修改时间戳,我们可以使用函数 filemtime($filename) 或 SplFileInfo::getMTime() 方法。
注意:SplFileInfo 类实例化时接收 $filename 文件路径作为参数,后续没有特别说明默认我们已经获取到了 SplFileInfo 实例才能进行 getMTime() 等类似处理。
2、获取文件的上次访问时间
可以使用函数 fileatile($filename) 或 SplFileInfo::getATime() 方法,来获取文件的最后被访问时间戳。
除了filemtile和fileatime之外,还有filectime来获取文件的 inode 修改时间(可认为是创建时间)。
有关时间的函数常用的就这些,为了方便记住,我们来看看它们是如何命名的:
2.1 面向过程 file 前缀,面向对象 get 前缀
2.2 a: access(访问);m:modify(修改);c:create(创建)
2.3 time 后缀
2.4 fileatime,SplFileInfo::getATime;filemtime,SplFileInfo::getMTime;filectime,SplFileInfo::getCTime。
是不是很简单呢!
注意,使用 filectime 时,对于 Windows 系统会获取创建时间,但对于类 Unix 系统是修改时间,因为在类 Unix 系统中多数文件系统并没有创建时间的概念。具体说明可以看 PHP: how can I get file creation date?。
3、获取文件的路径信息
除了时间这些元数据,另一个经常遇到的情况是获取文件的路径信息,包括:
3.1 目录信息
获取目录信息我们可以使用pathinfo(\$filename, PATHINFO_DIRNAME)、dirname(\$filename)和SplFileInfo::getPath()
比如下面给出的文件:
将会获取到F:\Program Files\SSH Communications Security\SSH Secure Shell这部分目录信息。
3.2 文件名信息
这里我们所有的文件名指的是不带扩展名后缀的文件名称,比如需要获取your_path/filename.txt中的filename部分。
需要取得文件名信息,我们可以使用pathinfo(\$filename, PATHINFO_FILENAME)、basename(\$filename, \$suffix)和SplFileInfo::getBasename(\$suffix)获取。
这里给出的$suffix指不获取$suffix扩展名部分(比如不获取$suffix = '.txt')。
请看下面的示例:
将会获取到Output这部分文件名信息。
3.3 扩展名信息
扩展名我们可以使用pathinfo(\$filename, PATHINFO_EXTENSION)和SplFileInfo::getExtension()方法拿到。
基于前面的了解,我们可以获取到txt这部分扩展信息,这里不再赘述。
3.4 basename(文件名 + 扩展名)信息
basename指的是文件名 + 扩展名内容信息,可以使用pathinfo(\$filename, PATHINFO_BASENAME)、basename(\$filename)、SplFileInfo::getBasename()和SplFileInfo::getFilename()方法拿到。
虽然这里我们列出了很多的函数,但是基本上还是比较容易理解的,需要注意的是:
pathinfo 可以获取所有文件相关的路径信息,如果指定第二个参数选项将仅获取该部分的信息
文件名和 basename 不是特别容易理解,你可以使用完全相同的方法或函数basename和SplFileInfo::getBasename()获取他们,区别在于是否摘除指定的$suffix后缀。
3.5 示例
它们的运行结果如下:
3.6 文件路径信息关系图
另外需要注意的一点是在使用 SplFileInfo 获取 basename 时,getBasename() 和 getFilename() 返回基本一致,但是在处理根目录下的文件名获取时表现稍有不同。这里可以到官方文档中用户 提交的反馈 去详细了解一下。
4、获取文件的绝对路径
绝对路径由realpath($path)和SplFileInfo::getRealpath()获取。
5、获取文件类型
可以使用filetype($filename)和SplFileInfo::getType()来获取文件的类型。
返回值范围:
dir
file
char
fifo
block
link
unknown
可以查看 Linux 文件类型与扩展名 相关文件类型,这里我们重点关注下dir目录和file普通文件类型即可。
6、获取文件大小
可以使用filesize(\$filename)和SplFileInfo::getSize()来获取文件的大小,不再赘述。
7、 获取文件权限
可以使用fileperms(\$filename)和SplFileInfo::getPerms()来获取到文件的所属权限。
值得注意的是它们的返回值是十进制表示的权限,如果需要获取类似0655八进制权限表示法,我们需要对返回值进行处处理才行:
领取专属 10元无门槛券
私享最新 技术干货