Appearance
13.1 文件上传表单
文件上传是 Web 应用中常见的功能,如上传头像、上传图片、上传文档等。本章节将介绍如何创建文件上传表单。
基本原理
文件上传的基本流程:
- 创建包含
enctype="multipart/form-data"的表单 - 添加
<input type="file">元素 - 服务器接收并处理上传的文件
创建文件上传表单
基本表单
html
<!DOCTYPE html>
<html>
<head>
<title>文件上传</title>
<style>
body { font-family: Arial, sans-serif; max-width: 500px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; color: #333; }
.form-group { margin: 15px 0; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="file"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; width: 100%; box-sizing: border-box; }
input[type="submit"] { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
.message { padding: 10px; margin: 10px 0; border-radius: 4px; }
.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
</style>
</head>
<body>
<h1>文件上传</h1>
<?php if (isset($_GET['success'])): ?>
<div class="message success">
<?php echo $_GET['success']; ?>
</div>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<div class="message error">
<?php echo $_GET['error']; ?>
</div>
<?php endif; ?>
<form action="upload.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>选择文件: <input type="file" name="fileToUpload" id="fileToUpload"></label>
</div>
<input type="submit" value="上传文件" name="submit">
</form>
</body>
</html>多文件上传
html
<!DOCTYPE html>
<html>
<head>
<title>多文件上传</title>
<style>
body { font-family: Arial, sans-serif; max-width: 500px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; color: #333; }
.form-group { margin: 15px 0; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="file"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; width: 100%; box-sizing: border-box; margin-bottom: 10px; }
input[type="submit"] { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h1>多文件上传</h1>
<form action="upload_multiple.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>选择文件 1: <input type="file" name="files[]"></label>
<label>选择文件 2: <input type="file" name="files[]"></label>
<label>选择文件 3: <input type="file" name="files[]"></label>
</div>
<input type="submit" value="上传文件" name="submit">
</form>
</body>
</html>带额外字段的表单
html
<!DOCTYPE html>
<html>
<head>
<title>带额外字段的文件上传</title>
<style>
body { font-family: Arial, sans-serif; max-width: 500px; margin: 0 auto; padding: 20px; }
h1 { text-align: center; color: #333; }
.form-group { margin: 15px 0; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="text"], input[type="file"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; width: 100%; box-sizing: border-box; }
input[type="submit"] { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h1>带额外字段的文件上传</h1>
<form action="upload_with_fields.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label>文件名: <input type="text" name="fileName"></label>
</div>
<div class="form-group">
<label>文件描述: <input type="text" name="fileDescription"></label>
</div>
<div class="form-group">
<label>选择文件: <input type="file" name="fileToUpload"></label>
</div>
<input type="submit" value="上传文件" name="submit">
</form>
</body>
</html>表单属性说明
1. enctype 属性
必须设置 enctype="multipart/form-data",否则文件无法上传。
2. method 属性
必须使用 method="post",因为文件上传需要发送大量数据。
3. input type="file"
name属性:用于在服务器端获取文件id属性:用于关联 labelmultiple属性:允许选择多个文件accept属性:限制文件类型
4. accept 属性
限制可选择的文件类型:
html
<!-- 只允许图片文件 -->
<input type="file" name="fileToUpload" accept="image/*">
<!-- 只允许特定图片类型 -->
<input type="file" name="fileToUpload" accept=".jpg,.jpeg,.png,.gif">
<!-- 只允许 PDF 文件 -->
<input type="file" name="fileToUpload" accept=".pdf">5. multiple 属性
允许选择多个文件:
html
<input type="file" name="files[]" multiple>服务器端处理
基本处理
php
<?php
// upload.php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// 检查文件是否是真实的图片
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "文件是一个图片 - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "文件不是一个图片.";
$uploadOk = 0;
}
}
// 检查文件是否已存在
if (file_exists($target_file)) {
echo "抱歉,文件已存在.";
$uploadOk = 0;
}
// 检查文件大小
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "抱歉,你的文件太大了.";
$uploadOk = 0;
}
// 允许的文件格式
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "抱歉,只允许 JPG, JPEG, PNG & GIF 文件.";
$uploadOk = 0;
}
// 检查 $uploadOk 是否为 0
if ($uploadOk == 0) {
echo "抱歉,你的文件没有上传.";
// 如果一切正常,尝试上传文件
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "文件 " . htmlspecialchars( basename( $_FILES["fileToUpload"]["name"]). " 已成功上传.";
} else {
echo "抱歉,上传文件时出错.";
}
}
?>多文件处理
php
<?php
// upload_multiple.php
$target_dir = "uploads/";
$uploadOk = 1;
if(isset($_POST["submit"])) {
foreach ($_FILES["files"]["name"] as $key => $name) {
$target_file = $target_dir . basename($name);
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// 检查文件是否是真实的图片
$check = getimagesize($_FILES["files"]["tmp_name"][$key]);
if($check !== false) {
echo "文件 " . $name . " 是一个图片 - " . $check["mime"] . ".<br>";
$uploadOk = 1;
} else {
echo "文件 " . $name . " 不是一个图片.<br>";
$uploadOk = 0;
}
// 检查文件大小
if ($_FILES["files"]["size"][$key] > 500000) {
echo "抱歉,文件 " . $name . " 太大了.<br>";
$uploadOk = 0;
}
// 允许的文件格式
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "抱歉,文件 " . $name . " 类型不允许.<br>";
$uploadOk = 0;
}
// 尝试上传文件
if ($uploadOk == 1) {
if (move_uploaded_file($_FILES["files"]["tmp_name"][$key], $target_file)) {
echo "文件 " . htmlspecialchars( basename( $name)). " 已成功上传.<br>";
} else {
echo "抱歉,上传文件 " . $name . " 时出错.<br>";
}
}
}
}
?>注意事项
- 创建上传目录:确保
uploads目录存在且具有写入权限 - 文件验证:验证文件类型、大小、是否为真实图片等
- 安全处理:
- 重命名文件,避免文件名冲突
- 防止恶意文件上传
- 限制上传文件的大小和类型
- 错误处理:提供清晰的错误提示
- 文件存储:考虑使用唯一文件名存储文件
练习
- 创建一个基本的文件上传表单
- 创建一个多文件上传表单
- 实现文件类型和大小的验证
- 实现文件重命名功能
- 显示上传成功的文件
