首页 / PHP 入门教程 / PHP 文件读写

PHP 入门教程

PHP 文件读写

本教程共 65 篇 · 第 30 篇 · 更新于 2026-07-24 · 约 5 分钟阅读

PHPPHP8文件读写fopenfwrite日志文件锁

30. PHP 文件读写

本节目标:学会用 fopenfreadfwrite 等函数读写文件,掌握文件指针操作和文件锁。

除了数据库,PHP 也经常直接操作文件:写日志、生成缓存、读取配置文件等。本章教你安全地进行文件读写。

30.1 打开文件

fopen() 用于打开文件,返回文件句柄(resource):

<?php
$file = fopen("data.txt", "r");

if ($file === false) {
    die("无法打开文件");
}

常用打开模式

模式说明
r只读,指针在开头
r+读写,指针在开头
w只写,清空内容或创建新文件
w+读写,清空内容或创建新文件
a追加写,指针在末尾,不存在则创建
a+追加读写,指针在末尾
x只写创建新文件,存在则返回 false
x+读写创建新文件,存在则返回 false
Note

w 模式会清空原有内容,想保留内容请用 a 追加模式。

30.2 读取文件内容

逐行读取(适合大文件)

<?php
$file = fopen("log.txt", "r");

if ($file) {
    while (($line = fgets($file)) !== false) {
        echo htmlspecialchars($line) . "<br>";
    }
    fclose($file);
}

读取全部内容

<?php
// 方式一:file_get_contents(最简单,适合小文件)
$content = file_get_contents("article.txt");
echo nl2br(htmlspecialchars($content));

// 方式二:fread(适合控制读取长度)
$file = fopen("image.jpg", "rb");
$data = fread($file, filesize("image.jpg"));
fclose($file);
Tip

二进制文件(如图片)要加 b 模式标志,避免 Windows 下换行符被转换。

读取为数组(每行一个元素)

<?php
$lines = file("data.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

foreach ($lines as $line) {
    echo $line . "<br>";
}

30.3 写入文件

<?php
// 方式一:file_put_contents(简单场景首选)
file_put_contents("note.txt", "Hello, PHP!\n");

// 追加模式
file_put_contents("log.txt", "新日志\n", FILE_APPEND | LOCK_EX);
<?php
// 方式二:fwrite(需要精细控制时用)
$file = fopen("output.txt", "w");

if ($file) {
    fwrite($file, "第一行内容\n");
    fwrite($file, "第二行内容\n");
    fclose($file);
    echo "写入成功";
}
Note

FILE_APPEND 表示追加,LOCK_EX 表示获取独占锁,防止并发写入冲突。

30.4 文件指针操作

<?php
$file = fopen("data.txt", "r+");

// 获取当前位置
echo ftell($file);  // 0

// 移动到第 10 个字节
fseek($file, 10);

// 移到末尾
fseek($file, 0, SEEK_END);

// 回到开头
rewind($file);

fclose($file);

30.5 文件锁定

多进程同时读写同一文件时,需要加锁防止数据损坏:

<?php
$file = fopen("counter.txt", "c+"); // c+ 模式可读写且不截断

if ($file && flock($file, LOCK_EX)) { // 获取独占锁
    $count = (int) stream_get_contents($file);
    $count++;

    rewind($file);
    fwrite($file, (string) $count);
    fflush($file);      // 刷新到磁盘

    flock($file, LOCK_UN); // 释放锁
    fclose($file);

    echo "当前计数:{$count}";
} else {
    echo "无法获取文件锁";
}
Tip

flock 是建议性锁,不是所有程序都遵守。但在同一套 PHP 代码内是有效的。

30.6 文件存在性与权限检查

操作前先检查文件状态:

<?php
$path = "config.ini";

if (file_exists($path)) {
    echo "文件存在\n";
}

if (is_readable($path)) {
    echo "可读\n";
}

if (is_writable($path)) {
    echo "可写\n";
}

if (is_file($path)) {
    echo "是普通文件\n";
}

if (is_dir($path)) {
    echo "是目录\n";
}

30.7 完整示例:日志记录器

<?php
function writeLog(string $message, string $level = "INFO"): void {
    $file = "app.log";
    $time = date("Y-m-d H:i:s");
    $line = "[{$time}] [{$level}] {$message}" . PHP_EOL;

    file_put_contents($file, $line, FILE_APPEND | LOCK_EX);
}

function readLogs(int $lines = 20): array {
    $file = "app.log";
    if (!file_exists($file)) {
        return [];
    }

    $all = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    return array_slice($all, -$lines);
}

// 使用
writeLog("用户登录成功", "INFO");
writeLog("数据库连接失败", "ERROR");

foreach (readLogs(10) as $log) {
    echo htmlspecialchars($log) . "<br>";
}

来源:参考了 runoob「PHP 文件」、w3cschool「PHP 文件」等,改写后所得。