PHP语法高级篇(二):文件处理

文件处理是任何 Web 应用程序的重要组成部分,PHP 拥有用于创建、读取、上传和编辑文件的多个函数。本篇文章将记录文件处理的学习过程。

本篇文章内容包括:

  • 文件打开/读取
  • 文件创建/写入
  • 文件上传

一、文件打开/读取

在本节中,我们将学习如何在服务器上打开、读取和关闭文件。

1、打开文件 - fopen()

fopen() 函数用于打开文件或者 URL。

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

fopen() 将 filename指定的名字资源绑定到一个流上。

参数

filename

必需。如果 filename 是 "scheme://..." 的格式,则被当成一个 URL,PHP 将搜索协议处理器(也被称为封装协议)来处理此模式。如果该协议尚未注册封装协议,PHP 将发出一条消息来帮助检查脚本中潜在的问题并将 filename 当成一个普通的文件名继续执行下去。

mode

必需。mode 参数指定了所要求到该流的访问类型。如下表所示:

|----|---------------------------------------------------------|
| 模式 | 描述 |
| r | 只读方式打开文件。文件指针指向文件开头。 |
| w | 只写方式打开文件。 如果文件不存在则创建新文件。 如果文件存在,则清空文件内容。 文件指针指向文件开头。 |
| a | 只写方式打开文件。 如果文件不存在,则创建新文件。 如果文件存在,则不会清空文件内容。 文件指针指向文件末尾。 |
| x | 以只写方式创建新文件。 如果文件已存在,则返回 FALSE 并产生错误。 |
| r+ | 读写方式打开文件。文件指针指向文件开头。 |
| w+ | 读写方式打开文件。 如果文件不存在则创建新文件。 如果文件存在,则清空文件内容。 文件指针指向文件开头。 |
| a+ | 读写方式打开文件。 如果文件不存在则创建新文件。 如果文件存在,则不会清空文件内容。 文件指针指向文件末尾。 |
| x+ | 以读写方式创建新文件。 如果文件已存在,则返回 FALSE 并产生错误。 |

use_include_path

可选。如果需要在 include_path中搜寻文件的话,可以将可选的第三个参数 use_include_path 设为 '1' 或 true。

context

可选。上下文流(context stream) resource。

返回值

成功时返回文件指针资源, 或者在失败时返回 false。

2、读取文件 - fread()

使用 fopen() 函数打开文件后,接下来我们就可以开始读取文件内容了。

fread() 函数从打开的文件中读取内容。

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

fread() 从文件指针 stream 读取最多 length 个字节。该函数在遇上以下几种情况时停止读取文件:

  • 读取了 length个字节
  • 到达了文件末尾(EOF)

参数

stream

必需。文件系统指针。

length

必需。最多读取 length 个字节。

返回值

返回所读取的字符串, 或者在失败时返回 false。

3、关闭文件 - fclose()

使用 fopen() 函数打开的文件在完成操作后,需要将打开的文件进行关闭。

fclose() 函数用于关闭打开的文件。

php 复制代码
fclose(resource $stream): bool

stream指向的文件关闭。

参数

stream

必需。文件系统指针。

返回值

成功时返回 true, 或者在失败时返回 false。

接下来我们通过一个示例来看一下如何使用 fopen()、fread()、fclose() 函数来完成对文件的读取操作。

首先,准备一个文本文件,向其中写入一些内容,这个文件将作为稍后文件读取时使用的测试文件。将文件命名为 test.txt(其它的什么名字都可以),内容如下(随便写点什么内容就行):

php 复制代码
AJAX = Asynchronous JavaScript and XML
CSS = Cascading Style Sheets
HTML = Hyper Text Markup Language
PHP = PHP Hypertext Preprocessor
SQL = Structured Query Language
SVG = Scalable Vector Graphics
XML = EXtensible Markup Language

接下来我们来写读取文件内容的代码:

php 复制代码
$file_name = "test.txt";
$file = fopen($file_name, "r"); // 以只读的方式打开 test.txt 文件
// filesize(文件路径):取得指定文件的大小。 
$content = fread($file, filesize($file_name)); // 读取全部文件内容
fclose($file); // 关闭打开的文件

echo $content;

