Appearance
13.2 $_FILES 获取上传信息
$_FILES 数组
当用户通过表单上传文件时,PHP 会将文件信息存储在 $_FILES 超全局数组中。这个数组包含了上传文件的详细信息,如文件名、临时路径、文件大小、文件类型等。
$_FILES 数组结构
对于单个文件上传,$_FILES 数组的结构如下:
php
Array(
[fileToUpload] => Array(
[name] => filename.jpg // 原始文件名
[type] => image/jpeg // 文件 MIME 类型
[tmp_name] => /tmp/php123.tmp // 临时文件路径
[error] => 0 // 错误代码
[size] => 123456 // 文件大小(字节)
)
)对于多文件上传,$_FILES 数组的结构如下:
php
Array(
[files] => Array(
[name] => Array(
[0] => file1.jpg
[1] => file2.png
)
[type] => Array(
[0] => image/jpeg
[1] => image/png
)
[tmp_name] => Array(
[0] => /tmp/php123.tmp
[1] => /tmp/php456.tmp
)
[error] => Array(
[0] => 0
[1] => 0
)
[size] => Array(
[0] => 123456
[1] => 789012
)
)
)错误代码
$_FILES['file']['error'] 可能的错误代码:
| 错误代码 | 描述 |
|---|---|
| 0 | 没有错误,文件上传成功 |
| 1 | 文件大小超过了 php.ini 中的 upload_max_filesize 限制 |
| 2 | 文件大小超过了 HTML 表单中 MAX_FILE_SIZE 隐藏字段指定的限制 |
| 3 | 文件只有部分被上传 |
| 4 | 没有文件被上传 |
| 6 | 找不到临时文件夹 |
| 7 | 文件写入失败 |
| 8 | 文件上传被 PHP 扩展中断 |
获取上传信息示例
1. 单个文件上传
php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 检查是否有文件上传
if (isset($_FILES['fileToUpload'])) {
$file = $_FILES['fileToUpload'];
// 输出文件信息
echo "原始文件名: " . $file['name'] . "<br>";
echo "文件类型: " . $file['type'] . "<br>";
echo "临时路径: " . $file['tmp_name'] . "<br>";
echo "错误代码: " . $file['error'] . "<br>";
echo "文件大小: " . $file['size'] . " 字节<br>";
// 检查是否上传成功
if ($file['error'] === 0) {
echo "文件上传成功!<br>";
} else {
echo "上传失败,错误代码: " . $file['error'] . "<br>";
}
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload">
<input type="submit" value="上传">
</form>2. 多文件上传
php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 检查是否有文件上传
if (isset($_FILES['files'])) {
$files = $_FILES['files'];
$fileCount = count($files['name']);
echo "上传了 $fileCount 个文件:<br><br>";
// 遍历所有文件
for ($i = 0; $i < $fileCount; $i++) {
echo "文件 " . ($i + 1) . ":<br>";
echo "原始文件名: " . $files['name'][$i] . "<br>";
echo "文件类型: " . $files['type'][$i] . "<br>";
echo "临时路径: " . $files['tmp_name'][$i] . "<br>";
echo "错误代码: " . $files['error'][$i] . "<br>";
echo "文件大小: " . $files['size'][$i] . " 字节<br><br>";
}
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple>
<input type="submit" value="上传">
</form>验证上传文件
1. 检查文件是否存在
php
if (isset($_FILES['fileToUpload']) && $_FILES['fileToUpload']['error'] === 0) {
// 文件存在且上传成功
}2. 检查文件大小
php
// 检查文件大小(限制为 5MB)
if ($_FILES['fileToUpload']['size'] > 5 * 1024 * 1024) {
echo "文件太大,最大允许 5MB";
}3. 检查文件类型
php
// 检查文件类型
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($_FILES['fileToUpload']['type'], $allowedTypes)) {
echo "只允许上传 JPG、PNG 和 GIF 图片";
}
// 或者检查文件扩展名
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
$fileExtension = strtolower(pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION));
if (!in_array($fileExtension, $allowedExtensions)) {
echo "只允许上传 JPG、PNG 和 GIF 图片";
}4. 检查是否为真实图片
php
// 检查是否为真实图片
if (getimagesize($_FILES['fileToUpload']['tmp_name']) === false) {
echo "请上传真实的图片文件";
}处理上传文件
1. 移动上传的文件
使用 move_uploaded_file() 函数将临时文件移动到指定位置:
php
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES['fileToUpload']['name']);
// 确保上传目录存在
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
}
// 移动文件
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $targetFile)) {
echo "文件上传成功!";
} else {
echo "上传失败";
}2. 重命名文件
为了避免文件名冲突,可以重命名上传的文件:
php
$targetDir = "uploads/";
$fileExtension = strtolower(pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION));
$newFileName = uniqid() . '.' . $fileExtension;
$targetFile = $targetDir . $newFileName;
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $targetFile)) {
echo "文件上传成功,新文件名: " . $newFileName;
}3. 多文件处理
php
$targetDir = "uploads/";
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
}
if (isset($_FILES['files'])) {
$files = $_FILES['files'];
$fileCount = count($files['name']);
for ($i = 0; $i < $fileCount; $i++) {
if ($files['error'][$i] === 0) {
$fileExtension = strtolower(pathinfo($files['name'][$i], PATHINFO_EXTENSION));
$newFileName = uniqid() . '.' . $fileExtension;
$targetFile = $targetDir . $newFileName;
if (move_uploaded_file($files['tmp_name'][$i], $targetFile)) {
echo "文件 " . $files['name'][$i] . " 上传成功!<br>";
} else {
echo "文件 " . $files['name'][$i] . " 上传失败!<br>";
}
}
}
}配置文件上传限制
1. php.ini 配置
在 php.ini 文件中,与文件上传相关的配置项:
upload_max_filesize:单个文件的最大大小post_max_size:POST 请求的最大大小max_file_uploads:一次最多上传的文件数upload_tmp_dir:临时文件存储目录
2. HTML 表单限制
在 HTML 表单中,可以添加隐藏字段来限制文件大小:
html
<form action="" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="5242880"> <!-- 5MB -->
<input type="file" name="fileToUpload">
<input type="submit" value="上传">
</form>注意事项
安全:
- 不要直接使用用户上传的文件名
- 验证文件类型和大小
- 防止恶意文件上传
- 限制上传目录的权限
错误处理:
- 检查
$_FILES['file']['error']错误代码 - 提供清晰的错误提示
- 检查
性能:
- 限制上传文件的大小
- 优化文件存储方式
- 考虑使用云存储服务
兼容性:
- 不同浏览器可能有不同的文件上传行为
- 考虑大文件上传的处理
练习
- 创建一个表单,上传单个文件并显示文件信息
- 创建一个表单,上传多个文件并显示所有文件信息
- 实现文件类型和大小的验证
- 实现文件重命名功能
- 配置 php.ini 文件,调整文件上传限制
