在PHP开发中,我们通常需要将用户上传的文件保存至服务器,此时我们就可以编写PHP脚本来执行该操作。

那怎么上传呢?分两步走:

1. 决定上传什么类型的文件,多大内存的文件。

2. 指定服务器路径,上传至服务器的哪个地方保存。


1. 1 先查看PHP配置,调整为允许上传文件。找到php.ini配置文件,保证file_uploads=On

在终端输入:

php -i | grep "php.ini"  #找php.ini的路径,自己通过vim编辑

file_uploads=On

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=value1
name2=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图片:

up.php

2.2.2上传结果:

process.php

文件上传成功!


总结:PHP文件上传主要应用于用户提交多媒体内容(如图片、视频)、文档资料、数据备份等需要将本地文件传输到服务器的所有Web交互场景,存储用户信息,是PHP开发的重要技能!

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)