4、读取单行 - fgets()

fgets() 函数用于从文件中读取一行。相比于 fread() 函数,fgets() 函数更适合处理文本文件。

php 复制代码
fgets(resource $stream, ?int $length = null): string|false

从文件指针中读取一行。

参数

stream

必需。文件系统指针。

length

可选。从指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length,则默认为 1K,或者说 1024 字节。

返回值

从指向的文件中读取了 length - 1 字节后返回字符串。如果文件指针中没有更多的数据了则返回 false。

示例

php 复制代码
$file = fopen("test.txt", "r"); // 以只读的方式打开 test.txt 文件
$content = fgets($file); // 读取一行内容
fclose($file); // 关闭打开的文件

echo $content;

注意:在调用 fgets() 函数后,文件指针已移至下一行。

5、读取单个字符 - fgetc()

我们除了可以用 fgets() 函数读取一行内容外,还可以使用 fgetc() 函数从文件中读取单个字符。

php 复制代码
fgetc(resource $stream): string|false

从文件中读取单个字符。

参数

stream

必需。文件系统指针。

返回值

返回一个包含有一个字符的字符串,该字符从 stream 指向的文件中得到。碰到 EOF 则返回 false。

示例

php 复制代码
$file = fopen("test.txt", "r"); // 以只读的方式打开 test.txt 文件
$content = fgetc($file); // 读取一个字符内容
fclose($file); // 关闭打开的文件

echo $content;

注意:在调用 fgetc() 函数后,文件指针移至下一个字符。

6、检查文件末尾 - feof()

feof() 函数用于检查是否已达到"文件末尾"(EOF),在遍历读取文件内容时十分有用。

php 复制代码
feof(resource $stream): bool

测试文件指针是否到了文件结束的位。

参数

stream

必需。文件系统指针。

返回值

如果文件指针到了 EOF 或者出错时则返回 true,否则返回一个错误(包括 socket 超时),其它情况则返回 false。

示例 逐行读取 test.txt 文件内容,直至文件末尾

php 复制代码
$file = fopen("test.txt", "r");
while (!feof($file)) {
    $content = fgets($file);
    echo "$content <br>";
}
fclose($file);

二、文件创建/写入

在本节中,我们将学习如何在服务器上创建和写入文件。

1、创建文件 - fopen()

fopen() 函数也用于创建文件。如果在不存在的文件上使用 fopen(),并且该文件是打开以进行写入(w)或追加(a)的,那么它将创建该文件。

下面的示例创建了一个名为 "testfile.txt" 的新文件,该文件将在 PHP 代码所在的同一目录中创建:

php 复制代码
$file = fopen("testfile.txt", "w");

如果在运行此代码时遇到错误,请检查是否已授予 PHP 文件向硬盘写入信息的权限。

2、写入文件 - fwrite()

fwrite() 函数用于向文件写入。

php 复制代码
fwrite(resource $stream, string $data, ?int $length = null): int|false

fwrite() 把 data 的内容写入文件指针 stream 处。

参数

stream

必需。文件系统指针。

data

必需。要写入的字符串。

length

可选。当写入了 length 个字节或者写完了 string 以后,写入就会停止,看先碰到哪种情况。

返回值

fwrite() 返回写入的字符数, 或者在失败时返回 false。

示例

php 复制代码
$file = fopen("testfile.txt", "w");
fwrite($file, "Hello World!\n");
fwrite($file, "你好,世界!\n");
fclose($file);

三、文件上传

在本节中,我们将学习如何处理文件上传。

1、配置 "php.ini" 文件

首先,确保 PHP 配置为允许文件上传。在你的 "php.ini" 文件中,搜索 file_uploads 指令,并将其设置为 On:

php 复制代码
file_uploads = On

2、创建 HTML 表单

接下来,创建一个 HTML 表单,允许用户选择要上传的文件:

html 复制代码
<!DOCTYPE html>
<html>
    <meta charset="utf-8">
    <body>
        <form action="upload.php" method="post" enctype="multipart/form-data">
            选择上传的文件:
            <input type="file" name="userfile">
            <input type="submit" value="上传文件">
        </form>
    </body>
</html>

