在PHP开发中,我们通常需要将用户上传的文件保存至服务器,此时我们就可以编写PHP脚本来执行该操作。
那怎么上传呢?分两步走:
1. 决定上传什么类型的文件,多大内存的文件。
2. 指定服务器路径,上传至服务器的哪个地方保存。
1. 1 先查看PHP配置,调整为允许上传文件。找到php.ini配置文件,保证file_uploads=On。
在终端输入:
php -i | grep "php.ini" #找php.ini的路径,自己通过vim编辑

1.2 确保PHP允许上传文件后,我们准备两个PHP文件:up.php,用于表单提交,process.php,用于处理表单提交的信息,决定提交后的文件放哪里。
1.3 准备up.php提交表单:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h2>Dotcpp编程——PHP上传文件</h2> <form action="process.php" method="POST" enctype="multipart/form-data"> <input type="file" name="file"><button>上传</button> </form> </body> </html>
表单通过http post(method="POST")提交至process.php(action="process.php"),在$_FILES数组里我们可以获取上传的文件。注意form表单里有一个重要的参数enctype(encoding type),它指定表单数据在发送到服务器时的编码方式。
下面我们通过表格的方式总览一下enctype可以有哪些参数:
| 参数值 | 编码方式 | 数据格式 | 适用场景 |
|---|---|---|---|
application/x-www-form-urlencoded(默认值) | URL 编码 | 键值对拼接:name1=value1&name2=value2特殊字符转义为 %XX | 普通文本表单提交 (登录、搜索、注册等) |
multipart/form-data(最重要) | 多部分混合编码 | 每个字段/文件作为独立部分, 用边界分隔符分隔 | 必须用于文件上传 混合文本和文件的表单 |
text/plain(较少用) | 纯文本编码 | 简单键值对换行:name1=value1name2=value2 | 调试、简单文本传输 邮件表单等 |
不同的编码方式适配不同的上传文件,这里只需要记住上传文件时保证:enctype="multipart/form-data"即可!
2.1 process.php处理上传的文件:
<?php
// process.php - 文件上传处理
// 1. 检查是否有文件上传
if (!isset($_FILES['file'])) {
die('没有选择文件');//终止PHP脚本并输出"没有选择文件"
}
// 2. 获取文件信息(上传后的文件都在file_Tmp路径下)
$file = $_FILES['file'];//获取通过post来的file
$fileName = $file['name'];//获取原始文件名
$fileTmp = $file['tmp_name'];//获取临时上传文件路径
$fileError = $file['error'];//获取报错代码
$fileSize = $file['size'];//获取文件大小(后面要用)
// 3. 检查上传错误
if ($fileError !== 0) {
switch ($fileError) {
case 1: die('文件太大,超过服务器限制');//UPLOAD_ERR_INI_SIZE
case 2: die('文件太大,超过表单限制');//UPLOAD_ERR_FORM_SIZE
case 3: die('文件只有部分被上传');//UPLOAD_ERR_PARTIAL
case 4: die('没有选择文件');//UPLOAD_ERR_NO_FILE
default: die('上传失败,错误代码: ' . $fileError);//其他错误
}
}
// 4. 安全验证
// 获取文件扩展名
$fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));//提取扩展名并转小写
$allowedExt = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'txt'];//允许扩展名范围
//出现不允许的扩展名,直接pass掉,提示allowedExt数组内容。
if (!in_array($fileExt, $allowedExt)) {
die('不允许的文件类型,只支持: ' . implode(', ', $allowedExt));//转字符串显示
}
// 5. 生成安全文件名(防止重名和中文乱码)
$safeFileName = $uploadDir.$fileName;//保持原有文件名
$uploadDir = 'uploads/';//上传目录
$destination = $uploadDir . $safeFileName;//完整的目标文件路径
// 6. 创建上传目录(如果不存在)
if (!is_dir($uploadDir)) {//检查目录是否存在
mkdir($uploadDir, 0777, true);//创建目录(递归创建)
}
// 7. 移动文件到目标位置
// move_uploaded_file(临时文件路径, 目标文件路径)
if (move_uploaded_file($fileTmp, $destination)) {
// 上传成功
echo '<h2>文件上传成功!</h2>';
echo '<p><strong>原始文件名:</strong> ' . htmlspecialchars($fileName) . '</p>';//防止XSS攻击
echo '<p><strong>保存文件名:</strong> ' . $safeFileName . '</p>';//显示生成的安全文件名
echo '<p><strong>文件大小:</strong> ' . round($fileSize / 1024, 2) . ' KB</p>';//显示大小(转KB)
echo '<p><strong>保存路径:</strong> ' . $destination . '</p>';//显示完整保存路径
// 如果是图片,显示预览
if (in_array($fileExt, ['jpg', 'jpeg', 'png', 'gif'])) {
echo '<p><strong>图片预览:</strong></p>';
echo '<img src="' . $destination . '" style="max-width: 300px; border: 1px solid #ddd; margin: 10px 0;">';//显示图片
}
// 返回链接
echo '<p><a href="' . $destination . '" target="_blank">查看文件</a></p>';//新窗口打开文件
echo '<p><a href="javascript:history.back()">继续上传</a></p>';//返回上一页
} else {
die('文件保存失败');//移动文件失败
}
?>为了防止非法脚本注入,这里只允许上传['jpg', 'jpeg', 'png', 'gif', 'pdf', 'txt']类文件。总的处理过程是:上传文件在不在->文件合不合法->通过move_uploaded_file()进行移动->反馈处理结果。
2.2 效果展示:
2.2.1 上传一张png图片:

2.2.2上传结果:

文件上传成功!
总结:PHP文件上传主要应用于用户提交多媒体内容(如图片、视频)、文档资料、数据备份等需要将本地文件传输到服务器的所有Web交互场景,存储用户信息,是PHP开发的重要技能!
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程