PHP 中的文件读写与上传

PHP 中的文件读写与上传

判断与信息获取

判断文件

函数 说明 返回值
file_exists($path) 判断文件或目录是否存在 bool
is_file($path) 判断是否是文件 bool
is_dir($path) 判断是否是目录 bool
is_readable($path) 判断是否可读 bool
is_writable($path) 判断是否可写 bool
php 复制代码
<?php
$file = './config.php';
$dir = './logs';

// 1. 判断文件是否存在
if (file_exists($file)) {
    echo "文件存在<br>";
    
    // 2. 判断是否是文件
    if (is_file($file)) {
        echo "这是一个文件<br>";
    }
}

// 3. 判断目录是否存在且可写
if (is_dir($dir) && is_writable($dir)) {
    echo "目录存在且可写<br>";
}
?>

获取文件信息

函数 说明
filesize($path) 获取文件大小(字节)
filemtime($path) 获取文件最后修改时间(时间戳)
pathinfo($path) 获取文件路径信息(目录、文件名、后缀)
php 复制代码
<?php
$file = './photo.jpg';

// 获取文件大小
$size = filesize($file);
echo "文件大小:" . round($size / 1024, 2) . " KB<br>";

// 获取最后修改时间
$mtime = filemtime($file);
echo "最后修改时间:" . date('Y-m-d H:i:s', $mtime) . "<br>";

// 获取路径信息
$info = pathinfo($file);
echo "文件名:" . $info['filename'] . "<br>";
echo "后缀名:" . $info['extension'] . "<br>";
echo "目录:" . $info['dirname'] . "<br>";
?>

文件读写

简单方式:file_get_contents() / file_put_contents()

php 复制代码
// 读取文件内容到字符串
$content = file_get_contents(string $filename);

// 将字符串写入文件(返回写入的字节数)
file_put_contents(string $filename, mixed $data, int $flags = 0);

读取 JSON 配置文件

php 复制代码
<?php
// 假设 config.json 内容:{"db_host": "localhost", "db_user": "root"}
$json = file_get_contents('./config.json');
$config = json_decode($json, true); // 转数组

echo "数据库主机:" . $config['db_host']; // 数据库主机:localhost
?>

写入日志文件(追加模式)

php 复制代码
<?php
// 日志内容
$log = "[".date('Y-m-d H:i:s')."] 用户登录成功\n";

// FILE_APPEND:追加写入(不覆盖原内容)
// LOCK_EX:独占锁(防止多人同时写入导致数据混乱)
file_put_contents('./logs/app.log', $log, FILE_APPEND | LOCK_EX);
?>

底层方式:fopen() / fwrite() / fclose()

当你需要逐行读取写入大文件更精细的控制时,使用这组函数。

php 复制代码
// 打开文件,返回资源句柄
$handle = fopen(string $filename, string $mode);

// 写入文件
fwrite(resource $handle, string $data);

// 读取一行
$line = fgets(resource $handle);

// 关闭文件
fclose(resource $handle);

常用 mode 参数

模式 说明
r 只读,指针在开头
w 只写,清空文件内容,指针在开头
a 追加,指针在末尾
r+ 读写,指针在开头

逐行读取大文件(不占内存)

php 复制代码
<?php
// 打开一个大文件(比如 1GB 的日志)
$handle = fopen('./large_file.log', 'r');

if ($handle) {
    // 逐行读取,直到文件结束
    while (($line = fgets($handle)) !== false) {
        // 处理每一行(比如过滤错误日志)
        if (strpos($line, 'ERROR') !== false) {
            echo "发现错误:" . $line . "<br>";
        }
    }
    fclose($handle);
}
?>

目录操作:创建、删除与遍历

函数 说明
mkdir($path) 创建目录
rmdir($path) 删除空目录
unlink($path) 删除文件

递归创建多级目录

php 复制代码
<?php
// 要创建的目录路径
$dir = './uploads/2023/10/01';

