🤖 AI智能摘要

暂未配置

前言

文件上传是网站开发最常用、必考的功能之一。头像上传、图片发布、附件提交、后台素材上传等功能,全部基于PHP文件上传技术实现。

本章核心掌握:表单上传原理、$\_FILES 超级变量、文件类型/大小校验、防止覆盖上传、随机文件名、上传漏洞防护、完整通用上传类实战。

一、文件上传基础原理

1. 上传必备表单条件

普通表单无法上传文件,文件上传表单必须满足两个核心条件:

  1. form 表单必须添加属性:enctype="multipart/form-data"
  2. 表单提交方式必须为 method="post"(get无法传输文件二进制数据)

2. 上传表单完整代码

<!-- 文件上传专属表单 -->
<form action="upload.php" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="upfile"><br/>
    <input type="submit" value="开始上传">
</form>

二、$\_FILES 超级全局变量(核心)

文件上传后,所有文件信息(名称、类型、大小、临时路径、错误码)全部存储在 **$\_FILES** 中,$\_POST 无法获取文件数据。

1. $\_FILES 五大核心参数

  • name:文件原始名称(用户本地文件名)
  • type:文件MIME类型(文件格式标识)
  • tmp\_name:服务器临时存储路径(核心!文件先存在服务器临时目录)
  • size:文件大小(单位:字节Byte)
  • error:上传错误码(0代表上传成功,无错误)

2. 打印文件上传信息(调试代码)

<?php
// 打印上传文件所有信息
var_dump($_FILES['upfile']);
?>

3. 上传错误码详解

错误码含义
0上传成功,无任何错误
1文件超过 php.ini 最大上传限制
2文件超过表单 MAX\_FILE\_SIZE 限制
4未选择任何文件,空上传
6/7服务器临时目录异常、磁盘已满

三、核心上传函数:move\_uploaded\_file()

文件上传的本质:将服务器临时目录中的文件,移动到网站永久存储目录。临时文件执行完毕会自动销毁,必须移动保存。

语法:move_uploaded_file(临时路径, 目标保存路径)

1. 最简基础上传代码(入门版)

<?php
// upload.php 基础上传逻辑
if($_FILES['upfile']['error'] == 0){
    // 定义保存路径+文件名
    $path = "./upload/".$_FILES['upfile']['name'];
    // 移动临时文件到永久目录
    if(move_uploaded_file($_FILES['upfile']['tmp_name'],$path)){
        echo "上传成功!<br/><a href='".$path."' target='_blank'>查看图片</a>";
    }else{
        echo "文件移动失败";
    }
}else{
    echo "上传出错,错误码:".$_FILES['upfile']['error'];
}
?>

2. 基础版本两大致命问题

  1. 文件覆盖问题:同名文件会直接覆盖旧文件,造成数据丢失
  2. 安全漏洞问题:允许上传php、exe等恶意文件,黑客可上传木马控制网站

四、上传功能安全优化(必做)

1. 解决文件覆盖:生成随机唯一文件名

通过 time()时间戳 + 随机字符串 + 原文件后缀 生成唯一文件名,彻底避免覆盖。

2. 限制上传文件类型(禁止恶意文件)

白名单机制:只允许指定格式上传(推荐),禁止php、html、exe、js等脚本文件。

常用图片白名单:jpg、jpeg、png、gif、webp

3. 限制上传文件大小

防止超大文件占用服务器磁盘、恶意刷流量,日常图片上传限制 2MB 以内即可。

五、工业级完整上传代码(可直接商用)

整合:空判断、错误判断、类型校验、大小校验、随机文件名、自动创建文件夹、安全防护

<?php
// 1. 判断是否上传空文件
if($_FILES['upfile']['error'] != 0){
    exit("文件上传异常,请重新上传!");
}

// 2. 配置上传规则
$allow_type = ['jpg','jpeg','png','gif','webp']; // 允许的文件后缀
$max_size = 2 * 1024 * 1024; // 最大限制2MB
$save_path = "./upload/"; // 文件保存目录

// 3. 获取文件后缀(统一小写,避免大小写绕过)
$file_name = $_FILES['upfile']['name'];
$file_ext = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));

// 4. 类型校验
if(!in_array($file_ext,$allow_type)){
    exit("仅允许上传 JPG、PNG、GIF、WEBP 格式图片!");
}

// 5. 大小校验
if($_FILES['upfile']['size'] > $max_size){
    exit("文件过大!最大允许上传2MB文件");
}

// 6. 不存在目录则自动创建
if(!file_exists($save_path)){
    mkdir($save_path,0777,true);
}

// 7. 生成唯一随机文件名
$new_name = time().rand(1000,9999).".".$file_ext;
$final_path = $save_path.$new_name;

// 8. 执行上传
if(move_uploaded_file($_FILES['upfile']['tmp_name'],$final_path)){
    echo "✅ 上传成功<br/>";
    echo "文件地址:<a href='{$final_path}' target='_blank'>{$final_path}</a>";
}else{
    echo "❌ 文件保存失败";
}
?>

六、php.ini 上传配置(服务器调优)

如需修改网站上传大小限制、超时时间,需修改 php.ini 核心配置:

配置项作用默认值
file\_uploads是否开启文件上传功能On(开启)
upload\_max\_filesize单个文件最大上传大小2M
post\_max\_sizePOST表单最大提交大小8M
max\_execution\_time脚本最大执行超时时间30秒

修改配置后需重启Apache/Nginx服务器方可生效。

七、文件上传高危漏洞与防护总结

1. 常见漏洞

  • 未校验文件后缀,上传 PHP 木马文件,被直接执行篡改网站
  • 仅校验前端后缀,后端无校验,被抓包修改文件类型绕过
  • 文件名可控,造成路径遍历、文件覆盖风险

2. 终极防护方案

  1. 后端白名单校验:只允许指定图片后缀,拒绝所有脚本格式
  2. 禁用上传目录执行权限:upload目录禁止运行PHP文件
  3. 统一重命名文件:不使用用户原始文件名,杜绝路径漏洞
  4. 限制文件大小:防止超大文件攻击

八、本章核心总结

  1. 文件上传表单必须满足:method="post" + enctype="multipart/form-data"
  2. 所有文件数据通过 **$\_FILES** 获取,$\_POST 无法接收文件;
  3. 上传核心函数:move_uploaded_file(临时路径, 永久路径)
  4. 开发必须做四层校验:错误码校验、空校验、后缀白名单、大小限制
  5. 必须生成随机文件名,解决文件覆盖问题;
  6. 安全第一:永远不信任前端提交的数据,所有校验必须放在后端。
(注:部分内容可能由 AI 生成)