从零开始:PHP 文件读写全攻略

2025-12-17 5138阅读

在PHP开发中,文件读写是处理数据持久化、配置管理和日志记录的核心技能。无论是读取用户上传的CSV文件,还是生成动态配置,掌握文件操作都能帮助开发者构建更健壮的应用。本文将从基础语法到实战场景,系统讲解PHP文件读写的关键知识点与最佳实践。

一、文件读取基础:从打开到关闭

PHP通过fopen()函数打开文件,返回文件资源句柄,后续操作基于此句柄。常见的文件打开模式及适用场景如下:

模式 含义 适用场景
r 只读,文件必须存在 读取已存在的文本文件
r+ 读写,文件必须存在 需同时读写的场景
w 只写,覆盖原内容,文件不存在则创建 新建或覆盖写入文件
a 只写,追加内容,文件不存在则创建 日志记录、数据追加

1. 逐行读取文本文件

对于大文件,逐行读取可避免一次性加载全部内容到内存。使用fgets()配合循环实现:

// 打开文件
$handle = fopen('data.txt', 'r');
if ($handle) {
    // 循环读取每一行
    while (($line = fgets($handle)) !== false) {
        echo trim($line) . '<br>'; // 输出每行内容
    }
    fclose($handle); // 必须关闭文件句柄
} else {
    echo "文件打开失败";
}

2. 一次性读取文件内容

小文件可直接用file_get_contents()简化操作:

$content = file_get_contents('small.txt');
if ($content === false) {
    die("文件读取失败:可能不存在或权限不足");
}
echo "文件内容:" . $content;

二、文件写入基础:覆盖与追加

文件写入需明确“覆盖”或“追加”模式,核心函数为fwrite()file_put_contents()

1. 覆盖写入文件

使用w模式打开文件,原有内容会被清空:

$content = "这是新内容\n";
$handle = fopen('output.txt', 'w');
if ($handle) {
    $bytes_written = fwrite($handle, $content);
    if ($bytes_written === false) {
        echo "写入失败";
    } else {
        echo "成功写入 $bytes_written 字节";
    }
    fclose($handle);
}

2. 追加写入文件

a模式追加内容,不影响原有数据:

$log = "[" . date('Y-m-d H:i:s') . "] 新日志\n";
$handle = fopen('app.log', 'a');
fwrite($handle, $log);
fclose($handle);

3. 简化写入:file_put_contents()

一行代码完成写入,支持追加参数:

// 覆盖写入
file_put_contents('test.txt', '覆盖内容', LOCK_EX);

// 追加写入
file_put_contents('test.txt', '追加内容', FILE_APPEND);

三、实战场景:常见文件读写应用

1. 日志记录系统

每天生成独立日志文件,按日期命名并追加写入:

$logDir = 'logs/';
$logFile = $logDir . date('Ymd') . '.log';

// 确保日志目录存在
if (!file_exists($logDir)) {
    mkdir($logDir, 0755, true);
}

// 写入日志
$logMessage = "用户登录成功:IP=" . $_SERVER['REMOTE_ADDR'] . "\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);

2. 配置文件管理

读取自定义配置文件(如config.ini)并解析:

// 读取配置文件
$config = parse_ini_file('config.ini', true); // true表示返回多维数组
if ($config) {
    echo "数据库地址:" . $config['db']['host'];
}

// 更新配置文件
$newConfig = ['db' => ['host' => '192.168.1.1', 'port' => 3306]];
file_put_contents('config.ini', parse_ini_array($newConfig, true));

3. CSV文件处理

读取CSV数据并转换为数组:

// 读取CSV
$csvData = [];
$handle = fopen('data.csv', 'r');
while (($row = fgetcsv($handle)) !== false) {
    $csvData[] = $row;
}
fclose($handle);

// 写入CSV
$newRow = ['ID' => 1, 'Name' => '测试', 'Score' => 95];
$handle = fopen('data.csv', 'a');
fputcsv($handle, $newRow);
fclose($handle);

四、进阶技巧:性能与安全优化

1. 大文件处理:分块读取

处理GB级大文件时,避免一次性加载到内存:

$handle = fopen('large_file.txt', 'r');
$bufferSize = 4096; // 4KB块
while (!feof($handle)) {
    $chunk = fread($handle, $bufferSize);
    processChunk($chunk); // 处理数据块
}
fclose($handle);

2. 异常处理与错误捕获

使用try-catch捕获文件操作异常:

try {
    $content = file_get_contents('critical.txt');
    if ($content === false) {
        throw new Exception("文件读取失败");
    }
} catch (Exception $e) {
    error_log("文件操作错误:" . $e->getMessage());
    // 记录错误日志后可返回友好提示
}

3. 安全防护:防止路径遍历

验证文件路径,避免恶意路径:

$userInput = $_GET['file'];
$validPath = realpath('files/' . basename($userInput)); // 过滤路径
if ($validPath && strpos($validPath, realpath('files')) === 0) {
    readfile($validPath);
} else {
    die("非法文件访问");
}

五、总结与注意事项

PHP文件读写需注意以下关键点:

  1. 资源释放:无论成功失败,使用fclose()关闭文件句柄,或用try-finally确保释放。
  2. 异常处理:始终检查文件打开/读写失败的情况,避免程序崩溃。
  3. 权限控制:目录和文件权限需设置合理(如Linux下0755目录,0644文件)。
  4. 安全过滤:严格验证文件路径,防止路径遍历攻击,避免直接拼接用户输入。

通过本文掌握基础读写操作后,可进一步结合数据库、缓存等技术,实现更复杂的数据处理需求。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

目录[+]