PHP文件读写核心是fopen()配合fread()/fwrite()和fclose(),选择正确模式如'r'读、'w'写(清空)、'a'追加,避免数据丢失;需检查fopen()返回值确保文件打开成功,使用flock()处理并发写入,防止数据损坏;安全上禁用用户输入路径防目录遍历,用basename()过滤文件名,限制open_basedir和文件权限;大文件应分块读写避免内存溢出,可用stream_copy_to_stream()高效复制;高并发场景推荐消息队列或Monolog等日志库替代直接文件操作。

PHP中实现文件读写,最核心也是最基础的方式就是通过
fopen()
fread()
fwrite()
fclose()
在PHP里,文件操作常常围绕着几个核心函数展开,
fopen()
fwrite()
fread()
fclose()
首先,
fopen($filename, $mode)
$filename
$mode
'w'
'a'
'r'
打开文件后,如果
fopen()
false
fwrite($handle, $string)
$handle
$string
fwrite()
立即学习“PHP免费学习笔记(深入)”;
要读取文件,则使用
fread($handle, $length)
$handle
$length
filesize($filename)
$length
fread()
无论你做了什么操作,最后一步,也是非常重要的一步,就是调用
fclose($handle)
这里有一个简单的例子,演示如何先写入后读取一个文件:
<?php
$filePath = 'my_data.txt';
$dataToWrite = "这是我今天的一些想法,记录于 " . date('Y-m-d H:i:s') . "\n";
$moreData = "或许明天会有新的灵感。\n";
// 尝试写入文件
// 'a' 模式表示如果文件不存在则创建,如果存在则在末尾追加内容
$fileHandle = fopen($filePath, 'a');
if ($fileHandle === false) {
// 哎呀,文件打不开,可能是权限问题或者路径不对
echo "抱歉,无法打开文件 '$filePath' 进行写入。请检查文件权限或路径。<br>";
} else {
// 成功打开,开始写入
$bytesWritten1 = fwrite($fileHandle, $dataToWrite);
$bytesWritten2 = fwrite($fileHandle, $moreData);
if ($bytesWritten1 === false || $bytesWritten2 === false) {
echo "写入文件 '$filePath' 时发生错误。<br>";
} else {
echo "成功写入 $bytesWritten1 字节和 $bytesWritten2 字节到 '$filePath'。<br>";
}
fclose($fileHandle); // 写入完成后记得关闭
}
// 尝试读取文件内容
// 'r' 模式表示只读
$fileHandle = fopen($filePath, 'r');
if ($fileHandle === false) {
echo "抱歉,无法打开文件 '$filePath' 进行读取。<br>";
} else {
// 读取整个文件内容,这里用 filesize() 获取文件大小
$fileContent = fread($fileHandle, filesize($filePath));
if ($fileContent === false) {
echo "读取文件 '$filePath' 时发生错误。<br>";
} else {
echo "文件 '$filePath' 的内容如下:<br>";
echo "<pre>" . htmlspecialchars($fileContent) . "</pre>"; // 用 pre 和 htmlspecialchars 保持格式和避免XSS
}
fclose($fileHandle); // 读取完成后也要关闭
}
?>这个例子展示了最基本的流程,但实际应用中,错误处理和权限管理是同样重要的。
fopen
r
w
a
我个人觉得,理解
fopen
'r'
fopen()
false
'w'
'w'
'a'
'x'
fopen()
false
'r+'
fopen()
false
'w+'
'w'
'a+'
'a'
此外,你还可以在这些模式后面加上
'b'
'rb'
'wb'
'b'
很多时候,我们写代码只想着功能实现,却忽略了这些“脏活累活”。但说真的,一个没有健壮错误处理和安全考量的文件操作,迟早会出问题,甚至可能导致严重的安全漏洞。
错误处理:
fopen()
fopen()
false
error_get_last()
$handle = fopen('non_existent_file.txt', 'r');
if ($handle === false) {
$error = error_get_last();
echo "文件打开失败: " . $error['message'] . "<br>";
}flock()
flock()
$handle = fopen('shared_log.txt', 'a');
if ($handle && flock($handle, LOCK_EX)) { // 独占写入锁
fwrite($handle, "并发写入测试:" . date('H:i:s') . "\n");
fflush($handle); // 确保数据写入磁盘
flock($handle, LOCK_UN); // 释放锁
} else {
echo "无法获取文件锁或打开文件。<br>";
}
fclose($handle);需要注意的是,
flock()
flock()
安全实践:
../../../../etc/passwd
basename()
basename()
chmod()
777
open_basedir
php.ini
open_basedir
当我第一次遇到要处理几GB的日志文件时,直接
file_get_contents()
性能优化:
fread($handle, $bufferSize)
fwrite($handle, $dataChunk)
// 示例:分块读取大文件
$handle = fopen('large_file.log', 'r');
if ($handle) {
$bufferSize = 4096; // 4KB缓冲区
while (!feof($handle)) {
$chunk = fread($handle, $bufferSize);
// 处理 $chunk 数据,例如写入数据库或另一个文件
// echo $chunk;
}
fclose($handle);
}stream_copy_to_stream()
stream_copy_to_stream()
$source = fopen('source.txt', 'r');
$dest = fopen('destination.txt', 'w');
if ($source && $dest) {
stream_copy_to_stream($source, $dest);
fclose($source);
fclose($dest);
echo "文件复制完成。<br>";
}file_get_contents()
file_put_contents()
替代方案:
当文件操作成为性能瓶颈,或者数据结构化程度较高、需要复杂查询时,就应该考虑更专业的解决方案了。
选择哪种方案,最终还是要看你的具体需求:数据的结构化程度、读写频率、并发量、数据量大小以及对数据一致性和持久性的要求。没有银弹,只有最适合的工具。
以上就是PHP如何实现文件读写?使用fopen和fwrite操作文件的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号