Skip to content

php_ref_filesystem

PHP 提供了一整套用于与服务器文件系统交互的函数。这些函数允许您读取、写入、创建、删除和管理文件及目录。

安全注意事项:文件系统操作可能带来重大的安全隐患。务必验证和清理用户提供的路径或文件名,以防止目录遍历攻击(例如,访问预定目录之外的文件,如 ../../etc/passwd)。确保在您的服务器上设置适当的文件和目录权限。

文件系统函数是 PHP 核心的一部分。无需安装。

路径分隔符(Unix / Windows 兼容性)

Section titled “路径分隔符(Unix / Windows 兼容性)”

PHP 提供了 DIRECTORY_SEPARATOR 常量,它会自动使用正确的分隔符(Unix 类系统使用 /,Windows 使用 \)。在构建路径时使用此常量是最佳实践,以确保跨平台兼容性。

<?php
// 跨平台路径的良好实践
$filePath = 'data' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'logo.png';
// 即使在 Windows 上,PHP 通常也能正确处理正斜杠 '/'
$filePathSimple = 'data/images/logo.png';
// 使用 '/' 通常是安全的,并且出于简洁性考虑常被首选
?>

在处理用户输入或来自不同源的路径时,可以考虑使用 realpath() 等函数来规范化和解析路径。

以下是一些常用的文件系统函数:

函数 / 类别描述
读取文件
file_get_contents()将整个文件读取为字符串(适用于较小文件)。
fopen()打开一个文件或 URL,返回文件指针资源。
fread()从打开的文件指针中读取指定数量的字节。
fgets()从打开的文件指针中读取一行。
fgetcsv()从打开的文件指针中解析 CSV 字段的一行。
file()将整个文件读取为行数组。
readfile()读取文件并将其直接写入输出缓冲区。
写入文件
file_put_contents()将数据(字符串或数组)写入文件(方便简单的写入,可以创建/覆盖)。
fwrite() / fputs()写入打开的文件指针。
fputcsv()将一行格式化为 CSV 并将其写入打开的文件指针。
文件/目录检查
file_exists()检查文件或目录是否存在。
is_file()检查路径是否为普通文件。
is_dir()检查路径是否为目录。
is_readable()检查文件/目录是否存在且可读。
is_writable() / is_writeable()检查文件/目录是否存在且可写。
is_executable()检查路径是否可执行。
文件/目录操作
copy()复制文件。
rename()重命名或移动文件或目录。
unlink()删除文件。
mkdir()创建目录。
rmdir()移除空目录。
touch()设置文件的访问和修改时间(如果不存在则创建)。
chmod()更改文件模式(权限)。
chown()更改文件所有者。
chgrp()更改文件组。
文件信息
filesize()获取文件大小(以字节为单位)。
filetype()获取文件类型(例如,文件、目录、链接)。
filemtime()获取文件修改时间(Unix 时间戳)。
fileatime()获取文件最后访问时间(Unix 时间戳)。
filectime()获取文件 inode 更改时间(Unix 时间戳)。
stat() / fstat()提供有关文件/打开的文件指针的详细信息。
pathinfo()返回有关文件路径的信息(目录、基本名称、扩展名、文件名)。
basename()返回路径的尾部名称组件。
dirname()返回父目录的路径。
realpath()返回规范化的绝对路径名。
目录操作
scandir()将指定路径内的文件和目录列出到一个数组中。
opendir() / readdir() / closedir()按过程方式逐个读取目录条目。
glob()查找匹配模式的路径名(例如 *.txt)。
文件指针
fclose()关闭打开的文件指针。
feof()测试文件指针是否到达文件末尾。
fseek()在文件指针中定位。
ftell()返回文件读/写指针的当前位置。
rewind()将文件指针的位置倒回开始。

注意:fgetss() 在 PHP 7.3 中已弃用,并在 PHP 8.0 中移除。请勿使用它。

PHP 还通过标准 PHP 库 (SPL) 提供了用于文件系统交互的面向对象接口:

  • SplFileInfo:为特定文件或目录的信息提供高级的面向对象接口。
  • DirectoryIterator:一个迭代器,用于轻松遍历目录内容,生成 SplFileInfo 对象。
  • RecursiveDirectoryIterator / RecursiveIteratorIterator:用于遍历嵌套目录。

使用 DirectoryIterator 的示例:

<?php
$path = './my_directory'; // 确保此目录存在
try {
$iterator = new DirectoryIterator($path);
foreach ($iterator as $fileInfo) {
if ($fileInfo->isFile()) {
echo $fileInfo->getFilename() . " - Size: " . $fileInfo->getSize() . " bytes\n";
} elseif ($fileInfo->isDir() && !$fileInfo->isDot()) { // 排除 '.' 和 '..'
echo $fileInfo->getFilename() . " [Directory]\n";
}
}
} catch (Exception $e) {
echo "Error accessing directory: " . $e->getMessage();
}
?>

许多文件系统函数不仅可以处理本地文件。PHP 的流包装器 (Stream Wrappers) 系统允许将各种资源视为文件。常见示例包括:

  • file://:访问本地文件系统(通常是默认值)。
  • http://, https://:通过 HTTP(S) 访问 URL。需要在 php.ini 中设置 allow_url_fopen=On。
  • ftp://, ftps://:通过 FTP(S) 访问资源。需要 allow_url_fopen=On。
  • php://:访问各种 I/O 流(例如,php://stdin, php://stdout, php://stderr, php://input, php://output, php://memory, php://temp)。

读取请求体的示例:

<?php
// 获取原始 POST 数据
$requestBody = file_get_contents('php://input');
// 注意:'php://input' 在 enctype="multipart/form-data" 时不可用
?>

注意:如果 allow_url_fopen 被启用,且用户输入未经适当验证直接用于 file_get_contents() 或 include 等函数,可能会带来安全风险,可能导致远程文件包含 (RFI) 漏洞。考虑使用 cURL 来更健壮、更安全地处理远程 HTTP 请求。