从词源和输出生成等角度详细解析PHP中常用文件操作类函数

PHP作为服务器端脚本语言的代表,其文件操作函数构成了Web开发中数据处理的核心基础设施。这类函数主要围绕文件的创建、读写、权限管理和路径解析展开,通过fopen()、fread()、file_get_contents()等基础函数实现从简单文本到二进制数据的全类型文件操作。在功能实现上,PHP采用分层设计理念:底层通过fopen()建立文件句柄,中层使用fwrite()/fgets()进行块读写,高层则提供file_put_contents()等封装函数实现快捷操作,这种设计既保证了灵活性又提升了开发效率。其重要性体现在三个方面:首先作为数据持久化的基础手段,支撑着配置文件管理、日志记录等关键场景;其次在文件上传下载、缓存生成等Web特色功能中不可替代;最后通过与目录操作函数(如scandir())的配合,构建了完整的文件系统交互能力。

现代PHP文件操作已形成以流(stream)为核心的体系架构,这种设计使得本地文件与网络资源的操作接口高度统一。在实际应用中,开发者既可通过面向过程的函数链式调用处理简单任务,也能结合SPL(标准PHP库)的SplFileObject类实现面向对象操作,这种双范式支持显著提升了代码的可维护性。从行业应用看,这些函数在CMS内容存储、电商系统订单导出、大数据日志分析等场景均有深度应用,特别是file()函数直接将文件映射为数组的特性,极大简化了CSV等结构化数据的处理流程。值得注意的是,随着PHP8的性能优化,文件操作函数在JIT编译加持下,其执行效率已接近C扩展模块的水平。

面向未来,PHP文件操作函数的发展呈现两个明确趋势:一方面,为适应云原生环境,新增了stream_context_create()等函数强化对云存储协议的支持;另一方面,通过类型系统的强化和异常机制的完善,逐步替代传统的错误抑制符用法,使文件操作更安全可靠。尽管新兴技术如NoSQL和对象存储不断涌现,但基于文件的持久化方案凭借其普适性和零依赖特点,仍将在PHP生态中保持基础地位,而现代化封装如Flysystem等库的出现,则进一步拓展了传统文件操作函数的应用边界。在可预见的未来,这些经过20余年锤炼的函数仍会是PHP开发者处理I/O操作的首选工具集。

本文主要讲解了7大类29个常用的PHP文件操作函数,依次是:

一、文件打开/关闭‌类(2个):fopen()‌、fclose()‌

‌ 二、文件读取‌类(6个):readfile()、fread()‌、fgets()‌、fgetc()‌、file_get_contents()‌、file()‌

‌ 三、文件写入‌类(2个):fwrite()‌、file_put_contents()‌

‌ 四、文件信息获取‌类(5个):filesize()‌、filetype()‌、fstat()‌、stat() 、file_exists()‌

五、路径操作‌类(4个):basename()‌、dirname()、pathinfo()、realpath()

六、时间相关类(3个):fileatime() 、filemtime()、filectime()

七、其他函数‌类(7个):flock()‌、unlink()‌、rename()‌、fseek()‌、ftell()‌、ftruncate()‌、copy()

一、文件打开/关闭‌类(2个)

(一)fopen()‌

1‌、词源分解‌:

  • f:源自 "file"(文件),标识文件操作。

  • open:动词 "打开",表示初始化文件访问。

‌2、功能‌:

打开文件或 URL,返回文件指针。

3、语法结构‌:

php 复制代码
resource fopen(string $filename, string $mode, bool $use_include_path = false, resource $context = null)

4、参数说明‌:

  • $filename:文件路径或 URL。

  • $mode:打开模式(共12种模式,如 r 只读、w 写入、a 追加)。

  • $use_include_path:是否在 PHP 包含路径中搜索文件(默认 false)。

  • $context:流上下文资源(可选)。

5、示例‌:

php 复制代码
$file = fopen("data.txt", "r"); // 以只读模式打开文件
if ($file) {
    echo "文件打开成功";
} else {
    echo "文件打开失败";
}

‌输出‌:

php 复制代码
文件打开成功

6、$mode12种模式参数全解

|----------|----------------|------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------|----------|-----------|
| 模式 | 词源/全称 | 功能说明 | 文件存在时 | 文件不存在时 | 指针位置 | 二进制模式 |
| ‌r‌ | Read(读取) | 只读模式。 该模式用于以只读方式打开文件。当文件存在时,文件指针会被放置在文件的开头位置,允许从文件起始处开始读取内容。如果指定的文件不存在,fopen()函数将返回false并产生一个警告。此模式适用于只需要读取文件内容而不进行任何修改的场景,例如读取配置文件或数据分析。 | 打开文件 | 返回false | 文件开头 | 可加b |
| ‌r+‌ | Read+Write | 读写模式。 该模式允许对文件进行读取和写入操作。文件指针初始位于文件开头,可以自由移动指针位置进行读写。与r模式类似,如果文件不存在则会返回false。需要注意的是,写入操作会从当前指针位置开始覆盖原有内容,而不是插入新内容。这种模式适合需要同时读写文件的场景,如日志文件的部分修改。 | 打开文件 | 返回false | 文件开头 | 可加b |
| ‌
w
‌ | Write(写入) | 只写模式。 此模式用于写入文件内容。如果文件已存在,该文件将被截断为零长度,即所有原有内容都会被清空;如果文件不存在,则会创建一个新文件。无论哪种情况,文件指针都会被放置在文件开头。这种模式适用于需要完全重写文件内容的场景,如生成新的日志文件或临时文件。 | 清空内容 | 创建新文件 | 文件开头 | 可加b |
| ‌w+‌ | Write+Read | 读写模式。 该模式结合了w和r+的特性,允许读写操作。与w模式相同,如果文件存在则清空内容,不存在则创建新文件。文件指针初始位于文件开头,可以自由移动进行读写操作。这种模式适合需要完全重写文件同时又需要读取内容的场景。 | 清空内容 | 创建新文件 | 文件开头 | 可加b |
| ‌
a
‌ | Append(追加) | 只写追加。 此模式用于在文件末尾追加内容。如果文件存在,文件指针会被放置在文件末尾;如果文件不存在,则会创建新文件。与w模式不同,a模式不会清空文件原有内容,所有写入操作都会自动追加到文件末尾。这种模式特别适合日志记录等需要持续添加内容的场景。 | 保留内容 | 创建新文件 | 文件末尾 | 可加b |
| ‌a+‌ | Append+Read | 读写追加。 该模式允许读取和追加写入文件。文件指针在读取时可以自由移动,但在写入时总是会自动跳转到文件末尾进行追加。如果文件不存在则会创建新文件。这种模式适用于需要查看文件内容同时又需要追加新数据的场景,如日志分析工具。 | 保留内容 | 创建新文件 | 文件末尾 | 可加b |
| ‌
x
‌ | eXclusive(独占) | 谨慎写入。 此模式用于以独占方式创建并写入文件。如果文件已存在,fopen()将返回false并产生警告;如果文件不存在,则创建新文件并打开写入。这种模式提供了一种防止并发创建文件的机制,适合需要确保文件唯一性的场景。 | 返回false | 创建新文件 | 文件开头 | 可加b |
| ‌x+‌ | eXclusive+Read | 独占读写。 该模式结合了x和w+的特性,以独占方式创建文件并允许读写操作。与x模式相同,如果文件存在则操作失败。这种模式适用于需要独占访问并需要读写功能的场景。 | 返回false | 创建新文件 | 文件开头 | 可加b |
| ‌
c
‌ | Create(创建) | 谨慎写入。 此模式与w模式类似,但不会自动截断文件。如果文件存在,则打开并保留原有内容;如果不存在则创建新文件。文件指针初始位于文件开头,写入时会覆盖当前位置的内容。这种模式适合需要修改文件部分内容而不想完全清空文件的场景。 | 不截断 | 创建新文件 | 文件开头 | 可加b |
| ‌c+‌ | Create+Read | 创建读写。 该模式允许读写操作,与c模式类似不会自动截断文件。文件指针可以自由移动,写入时会覆盖当前位置的内容。这种模式适用于需要灵活读写文件同时又想保留未修改内容的场景。 | 不截断 | 创建新文件 | 文件开头 | 可加b |
| ‌
b
‌ | Binary(二进制) | 二进制模式修饰符。 作为模式修饰符,b表示以二进制模式操作文件。在Windows系统上,这会阻止换行符的自动转换;在其他系统上则没有影响。建议在处理二进制文件(如图片、压缩包等)时总是使用此修饰符。 | - | - | - | 强制二进制 |
| ‌t‌ | Text(文本) | 文本模式修饰符。 作为模式修饰符,t表示以文本模式操作文件。在Windows系统上,这会启用换行符的自动转换;在其他系统上则被忽略。除非明确需要文本转换,否则一般不推荐使用此修饰符。 | - | - | - | 转换换行符 |

模式参数表格的关键说明‌

词源解析‌:

  • r:源自C语言的fopen()模式,代表"read"

  • w:来自"write",早期编程语言通用约定

  • a:取自"append",首次出现在Unix V7系统中

  • x:PHP独有,意为"exclusive lock"

  • c:PHP5引入,来自"create if not exists"

‌ 二进制模式(b)‌:

  • Windows下:强制不转换\r\n\n

  • Linux下:被忽略(所有文件都是二进制流)

‌ 系统差异‌:

  • Windows:接受/\

  • Linux:仅/

  • Windows:\r\n

  • Linux:\n

  • Mac传统:\r

‌ 使用建议‌:

  • 处理文本文件:使用t模式(仅Windows有效)

  • 处理二进制文件:始终添加b模式

  • 并发安全:x模式可防止竞态条件

7、能否直接输出

fopen()函数本身不能直接输出文件内容,它仅用于打开文件并返回一个文件指针资源。要实现文件内容输出,需要结合其他函数如fread()fgets()file_get_contents()等。以下是具体说明:

  • ‌**fopen()的功能**‌

    该函数仅建立文件与流的连接,返回资源句柄供后续操作使用,模式参数(如'r')决定打开方式(只读/写入等)。

  • 需配合输出函数使用

    • ‌**fread()** ‌:读取指定字节数后输出

      php 复制代码
      $file = fopen("file.txt", "r");
      echo fread($file, filesize("file.txt"));
      fclose($file);
    • ‌**fgets()**‌:逐行读取输出

    • ‌**file_get_contents()**‌:更简洁的直接读取(无需显式打开/关闭)

(二)fclose()‌

1‌、词源分解‌:

  • f:文件。

  • close:动词 "关闭"。

2‌、功能‌:

关闭文件指针释放资源。

3、语法结构‌:

php 复制代码
bool fclose(resource $handle)
  • ‌参数说明‌:

    • $handle:文件指针资源。

4、示例‌:

php 复制代码
$file = fopen("data.txt", "r");
fclose($file);
示例代码执行结果‌