// mkdir 第三个参数 true:递归创建父目录
if (!is_dir($dir)) {
    mkdir($dir, 0755, true);
    echo "目录创建成功";
}
?>

遍历目录

  1. scandir()(简单遍历,适合单层目录)
php 复制代码
<?php
$dir = './uploads';

// 获取目录下所有文件和目录(包含 . 和 ..)
$files = scandir($dir);

// 遍历并过滤掉 . 和 ..
foreach ($files as $file) {
    if ($file != '.' && $file != '..') {
        // 判断是文件还是目录
        $type = is_file($dir . '/' . $file) ? '文件' : '目录';
        echo $type . ":" . $file . "<br>";
    }
}
?>
  1. RecursiveDirectoryIterator(递归遍历,适合多层目录)
php 复制代码
<?php
$dir = './uploads';

// 使用递归迭代器
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
    RecursiveIteratorIterator::SELF_FIRST
);

foreach ($iterator as $file) {
    // $file 是 SplFileInfo 对象
    echo "路径:" . $file->getPathname() . " - 大小:" . $file->getSize() . " 字节<br>";
}
?>

文件上传 :图片上传

文件上传是 Web 开发的经典需求,PHP 通过 $_FILES 超全局变量和 move_uploaded_file() 函数处理。

html 复制代码
<form action="upload.php" method="post" enctype="multipart/form-data">
    选择图片:<input type="file" name="avatar" accept="image/*">
    <input type="submit" value="上传">
</form>
php 复制代码
<?php
// 检查是否有上传错误
if ($_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
    exit('上传错误:' . $_FILES['avatar']['error']);
}

// 定义上传目录
$uploadDir = './uploads/';
if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0755, true);
}

// 获取文件后缀,生成唯一文件名
$ext = pathinfo($_FILES['avatar']['name'], PATHINFO_EXTENSION);
$filename = uniqid() . '.' . $ext;
$destPath = $uploadDir . $filename;

// 验证文件类型(简单验证:只允许图片)
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif'];
if (!in_array(strtolower($ext), $allowedTypes)) {
    exit('只允许上传图片文件');
}

// 验证文件大小(限制 2MB)
if ($_FILES['avatar']['size'] > 2 * 1024 * 1024) {
    exit('文件大小不能超过 2MB');
}

// 从临时目录移动到目标目录
if (move_uploaded_file($_FILES['avatar']['tmp_name'], $destPath)) {
    echo "上传成功!文件路径:" . $destPath;
} else {
    exit('文件移动失败');
}
?>
相关推荐
沫璃染墨8 分钟前
现代C++⊂C++11篇(一)列表初始化全解 & std::initializer_list
开发语言·c++
pengyu11 分钟前
【Kotlin 协程修仙录 · 金丹境 · 后阶】 | 异常防火墙:supervisorScope 与异常隔离的终极奥义
android·kotlin
阿米亚波16 分钟前
【C++ STL】std::forward_list
开发语言·c++·笔记·stl·visual studio·forward_list
buhuizhiyuci32 分钟前
【python篇——一周速通python语法】python的条件语句和循环语句
开发语言·python
geovindu35 分钟前
go: Recursion Algorithm
开发语言·后端·算法·golang·递归算法
cheng21910138 分钟前
Cocos Creator打包安卓并支持 Android 16KB 页面大小
android
geovindu41 分钟前
CSharp: Composite Pattern
开发语言·后端·c#·组合模式·结构型模式
消失的旧时光-19431 小时前
KMP Web 开发实战(二):js、wasmJs、browser、executable 到底是什么意思?
开发语言·前端·javascript·跨平台·kmp
sycmancia1 小时前
Qt——线程的生命期问题
开发语言·qt
影寂ldy1 小时前
C# 多线程进阶知识点(线程优先级、多委托传参、线程锁、死锁)
开发语言·数据库·c#