上述 HTML 表单需要遵循的一些规则:

  • 确保表单使用 method="post"
  • 表单还需要以下属性:enctype="multipart/form-data"。它指定提交表单时要使用的 content-type

如果不满足上述要求,文件上传将无法工作。

上述表单将数据发送到名为 "upload.php" 的文件,接下来我们就来创建该文件。

3、创建上传文件的 PHP 脚本

全局变量 $_FILES 包含有所有上传的文件信息。数组的内容来自以下范例表单。我们假设文件上传字段的名称如下例所示,为 userfile。名称可随意命名。

|--------------------------------------|---------------------------------------------------------------------------------|
| _FILES\['userfile'\]\['name'\] | 客户端机器文件的原名称。 | | _FILES['userfile']['type'] | 文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是"image/gif"。不过此 MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。 |
| _FILES\['userfile'\]\['size'\] | 已上传文件的大小,单位为字节。 | | _FILES['userfile']['tmp_name'] | 文件被上传后在服务端储存的临时文件名。 |
| _FILES\['userfile'\]\['error'\] | 和该文件上传相关的错误代码。 | | _FILES['userfile']['full_path'] | 浏览器提交的完整路径。该值并不总是包含真实的目录结构,因此不能被信任。从 PHP 8.1.0 起可用。 |

创建 "upload.php" 文件来接收上传的文件。

php 复制代码
$uploaddir = 'uploads/'; // 指定上传文件要放置的目录
// basename(): 返回路径中的文件名部分
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']); // 指定要上传的文件的路径

/*
    move_uploaded_file --- 将上传的文件移动到新位置
        move_uploaded_file(string $from, string $to): bool
        本函数检查并确保由 from 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST 上传机制所上传的)。如果文件合法,则将其移动为由 to 指定的文件。 
        参数 
            from: 上传的文件的文件名。 
            to: 移动文件到这个位置。 
        返回值
            成功时返回 true。 
            如果 from 不是合法的上传文件,不会出现任何操作,move_uploaded_file() 将返回 false。 
            如果 from 是合法的上传文件,但出于某些原因无法移动,不会出现任何操作,move_uploaded_file() 将返回 false。此外还会发出一条警告。 
 */
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "文件上传成功.\n";
} else {
    echo "文件上传失败!\n";
}

注意:需要在 "upload.php" 文件所在的目录中创建一个名为 "uploads" 的新目录。上传的文件将保存在那里。

接受上传文件的 PHP 脚本为了决定接下来要对该文件进行哪些操作,应该实现任何逻辑上必要的检查。例如可以用 _FILES\['userfile'\]\['size'\] 变量来排除过大或过小的文件,也可以通过 _FILES['userfile']['type'] 变量来排除文件类型不相符合上传标准的文件。

如果表单中没有选择上传的文件,则 PHP 变量 _FILES\['userfile'\]\['size'\] 的值将为 0,_FILES['userfile']['tmp_name'] 将为空。

如果该文件没有被移动到其它地方也没有被改名,则该文件将在表单请求结束时被删除。

关于文件处理的学习过程就记录到此,更多关于文件处理的函数,可以查看文件系统函数

相关推荐
SuperherRo7 小时前
Web攻防-PHP反序列化&原生内置类&Exception类&SoapClient类&SimpleXMLElement
php·xss·反序列化·exception·ssrf·原生类·soapclient
阿维的博客日记9 小时前
TCP和UDP区别
tcp/ip·udp·php
MZ_ZXD00111 小时前
flask校园学科竞赛管理系统-计算机毕业设计源码12876
java·spring boot·python·spring·django·flask·php
Q_Q196328847514 小时前
python的平安驾校管理系统
开发语言·spring boot·python·django·flask·node.js·php
是阿建吖!18 小时前
【Linux | 网络】应用层
linux·网络·php
夏至春来-美美21 小时前
php绘图添加水印,文字使用imagick库的操作
php
果子⌂21 小时前
Docker高级管理
开发语言·docker·云计算·php
Q_Q5110082851 天前
python的婚纱影楼管理系统
开发语言·spring boot·python·django·flask·node.js·php
拓端研究室1 天前
专题:2025供应链数智化与效率提升报告|附100+份报告PDF、原数据表汇总下载
开发语言·php