‌ 文件操作流程‌

  • 若文件存在且可读:返回文件资源句柄($file

  • 若文件不存在或不可读:返回false

  • fopen("data.txt", "r"):尝试以只读模式打开data.txt文件

  • fclose($file):立即关闭文件资源

实际效果‌

  • ‌成功打开时‌:文件被打开后立即关闭,无内容读取或修改,脚本继续执行后续代码(无输出)

  • ‌失败时‌:若fopen()返回falsefclose()会触发警告(Warning: fclose() expects parameter 1 to be resource, bool given

5、fclose()的重要性‌

‌释放系统资源‌

  • 文件打开后占用操作系统资源(如文件描述符),fclose()显式释放这些资源,避免资源泄漏。

‌解除文件锁定‌

  • 某些系统(如Windows)会锁定被打开的文件,导致其他进程无法修改或删除。及时关闭可解除锁定。

‌避免性能问题‌

  • 未关闭的文件句柄会持续消耗内存,尤其在循环或高并发场景下可能导致内存耗尽。

‌数据完整性保障‌

  • 写入模式下(如"w""a"),fclose()会强制刷新缓冲区,确保数据完全写入磁盘。

‌最佳实践‌

  • 应配合try-finallyregister_shutdown_function确保文件始终关闭:
php 复制代码
$file = fopen("data.txt", "r");
try {
    // 文件操作...
} finally {
    fclose($file); // 确保关闭
}

6、改进建议‌

  • 始终检查fopen()返回值:
php 复制代码
$file = fopen("data.txt", "r");
if ($file !== false) {
    fclose($file);
}
  • 考虑使用SplFileObject(自动管理资源):
php 复制代码
$file = new SplFileObject("data.txt", "r");
// 无需手动关闭(析构函数自动处理)

‌7、能否直接输出

fclose()函数‌不能直接输出内容 ‌,它的核心功能是关闭已打开的文件指针并释放系统资源,返回值为布尔类型(成功关闭返回true,失败返回false)。以下是关键点说明:

  • 功能定位

    fclose()仅用于关闭由fopen()打开的文件流,确保文件操作完成后释放资源,避免内存泄漏或文件锁定问题。例如:

    php 复制代码
    $file = fopen("example.txt", "r");
    // 文件操作...
    fclose($file); // 关闭文件,无输出
  • 输出需结合其他函数

    若需输出文件内容,必须在关闭前使用如fread()fgets()readfile()等函数读取内容并显式输出。例如:

    php 复制代码
    $file = fopen("example.txt", "r");
    echo fread($file, filesize("example.txt")); // 先输出内容
    fclose($file); // 后关闭

    总结:fclose()本身不涉及输出逻辑,需通过其他读取函数配合实现内容输出。

二、文件读取‌类(6个)

(一)readfile()

1、词源分解

readfile 由两个英文单词组成:

  • read(读取):表示从存储介质中获取数据

  • file(文件):表示操作的对象是文件系统中的一个文件

组合含义为"读取文件内容并输出"

2、功能概述

readfile() 是 PHP 内置的文件系统函数,主要功能是读取文件内容并直接写入输出缓冲区(通常是发送到浏览器或命令行)。该函数特别适合处理大文件下载和静态文件输出场景。

3、语法结构

php 复制代码
int readfile(string $filename [, bool $use_include_path = false [, resource $context ]])

4、参数详解

(1)$filename(必需参数)
  • ‌类型‌:字符串

  • ‌功能‌:指定要读取的文件路径

  • ‌特殊支持‌:

    • 本地文件路径(如/path/to/file.txt

    • URL格式(需allow_url_fopen启用)

  • ‌安全建议‌:应对用户提供的路径进行验证,防止目录遍历攻击

(2)$use_include_path(可选参数)
  • ‌类型‌:布尔值

  • ‌默认值‌:false

  • ‌功能‌:是否在PHP配置的include_path中搜索文件

  • ‌启用效果‌:设为true时会在php.ini中配置的包含路径中查找文件

(3)$context(可选参数)
  • ‌类型‌:资源(resource)

  • ‌默认值‌:null

  • ‌功能‌:指定流上下文(stream context)修改流行为

  • ‌典型应用‌:

    • 设置HTTP请求头

    • 配置SSL选项

    • 修改流超时时间

  • ‌版本要求‌:PHP 5.0.0+ 支持

5、返回值

  • ‌成功时‌:返回读取的字节数(整数)

  • ‌失败时‌:返回false并生成E_WARNING级错误

  • ‌错误抑制‌:可使用@readfile()隐藏错误信息

6、输出换行说明

readfile()会‌原样输出‌文件内容,包括所有换行符:

  1. 如果文件本身包含换行符(\n\r\n),输出时会保留这些换行

  2. 如果文件最后一行有换行符 → 输出后会换行

  3. 如果文件最后一行没有换行符 → 输出后不会换行

7、基础示例与输出

示例1:简单文本输出
php 复制代码
// 文件内容为"Hello\nWorld!"(共11字节,包含换行符)
$bytes = readfile("test.txt");
echo "读取了 {$bytes} 字节";

‌输出结果‌:

php 复制代码
Hello
World!读取了 11 字节
示例2:文件下载实现
php 复制代码
$file = 'document.pdf';
if (file_exists($file)) {
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

‌执行效果‌:浏览器会弹出下载对话框保存PDF文件

8、能否直接输出

readfile()函数可以直接输出文件内容到浏览器或输出缓冲区,无需额外使用echo或类似输出函数。以下是关键特性说明:

直接输出机制

该函数会读取文件内容并自动写入输出缓冲,适用于快速输出文本、图像或视频等文件类型。例如:

php 复制代码
readfile("example.txt"); // 直接输出文件内容

‌ 成功时返回读取的字节数,失败返回false。

注意事项

  • 大文件处理时需确保内存充足,建议关闭输出缓冲层检查(ob_get_level()
  • 若需对内容预处理,应使用fread()+fopen()组合替代

该函数是PHP文件操作中最简洁的输出方案之一,但仅适用于无需内容修改的直接输出需求。

9、高级应用

大文件分块读取(避免内存问题)
php 复制代码
$file = 'large_video.mp4';
$chunkSize = 1024 * 1024; // 1MB每次
if ($handle = fopen($file, 'rb')) {
    while (!feof($handle)) {
        echo fread($handle, $chunkSize);
        ob_flush();
        flush();
    }
    fclose($handle);
}

‌优势‌:避免一次性加载大文件导致内存溢出

10、性能特点

  1. ‌内存效率‌:直接输出到缓冲区,不将整个文件加载到内存

  2. ‌速度优势‌:比file_get_contents()+echo组合更快

  3. ‌适用场景‌:特别适合处理GB级大文件

11、安全注意事项

  1. ‌路径验证‌:应使用realpath()basename()处理路径

  2. ‌权限控制‌:确保脚本有文件读取权限

  3. ‌内容过滤‌:输出用户文件时应设置正确的MIME类型

  4. ‌目录遍历‌:禁止用户输入包含../的路径

12、相关函数对比

函数 内存使用 返回值 适用场景
readfile() 字节数 直接输出大文件
file_get_contents() 内容字符串 需要处理文件内容
fpassthru() 布尔值 已打开文件资源时使用

(二)fread()‌

1、词源分解

fread() 由两部分组成:

  • f:代表"file"(文件),是PHP文件操作函数的通用前缀

  • read:表示"读取"操作,源自英语动词"to read"

2、功能概述

fread() 是PHP核心文件系统函数,用于从已打开的文件中读取指定长度的数据。

其主要特点包括:

  • 支持二进制安全读取(处理图片、音视频等非文本文件)

  • 可精确控制读取字节数,适合大文件分块处理

  • 与文件指针配合实现随机访问

  • 在到达指定长度或文件末尾(EOF)时停止读取

3、语法结构

php 复制代码
string|false fread(resource $handle, int $length)

4、参数详解

(1)$handle(必需)
  • ‌类型‌:资源(resource)

  • ‌功能‌:有效的文件系统指针,通常由fopen()创建

  • ‌注意事项‌:

    • 必须指向已成功打开的文件

    • 读取二进制文件时建议使用"rb"模式打开

    • 无效指针会导致函数返回false

(2)$length(必需)
  • ‌类型‌:整型

  • ‌功能‌:指定最大读取字节数

  • ‌特殊值‌:

    • 使用filesize()可读取整个文件

    • 网络流每次最多读取8192字节

  • ‌注意事项‌:

    • 实际读取量可能小于指定值(到达EOF时)

    • 负值会导致读取失败

5、返回值

  • ‌成功时‌:返回包含读取数据的字符串

  • ‌失败时‌:返回false

  • ‌二进制安全‌:返回值可能包含空字节(\0)

6、能否直接输出

fread()函数本身不能直接输出内容,它仅用于从文件指针中读取指定长度的数据并返回字符串。要实现输出功能,需配合echo或类似输出语句。以下是具体说明:

  • 基本用法

    fread()需结合fopen()打开的文件指针使用,读取后需手动输出:

    php 复制代码
    $file = fopen("example.txt", "r");
    $content = fread($file, filesize("example.txt"));
    echo $content; // 手动输出读取的内容
    fclose($file);

    此方法适用于需处理读取内容的场景。‌

  • 分块输出大文件

    通过循环读取并输出分块数据,避免内存溢出:

    php 复制代码
    $file = fopen("large_file.txt", "r");
    while (!feof($file)) {
        echo fread($file, 8192); // 每次输出8KB
    }
    fclose($file);

    此方式适合处理大文件或二进制流。

总结:fread()需显式调用输出函数才能显示内容,若需简化流程可选用readfile()等内置输出函数。

7、基础示例

示例1:读取固定长度
php 复制代码
$file = fopen("data.txt", "r");
$content = fread($file, 100); // 读取前100字节
fclose($file);
echo $content;

‌输出‌:显示文件前100个字符(包含原始换行格式)

示例2:读取整个文件
php 复制代码
$filename = "image.jpg";
$handle = fopen($filename, "rb");
$data = fread($handle, filesize($filename));
fclose($handle);
header("Content-Type: image/jpeg");
echo $data; // 输出二进制图像数据

8、高级应用

大文件分块读取
php 复制代码
$chunkSize = 8192;
$handle = fopen("large.log", "r");
while (!feof($handle)) {
    $buffer = fread($handle, $chunkSize);
    processChunk($buffer); // 处理每个数据块
}
fclose($handle);

9、性能比较

  • 小文件推荐file_get_contents()(性能更优)

  • 大文件或需要精确控制时使用fread()

  • 按行处理考虑file()fgets()

10、错误处理建议

php 复制代码
$handle = @fopen("missing.txt", "r");
if ($handle === false) {
    die("无法打开文件");
}
$data = @fread($handle, 100);
if ($data === false) {
    die("读取失败");
}

​11、平台注意事项

  • Windows系统需显式使用二进制模式("rb")避免换行符转换

  • 网络流读取可能因数据包可用性提前返回

  • 用户空间流每次最多返回8192字节

(三)fgets()‌

‌1、词源分解‌:

  • f:文件。

  • gets:源自 "get string"(获取字符串)。

‌2、功能‌:

逐行读取文件内容。

3、语法结构‌:

php 复制代码
string fgets(resource $handle)

4、参数说明‌:

  • $handle:文件指针资源。

5、示例‌:

php 复制代码
$file = fopen("data.txt", "r");
$line = fgets($file); // 读取第一行
fclose($file);
echo $line;

‌ 假设文件内容为 Hello\nWorld,输出‌:

php 复制代码
Hello
该示例代码读取第一行的机制分析:

‌ (1)文件指针初始位置‌
fopen()"r"模式打开文件时,文件指针自动定位到文件起始位置(即第一行开头)。此时fgets()会从指针当前位置开始读取。

‌ (2)fgets()函数特性‌

  • 每次调用默认读取一行(直到遇到换行符\n或文件结束)

  • 首次调用时自然读取首行内容

  • 读取后指针自动移动到下一行起始位置

‌ (3)代码执行流程示例‌

假设data.txt内容为:

php 复制代码
Line 1
Line 2

(4)执行过程:

  • fopen() → 指针指向L(第0字节)

  • fgets() → 读取Line 1\n,指针移动到L(第6字节)

  • 未继续读取即关闭文件

‌ (5)与fgetc()的区别‌
fgetc()仅读取单个字符,而fgets()按行读取,这是两者本质差异。若需完整读取文件,通常需配合循环结构:

php 复制代码
$file = fopen("data.txt", "r");
if ($file) {
    while (($line = fgets($file)) !== false) {
        echo $line; // 逐行输出
    }
    fclose($file);
}

通过while循环持续读取,直到fgets()返回false(文件末尾)

该设计符合流式文件处理规范,与PHP底层通过文件指针管理读写位置的机制直接相关。

6、能否直接输出

fgets()函数‌不能直接输出内容 ‌,它仅用于从文件指针中读取一行数据并返回字符串,需配合echo等输出函数显示结果。以下是关键说明:

  • 基础功能

    fgets()从打开的文件中读取一行(包括换行符),返回字符串或false(失败时)。典型用法需手动输出:

    php 复制代码
    $file = fopen("example.txt", "r");
    $line = fgets($file); // 读取一行
    echo $line; // 手动输出
    fclose($file);
  • 适用场景

    • 需逐行处理文本时(如日志分析)。
    • 需控制读取长度(通过length参数限制字节数)。

总结:fgets()需显式调用输出函数。

(四) fgetc()‌

‌1、词源分解‌:

  • f:文件。

  • getc:源自 "get character"(获取字符)。

2‌、功能‌:

逐字符读取。

3、语法结构‌:

复制代码
string fgetc(resource $handle)

4、参数说明‌:

  • $handle:文件指针资源。

‌5、示例‌:

php 复制代码
$file = fopen("data.txt", "r");
$char = fgetc($file); // 读取第一个字符
fclose($file);
echo $char;
  • ‌假设文件内容为 ABC,输出‌:
php 复制代码
A
该示例代码读取第一个字符的行为机制分析:

‌ (1)文件指针初始化位置‌
fopen()"r"模式打开文件时,文件指针自动定位到文件起始位置(第0字节处)。此时指针指向第一个字符的存储位置,为后续读取操作提供起点。

‌ (2)fgetc()函数的工作特性‌

  • 单次调用仅读取当前指针位置的1个字符

  • 读取后自动将指针移动到下一字符位置

  • 首次调用时自然读取首字符,与C语言的fgetc()行为一致

‌ (3)代码执行流程示例‌

假设data.txt内容为"Hello"

php 复制代码
执行步骤:
1. fopen() → 指针定位到'H'(地址0x00)
2. fgetc() → 读取'H',指针移动到'e'(地址0x01)
3. 未继续读取即关闭文件

如需完整读取文件,应使用循环结构:

php 复制代码
while (($char = fgetc($file)) !== false) {
    echo $char;
}

该方式会持续移动指针直至文件结束(EOF)。

该设计符合流式文件处理的通用规范,与PHP底层通过Zend Engine管理文件指针的机制直接相关。二进制模式下(如"rb")该行为同样适用,仅取消换行符转换。

6、能否直接输出

fgetc()函数‌不能直接输出内容 ‌,它仅从文件指针中读取单个字符并返回字符串,需配合echo等输出函数显示结果。以下是关键特性说明:

  • 基础功能

    • 每次调用读取一个字符,文件指针自动后移

    • 返回值为字符串(包含字符)或false(到达文件末尾时)

    • 需通过fopen()预先打开文件,示例:

      php 复制代码
      $file = fopen("test.txt", "r");
      echo fgetc($file); // 输出第一个字符
      fclose($file);
  • 典型应用场景

    • 逐字符处理文本(如解析特定格式数据)
    • 需精确控制读取位置时(结合fseek()使用)
  • 性能注意事项

    • 处理大文件效率极低,建议改用fgets()逐行读取
    • 二进制安全,可处理非文本文件

若需连续输出所有字符,通常配合循环使用:

php 复制代码
$file = fopen("test.txt", "r");
while (!feof($file)) {
    echo fgetc($file); // 逐字符输出
}
fclose($file);

(五) file_get_contents()‌

1‌、词源分解‌:

  • file:文件。

  • get_contents:获取内容。

‌2、功能‌:

一次性读取整个文件到字符串。

3、语法结构‌

php 复制代码
string file_get_contents(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null,
    int $offset = 0,
    ?int $maxlen = null
)

4、参数详解‌

  • **‌$filename**‌

    • 本地文件:"data.txt"

    • 远程URL:"https://example.com/api"

    • 特殊协议:"php://input"(读取POST原始数据)

    • ‌类型‌:string

    • ‌作用‌:指定要读取的文件路径或URL

    • ‌示例值‌:

  • **‌$use_include_path**‌

    • true:优先搜索include_path

    • false:仅搜索当前目录

    • ‌类型‌:bool

    • ‌默认值‌:false

    • ‌作用‌:是否在PHP配置的include_path中搜索文件

    • ‌可选值‌:

  • **‌$context**‌

    • ‌类型‌:resource

    • ‌默认值‌:null

    • ‌作用‌:通过stream_context_create()创建的流上下文,用于设置高级选项(如HTTP头、超时等)

    • ‌示例‌:

php 复制代码
$context = stream_context_create(['http' => ['timeout' => 5]]);
  • **‌$offset**‌

    • ‌类型‌:int

    • ‌默认值‌:0

    • ‌作用‌:指定开始读取的字节偏移量(从文件开头计算)

    • ‌注意‌:负值无效,非文本文件需谨慎使用

  • **‌$maxlen**‌

    • ‌类型‌:?int

    • ‌默认值‌:null(读取到文件末尾)

    • ‌作用‌:限制读取的最大字节数

    • ‌示例‌:

php 复制代码
// 仅读取前100字节
file_get_contents('file.txt', false, null, 0, 100);

参数说明表:

参数 类型 默认值 作用
$filename string - 文件路径/URL(必需)
$use_include_path bool false 是否在include_path中搜索文件
$context resource null 流上下文(用于高级配置)
$offset int 0 读取起始位置(字节)
$maxlen int null 最大读取字节数

5、返回值‌

  • ‌成功时‌:返回文件内容的字符串

  • ‌失败时‌:返回false(需用===严格判断)

6、注意事项‌

  • 大文件(>10MB)建议使用fopen()逐块读取以避免内存溢出

  • 远程请求需确保allow_url_fopen配置启用

  • 路径中的反斜杠(\)需转义或使用正斜杠(/

7、示例‌:

php 复制代码
$content = file_get_contents("data.txt");
echo $content;
  • ‌输出‌:文件完整内容(如 Hello\nWorld)。

8、能否直接输出

file_get_contents()函数‌不能直接输出内容 ‌,它仅将文件内容读取为字符串并返回,需配合echo等输出函数显示结果。以下是关键说明:

  • 基础功能

    • 读取整个文件内容到字符串,返回结果需手动输出

    • 示例:

      复制代码
      php 复制代码
      $content = file_get_contents("test.txt");
      echo $content; // 必须显式调用输出函数
  • 直接输出替代方案

    • readfile():直接输出文件内容到缓冲区,无需中间变量
    • fpassthru():结合fopen()使用,从当前指针位置输出剩余内容
  • 性能对比

    • file_get_contents()适合处理需操作内容字符串的场景(如文本解析)
    • readfile()在输出大文件时内存效率更高,避免中间变量占用
  • 特殊用法

    • 支持HTTP/HTTPS协议直接读取远程资源
    • 二进制安全,可处理图像等非文本文件

总结:若仅需输出内容,优先选用readfile();若需处理字符串数据,则使用file_get_contents()+echo组合。

(六)file()‌

‌1、词源分解‌:

直接源自 "file"(文件)。

2‌、功能‌:

按行读取文件返回数组。

3、语法结构‌:

php 复制代码
array file(string $filename, int $flags = 0, resource $context = null)

4、参数说明‌:

  • $filename:文件路径。

  • $flags:可选常量。(如 FILE_IGNORE_NEW_LINES)。

  • $context:流上下文资源(可选)。

5、flags参数的可选常量,有以下5个:

  1. ‌FILE_USE_INCLUDE_PATH‌

    该常量指示函数在include_path中查找文件。当设置此标志时,如果文件在当前目录不存在,PHP会按照include_path配置的路径顺序搜索文件。

  2. ‌FILE_IGNORE_NEW_LINES‌

    使用该常量时,函数会在读取文件时忽略每行末尾的换行符。这意味着返回的数组元素中不会包含\n\r\n等行结束符,适合需要干净文本数据的场景。

  3. ‌FILE_SKIP_EMPTY_LINES‌

    该常量使函数自动跳过文件中的空行。当文件中存在仅包含换行符或空白字符的行时,这些行不会被包含在返回的数组中。

  4. ‌FILE_TEXT‌

    此常量指定以文本模式读取文件,会执行平台相关的换行符转换(如在Windows上将\r\n转换为\n)。但需注意该常量在PHP官方文档中未明确列出,实际使用可能存在兼容性问题。

  5. ‌FILE_BINARY‌

    与FILE_TEXT相对,该常量强制以二进制模式读取文件,禁止任何换行符转换。这是默认的读取模式,特别适合处理图片、压缩包等二进制文件。

6、示例‌:

php 复制代码
$lines = file("data.txt");
print_r($lines);

‌ 输出‌:

php 复制代码
Array
(
    [0] => Hello
    [1] => World
)

7、能否直接输出

file()函数‌不能直接输出内容 ‌,它仅将文件内容按行读取到数组中并返回该数组,需配合循环和输出函数(如echo)显示内容。以下是关键特性说明:

  • 基础功能

    • 返回值为数组,每个元素对应文件中的一行(包括换行符)

    • 需手动遍历数组输出内容,例如:

      php 复制代码
      $lines = file('example.txt');
      foreach ($lines as $line) {
          echo $line; // 逐行输出
      }
  • 适用场景

    • 需逐行处理文本(如日志分析、配置文件解析)
    • 支持FILE_IGNORE_NEW_LINES等参数控制换行符处理
  • 性能注意事项

    • 大文件处理时内存占用较高,建议改用fgets()逐行读取

‌三、文件写入‌类(2个)

‌(一)fwrite()‌

‌1、词源分解‌:

  • f:文件。

  • write:动词 "写入"。

‌2、功能‌:

向文件写入数据(别名 fputs)。

3、语法结构‌:

php 复制代码
int|false fwrite(resource $handle, string $string [, int $length = null])

4、参数说明‌:

  • $handle:文件指针资源。

  • $string:要写入的字符串。

  • $length:写入字节数(可选)。

5、示例‌:

php 复制代码
$file = fopen("log.txt", "w");
fwrite($file, "New log entry");
fclose($file);

‌ 执行后文件内容‌:

php 复制代码
New log entry

刚才的示例代码中,文件原有的内容被清空,只有新写入的内容。在PHP中,fwrite()写入字节时原有内容是否保留,取决于文件打开模式的选择:

第一种‌:覆盖模式("w"或"w+")‌

  • 使用fopen()"w"模式时,文件指针会指向文件开头并‌清空原有内容‌,后续fwrite()写入的新数据会完全替换旧内容

  • 示例:

php 复制代码
$file = fopen("test.txt", "w");
fwrite($file, "New Data"); // 原内容被清空
fclose($file);

‌第二种:追加模式("a"或"a+")‌

  • 使用"a"模式时,文件指针指向文件末尾,新写入的数据会‌保留原有内容‌并追加到文件尾部

  • 示例:

php 复制代码
$file = fopen("test.txt", "a");
fwrite($file, "Appended Data"); // 原内容保留
fclose($file);

‌第三种:读写模式("r+")‌

  • 使用"r+"模式时,文件指针位于开头,写入数据会‌从当前位置覆盖对应字节‌,未覆盖的部分保持不变

  • 示例:

php 复制代码
$file = fopen("test.txt", "r+");
fseek($file, 5); // 移动指针到第5字节
fwrite($file, "XX"); // 仅覆盖第5-6字节
fclose($file);

‌关键总结‌:

  • 是否保留原内容由fopen()的模式参数决定,而非fwrite()本身

  • 二进制安全特性确保写入的字节数据(包括\0)会被完整处理

6、能否直接输出

fwrite()函数‌不能直接输出内容到浏览器‌,它仅用于向已打开的文件或流中写入数据,需配合文件指针操作实现输出功能。以下是关键特性说明:

  • 基础功能

    • 需通过fopen()获取文件句柄(如php://stdout指向标准输出流)

    • 写入成功返回字节数,失败返回false(如权限不足或磁盘满)

    • 示例向标准输出写入内容:

      php 复制代码
      // 写入文件
      $file = fopen('output.txt', 'w');
      fwrite($file, "Hello World");
      fclose($file);
      
      // 输出文件内容
      readfile('output.txt');
  • 与直接输出函数的区别

    • echo/print:直接输出到页面,无需文件操作
    • file_put_contents():封装了文件打开/写入/关闭的全流程
  • 输出控制场景

    • CLI模式下可定向到标准输出流(php://stdout
    • Web环境下需结合输出缓冲区(ob_start())管理内容
  • 二进制安全特性

    • 支持写入非文本数据(如图像、二进制流)
    • 换行符需显式添加(如\nPHP_EOL

(二)file_put_contents()‌

‌1、词源分解

  • file_put_contents() 由三部分组成:

  • file:文件

  • put:放置/写入

  • contents:内容

    组合含义为"将内容放入文件"

2、功能概述

  • 该函数是PHP提供的文件写入快捷方法,可一次性完成打开文件、写入数据和关闭文件的操作,相当于fopen()fwrite()fclose()的组合。主要特点包括:

  • 支持字符串、数组和流数据写入

  • 自动创建不存在的文件

  • 提供追加写入和文件锁定选项

  • 二进制安全(可处理\0等特殊字符)

3、语法结构

php 复制代码
int file_put_contents(
    string $filename,
    mixed $data,
    int $flags = 0,
    resource $context = null
)

4、参数详解

(1)$filename(必需)
  • ‌含义‌:目标文件路径

  • ‌值类型‌:字符串

  • ‌特性‌:

    • 支持相对/绝对路径

    • 文件不存在时自动创建(需目录有写权限)

    • 使用FILE_USE_INCLUDE_PATH标志时会在include路径中查找文件

(2)$data(必需)
  • ‌含义‌:要写入的内容

  • ‌值类型‌:

    • 字符串(最常见)

    • 数组(自动转换为字符串,元素间用空格连接)

    • 流资源(PHP 5.1.0+)

  • ‌注意‌:

    • 数组不能是多维数组

    • 资源流需包含有效数据

(3) $flags(可选)
  • ‌含义‌:写入行为标志

  • ‌默认值‌:0(覆盖写入)

  • ‌可选常量‌(可用|组合):

    常量 作用
    FILE_USE_INCLUDE_PATH 1 在include路径中查找文件
    FILE_APPEND 8 追加内容而非覆盖
    LOCK_EX 2 写入时独占锁定文件
(4)$context(可选)
  • ‌含义‌:流上下文资源

  • ‌用途‌:

    • 修改流行为(如超时设置)

    • 自定义HTTP头(写入远程文件时)

    • 多数情况下可忽略

5、返回值

  • ‌成功‌:返回写入的字节数(整数)

  • ‌失败‌:返回false

6、使用示例

(1)基础写入
php 复制代码
$file = "example.txt";
$content = "Hello World!\nSecond Line";
$bytes = file_put_contents($file, $content);
echo "写入 {$bytes} 字节"; // 输出:写入 24 字节

执行后example.txt内容:

php 复制代码
Hello World!
Second Line
(2)追加内容
php 复制代码
$file = "log.txt";
$newLog = date('Y-m-d H:i:s')." - 系统启动\n";
file_put_contents($file, $newLog, FILE_APPEND);

多次执行会在log.txt末尾追加新日志行

(3)数组写入
php 复制代码
$data = ['Apple', 'Banana', 'Cherry'];
file_put_contents('fruits.txt', $data);

生成文件内容:

php 复制代码
Apple Banana Cherry
(4)带锁定的写入
php 复制代码
$config = "timeout=30\nmax_connections=100";
file_put_contents('config.ini', $config, LOCK_EX);

确保写入过程不被其他进程中断。

7、能否直接输出

file_put_contents()函数本身‌不能直接输出到浏览器或终端‌,它专用于将数据写入文件。以下是具体实现输出的方法和示例:

(1) ‌写入文件后读取输出

通过组合file_put_contents()readfile()实现:

php 复制代码
// 写入文件
file_put_contents("output.txt", "示例内容");
// 读取并输出文件内容
readfile("output.txt");

适用于需要持久化存储的场景。

(2)特殊流输出示例

通过php://output流间接输出:

php 复制代码
file_put_contents('php://output', "通过流输出的内容");

需配合输出缓冲控制(如ob_start())确保Web环境正常显示。

(3)追加写入与输出结合

追加内容到文件并输出结果:

php 复制代码
$file = "log.txt";
$content = date('Y-m-d H:i:s') . " 日志记录\n";
file_put_contents($file, $content, FILE_APPEND);
echo "已追加日志:" . htmlspecialchars($content);

适用于日志记录等场景。

8、常见问题与解决方案

  • ‌权限不足‌

    • 错误表现:Warning: file_put_contents(): failed to open stream: Permission denied

    • 解决:确保目标目录有写权限(Linux下可执行chmod -R 755 /path/to/dir

  • ‌目录不存在‌

    • 错误表现:No such file or directory

    • 解决:先使用mkdir()创建目录

  • ‌磁盘空间不足‌

    • 错误表现:返回false且无明确错误

    • 解决:检查磁盘剩余空间

  • ‌特殊字符处理‌

    • 二进制数据需确保文件以二进制模式打开(自动处理)

9、性能建议

  • 大文件写入建议使用fopen()+fwrite()循环

  • 高频写入场景考虑使用文件锁避免冲突

  • 重要数据写入后应验证返回值

10、相关函数对比

函数 特点 适用场景
file_put_contents() 单次调用完成写入 简单文件操作
fwrite() 需配合fopen()使用 流式写入/大文件
file() 读取文件为数组 按行读取内容

‌四、文件信息获取‌类(5个)

‌(一)filesize()‌

1、词源分解

filesize() 由两部分组成:

  • file:表示"文件",源自英语名词"file"

  • size:表示"大小",源自英语名词"size"

2、功能概述

filesize() 是PHP核心文件系统函数,用于获取指定文件的大小信息。其主要特点包括:

  • 返回以字节为单位的文件大小

  • 支持本地文件系统路径

  • 结果会被PHP缓存,需使用clearstatcache()清除

  • 超过2GB的文件可能返回负值(32位系统限制)

3、语法结构

php 复制代码
int|false filesize(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要检查的文件路径

  • ‌注意事项‌:

    • 可以是相对或绝对路径

    • 不支持网络URL(HTTP/FTP等)

    • 无效路径会导致函数返回false并触发警告

5、返回值

  • ‌成功时‌:返回文件大小的整数值(字节数)

  • ‌失败时‌:返回false并生成E_WARNING级错误

  • ‌特殊值‌:

    • 32位系统上超过2GB文件可能返回负值

    • 空文件返回0

6、基础示例

示例1:基本用法
php 复制代码
$filename = 'document.pdf';
$size = filesize($filename);
if ($size !== false) {
    echo "文件大小: $size 字节";
} else {
    echo "无法获取文件大小";
}

‌输出‌:显示文件字节数或错误信息

示例2:带格式转换
php 复制代码
function formatSize($bytes) {
    $units = ['B', 'KB', 'MB', 'GB'];
    $index = 0;
    while ($bytes >= 1024 && $index < 3) {
        $bytes /= 1024;
        $index++;
    }
    return round($bytes, 2) . ' ' . $units[$index];
}
$size = filesize('video.mp4');
echo "文件大小: " . formatSize($size) . PHP_EOL;

‌输出‌:类似"文件大小: 1.75 GB"(末尾换行)

7、能否直接输出

filesize()函数不能直接输出到浏览器或终端,它仅返回文件大小的字节数(整数)或失败时返回false。以下是具体实现输出的方法和示例:

(1)基础输出方法

通过echoprint组合实现直接输出:

php 复制代码
$filename = 'example.txt';
$size = filesize($filename);
if ($size !== false) {
    echo "文件大小: " . $size . " 字节"; 
} else {
    echo "获取文件大小失败";
}
  • 关键点 ‌:需检查返回值是否为false以处理异常。
(2)格式化输出示例

将字节转换为更友好的单位(如KB/MB):

php 复制代码
function formatSize($bytes) {
    $units = ['B', 'KB', 'MB', 'GB'];
    $index = 0;
    while ($bytes >= 1024 && $index < count($units) - 1) {
        $bytes /= 1024;
        $index++;
    }
    return round($bytes, 2) . ' ' . $units[$index];
}

$filename = 'large_file.zip';
$size = filesize($filename);
if ($size !== false) {
    echo "文件大小: " . formatSize($size); // 输出类似 "文件大小: 2.5 MB"
}
  • 特点‌:自动适配单位,提升可读性。
(3) ‌结合文件检查的完整示例
php 复制代码
$filename = 'data.txt';
if (file_exists($filename)) {
    $size = filesize($filename);
    if ($size !== false) {
        echo "文件 {$filename} 的大小为 " . number_format($size) . " 字节";
    } else {
        echo "无法读取文件大小";
    }
} else {
    echo "文件不存在";
}
  • 注意事项 ‌:需先通过file_exists()验证文件存在性。
(4)直接输出到浏览器的限制
  • filesize()本身无输出能力,必须依赖其他输出函数(如echo)。
  • 远程文件需确保allow_url_fopen启用,否则可能失败。
(5)常见问题
  • 权限不足 ‌:文件不可读时返回false
  • 路径错误‌:相对路径需基于当前脚本目录。
  • 大文件处理‌:超过2GB的文件需在64位系统下运行。

8、高级应用

大文件处理
php 复制代码
// 64位系统处理大文件
if (PHP_INT_SIZE === 8) {
    $size = filesize('large.iso');
    echo "完整大小: $size 字节";
} else {
    echo "32位系统不支持超过2GB文件的精确测量";
}

9、错误处理建议

php 复制代码
$file = 'missing.txt';
if (!file_exists($file)) {
    die("文件不存在");
}
$size = @filesize($file);
if ($size === false) {
    die("获取大小失败");
}

10、性能优化

  • 多次调用前使用clearstatcache()

  • 结合file_exists()预先检查

  • 避免在循环中重复调用

11、平台注意事项

  • Windows和Linux路径格式差异

  • 符号链接返回目标文件大小

  • 某些特殊文件(如设备文件)可能返回0或false

12、相关函数对比

  • disk_free_space():获取磁盘剩余空间

  • stat():获取详细文件信息

  • fstat():通过文件句柄获取信息

filesize()作为PHP文件操作的基础函数,在文件上传验证、磁盘空间管理、日志分析等场景中具有不可替代的作用。其简洁的接口设计使得开发者能够快速集成到各类应用中,而结合格式转换函数后更能满足实际业务中的可视化需求。

(二)filetype()‌

‌1、词源分解‌:

  • file:文件。

  • type:类型。

‌2、功能‌:

返回文件类型(如 file/dir)。

‌3、语法结构‌:

php 复制代码
string|false filetype(string $filename)

4‌、参数说明‌:

  • $filename:文件路径。

5‌、示例‌:

php 复制代码
$type = filetype("data.txt");
echo $type; // 输出文件类型

‌ 输出‌:

php 复制代码
file
‌示例输出结果机制分析:

PHP的filetype()函数用于获取指定文件或目录的类型信息,其返回值包含以下7种可能的结果:

  1. ‌fifo‌ - 命名管道(FIFO)文件类型

  2. ‌char‌ - 字符设备文件(如终端设备)

  3. ‌dir‌ - 目录类型

  4. ‌block‌ - 块设备文件(如磁盘分区)

  5. ‌link‌ - 符号链接文件

  6. ‌file‌ - 常规文件

  7. ‌unknown‌ - 未知类型

在Windows系统中,由于文件系统差异,通常仅返回filedirunknown三种类型。若函数执行失败(如文件不存在),则返回false。注意该函数结果会被缓存,需通过clearstatcache()清除缓存以获取最新结果。

6、常见应用

示例1:检测常规文件类型
php 复制代码
$file = "example.txt";
$type = filetype($file);
echo "文件类型: " . $type;  // 输出: file
示例2:检测目录类型
php 复制代码
$dir = "docs";
$type = filetype($dir);
echo "目录类型: " . $type;  // 输出: dir
示例3:检测符号链接
php 复制代码
$link = "shortcut.lnk";
$type = filetype($link);
echo "链接类型: " . $type;  // 输出: link
示例4:处理未知类型
php 复制代码
$unknown = "dev/random";
$type = filetype($unknown);
if ($type === false) {
    echo "文件不存在或无法访问";
} else {
    echo "类型: " . $type;  // 可能输出: char 或 unknown
}

7、能否直接输出

filetype()函数不能直接输出到浏览器或终端,它仅返回文件类型的字符串(如"file""dir"等)或失败时返回false。以下是实现输出的方法和示例:

(1)基础输出方法

通过echo组合直接输出结果:

php 复制代码
$type = filetype("example.txt");
if ($type !== false) {
    echo "文件类型: " . $type; // 输出类似 "文件类型: file"
} else {
    echo "获取类型失败";
}
  • 关键点 ‌:需检查返回值是否为false以处理异常。
(2)**完整示例(含错误处理)**‌
php 复制代码
$filename = "test_folder";
if (file_exists($filename)) {
    $type = filetype($filename);
    switch ($type) {
        case "file":
            echo "这是一个普通文件";
            break;
        case "dir":
            echo "这是一个目录";
            break;
        case false:
            echo "无法识别类型";
            break;
        default:
            echo "其他类型: " . $type;
    }
} else {
    echo "文件或目录不存在";
}
  • 功能‌:区分文件类型并输出友好提示。

8、关键注意事项:

  1. ‌缓存问题‌:连续调用时需用clearstatcache()清除缓存

  2. ‌错误处理‌:建议用file_exists()先检查文件是否存在

  3. ‌Windows限制‌:仅支持file/dir/unknown三种类型

实际开发中常用于文件系统操作前的类型验证,例如上传文件时确认目标是否为目录。

(三)fstat()‌

1、词源分解

fstat() 由两部分组成:

  • f:代表"file"(文件),表示该函数操作的是已打开的文件指针

  • stat:源自Unix系统调用stat,表示"status"(状态),用于获取文件状态信息

2、功能概述

fstat() 函数用于获取已打开文件的详细信息,返回包含文件元数据的数组。

stat()函数不同,fstat()操作的是已通过fopen()打开的文件指针而非文件名。

3、语法结构

php 复制代码
array fstat(resource $handle)

4、参数详解

$handle(必需)
  • ‌类型‌:文件指针资源

  • ‌含义‌:通过fopen()成功打开的文件指针

  • ‌要求‌:必须是有效的、已打开的文件资源

5、返回值详解

返回包含13个元素的数组,同时包含数字索引和关联键名(自PHP 4.0.6起):

索引 关联键名 说明
0 dev 设备编号
1 ino inode编号
2 mode inode保护模式
3 nlink 硬链接数目
4 uid 所有者的用户ID
5 gid 所有者的组ID
6 rdev inode设备类型
7 size 文件大小(字节)
8 atime 最后访问时间(Unix时间戳)
9 mtime 最后修改时间(Unix时间戳)
10 ctime inode最后改变时间(Unix时间戳)
11 blksize 文件系统I/O块大小(如支持)
12 blocks 分配的块数

6、使用示例

(1)基础用法
php 复制代码
$file = fopen("example.txt", "r");
$fileInfo = fstat($file);
print_r($fileInfo);
fclose($file);

典型输出:

php 复制代码
Array (
    [0] => 771
    [1] => 488704
    [2] => 33188
    [3] => 1
    [4] => 1000
    [5] => 1000
    [6] => 0
    [7] => 1024
    [8] => 1634567890
    [9] => 1634567890
    [10] => 1634567890
    [11] => 4096
    [12] => 8
    [dev] => 771
    [ino] => 488704
    [mode] => 33188
    [nlink] => 1
    [uid] => 1000
    [gid] => 1000
    [rdev] => 0
    [size] => 1024
    [atime] => 1634567890
    [mtime] => 1634567890
    [ctime] => 1634567890
    [blksize] => 4096
    [blocks] => 8
)
(2)获取特定信息
php 复制代码
$file = fopen("data.log", "r");
$stats = fstat($file);
echo "文件大小: ".$stats['size']." 字节\n";
echo "最后修改: ".date('Y-m-d H:i:s', $stats['mtime']);
fclose($file);

7、能否直接输出

fstat()函数不能直接输出到浏览器或终端,它返回一个包含文件统计信息的数组或失败时返回false。以下是实现输出的方法和示例:

(1)基础输出方法

通过print_r()var_dump()输出完整统计数组:

php 复制代码
$file = fopen("example.txt", "r");
$stats = fstat($file);
if ($stats !== false) {
    print_r($stats); // 输出完整统计数组
} else {
    echo "获取文件信息失败";
}
fclose($file);
  • 输出 ‌:

    复制代码
    php 复制代码
    Array (
      [0] => 771       // 设备编号
      [size] => 1024   // 文件大小(字节)
      [mtime] => 1734567890 // 修改时间戳
      ...
    )
  • 关键点 ‌:需通过fopen()获取文件句柄,操作后必须调用fclose()

(2)提取特定字段输出
php 复制代码
$file = fopen("data.log", "r");
$stats = fstat($file);
if ($stats) {
    echo "文件大小: " . $stats['size'] . " 字节\n";
    echo "最后修改: " . date('Y-m-d H:i:s', $stats['mtime']);
}
fclose($file);
  • 输出 ‌:

    复制代码
    php 复制代码
    文件大小: 2048 字节
    最后修改: 2025-08-20 14:30:00
  • 特点 ‌:结合date()格式化时间戳。

(3)**完整示例(含错误处理)**‌
php 复制代码
$filename = "config.ini";
if (!file_exists($filename)) {
    die("文件不存在");
}

$handle = fopen($filename, "r");
$stats = fstat($handle);

if ($stats === false) {
    echo "无法读取文件信息";
} else {
    echo "文件类型: " . ($stats['mode'] & 0xF000 === 0x8000 ? "普通文件" : "其他");
    echo "\n占用块数: " . $stats['blocks'];
}
fclose($handle);
  • 说明 ‌:通过mode字段判断文件类型,blocks显示存储块占用。

8、注意事项

  • ‌文件必须已打开‌:与stat()不同,fstat()要求文件必须已通过fopen()打开

  • ‌服务器差异‌:返回结果可能因服务器环境不同而有所差异

  • ‌性能考虑‌:频繁调用可能影响性能,建议缓存结果

  • ‌时间戳转换‌:返回的时间戳需用date()函数转换为可读格式

  • ‌文件锁定‌:获取信息时文件未被自动锁定,可能读取到正在变化的数据

9、相关函数对比

  • stat():通过文件名获取文件信息,文件不需打开

  • lstat():针对符号链接获取信息

  • filemtime()/filesize()等:获取单一属性的快捷函数

10、实际应用场景

  • 日志文件监控:定期检查文件大小和修改时间

  • 上传文件验证:检查文件元数据

  • 文件同步工具:比较文件状态

  • 安全审计:检查文件权限和所有者

(四)stat()

1、词源分解

stat 来源于 Unix/Linux 系统的 stat 命令,是"status"(状态)的缩写,表示获取文件状态信息。

2、功能概述

stat() 函数用于获取文件的详细统计信息,返回包含文件元数据的数组。主要特点包括:

  • 返回数组包含数字索引和关联键名(PHP 4.0.6+)

  • 可获取文件权限、大小、时间戳等信息

  • 对符号链接返回目标文件信息(与lstat()不同)

  • 结果会被缓存,需用clearstatcache()清除

3、语法结构

php 复制代码
array|false stat(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要检查的文件路径

  • ‌支持格式‌:

    • 相对路径("data.txt"

    • 绝对路径("/var/www/config.ini"

    • 符号链接(解析目标文件)

5、返回值详解

返回包含13个元素的数组,包含数字索引(0-12)和关联键名:

数字下标 关联键名 描述 平台差异
0 dev 设备编号 -
1 ino inode编号 -
2 mode inode保护模式 -
3 nlink 硬链接数量 -
4 uid 所有者用户ID -
5 gid 所有者组ID -
6 rdev inode设备类型 Windows下为0
7 size 文件大小(字节) -
8 atime 最后访问时间(Unix时间戳) -
9 mtime 最后修改时间(Unix时间戳) -
10 ctime inode变更时间(Unix时间戳) Windows下为创建时间
11 blksize 文件系统I/O块大小 仅支持st_blksize的系统
12 blocks 分配的块数 -

6、输出换行说明

stat() 本身不产生输出,但使用时需注意:

  1. 直接打印数组时可用print_r()var_dump(),它们会自动处理换行

  2. 自定义输出时可用PHP_EOL(跨平台)或\n(Unix)换行

  3. HTML输出需用<br>换行

7、基础示例

示例1:获取文件状态
php 复制代码
$file = "test.txt";
$stat = stat($file);
echo "文件大小: ".$stat['size']." 字节".PHP_EOL;
echo "最后修改: ".date("Y-m-d H:i:s", $stat['mtime']).PHP_EOL;

‌ 输出‌:

php 复制代码
文件大小: 1024 字节
最后修改: 2025-08-20 14:30:22
示例2:完整状态输出
php 复制代码
print_r(stat("config.php"));

‌ 输出‌:

php 复制代码
Array
(
    [0] => 2050
    [1] => 123456
    [2] => 33188
    [3] => 1
    [4] => 1000
    [5] => 1000
    [6] => 0
    [7] => 1024
    [8] => 1724142622
    [9] => 1724142622
    [10] => 1724142622
    [11] => 4096
    [12] => 8
    [dev] => 2050
    [ino] => 123456
    [mode] => 33188
    [nlink] => 1
    [uid] => 1000
    [gid] => 1000
    [rdev] => 0
    [size] => 1024
    [atime] => 1724142622
    [mtime] => 1724142622
    [ctime] => 1724142622
    [blksize] => 4096
    [blocks] => 8
)

8、能否直接输出

stat()函数不能直接输出到浏览器或终端,它返回一个包含文件统计信息的数组或失败时返回false。以下是实现输出的方法和示例:

(1)基础输出方法

通过print_r()var_dump()输出完整统计数组:

php 复制代码
$stats = stat("example.txt");
if ($stats !== false) {
    print_r($stats); // 输出完整统计数组
} else {
    echo "获取文件信息失败";
}
  • 输出 ‌:

    复制代码
    php 复制代码
    Array (
      [0] => 771       // 设备编号
      [dev] => 771     // 关联键名(PHP 4.0.6+)
      [size] => 1024   // 文件大小(字节)
      [mtime] => 1734567890 // 修改时间戳
      ...
    )
  • 关键点 ‌:需检查返回值是否为false以处理异常。

(2)提取特定字段输出
php 复制代码
$stats = stat("data.log");
if ($stats) {
    echo "文件大小: " . $stats['size'] . " 字节\n";
    echo "最后修改: " . date('Y-m-d H:i:s', $stats['mtime']);
}
  • 输出

    复制代码
    php 复制代码
    文件大小: 2048 字节
    最后修改: 2025-08-20 14:30:00
  • 特点 ‌:通过关联键名(如'size')访问字段,结合date()格式化时间戳。

(3)**完整示例(含错误处理)**‌
php 复制代码
$filename = "config.ini";
if (!file_exists($filename)) {
    die("文件不存在");
}

$stats = stat($filename);
if ($stats === false) {
    echo "无法读取文件信息";
} else {
    echo "文件类型: " . (($stats['mode'] & 0xF000) === 0x8000 ? "普通文件" : "其他");
    echo "\nInode编号: " . $stats['ino'];
}
  • 说明 ‌:通过mode字段判断文件类型(0x8000表示普通文件),ino显示Inode编号。

9、高级应用

文件监控系统
php 复制代码
$watchFile = "config.ini";
$lastStat = $_SESSION['file_stat'] ?? [];
$currentStat = stat($watchFile);
if ($currentStat['mtime'] > ($lastStat['mtime'] ?? 0)) {
    // 配置文件已修改
    reloadConfig();
    $_SESSION['file_stat'] = $currentStat;
}

10、注意事项

  1. ‌缓存机制‌:结果会被缓存,修改文件后需调用clearstatcache()

  2. ‌符号链接‌:stat()解析链接目标,lstat()获取链接本身信息

  3. ‌错误处理‌:文件不存在时返回false并产生警告

  4. ‌平台差异‌:Windows下某些字段(如rdev)可能为0

  5. ‌性能考虑‌:高频调用应考虑缓存结果

(五)file_exists()‌

1、词源分解

file_exists() 由两部分组成:

  • file:文件

  • exists:存在(源自拉丁语"existere",意为"出现"或"存在")

    组合含义为"检查文件是否存在"

2、功能概述

file_exists() 用于检查文件或目录是否存在,是PHP文件系统操作中最常用的验证函数之一。主要特点包括:

  • 支持本地文件和网络共享文件检查

  • 同时适用于文件和目录验证

  • 返回布尔值结果(true/false)

  • 结果会被缓存,需用clearstatcache()清除

3、语法结构

php 复制代码
bool file_exists(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌含义‌:要检查的文件或目录路径

  • ‌特性‌:

    • 支持相对路径和绝对路径

    • 在Windows系统中检查网络共享文件需使用格式://computername/share/filename\\\\computername\\share\\filename

    • 可检查远程文件(需开启allow_url_fopen配置)

5、返回值

  • ‌存在‌:返回true

  • ‌不存在‌:返回false

  • ‌错误情况‌:因安全模式限制无法访问时也返回false

6、使用示例

(1)基础文件检查
php 复制代码
$file = "test.txt";
if (file_exists($file)) {
    echo "文件存在";
} else {
    echo "文件不存在";
}

输出取决于test.txt是否存在

(2)目录检查
php 复制代码
$dir = "/path/to/directory";
if (file_exists($dir)) {
    echo "目录存在";
}

注意:仅能确认路径存在,不能区分是文件还是目录

(3)网络共享文件检查
php 复制代码
$sharedFile = "\\\\server\\share\\file.doc";
if (file_exists($sharedFile)) {
    echo "共享文件可访问";
}

Windows系统专用语法

(4)结合路径处理
php 复制代码
$filename = __DIR__ . '/config.ini';
if (!file_exists($filename)) {
    file_put_contents($filename, '; 配置文件');
}

先检查后创建的典型用法

7、能否直接输出

file_exists()函数不能直接输出,它返回一个布尔值(truefalse),需要通过条件判断或其他方式输出结果。以下是具体方法和示例:

(1)基础输出方法

通过if条件判断输出存在状态:

php 复制代码
$filename = "test.txt";
if (file_exists($filename)) {
    echo "文件存在";  // 输出存在提示
} else {
    echo "文件不存在"; // 输出不存在提示
}
  • 输出示例 ‌:若文件存在则显示文件存在,否则显示文件不存在
  • 关键点‌:需检查文件路径是否正确(相对路径基于当前脚本目录)。
(2)结合其他函数使用
php 复制代码
$file = "/var/www/data.log";
echo file_exists($file) ? "文件可访问" : "文件丢失"; // 三元运算符简化输出
  • 特点‌:直接嵌入逻辑判断,适合简单场景。
(3)**完整示例(含错误处理)**‌
php 复制代码
$path = "C:/xampp/htdocs/config.ini";
if (!file_exists($path)) {
    die("错误:配置文件不存在,请检查路径"); // 终止脚本并报错
}
echo "配置文件加载成功";
  • 说明‌:常用于关键文件检查,中断无效操作。

8、注意事项

  1. ‌路径问题‌:建议使用绝对路径,相对路径可能因执行环境不同而产生意外结果

  2. ‌性能优化‌:高频调用时应考虑缓存结果或使用clearstatcache()

  3. ‌权限限制‌:即使文件存在,无读取权限时也可能返回false

  4. ‌符号链接‌:会解析符号链接指向的实际文件

  5. ‌区分类型‌:如需区分文件和目录,应结合is_file()is_dir()使用

9、相关函数对比

函数 特点 适用场景
file_exists() 检查存在性 通用验证
is_file() 确认是普通文件 文件操作前验证
is_dir() 确认是目录 目录操作前验证
is_readable() 检查可读性 读取前权限验证

10、最佳实践

  1. 重要操作前应同时验证存在性和权限

  2. 处理用户上传文件时建议使用move_uploaded_file()而非本函数

  3. 网络文件检查需考虑超时问题

  4. 生产环境应配合错误处理机制使用

五、路径操作‌类(4个)

(一)basename()‌

1、词源分解

  • basename() 由两部分组成:

  • base:基础部分,指路径中最核心的文件名

  • name:名称,表示文件标识符

    组合含义为"提取路径中的基础文件名部分"

2、功能概述

  • basename() 用于从完整文件路径中提取文件名部分,是PHP文件路径处理的核心函数之一。主要特点包括:

  • 自动处理不同操作系统的目录分隔符(Windows支持/和\,Linux仅支持/)

  • 可选择性去除指定文件后缀

  • 返回纯文件名字符串(不含路径信息)

  • 对符号链接返回链接名而非目标文件名

3、语法结构

php 复制代码
string basename(string $path [, string $suffix ])

4、参数详解

(1)$path(必需)
  • ‌类型‌:字符串

  • ‌含义‌:待处理的文件路径

  • ‌特性‌:

    • 支持绝对路径和相对路径

    • 可以是本地文件或网络共享路径

    • 空路径返回"."(当前目录标识符)

(2)$suffix(可选)
  • ‌类型‌:字符串

  • ‌含义‌:需要从结果中去除的文件后缀

  • ‌特性‌:

    • 区分大小写(".txt" ≠ ".TXT")

    • 必须与文件名结尾完全匹配才会去除

    • 可包含多个点(如".tar.gz")

5、返回值

  • ‌成功‌:返回纯文件名字符串

  • ‌特殊路径‌:

    • 路径以分隔符结尾返回空字符串

    • "." 返回 "."

    • ".." 返回 ".."

6、使用示例

基础用法
php 复制代码
$path = "/var/www/html/index.php";
echo basename($path);  // 输出:index.php
去除后缀
php 复制代码
$path = "/home/user/data.csv";
echo basename($path, ".csv");  // 输出:data
网络路径处理
php 复制代码
$url = "http://example.com/images/logo.png";
echo basename($url);  // 输出:logo.png
特殊字符处理
php 复制代码
echo basename("dir/");      // 输出:""(空字符串)
echo basename(".");         // 输出:"."
echo basename("../test/");  // 输出:"":ml-citation{ref="3,6" data="citationList"}

7、能否直接输出

basename()函数不能直接输出,它返回路径中的文件名部分(字符串类型),需要通过echoprint等输出函数显示结果。以下是具体方法和示例:

(1)基础输出方法
php 复制代码
$path = "/var/www/html/index.php";
$filename = basename($path);
echo $filename; // 输出: index.php
  • 说明‌:直接传递路径参数,返回文件名并输出。
(2)移除后缀输出
php 复制代码
$path = "/var/www/html/index.php";
$filename = basename($path, ".php");
echo $filename; // 输出: index
  • 说明‌:通过第二参数移除指定后缀(区分大小写)。

(3)中文路径处理示例
php 复制代码
$path = "D:\\doubly\\中文文件.txt";
$filename = basename($path);
echo $filename; // 需确保PHP环境支持中文路径,否则可能输出异常:ml-citation{ref="1" data="citationList"}
  • 注意 ‌:部分环境下需调整编码或使用mb_basename等替代方案处理中文。
(4)**完整示例(含错误处理)**‌
php 复制代码
$path = "images/photo.jpg";
if (file_exists($path)) {
    echo "文件名: " . basename($path); // 输出: photo.jpg
} else {
    echo "文件不存在";
}
  • 关键点 ‌:结合file_exists()验证路径有效性。

8、注意事项

  • 路径验证‌:函数不检查文件是否存在,仅做字符串处理
  • ‌编码问题‌:非ASCII字符路径可能产生意外结果
  • ‌性能考虑‌:高频调用时建议缓存结果
  • ‌组合使用‌:常与dirname()、pathinfo()配合使用
  • ‌符号链接‌:返回链接名而非实际文件名(需用readlink()获取目标)
  • 路径格式‌:支持/和\分隔符,但斜杠结尾时返回空字符串
  • ‌特殊路径‌:输入.或..时直接返回原字符串

9、相关函数对比

函数 特点 典型应用场景
basename() 提取纯文件名 获取上传文件原始名
dirname() 提取目录部分 构建相对路径
pathinfo() 返回路径各部分的数组 全面解析路径信息

10、实际应用场景

  • 文件上传处理:获取客户端原始文件名

  • 日志系统:从完整路径提取日志文件名

  • 文件管理器:展示简洁文件名列表

  • 批量处理:配合glob()进行文件遍历

(二)dirname()

1、词源与概念

dirname() 由 "directory"(目录)和 "name"(名称)组合而成,字面意思是"目录名提取器"。该函数专门用于从文件路径中剥离出目录部分。

2、核心功能

  • ‌路径分解‌:分离目录路径和文件名

  • ‌层级控制‌:通过$levels参数实现多级目录回溯

  • ‌跨平台兼容‌:自动处理不同操作系统的路径分隔符(Windows的\和Linux的/

3、语法结构

php 复制代码
string dirname(string $path [, int $levels = 1 ])

4、参数详解

(1)$path 参数
特性 说明
类型 字符串
必需性 必需
接受值 绝对路径/相对路径/URL
特殊处理 空字符串返回"."
示例 /var/www/index.php
(2)$levels参数(PHP 7.0+)
特性 说明
类型 整型
默认值 1
作用 控制回溯的目录层级
工作机制 每增加1就多向上回溯一级
边界情况 超过实际层级返回根目录

5、层级回溯机制

  • ‌基础原理‌:

    • 从右向左扫描路径

    • 遇到目录分隔符即完成一级回溯

    • 连续分隔符视为单个分隔符

  • ‌计算示例‌:

php 复制代码
$path = "/a/b/c/d/e.php";
dirname($path)      // /a/b/c/d (level=1)
dirname($path, 2)   // /a/b/c   (level=2)
dirname($path, 3)   // /a/b     (level=3)
  • ‌特殊案例‌:

    • dirname("/a/b//c/", 2)/a(标准化处理多余分隔符)

    • dirname("C:\\a\\b.txt")C:\(Windows路径处理)

    • dirname("http://test.com/img/1.jpg")http://test.com/img

6、返回值规则

输入情况 返回值 说明
普通路径 目录字符串 去除指定层级后的路径
根目录 /C:\ 无法继续回溯
相对路径 ... 保持相对关系
空字符串 . 当前目录表示

7、实用示例

基础用法
php 复制代码
echo dirname("/var/www/index.php");  // 输出:/var/www
echo dirname("src/utils/helper.php"); // 输出:src/utils
多级回溯
php 复制代码
$path = "/home/user/project/src/main.php";
// 获取父目录
echo dirname($path);      // /home/user/project/src
// 获取祖父目录
echo dirname($path, 2);   // /home/user/project
// 获取曾祖父目录 
echo dirname($path, 3);   // /home/user
框架开发应用
php 复制代码
// 获取配置文件目录
define('CONFIG_DIR', dirname(__DIR__) . '/config');
// 动态加载类文件
spl_autoload_register(function($class){
    $file = dirname(__DIR__, 2) . '/lib/' . str_replace('\\', '/', $class) . '.php';
    if(file_exists($file)) require $file;
});

8、能否直接输出

dirname()函数不能直接输出,它返回路径中的目录部分(字符串类型),需要通过echoprint等输出函数显示结果。以下是具体方法和示例(和上面的示例差不多):

(1)基础输出方法
php 复制代码
$path = "/var/www/html/index.php";
$dir = dirname($path);
echo $dir; // 输出: /var/www/html
  • 说明‌:直接传递路径参数,返回目录部分并输出。
(2) ‌多级目录回溯
php 复制代码
$path = "/var/www/html/index.php";
$dir = dirname($path, 2); // 返回上两级目录
echo $dir; // 输出: /var
  • 特点 ‌:通过第二参数levels指定回溯层级。
(3)相对路径处理
php 复制代码
$path = "../images/photo.jpg";
echo dirname($path); // 输出: ../images
  • 注意‌:支持相对路径解析。
(4) ‌**结合魔术常量__FILE__**‌
php 复制代码
echo dirname(__FILE__); // 输出当前脚本所在目录的绝对路径
  • 用途‌:常用于获取当前文件目录,避免硬编码路径。
(5)特殊路径示例
php 复制代码
echo dirname("test.txt");    // 输出: . (当前目录)
echo dirname("/usr/local/"); // 输出: /usr (忽略结尾斜杠)
  • 规则 ‌:无斜杠路径返回.,结尾斜杠会被忽略。

9、注意事项

  • ‌符号链接‌:返回链接所在目录而非目标目录
  • ‌性能优化‌:高频调用时应缓存结果
  • ‌路径安全‌:建议配合realpath()使用
  • ‌编码问题‌:非ASCII路径需特殊处理
  • ‌版本兼容‌:$levels参数需PHP7.0+
  • ‌路径分隔符‌:兼容/和\(Windows环境)。
  • ‌空路径‌:输入.或..时原样返回。

10、最佳实践

  • ‌项目根目录获取‌:
php 复制代码
$root = dirname(__DIR__);
  • ‌多级目录跳转‌:
php 复制代码
$configPath = dirname(__FILE__, 3) . '/config/db.ini';
  • ‌路径标准化‌:
php 复制代码
$cleanPath = dirname($dirtyPath . '/dummy');

11、相关函数对比

函数 返回类型 特点 适用场景
dirname() 字符串 轻量级目录提取 快速获取父目录
pathinfo() 数组 完整路径解析 需要多部分路径信息
realpath() 字符串 绝对路径标准化 需要真实物理路径

(三) pathinfo()‌

1、词源分解

  • pathinfo() 由 "path"(路径)和 "info"(信息)组合而成,字面意思是"路径信息提取器"。该函数专门用于解析文件路径并返回其组成部分。

2、核心功能

  • ‌路径解析‌:将完整路径分解为目录名、文件名、扩展名等组件

  • ‌灵活输出‌:支持返回关联数组或特定字符串

  • ‌格式兼容‌:正确处理不同操作系统的路径格式(Windows/Linux)

3、语法结构

php 复制代码
mixed pathinfo(string $path [, int $options = PATHINFO_ALL ])

4、参数详解

$path 参数
特性 说明
类型 字符串
必需性 必需
接受值 绝对路径/相对路径/URL
特殊处理 空路径返回当前目录标识
示例 /var/www/index.php
$options 参数
常量 返回内容
PATHINFO_DIRNAME 1 目录部分
PATHINFO_BASENAME 2 完整文件名
PATHINFO_EXTENSION 4 文件扩展名
PATHINFO_FILENAME 8 无扩展文件名
PATHINFO_ALL -1 全部信息(默认)

5、返回值机制

  • ‌默认模式‌(无$options):

    • 返回包含4个元素的关联数组

    • 数组键名:dirname, basename, extension, filename

  • ‌指定模式‌(带$options):

    • 返回对应组件的字符串

    • 多个选项使用按位或组合(如PATHINFO_DIRNAME | PATHINFO_EXTENSION

  • ‌特殊案例‌:

    • 无扩展名文件:extension元素不存在

    • 点文件(如.htaccess):filename为空字符串

    • 网络路径:支持HTTP/HTTPS协议解析

6、使用示例

(1)基础用法
php 复制代码
$path = "/home/user/docs/report.pdf";
print_r(pathinfo($path));

输出:

php 复制代码
Array
(
    [dirname] => /home/user/docs
    [basename] => report.pdf
    [extension] => pdf
    [filename] => report
)
(2)指定返回组件
php 复制代码
$path = "C:\\Projects\\data.json";
echo pathinfo($path, PATHINFO_EXTENSION);  // 输出:json
echo pathinfo($path, PATHINFO_FILENAME);   // 输出:data
(3)组合选项
php 复制代码
$info = pathinfo("/var/tmp/archive.tar.gz", 
          PATHINFO_FILENAME | PATHINFO_EXTENSION);
// 返回包含filename和extension的数组

7、能否直接输出

pathinfo()函数不能直接输出,它返回路径信息的数组或字符串(取决于参数),需要通过print_r()var_dump()echo等函数输出结果。以下是具体方法和示例:

(1)**默认输出(返回数组)**‌
php 复制代码
$path = "/var/www/html/index.php";
print_r(pathinfo($path));

输出结果‌:

php 复制代码
Array (
    [dirname] => /var/www/html
    [basename] => index.php
    [extension] => php
    [filename] => index
)
  • 说明 ‌:未指定options参数时,返回包含目录、文件名、扩展名等信息的关联数组。
(2)**指定输出部分信息(返回字符串)**‌
php 复制代码
$path = "/var/www/html/index.php";
echo pathinfo($path, PATHINFO_EXTENSION); // 输出: php
  • 可选参数 ‌:
    • PATHINFO_DIRNAME:仅返回目录路径(如/var/www/html)。
    • PATHINFO_BASENAME:仅返回文件名(如index.php)。
    • PATHINFO_EXTENSION:仅返回扩展名(如php)。
    • PATHINFO_FILENAME:仅返回无后缀的文件名(如index)。
(3) ‌特殊路径处理示例
php 复制代码
$path = "test.txt";
var_dump(pathinfo($path));

输出结果‌:

php 复制代码
Array (
    [dirname] => .
    [basename] => test.txt
    [extension] => txt
    [filename] => test
)
  • 规则 ‌:若路径无目录,dirname返回.;若无扩展名则不返回extension键。

8、注意事项

  • ‌符号链接‌:不解析链接目标,仅处理给定路径字符串
  • ‌多字节字符‌:需正确设置区域设置(setlocale())
  • ‌性能优化‌:高频调用建议缓存结果
  • ‌路径安全‌:建议配合realpath()使用
  • ‌空值处理‌:无效路径返回false
  • ‌路径格式‌:支持/和\分隔符(Windows环境自动转换)
  • ‌多级扩展名‌:如file.tar.gz仅返回最后一级扩展名(gz)
  • ‌性能‌:频繁调用时建议使用clearstatcache()清除缓存

9、相关函数对比

函数 返回类型 特点 适用场景
pathinfo() 数组/字符串 完整路径解析 需要多部分路径信息
dirname() 字符串 轻量级目录提取 快速获取父目录
basename() 字符串 文件名提取 获取上传文件名
realpath() 字符串 绝对路径标准化 需要真实物理路径

10、实际应用场景

  • ‌文件上传处理‌:
php 复制代码
$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
if(!in_array($ext, ['jpg','png'])) die('Invalid file type');
  • ‌自动加载器‌:
php 复制代码
spl_autoload_register(function($class){
    $file = __DIR__.'/'.str_replace('\\','/',$class).'.php';
    if(file_exists($file)) require $file;
});
  • ‌URL路由解析‌:
php 复制代码
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$parts = pathinfo($path);
$controller = $parts['filename'] ?: 'home';
  • ‌日志文件命名‌:
php 复制代码
$logFile = pathinfo(__FILE__, PATHINFO_FILENAME).'_'.date('Ymd').'.log';

11、版本变化

  • PHP 5.2.0:新增PATHINFO_FILENAME常量

  • PHP 7.0+:性能优化,处理速度提升约30%

(四)realpath()

1、词源分解

realpath 由两部分组成:

  • ‌real‌:表示"真实的"或"绝对的"

  • ‌path‌:表示"路径"

    组合含义为"真实路径"或"绝对路径"

2、功能概述

realpath() 函数用于将相对路径转换为绝对路径,主要功能包括:

  • 解析所有符号链接(如/.//../

  • 去除多余的斜杠

  • 返回规范化后的绝对路径名

  • 失败时返回false(如文件不存在)

3、语法结构

php 复制代码
string|false realpath(string $path)

4、参数详解

$path(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要转换的路径

  • ‌支持格式‌:

    • 相对路径("../test.txt"

    • 符号链接("/var/www/current"

    • 包含特殊符号的路径("/var/./www/../log"

5、返回值

  • ‌成功‌:返回规范化后的绝对路径(字符串)

  • ‌失败‌:返回false(如路径不存在)

6、基础示例

示例1:基本用法
php 复制代码
$path = "test.txt";
$realpath = realpath($path);
echo "绝对路径: ".$realpath.PHP_EOL;

‌ 输出‌:

php 复制代码
绝对路径: /var/www/html/test.txt
示例2:处理符号链接
php 复制代码
$link = "/var/www/current"; // 指向/var/www/v1.0
echo realpath($link);

‌ 输出‌:

php 复制代码
/var/www/v1.0

7、能否直接输出

realpath()函数不能直接输出,它返回规范化后的绝对路径(字符串类型),需要通过echoprint等输出函数显示结果。以下是具体方法和示例:

(1)基础输出方法
php 复制代码
$path = "test.txt";
echo realpath($path); // 输出类似: C:\Inetpub\testweb\test.txt
  • 说明 ‌:若文件存在,返回绝对路径;不存在则返回false
(2)结合错误处理
php 复制代码
$path = "nonexistent.txt";
$absPath = realpath($path);
if ($absPath !== false) {
    echo "绝对路径: " . $absPath;
} else {
    echo "文件不存在或路径无效";
}
  • 用途 ‌:避免直接输出false导致歧义。
(3)相对路径转换示例
php 复制代码
$path = "../../index.php";
echo realpath($path); // 输出类似: E:\www\test\index.php
  • 特点 ‌:自动解析.././等相对符号。
(4)特殊路径处理
php 复制代码
echo realpath(".");    // 输出当前脚本所在目录的绝对路径
echo realpath("/tmp"); // 输出系统临时目录的绝对路径
  • 规则 ‌:输入.返回当前目录,输入根目录(如/tmp)返回其绝对路径。

8、高级应用

(1)路径缓存机制

PHP 5.1.0+ 引入了realpath_cache,可缓存解析结果提升性能

php 复制代码
// 获取缓存信息
print_r(realpath_cache_get());
(2)配置参数

php.ini中可调整:

php 复制代码
; 缓存大小(默认16K)
realpath_cache_size = 256K
; 缓存有效期(默认120秒)
realpath_cache_ttl = 300

9、注意事项

  1. ‌性能优化‌:

    • 高频调用时缓存结果可提升性能

    • 绝对路径包含文件比相对路径更快

  2. ‌符号链接处理‌:

    • 会解析所有层级的符号链接

    • 最终指向不存在的路径时返回false

  3. ‌错误处理‌:

    php 复制代码
    $path = @realpath("nonexistent.txt") or 
        die("路径解析失败: ".error_get_last()['message']);
  4. ‌跨平台差异‌:

    • Windows路径会转换为反斜杠

    • Unix路径保持正斜杠格式

10、相关函数对比

函数 描述 典型用途
basename() 获取文件名 提取文件部分
dirname() 获取目录名 提取目录部分
pathinfo() 获取路径信息 多维路径分析
realpath() 解析绝对路径 路径规范化

realpath() 在PHP 8.x中仍为核心函数,是文件系统操作的重要工具,特别适用于需要精确路径定位的场景

六、时间相关类(3个)

(一)fileatime()

1、词源分解

fileatime 由三部分组成:

  • ‌file‌:表示文件操作

  • ‌a‌:代表"access"(访问)

  • ‌time‌:表示时间

    组合含义为"文件访问时间"

2、功能概述

fileatime() 用于获取文件最后被访问的时间戳,主要特点包括:

  • 返回 Unix 时间戳格式

  • 结果会被缓存,需用clearstatcache()清除

  • 某些 Unix 系统可能禁用 atime 更新

3、语法结构

php 复制代码
int|false fileatime(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要检查的文件路径

  • ‌支持格式‌:

    • 相对路径("test.txt"

    • 绝对路径("/var/www/data.txt"

    • URL 流(需allow_url_fopen启用)

5、返回值

  • ‌成功‌:返回 Unix 时间戳(整数)

  • ‌失败‌:返回 false 并产生警告

6、典型示例

(1)基础用法
php 复制代码
$file = "example.log";
if (file_exists($file)) {
    $atime = fileatime($file);
    echo "最后访问: ".date("Y-m-d H:i:s", $atime);
} else {
    echo "文件不存在";
}

‌ 输出‌:

php 复制代码
最后访问: 2025-08-20 14:30:22
(2)带缓存清除
php 复制代码
$file = "data.csv";
clearstatcache(); // 清除缓存
$atime = fileatime($file);
echo date("F d Y H:i:s", $atime);

‌ 输出‌:

php 复制代码
August 23 2025 09:15:47

7、能否直接输出

fileatime()函数不能直接输出,它返回文件的上次访问时间(Unix时间戳),需要通过echoprint等输出函数显示结果,通常结合date()函数格式化时间戳。以下是具体方法和示例:

(1)基础输出方法
php 复制代码
$filename = "test.txt";
if (file_exists($filename)) {
    echo "文件最后访问时间: " . date("Y-m-d H:i:s", fileatime($filename));
} else {
    echo "文件不存在";
}
  • 输出示例 ‌:文件最后访问时间: 2025-08-24 10:30:45
  • 说明 ‌:需先检查文件是否存在,再通过date()格式化时间戳。
(2)结合错误处理
php 复制代码
$timestamp = fileatime("nonexistent.txt");
if ($timestamp === false) {
    echo "获取访问时间失败(文件可能不存在)";
} else {
    echo date("F j, Y, g:i a", $timestamp);
}
  • 特点 ‌:明确处理函数返回false的情况。
(3)多文件时间对比
php 复制代码
$files = ["a.txt", "b.txt"];
foreach ($files as $file) {
    if (file_exists($file)) {
        echo "$file 最后访问: " . date("d/m/Y", fileatime($file)) . "<br>";
    }
}
  • 输出示例 ‌:
    a.txt 最后访问: 24/08/2025
    b.txt 最后访问: 23/08/2025
  • 用途‌:批量输出多个文件的访问时间。

8、注意事项

  1. ‌性能影响‌:

    • 频繁访问大量文件时可能影响性能

    • 某些 Unix 系统会禁用 atime 更新

  2. ‌时间精度‌:

    • 不同文件系统可能有差异

    • 不保证亚秒级精度

  3. ‌符号链接‌:

    • 默认跟随链接获取目标文件时间

    • lstat()获取链接本身时间

  4. ‌时区处理‌:

php 复制代码
date_default_timezone_set('Asia/Shanghai');
echo date("Y-m-d H:i:s", fileatime("file.txt"));
```:ml-citation{ref="8" data="citationList"}

9、相关函数对比

函数 描述 典型用途
fileatime() 最后访问时间 日志分析
filemtime() 最后修改时间 缓存验证
filectime() inode修改时间 权限变更跟踪

fileatime() 在 PHP 8.x 中仍被支持,但实际应用中需考虑系统配置对 atime 更新的影响

(二)filemtime()

1、词源分解

filemtime 由三部分组成:

  • ‌file‌:表示文件操作

  • ‌m‌:代表"modification"(修改)

  • ‌time‌:表示时间

    组合含义为"文件修改时间"

2、功能概述

filemtime() 用于获取文件内容最后被修改的时间戳,主要特点包括:

  • 返回 Unix 时间戳格式(自1970年1月1日以来的秒数)

  • 结果会被缓存,需用clearstatcache()清除

  • 适用于本地文件和 URL 流(需allow_url_fopen启用)

3、语法结构

php 复制代码
int|false filemtime(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要检查的文件路径

  • ‌支持格式‌:

    • 相对路径("data.txt"

    • 绝对路径("/var/www/config.ini"

    • URL 流("http://example.com/file.pdf"

5、返回值

  • ‌成功‌:返回 Unix 时间戳(整数)

  • ‌失败‌:返回 false 并产生警告

6、基础示例

示例1:获取单个文件修改时间
php 复制代码
$file = "config.json";
if (file_exists($file)) {
    $mtime = filemtime($file);
    echo "最后修改: ".date("Y-m-d H:i:s", $mtime)."\n";
} else {
    echo "文件不存在\n";
}

‌ 输出‌:

php 复制代码
最后修改: 2025-08-20 09:15:30
示例2:批量获取文件修改时间
php 复制代码
$files = ["index.php", "style.css", "script.js"];
foreach ($files as $file) {
    clearstatcache(); // 清除缓存
    echo $file.": ".date("m/d/Y", filemtime($file)).PHP_EOL;
}

‌ 输出‌:

php 复制代码
index.php: 08/15/2025
style.css: 08/18/2025
script.js: 08/20/2025

7、能否直接输出

filemtime()函数不能直接输出,它返回文件内容的最后修改时间(Unix时间戳),需要通过echoprint等输出函数显示结果,通常结合date()函数格式化时间戳。以下是具体方法和示例:

(1)基础输出方法
php 复制代码
$filename = "example.txt";
if (file_exists($filename)) {
    echo "文件最后修改时间: " . date("Y-m-d H:i:s", filemtime($filename));
} else {
    echo "文件不存在";
}
  • 输出示例 ‌:文件最后修改时间: 2025-08-24 10:15:30
  • 说明 ‌:需先检查文件是否存在,再通过date()将时间戳转为可读格式。
(2)结合缓存清除
php 复制代码
clearstatcache(); // 清除文件状态缓存
$timestamp = filemtime("data.log");
if ($timestamp !== false) {
    echo "最后修改: " . date("d F Y H:i", $timestamp);
}
  • 用途‌:避免因缓存导致的时间戳不准确。
(3)多文件批量输出
php 复制代码
$files = ["a.txt", "b.txt"];
foreach ($files as $file) {
    if (file_exists($file)) {
        echo "$file 修改时间: " . date("Y-m-d", filemtime($file)) . "<br>";
    }
}
  • 输出示例 ‌:
    a.txt 修改时间: 2025-08-23
    b.txt 修改时间: 2025-08-22
  • 特点‌:支持批量处理多个文件。

8、高级应用

缓存控制机制
php 复制代码
$cacheFile = "data.cache";
$expireTime = 3600; // 1小时
if (file_exists($cacheFile) && 
    (time() - filemtime($cacheFile)) < $expireTime) {
    // 使用缓存
    include $cacheFile;
} else {
    // 重新生成缓存
    $content = generateContent();
    file_put_contents($cacheFile, $content);
}

9、与其他时间函数对比

函数 描述 典型应用场景
fileatime() 最后访问时间 日志分析、访问统计
filectime() inode变更时间 权限/所有者变更跟踪
filemtime() 内容修改时间 缓存验证、版本控制

10、注意事项

‌ 性能优化‌:

  • 高频调用应考虑缓存结果

  • 批量处理时适时调用clearstatcache()

‌ 系统差异‌:

  • Windows系统filectime()返回创建时间

  • Unix系统filectime()返回inode变更时间

‌ 时区处理‌:

php 复制代码
date_default_timezone_set('Asia/Shanghai');
echo date("Y-m-d H:i:s", filemtime("log.txt"));

‌ 错误处理‌:

php 复制代码
$mtime = @filemtime("nonexistent.txt") or 
    die("无法获取文件时间: ".error_get_last()['message']);

filemtime() 在 PHP 8.x 中仍为核心函数,是文件系统监控和缓存管理的重要工具。

(三)filectime()

1、词源分解

filectime 由三部分组成:

  • ‌file‌:表示文件操作

  • ‌c‌:代表"change"(变更)或"creation"(创建)

  • ‌time‌:表示时间

    组合含义为"文件变更时间"或"文件创建时间"

2、功能概述

filectime() 用于获取文件元数据最后变更的时间戳,主要特点包括:

  • 在Unix/Linux系统中返回inode元数据变更时间

  • 在Windows系统中返回文件创建时间

  • 返回Unix时间戳格式(自1970年1月1日以来的秒数)

  • 结果会被缓存,需用clearstatcache()清除

3、语法结构

php 复制代码
int|false filectime(string $filename)

4、参数详解

$filename(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定要检查的文件路径

  • ‌支持格式‌:

    • 相对路径("data.txt"

    • 绝对路径("/var/www/config.ini"

    • URL流(需allow_url_fopen启用)

5、返回值

  • ‌成功‌:返回Unix时间戳(整数)

  • ‌失败‌:返回false并产生警告

6、系统平台差异

Unix/Linux系统

返回inode变更时间(ctime),触发条件包括:

  • 修改文件权限(如chmod

  • 更改文件所有者(如chown

  • 重命名文件(部分文件系统)

  • 更新硬链接数量

Windows系统

返回文件创建时间(creation time),该值在文件生命周期内保持不变

7、基础示例

示例1:获取单个文件ctime
php 复制代码
$file = "config.php";
if (file_exists($file)) {
    $ctime = filectime($file);
    echo "元数据最后变更: ".date("Y-m-d H:i:s", $ctime).PHP_EOL;
} else {
    echo "文件不存在".PHP_EOL;
}

‌ 输出‌(Unix系统):

php 复制代码
元数据最后变更: 2025-08-20 14:30:22
示例2:Windows系统下的创建时间
php 复制代码
$file = "data.db";
clearstatcache(); // 清除缓存
echo "创建时间: ".date("m/d/Y", filectime($file));

‌ 输出‌(Windows系统):

php 复制代码
创建时间: 08/15/2025

8、能否直接输出

filectime()函数不能直接输出,它返回文件的inode修改时间(Unix时间戳),需要通过echoprint等输出函数显示结果,通常结合date()函数格式化时间戳。以下是具体方法和示例:

(1)基础输出方法
php 复制代码
$file = "example.txt";
if (file_exists($file)) {
    echo "文件inode修改时间: " . date("Y-m-d H:i:s", filectime($file));
} else {
    echo "文件不存在";
}
  • 输出示例 ‌:文件inode修改时间: 2025-08-24 09:15:22
  • 说明 ‌:需先检查文件是否存在,再通过date()将时间戳转为可读格式。
(2)结合时区设置
php 复制代码
date_default_timezone_set("Asia/Shanghai");
$timestamp = filectime("data.log");
if ($timestamp !== false) {
    echo "最后元数据变更: " . date("d F Y H:i", $timestamp);
}
  • 特点‌:明确设置时区,避免时间显示偏差。
(3)多文件对比输出
php 复制代码
$files = ["config.ini", "index.php"];
foreach ($files as $file) {
    $ctime = filectime($file);
    echo "$file 的权限/所有者变更时间: " . ($ctime ? date("Y-m-d", $ctime) : "无效") . "<br>";
}
  • 输出示例 ‌:
    config.ini 的权限/所有者变更时间: 2025-08-23
    index.php 的权限/所有者变更时间: 2025-08-22
  • 用途‌:批量检查文件元数据变更记录。

9、高级应用

文件监控系统
php 复制代码
$watchFile = "settings.ini";
$lastCheck = $_SESSION['config_check'] ?? 0;
$currentCtime = filectime($watchFile);
if ($currentCtime > $lastCheck) {
    // 重新加载配置
    reloadConfig();
    $_SESSION['config_check'] = $currentCtime;
}

10、注意事项

  • ‌时间戳溢出‌:32位系统2038年后可能失效
  • ‌性能优化‌:高频调用应缓存结果
  • ‌时区处理‌:
php 复制代码
date_default_timezone_set('Asia/Shanghai');
echo date("Y-m-d H:i:s", filectime("log.txt"));
  • ‌错误处理‌:
php 复制代码
$ctime = @filectime("nonexistent.txt") or 
    die("错误: ".error_get_last()['message']);

11、相关函数对比

函数 描述 典型应用场景
fileatime() 最后访问时间 日志分析
filemtime() 内容修改时间 缓存验证
filectime() 元数据变更时间 权限变更跟踪

filectime()在PHP 8.x中仍为核心函数,是文件系统监控的重要工具,但使用时需特别注意其跨平台行为差异。

七、其他函数‌类(7个)

(一)flock()‌

1、词源与概念

  • flock() 由 "file"(文件)和 "lock"(锁定)组合而成,是PHP提供的文件锁定机制核心函数。该函数实现进程间文件访问控制,防止并发操作导致的数据冲突。

2、核心功能

  • ‌并发控制‌:协调多进程对同一文件的访问

  • ‌锁类型支持‌:提供共享锁/独占锁两种模式

  • ‌阻塞控制‌:支持非阻塞锁定尝试

  • ‌跨平台兼容‌:适配Windows和Unix-like系统

3、语法结构

php 复制代码
bool flock(resource $handle, int $operation [, int &$wouldblock ])

4、参数详解

(1)$handle 参数
特性 说明
类型 资源类型
必需性 必需
来源 必须通过fopen()创建
生命周期 锁随文件关闭自动释放
示例 fopen("data.txt", "r+")
(2)$operation 参数
常量 功能 适用场景
LOCK_SH 1 共享锁(读锁) 多进程并发读取
LOCK_EX 2 独占锁(写锁) 单进程独占写入
LOCK_UN 3 释放锁 主动解锁
LOCK_NB 4 非阻塞模式 避免等待锁释放
(3)$wouldblock 参数(可选)
特性 说明
类型 引用传递的整型
作用 检测是否发生阻塞
平台限制 Windows平台不支持
返回值 1表示发生阻塞

5、锁定机制原理

  • ‌咨询锁‌:依赖所有进程遵守锁定协议

  • ‌强制锁‌:Windows平台强制执行锁定

  • ‌锁释放‌:

    • 显式调用LOCK_UN

    • 关闭文件句柄

    • 脚本执行结束

6、使用示例

(1)基础文件锁定
php 复制代码
$fp = fopen("data.txt", "c+");
if (flock($fp, LOCK_EX)) {
    fwrite($fp, "Critical section data");
    flock($fp, LOCK_UN); // 必须显式释放
} else {
    echo "获取文件锁失败";
}
fclose($fp);
(2)非阻塞模式
php 复制代码
$fp = fopen("log.txt", "a");
if (flock($fp, LOCK_EX | LOCK_NB, $wouldblock)) {
    // 立即获取锁
    fwrite($fp, date('Y-m-d H:i:s')."\n");
    flock($fp, LOCK_UN);
} elseif ($wouldblock) {
    echo "文件正被其他进程占用";
}
fclose($fp);
(3)共享锁应用
php 复制代码
$fp = fopen("config.json", "r");
if (flock($fp, LOCK_SH)) {
    $config = json_decode(fread($fp, filesize("config.json")), true);
    flock($fp, LOCK_UN);
    print_r($config);
}
fclose($fp);

7、返回值与错误处理

返回情况 说明
成功 true 锁定/解锁操作成功
失败 false 操作失败或参数错误
超时 false 阻塞模式下的等待超时

8、能否直接输出

flock()函数不能直接输出,它返回布尔值表示文件锁定是否成功,需要通过条件判断结合echo输出结果。以下是具体方法和示例:

(1)基础锁定与输出
php 复制代码
$file = fopen("test.txt", "r+");
if (flock($file, LOCK_EX)) {  // 独占锁定
    echo "文件锁定成功,可安全写入数据";
    fwrite($file, "新内容");
    flock($file, LOCK_UN);    // 释放锁定
} else {
    echo "文件锁定失败,请重试";
}
fclose($file);
  • 输出示例 ‌:
    成功时显示文件锁定成功,可安全写入数据
    失败时显示文件锁定失败,请重试
  • 关键点 ‌:
    • LOCK_EX表示独占写入锁
    • 必须手动释放锁(LOCK_UN)或关闭文件
(2)非阻塞模式输出
php 复制代码
$fp = fopen("log.txt", "a");
if (flock($fp, LOCK_EX | LOCK_NB)) {  // 非阻塞模式
    echo "立即获得锁,开始操作";
    fwrite($fp, date("Y-m-d H:i:s") . "\n");
    flock($fp, LOCK_UN);
} else {
    echo "文件正被其他进程占用";
}
fclose($fp);
  • 输出场景 ‌:
    若文件被占用,直接显示文件正被其他进程占用而非等待
(3)共享锁示例
php 复制代码
$file = fopen("config.json", "r");
if (flock($file, LOCK_SH)) {  // 共享读取锁
    echo "获取共享锁,开始读取:";
    echo fread($file, filesize("config.json"));
    flock($file, LOCK_UN);
}
fclose($file);
  • 用途‌:多进程并发读取时保证数据一致性

9、最佳实践

  • ‌锁顺序‌:避免多文件锁定时的死锁风险

  • ‌超时机制‌:配合stream_set_timeout()使用

  • ‌异常处理‌:确保锁最终被释放

  • ‌性能优化‌:减少锁定区域和持续时间

10、特殊注意事项

  • ‌NFS文件系统‌:锁可能不可靠

  • ‌符号链接‌:锁定链接文件而非目标文件

  • ‌PHP-FPM环境‌:注意进程复用导致的锁异常

  • ‌锁继承‌:子进程不继承父进程的文件锁

11、相关函数对比

函数 作用域 特点 适用场景
flock() 文件级 轻量级进程间锁 本地文件并发控制
semaphore 系统级 更重量级的锁 复杂同步需求
MySQL锁 数据库级 事务隔离控制 数据库记录并发

12、版本变化

  • PHP 4.0.1:引入命名常量替代数字参数

  • PHP 5.3.2:修改锁自动释放机制

  • PHP 7.0+:性能优化和错误处理改进

(二) unlink()‌

1、词源分解

  • unlink() 由前缀 "un-"(表示"移除")和 "link"(文件链接)组成,字面意思是"解除文件链接"。该函数源自Unix系统的unlink()系统调用,用于删除文件系统条目。

2、核心功能

  • ‌文件删除‌:永久删除指定路径的文件

  • ‌权限验证‌:检查执行进程的文件操作权限

  • ‌资源释放‌:释放文件占用的磁盘空间

  • ‌错误处理‌:返回操作状态并触发相应错误

3、语法结构

php 复制代码
bool unlink(string $filename [, resource $context = null ])

4、参数详解

(1)$filename 参数
特性 说明
类型 字符串
必需性 必需
接受值 绝对路径/相对路径
特殊限制 不能是目录
示例 /var/tmp/test.txt
(2)$context 参数
特性 说明
类型 资源类型
默认值 null
功能 定义流上下文选项
适用场景 特殊协议处理时
示例 stream_context_create()创建

5、返回值机制

操作结果 返回值 附加行为
成功删除 true 释放文件资源
失败删除 false 触发E_WARNING
文件不存在 false 触发E_WARNING
权限不足 false 触发E_WARNING

6、使用示例

(1)基础文件删除
php 复制代码
$file = "data.log";
if (unlink($file)) {
    echo "文件删除成功";  // 输出成功提示:ml-citation{ref="2,6" data="citationList"}
} else {
    echo "删除失败,错误原因:".error_get_last()['message'];
}
(2)带错误抑制符
php 复制代码
@unlink("nonexistent.txt");  // 静默失败不报错:ml-citation{ref="3,4" data="citationList"}
(3)上下文应用
php 复制代码
$context = stream_context_create([
    'http' => ['timeout' => 5]
]);
unlink('http://example.com/tempfile', $context);  // 网络文件删除:ml-citation{ref="5" data="citationList"}

7、工作原理

  • ‌系统调用‌:通过操作系统API执行删除

  • ‌权限检查‌:验证PHP进程的写权限

  • ‌引用计数‌:减少文件链接计数至0时物理删除

  • ‌资源释放‌:立即回收磁盘空间

8、能否直接输出

unlink()函数不能直接输出,它返回布尔值表示文件是否删除成功,需要通过条件判断结合echo输出操作结果。以下是具体方法和示例:

(1)基础删除与输出
php 复制代码
$file = "test.txt";
if (unlink($file)) {
    echo "文件 $file 删除成功";
} else {
    echo "文件 $file 删除失败(可能不存在或权限不足)";
}
  • 输出示例 ‌:
    成功时显示文件 test.txt 删除成功
    失败时显示文件 test.txt 删除失败(可能不存在或权限不足)
  • 关键点 ‌:
    • 需检查文件是否存在(file_exists())后再操作
    • 失败原因可能是路径错误、权限不足或文件被占用
(2) ‌带安全检查的完整示例
php 复制代码
$filename = "/var/www/data.log";
if (file_exists($filename)) {
    if (is_writable($filename)) {
        if (unlink($filename)) {
            echo "[SUCCESS] $filename 已删除";
        } else {
            echo "[ERROR] 删除操作执行失败";
        }
    } else {
        echo "[DENIED] 文件不可写";
    }
} else {
    echo "[MISSING] 文件不存在";
}
  • 输出场景 ‌:
    • 文件存在且可写:[SUCCESS] /var/www/data.log 已删除
    • 文件无权限:[DENIED] 文件不可写
    • 文件不存在:[MISSING] 文件不存在
(3)批量删除文件
php 复制代码
$files = ["temp1.txt", "temp2.txt"];
foreach ($files as $file) {
    if (unlink($file)) {
        echo "$file 删除成功<br>";
    } else {
        echo "$file 删除失败<br>";
    }
}
  • 输出示例 ‌:
    temp1.txt 删除成功
    temp2.txt 删除失败

9、注意事项

  • ‌符号链接‌:删除链接文件而非目标文件

  • ‌文件锁定‌:被锁定的文件无法删除

  • ‌权限继承‌:受父目录权限限制

  • ‌NFS系统‌:网络文件系统可能延迟生效

  • ‌安全模式‌:受safe_mode限制(PHP5.4移除)

10、最佳实践

  • ‌前置检查‌:
php 复制代码
if (file_exists($file) && is_writable($file)) {
    unlink($file);
}
  • ‌批量删除‌:
php 复制代码
array_map('unlink', glob("tmp/*.cache"));
  • ‌错误处理‌:
php 复制代码
set_error_handler(function($errno, $errstr) {
    if (strpos($errstr, 'unlink') !== false) {
        // 自定义处理逻辑
    }
});

11、相关函数对比

函数 作用对象 特点 适用场景
unlink() 文件 立即删除 临时文件清理
rmdir() 空目录 严格限制 目录管理
unset() 变量 内存操作 资源释放

12、版本变化

  • PHP 4.0+:基础功能实现

  • PHP 5.0+:增强错误处理

  • PHP 7.0+:性能优化提升30%

  • PHP 8.0+:类型系统严格化

(三)rename()‌

1、词源分解

  • rename() 由前缀 "re-"(表示"重新")和 "name"(命名)组成,字面意思是"重新命名"。该函数源自Unix系统的rename()系统调用,用于改变文件系统对象的名称或位置。

2、核心功能

  • ‌重命名文件/目录‌:修改文件或目录的名称3

  • ‌移动文件/目录‌:跨目录甚至跨磁盘分区移动文件(PHP 4.3.3+)

  • ‌原子操作‌:保证操作完整性(要么完全成功,要么完全失败)

  • ‌覆盖能力‌:自动覆盖已存在的目标文件

3、语法结构

php 复制代码
bool rename(string $oldname, string $newname [, resource $context = null ])

4、参数详解

(1)$oldname 参数
特性 说明
类型 字符串
必需性 必需
接受值 绝对路径/相对路径
特殊限制 必须存在且可访问
示例 /var/tmp/oldfile.txt
(2)$newname 参数
特性 说明
类型 字符串
必需性 必需
接受值 新路径/新名称
特殊能力 可跨目录/分区(有限制)
示例 /home/user/newfile.txt
(3)$context 参数
特性 说明
类型 资源类型
默认值 null
功能 定义流上下文选项
适用场景 特殊协议处理时
示例 stream_context_create()创建

5、返回值机制

操作结果 返回值 附加行为
成功 true 完成重命名/移动
失败 false 触发E_WARNING
权限不足 false 触发E_WARNING
跨分区限制 false PHP 4.3.3前限制

6、使用示例

(1)基础重命名
php 复制代码
if (rename("old.txt", "new.txt")) {
    echo "重命名成功";  // 输出成功提示
} else {
    echo "操作失败:".error_get_last()['message'];
}
(2)目录移动
php 复制代码
// 将目录从/tmp/mydir移动到/var/www/mydir
rename("/tmp/mydir", "/var/www/mydir");
(3)跨分区文件移动(PHP 4.3.3+)
php 复制代码
// 从C盘移动到D盘(Windows)
rename("C:\\data\\file.txt", "D:\\backup\\file.txt");

7、能否直接输出

rename()函数不能直接输出,它返回布尔值表示重命名是否成功,需要通过条件判断结合echo输出操作结果。以下是具体方法和示例:

(1)基础重命名与输出
php 复制代码
$oldName = "old.txt";
$newName = "new.txt";
if (rename($oldName, $newName)) {
    echo "文件从 {$oldName} 重命名为 {$newName} 成功";
} else {
    echo "重命名失败(可能文件不存在或权限不足)";
}
  • 输出示例 ‌:
    成功时显示文件从 old.txt 重命名为 new.txt 成功
    失败时显示重命名失败(可能文件不存在或权限不足)
  • 关键点 ‌:
    • 需确保原文件存在且可访问
    • 目标路径需有写入权限
(2)跨目录移动并重命名
php 复制代码
if (rename("/var/www/temp/file.log", "/backup/logs/archive.log")) {
    echo "文件移动并重命名成功";
} else {
    echo "操作失败,检查路径权限或磁盘空间";
}
  • 功能‌:将文件从原目录移动到新目录同时改名
  • 注意‌:跨磁盘分区操作需PHP 4.3.3及以上版本
(3)目录重命名示例
php 复制代码
$oldDir = "project_old";
$newDir = "project_new";
if (is_dir($oldDir) && rename($oldDir, $newDir)) {
    echo "目录 {$oldDir} 已更名为 {$newDir}";
} else {
    echo "目录不存在或更名失败";
}
  • 输出场景 ‌:
    目录存在且可写时显示更名成功,否则提示失败

8、特殊行为说明

  • ‌非空目录‌:只能在同分区内移动

  • ‌空目录‌:可跨分区移动但父目录必须存在

  • ‌符号链接‌:操作链接文件本身而非目标文件

  • ‌并发安全‌:操作期间自动锁定文件

9、错误处理建议

  • ‌前置检查‌:
php 复制代码
if (!file_exists($oldname)) {
    throw new Exception("源文件不存在");
}
if (!is_writable(dirname($newname))) {
    throw new Exception("目标目录不可写");
}
  • ‌覆盖处理‌:
php 复制代码
if (file_exists($newname)) {
    unlink($newname);  // 先删除已存在文件:ml-citation{ref="8" data="citationList"}
}

10、性能优化

  • ‌替代方案‌:比copy+unlink方式快10倍以上

  • ‌大文件处理‌:特别适合大文件移动操作

  • ‌批量操作‌:结合glob()使用

11、平台差异

平台 特性
Windows 支持驱动器间移动
Unix-like 需要同文件系统(早期版本)
NFS 可能有延迟问题

12、安全注意事项

  • ‌权限检查‌:确保脚本有足够权限

  • ‌路径安全‌:建议配合realpath()使用

  • ‌竞争条件‌:检查与操作间可能存在时间差

13、相关函数对比

函数 作用 特点 适用场景
rename() 移动/重命名 原子操作 文件重组
copy() 复制文件 保留原文件 创建副本
unlink() 删除文件 不可逆 清理文件

14、版本变化

  • PHP 4.3.3:支持跨分区文件移动

  • PHP 5.0+:增强错误处理

  • PHP 7.0+:性能优化提升20%

  • PHP 8.0+:严格类型检查

15、高级用法

php 复制代码
// 使用上下文设置超时
$context = stream_context_create([
    'http' => ['timeout' => 5]
]);
rename('http://example.com/old', 'http://example.com/new', $context);

(四) fseek()‌

1、词源分解

  • fseek() 由 "f"(file,文件)和 "seek"(寻找)组合而成,字面意思是"在文件中寻找"。该函数源自C语言的fseek()函数,用于在文件流中定位指针位置。

2、核心功能

  • ‌文件指针定位‌:精确控制文件读写位置

  • ‌随机访问‌:支持非顺序文件操作

  • ‌大文件处理‌:高效操作大尺寸文件

  • ‌编辑控制‌:实现文件内容的精确修改

3、语法结构

php 复制代码
int fseek(resource $handle, int $offset [, int $whence = SEEK_SET ])

4、参数详解

(1)$handle 参数
特性 说明
类型 资源类型
必需性 必需
来源 必须通过fopen()创建
生命周期 随文件关闭失效
示例 fopen("data.txt", "r+")
(2)$offset 参数
特性 说明
类型 整型
必需性 必需
取值范围 正数/负数/零
单位 字节
特殊值 负数表示反向移动
(3)$whence 参数
常量 功能 典型用法
SEEK_SET 0 从文件头计算 绝对定位
SEEK_CUR 1 从当前位置计算 相对移动
SEEK_END 2 从文件尾计算 追加内容

5、返回值机制

操作结果 返回值 附加说明
成功 0 指针已移动
失败 -1 通常因权限问题
越界 0 超过EOF不报错

6、完整示例演示

示例1:基础定位与读取
php 复制代码
// 创建测试文件
file_put_contents('test.txt', '0123456789ABCDEFGHIJ');
$file = fopen('test.txt', 'r');
fseek($file, 5); // 移动到第5字节
echo "当前位置: ".ftell($file)."\n"; // 输出: 5
echo "读取内容: ".fread($file, 3);   // 输出: 567
fclose($file);
示例2:相对位置移动
php 复制代码
$file = fopen('test.txt', 'r+');
fseek($file, 10, SEEK_SET); // 定位到10字节
fseek($file, -3, SEEK_CUR); // 回退3字节
echo "最终位置: ".ftell($file)."\n"; // 输出: 7
fwrite($file, 'XXX'); // 覆盖写入
fclose($file);
// 查看文件内容
echo file_get_contents('test.txt'); 
// 输出: 0123456XXXDEFGHIJ (原7-9位置被替换)
示例3:文件末尾操作
php 复制代码
$file = fopen('test.txt', 'a');
fseek($file, -5, SEEK_END); // 定位到末尾前5字节
echo "读取末尾内容: ".fread($file, 5)."\n"; // 输出: FGHIJ
fclose($file);
示例4:二进制文件处理
php 复制代码
// 生成二进制测试文件
$binData = pack('C*', 0x48, 0x65, 0x6C, 0x6C, 0x6F);
file_put_contents('binary.bin', $binData);
$file = fopen('binary.bin', 'rb');
fseek($file, 2);
echo "二进制数据: ".bin2hex(fread($file, 3)); // 输出: 6c6c6f
fclose($file);
示例5:错误处理
php 复制代码
$file = @fopen('nonexist.txt', 'r');
if(!$file) {
    echo "文件打开失败\n"; // 输出: 文件打开失败
} else {
    if(fseek($file, 100) === -1) {
        echo "指针移动失败\n"; 
    }
    fclose($file);
}

7、能否直接输出

fseek()函数不能直接输出,它返回整数值表示操作状态(成功返回0,失败返回-1),需要通过条件判断结合echo输出操作结果。以下是具体方法和示例:

(1)基础定位与状态输出
php 复制代码
$file = fopen("data.txt", "r");
if (fseek($file, 10, SEEK_SET) === 0) {
    echo "文件指针成功移动到第10字节";
} else {
    echo "指针移动失败";
}
fclose($file);
  • 输出示例 ‌:
    成功时显示文件指针成功移动到第10字节
    失败时显示指针移动失败
  • 关键点 ‌:
    • 返回值严格用===比较(可能返回0或-1)
    • SEEK_SET表示从文件开头计算偏移量
(2) ‌结合ftell()输出当前位置
php 复制代码
$fp = fopen("log.txt", "r+");
fseek($fp, -5, SEEK_END); // 移动到末尾前5字节
echo "当前指针位置:" . ftell($fp); // 输出实际位置
fclose($fp);
  • 输出结果 ‌:
    若文件大小为20字节,则显示当前指针位置:15
  • 用途 ‌:
    验证偏移量是否生效
(3)完整读写操作示例
php 复制代码
$filename = "test.txt";
$file = fopen($filename, "r+");
if ($file) {
    // 移动到第5字节并读取后续内容
    fseek($file, 5, SEEK_SET);
    $content = fread($file, 10);
    echo "读取的内容:" . $content . "<br>";

    // 移动到末尾追加数据
    fseek($file, 0, SEEK_END);
    fwrite($file, "\n追加的数据");

    // 重置指针输出全文
    rewind($file);
    echo "全文内容:" . stream_get_contents($file);
    fclose($file);
}
  • 输出逻辑 ‌:
    1. 输出从第5字节开始的10个字符
    2. 追加数据后输出完整文件内容

8、关键特性

  • 支持大文件(最大可达2GB)

  • 二进制安全(适合处理非文本文件)

  • ftell()rewind()配合使用

  • 不同模式下的行为差异:

    • r模式:只读定位

    • r+模式:可读写定位

    • a模式:写入时自动跳到文件尾

9、最佳实践

  • 总是检查返回值

  • 二进制文件使用rb/r+b模式

  • 配合flock()实现线程安全

  • 处理大文件时注意内存限制

  • ‌系统调用‌:通过底层lseek()实现

  • ‌缓冲处理‌:自动刷新I/O缓冲区

  • ‌指针管理‌:不影响实际文件内容

  • ‌原子操作‌:保证定位的精确性

10、注意事项

  • ‌文本文件‌:Windows换行符可能影响定位精度

  • ‌网络流‌:部分协议不支持随机访问

  • ‌并发安全‌:需配合flock()使用

  • ‌性能优化‌:减少不必要的定位操作

11、相关函数对比

函数 作用 特点 适用场景
fseek() 指针定位 精确控制 随机访问
rewind() 重置指针 快捷操作 文件重读
ftell() 获取位置 状态查询 进度跟踪

12、版本变化

  • PHP 4.0.0:引入whence参数

  • PHP 5.0+:增强错误处理

  • PHP 7.0+:优化大文件支持

  • PHP 8.0+:严格类型检查

13、高级技巧

  • ‌二进制安全‌:配合pack()/unpack()处理结构化数据

  • ‌断点续传‌:记录并恢复文件处理位置

  • ‌内存映射‌:替代方案mmap()处理超大文件

(五)ftell()‌

1、词源分解

  • ftell() 由 "f"(file,文件)和 "tell"(告知)组合而成,字面意思是"告知文件位置"。该函数源自C语言的ftell()函数,用于获取文件指针的当前位置。

2、核心功能

  • ‌指针位置查询‌:获取当前文件指针的位置

  • ‌进度跟踪‌:监控文件读写进度

  • ‌断点续传‌:记录文件处理位置

  • ‌调试辅助‌:验证文件操作位置

3、语法结构

php 复制代码
int ftell(resource $handle)

4、参数详解

$handle 参数
特性 说明
类型 资源类型
必需性 必需
来源 必须通过fopen()创建的有效文件资源
状态要求 文件必须已打开且未被关闭
无效处理 传入无效资源会产生警告

5、返回值机制

结果 返回值 说明
成功 整数 当前指针位置(字节偏移量)
失败 false 通常因无效资源或错误状态

6、使用示例

(1)基础用法示例
php 复制代码
$file = fopen("data.txt", "r");
fseek($file, 50); // 移动指针到50字节位置
$position = ftell($file);
echo "当前指针位置: " . $position . "\n";
// 输出: 当前指针位置: 50
fclose($file);
(2)与fseek()配合使用
php 复制代码
$file = fopen("log.txt", "r+");
fwrite($file, "Hello");
echo "写入后位置: " . ftell($file) . "\n";
// 输出: 写入后位置: 5
fseek($file, 0, SEEK_END);
echo "文件末尾位置: " . ftell($file) . "\n";
// 假设文件原长度20字节,输出: 文件末尾位置: 20
fclose($file);
(3)二进制文件处理
php 复制代码
$file = fopen("image.jpg", "rb");
fseek($file, 10, SEEK_SET);
echo "JPEG文件标记位置: " . ftell($file) . "\n";
// 输出: JPEG文件标记位置: 10
fclose($file);
(4)错误处理示例
php 复制代码
$file = @fopen("nonexistent.txt", "r");
if ($file === false) {
    echo "文件打开失败\n";
    // 输出: 文件打开失败
} else {
    $pos = ftell($file);
    if ($pos === false) {
        echo "获取位置失败\n";
    } else {
        echo "初始位置: " . $pos . "\n";
        // 输出: 初始位置: 0
    }
    fclose($file);
}

7、能否直接输出

ftell()函数不能直接输出,它返回文件指针当前位置的字节偏移量(整型),需要通过echovar_dump()等函数输出结果。以下是具体方法和示例:

(1)基础输出示例
php 复制代码
$file = fopen("data.txt", "r");
fseek($file, 10); // 移动指针到第10字节
$position = ftell($file); // 获取当前位置
echo "当前指针位置:" . $position; // 输出结果
fclose($file);
  • 输出结果 ‌:
    成功时显示当前指针位置:10
    失败时返回false(需用===判断)
  • 关键点 ‌:
    • 需先通过fopen()打开有效文件资源
    • 指针位置从0开始计算(字节为单位)
(2)结合文件大小检测
php 复制代码
$filename = "log.txt";
$file = fopen($filename, "r");
if ($file) {
    fseek($file, 0, SEEK_END); // 移动到文件末尾
    $size = ftell($file); // 获取总字节数
    echo "文件大小:" . $size . "字节";
    fclose($file);
} else {
    echo "文件打开失败";
}
  • 输出场景 ‌:
    若文件大小为1024字节,则显示文件大小:1024字节
  • 用途 ‌:
    动态计算文件大小(需注意大文件内存限制)
(3)错误处理与调试
php 复制代码
$fp = fopen("nonexist.txt", "r");
$pos = ftell($fp);
if ($pos === false) {
    echo "获取指针位置失败:" . error_get_last()["message"];
} else {
    echo "指针位置:" . $pos;
}
  • 输出示例 ‌:
    文件不存在时显示获取指针位置失败:fopen(): Failed to open stream

8、工作原理

  • ‌系统调用‌:通过底层文件系统接口获取指针位置

  • ‌缓冲处理‌:反映实际物理位置而非缓冲位置

  • ‌字节计数‌:返回从文件头开始的字节偏移量

  • ‌流支持‌:适用于各种流类型(文件、内存流等)

9、注意事项

  • ‌文本模式‌:Windows平台换行符转换可能影响位置计算

  • ‌网络流‌:部分流类型可能不支持位置查询

  • ‌大文件‌:支持超大文件(PHP 7.0+支持64位文件系统)

  • ‌并发访问‌:非线程安全,需配合文件锁定使用

10、相关函数对比

函数 作用 与ftell()的关系
fseek() 移动指针 ftell()用于验证移动结果
rewind() 重置指针 等效于fseek($handle, 0)
fstat() 获取文件信息 包含文件大小,可与位置比较

11、版本变化

  • PHP 4.0.0:基础功能引入

  • PHP 5.0+:改进错误处理

  • PHP 7.0+:增强大文件支持

  • PHP 8.0+:严格类型检查

12、高级应用场景

  • ‌断点续传‌:

    php 复制代码
    // 记录上次读取位置
    $lastPos = file_get_contents('progress.log');
    $file = fopen('large.zip', 'rb');
    if ($lastPos) fseek($file, $lastPos);
    while (!feof($file)) {
        $data = fread($file, 8192);
        // 处理数据...
        file_put_contents('progress.log', ftell($file));
    }
    fclose($file);
  • ‌文件校验‌:

    php 复制代码
    $file = fopen('data.bin', 'rb');
    fseek($file, -100, SEEK_END);
    $endPos = ftell($file);
    echo "文件尾部100字节开始于: $endPos\n";
    // 输出示例: 文件尾部100字节开始于: 12300 (假设文件12400字节)
    fclose($file);

‌调试文件操作‌:

php 复制代码
function debugSeek($file, $offset, $whence = SEEK_SET) {
    $before = ftell($file);
    fseek($file, $offset, $whence);
    $after = ftell($file);
    echo "指针移动: $before → $after (变化: ".($after-$before)."字节)\n";
}
$file = fopen('test.txt', 'r');
debugSeek($file, 10);
// 输出: 指针移动: 0 → 10 (变化: 10字节)
debugSeek($file, -5, SEEK_CUR);
// 输出: 指针移动: 10 → 5 (变化: -5字节)
fclose($file);

(六)ftruncate()‌

1、词源分解

  • ftruncate() 由 "f"(file,文件)和 "truncate"(截断)组合而成,源自Unix系统调用ftruncate(),意为"文件截断操作"。该函数最早出现在XPG4.2标准中,后被PHP引入作为文件系统函数。

2、核心功能

  • ‌文件尺寸调整‌:将打开的文件截断或扩展到指定大小

  • ‌数据清理‌:快速清空文件内容(设置size=0)

  • ‌空间预分配‌:扩展文件时自动填充空字节

  • ‌日志管理‌:定期截断日志文件防止过大

3、语法结构

php 复制代码
bool ftruncate(resource $handle, int $size)

4、参数详解

(1)$handle 参数
特性 说明
类型 资源类型
必需性 必需
有效值 通过fopen()打开的文件资源
模式要求 必须具有写入权限("r+"、"w"、"a+"等)
无效处理 传入无效资源返回false并产生警告
(2)$size 参数
特性 说明
类型 整数
单位 字节
作用 设置文件的目标大小
特殊值 0表示清空文件
扩展机制 大于原尺寸时填充空字节(\x00)

5、返回值机制

结果 返回值 版本差异
成功 true 统一返回布尔值
失败 false PHP 4.3.3前返回1/0

6、使用示例

(1)基础文件截断
php 复制代码
// 创建测试文件
file_put_contents('data.txt', str_repeat('A', 200));
$file = fopen('data.txt', 'r+');
ftruncate($file, 100);
fclose($file);
echo filesize('data.txt'); // 输出: 100
  • 说明:将200字节文件截断为100字节,超出的100字节被删除
(2)文件清空操作
php 复制代码
$logFile = fopen('app.log', 'w');
ftruncate($logFile, 0); // 清空日志文件
fclose($logFile);
(3)文件扩展示例
php 复制代码
$file = fopen('empty.bin', 'w+');
ftruncate($file, 1024); // 创建1KB的空文件
echo filesize('empty.bin'); // 输出: 1024
fclose($file);
(4)错误处理示范
php 复制代码
$file = @fopen('readonly.txt', 'r');
if ($file === false || !ftruncate($file, 0)) {
    echo "操作失败:".(is_resource($file) ? "无写入权限" : "文件打开失败");
}
@fclose($file);

7、能否直接输出

ftruncate()函数不能直接输出,它返回布尔值表示操作是否成功,需要通过条件判断结合echo输出结果。以下是具体方法和示例:

(1)基础截断与输出
php 复制代码
$file = fopen("test.txt", "a+");
if (ftruncate($file, 100)) {
    echo "文件成功截断为100字节";
} else {
    echo "截断失败(可能文件不可写或指针无效)";
}
fclose($file);
  • 输出示例 ‌:
    成功时显示文件成功截断为100字节
    失败时显示截断失败(可能文件不可写或指针无效)
  • 关键点 ‌:
    • 需以可写模式(如"a+""r+")打开文件
    • 截断后需调用clearstatcache()更新文件状态缓存
(2)结合文件大小验证
php 复制代码
$filename = "data.log";
$file = fopen($filename, "r+");
ftruncate($file, 50);
clearstatcache(); // 清除缓存以获取最新大小
echo "当前文件大小:" . filesize($filename) . "字节";
fclose($file);
  • 输出结果 ‌:
    若操作成功,显示当前文件大小:50字节
  • 用途 ‌:
    验证截断后的实际文件大小
(3)错误处理示例
php 复制代码
$fp = fopen("/readonly/note.txt", "r");
if (ftruncate($fp, 0) === false) {
    $error = error_get_last();
    echo "操作失败:" . $error["message"];
}
  • 输出场景 ‌:
    文件只读时显示操作失败:ftruncate(): write of 0 bytes failed

8、工作原理

  • ‌系统调用‌:通过底层ftruncate()系统调用实现

  • ‌指针保留‌:不改变当前文件指针位置

  • ‌原子操作‌:保证操作过程的完整性

  • ‌权限检查‌:需要文件描述符具有写权限

9、注意事项

  • ‌模式限制‌:

    • a模式需配合fseek()使用

    • 网络流可能不支持此操作

  • ‌大文件处理‌:

    • 支持超过2GB的文件(PHP 7.0+)

    • 32位系统有2GB限制

  • ‌性能影响‌:

    • 频繁截断大文件影响I/O性能

    • 清空文件比重写更高效

  • ‌缓存问题‌:

    • 操作后建议使用clearstatcache()

    • 可能不会立即反映在filesize()

10、相关函数对比

函数 作用 与ftruncate()的关系
truncate() 通过路径截断文件 类似功能但参数不同
fseek() 移动文件指针 常配合使用调整位置
filesize() 获取文件大小 用于验证截断结果

11、版本变化

  • PHP 4.0.0:引入基础功能

  • PHP 4.3.3:返回值标准化(true/false)

  • PHP 5.0+:改进错误处理

  • PHP 7.0+:增强大文件支持

12、高级应用场景

(1)日志轮转系统
php 复制代码
function rotateLog($filePath, $maxSize) {
    if (filesize($filePath) > $maxSize) {
        $file = fopen($filePath, 'r+');
        ftruncate($file, 0);
        fwrite($file, "[".date('Y-m-d')."] Log rotated\n");
        fclose($file);
    }
}
(2)数据库文件维护
php 复制代码
$dbFile = 'data.db';
$file = fopen($dbFile, 'r+');
// 执行VACUUM操作后...
ftruncate($file, $newSize); // 收缩文件大小
fclose($file);
(3)文件下载断点续传
php 复制代码
$file = fopen('large.zip', 'r+');
// 下载中断后...
ftruncate($file, $downloadedSize); // 移除已下载部分
fclose($file);

13、常见错误处理

  • ‌权限问题‌:
php 复制代码
chmod($filePath, 0644); // 确保可写权限:ml-citation{ref="7" data="citationList"}
  • ‌SELinux限制‌:
php 复制代码
# 检查并调整安全上下文:ml-citation{ref="6" data="citationList"}
ls -Z /path/to/file
  • ‌磁盘空间不足‌:
php 复制代码
if (disk_free_space('/') < $requiredSize) {
    throw new Exception('磁盘空间不足');
}

(七)copy()

1、词源分解

copy 源自英语单词:

  • ‌copy‌(复制):表示创建文件副本的操作

  • 作为计算机术语,指代文件复制这一基础操作

2、功能概述

copy() 是 PHP 核心文件系统函数,用于将源文件复制到目标位置。主要特点包括:

  • 支持本地文件和 URL 流(需allow_url_fopen启用)

  • 目标文件已存在时会自动覆盖

  • 不自动创建目录结构

3、语法结构

php 复制代码
bool copy(string $source, string $dest [, resource $context ])

4、参数详解

(1) $source(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定源文件路径

  • ‌支持格式‌:

    • 相对路径("file.txt"

    • 绝对路径("/var/www/file.txt"

    • URL("http://example.com/file.txt"

(2)$dest(必需)
  • ‌类型‌:字符串

  • ‌功能‌:指定目标路径

  • ‌特殊说明‌:

    • 需有写入权限

    • 目录需已存在

    • 可指定新文件名

(3)$context(可选)
  • ‌类型‌:资源(resource)

  • ‌功能‌:流上下文配置

  • ‌典型应用‌:

    • 设置 HTTP 头

    • 配置 SSL 选项

    • 修改超时时间

5、返回值

  • ‌成功‌:返回 true

  • ‌失败‌:返回 false 并生成警告

6、输出换行说明

copy() 本身不产生输出,但使用时需注意:

  1. 成功/失败消息输出是否换行取决于调用代码

  2. 文件内容中的换行符会被原样保留

  3. 典型示例中常用 \nPHP_EOL 控制换行

7、基础示例

示例1:基本文件复制
php 复制代码
$source = "source.txt";
$dest = "backup.txt";
if (copy($source, $dest)) {
    echo "文件复制成功\n";  // 显式添加换行
} else {
    echo "复制失败 - " . error_get_last()['message'];
}

‌ 输出‌(成功时):

php 复制代码
文件复制成功
示例2:带错误处理
php 复制代码
$source = "data.csv";
$dest = "archive/data_" . date('Ymd') . ".csv";
if (!file_exists(dirname($dest))) {
    mkdir(dirname($dest), 0755, true);
}
if (@copy($source, $dest)) {
    echo "备份完成,大小: " . filesize($dest) . "字节";
} else {
    $error = error_get_last();
    echo "错误: " . $error['message'];
}

8、能否直接输出

copy()函数不能直接输出,它返回布尔值表示操作是否成功,需要通过条件判断结合echo输出结果。以下是具体方法和示例:

(1)基础文件复制与状态输出
php 复制代码
$source = "source.txt";
$target = "target.txt";
if (copy($source, $target)) {
    echo "文件复制成功";
} else {
    echo "复制失败(可能源文件不存在或目标不可写)";
}
  • 输出示例 ‌:
    成功时显示文件复制成功
    失败时显示复制失败(可能源文件不存在或目标不可写)
  • 关键点 ‌:
    • 目标文件若已存在会被覆盖
    • 需确保源文件可读且目标路径可写
(2)结合文件检查的完整示例
php 复制代码
$sourceFile = "data.log";
$destFile = "backup/data.log";
if (!file_exists($sourceFile)) {
    die("源文件不存在");
}
if (!is_writable(dirname($destFile))) {
    die("目标目录不可写");
}
if (copy($sourceFile, $destFile)) {
    echo "文件已备份至:" . realpath($destFile);
} else {
    echo "备份过程中发生错误";
}
  • 输出场景 ‌:
    成功备份后显示文件已备份至:/path/to/backup/data.log
    权限不足时显示目标目录不可写
(3) ‌错误处理扩展
复制代码
php 复制代码
$result = copy("nonexist.txt", "new.txt");
if ($result === false) {
    $error = error_get_last();
    echo "操作失败:" . $error["message"];
}
  • 输出示例 ‌:
    文件不存在时显示操作失败:copy(nonexist.txt): failed to open stream: No such file or directory

9、高级应用

大文件分块复制
php 复制代码
function copyLargeFile($source, $dest, $chunkSize = 1048576) {
    $src = fopen($source, 'rb');
    $dst = fopen($dest, 'wb');
    
    while (!feof($src)) {
        fwrite($dst, fread($src, $chunkSize));
    }
    
    fclose($src);
    fclose($dst);
    return true;
}

‌优势‌:避免内存溢出

10、安全注意事项

  1. ‌路径验证‌:使用realpath()处理用户输入路径

  2. ‌权限检查‌:

    php 复制代码
    phpCopy Codeis_readable($source) && is_writable(dirname($dest))
  3. ‌存在性检查‌:file_exists($source)

11、性能特点

  1. ‌系统调用‌:直接使用操作系统级复制操作

  2. ‌效率对比‌:比file_get_contents()+file_put_contents()组合更快

  3. ‌限制‌:无法复制超过php.inimemory_limit的大文件

12、相关函数对比

函数 内存使用 适用场景 是否保持权限
copy() 常规文件复制
rename() 最低 移动/重命名
流操作组合 需要处理内容时 可控制
相关推荐
林深时见鹿7498 小时前
使用k8s k3s kuboard 部署 php hyperf 框架
php
长城20248 小时前
PHP如何使用JpGraph生成3D饼形图?
开发语言·php·jpgraph·3d饼形图
熬夜苦读学习15 小时前
Reactor 反应堆模式
运维·服务器·网络·网络协议·http·智能路由器·php
小森林815 小时前
分享一次Guzzlehttp上传批量图片优化的经历
后端·php
THMAIL16 小时前
大模型0基础开发入门与实践:第11章 进阶:LangChain与外部工具调用
开发语言·langchain·php
分享点2 天前
Laravel 使用阿里云OSS S3 协议文件上传
阿里云·php·laravel
苏琢玉2 天前
订单号老是撞车?我写了个通用 PHP ID 生成器
php·composer
BingoGo2 天前
PHP 测试框架 Pest v4 正式发布 革命性的浏览器测试体验
后端·php
搬码临时工2 天前
通过自定义域名访问内网的web服务和tcp应用:内网ip到局域网外域名访问过程
服务器·tcp/ip·php