Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:代码封装是门技术
序号 | 配置项 | 默认值 | 描述 |
---|---|---|---|
1 | file_uploads |
On |
on 支持文件上传;off 不支持 |
2 | upload_tmp_dir |
/tmp |
临时目录 |
3 | max_file_uploads |
20 |
单次请求时允许上传的最大文件数量 |
4 | max_execution_time |
30 |
设置 PHP 最长执行时间(秒) |
5 | max_input_time |
60 |
设置 PHP 通过 POST/GET/PUT 接收数据的时长(秒) |
6 | memory_limit |
128M |
系统分配给当前脚本执行可用的最大内存容量 |
7 | post_max_size |
8M |
允许的 POST 数据的总大小(以字节为单位) |
8 | upload_max_filesize |
32M |
允许的尽可能最大的文件上传(以字节为单位) |
$_FILES
超全局变量
上传文件的描述信息,全部保存在系统全局变量$_FILES
中$_FILES
以二维数组形式保存:$_FILES['form_file_name']['key']
'form_file_name'
: 对应着表单中<input type="file" name="my_pic">
中name
属性值'key'
: 共有 5 个键名, 描述如下:
序号 | 键名 | 描述 |
---|---|---|
1 | name |
文件在客户端的原始文件名(即存在用户电脑上的文件名) |
2 | type |
文件的 MIME 类型, 由浏览器提供, PHP 并不检查它 |
3 | tmp_name |
文件被上传到服务器上之后,在临时目录中临时文件名 |
4 | error |
和该文件上传相关的错误代码 |
5 | size |
已上传文件的大小(单位为字节) |
序号 | 常量 | 值 | 描述 |
---|---|---|---|
1 | UPLOAD_ERR_OK |
0 |
没有错误发生,文件上传成功 |
2 | UPLOAD_ERR_INI_SIZE |
1 |
文件超过php.ini 中upload_max_filesize 值 |
3 | UPLOAD_ERR_FORM_SIZE |
2 |
文件大小超过表单中MAX_FILE_SIZE 指定的值 |
4 | UPLOAD_ERR_PARTIAL |
3 |
文件只有部分被上传 |
5 | UPLOAD_ERR_NO_FILE |
4 |
没有文件被上传 |
6 | UPLOAD_ERR_NO_TMP_DIR |
6 |
找不到临时文件夹 |
7 | UPLOAD_ERR_CANT_WRITE |
7 |
文件写入失败 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单文件上传</title>
<style>
form {
width: 240px;
}
fieldset {
background-color: #BED3DC;
}
legend {
font-size: 20px;
}
form button {
width: 60px;
margin-top: 15px;
}
</style>
</head>
<body>
<!-- action:处理上传脚本, method: 必须是POST, multipart/form-data:允许接收表单提交的文件 -->
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>单文件上传</legend>
<!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
<input type="hidden" name="MAX_FILE_SIZE" value="3000000">
<input type="file" name="user_pic">
<button>上传</button>
</fieldset>
</form>
</body>
</html>
<?php
//自定义异常类
use Exception;
class MyException extends Exception
{
// 改写__tostring方法
public function __toString() :string
{
return <<<HEREDOC
<style>
table {width: 238px;border-collapse: collapse;border:1px solid black;text-align: center;margin-top: 20px;}
td {border:1px solid black;padding: 5px;}
tr > td:first-of-type {background-color: yellow;font-size: 20px}
span {color: red}
</style>
<table>
<tr>
<td>异常<span>内容</span></td>
<td>$this->message</td>
</tr>
<tr>
<td>异常<span>代码</span></td>
<td>$this->code</td>
</tr>
<tr>
<td>异常<span>行号</span></td>
<td>$this->line</td>
</tr>
</table>
HEREDOC;
}
}
// 使用自定义异常类检测上传出错的代码
try {
$errorCode = $_FILES['user_pic']['error'];
if ($errorCode > UPLOAD_ERR_OK) {
switch ($errorCode) {
case UPLOAD_ERR_INI_SIZE:
throw new MyException('上传的文件超过了php.ini中upload_max_filesize选项限制的值');
break;
case UPLOAD_ERR_FORM_SIZE:
throw new MyException('上传文件的大小超过了HTML表单中 MAX_FILE_SIZE选项指定的值');
break;
case UPLOAD_ERR_PARTIAL:
throw new MyException('文件只有部分被上传');
break;
case UPLOAD_ERR_NO_FILE:
throw new MyException('没有文件被上传');
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new MyException('找不到临时文件夹');
break;
case UPLOAD_ERR_CANT_WRITE:
throw new MyException('文件写入失败');
break;
default:
// throw new MyException('未知类型错误');
}
}
// 判断文件类型
$fileType = $_FILES['user_pic']['type'];
// echo (strstr($fileType, '/', true));die;
if (strstr($fileType, '/', true) !== 'image') throw new MyException('文件类型错误');
// 将文件从临时目录 移动到用户自定义的目标目录中
// $tempFileName:临时文件名
$tempFileName = $_FILES['user_pic']['tmp_name'];
if (is_uploaded_file($tempFileName)) {
// 原始文件名
$originalFileName = $_FILES['user_pic']['name'];
// 目标文件名
$destFileName = 'images/'.md5(time().mt_rand(1,1000)).strstr($originalFileName, '.');
// 移动文件到目标目录使用的函数
if (move_uploaded_file($tempFileName, $destFileName)) {
echo "<p>$originalFileName: 上传成功...</p>";
// 预览
echo "<img src='{$destFileName}' width='200'>";
}
}
} catch (MyException $er) {
echo $er;
}
?>
演示效果:
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>多文件逐个上传</legend>
<!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
<input type="hidden" name="MAX_FILE_SIZE" value="3000000">
<input type="file" name="user_pic[]">
<input type="file" name="user_pic[]">
<input type="file" name="user_pic[]">
<input type="file" name="user_pic[]">
<button>上传</button>
</fieldset>
</form>
<?php
// 判断文件类型
$fileType = $_FILES['user_pic']['type'];
// echo (strstr($fileType, '/', true));die;
if (strstr($fileType, '/', true) !== 'image') throw new MyException('文件类型错误');
if ($_FILES['user_pic'])
foreach ($_FILES['user_pic']['error'] as $key => $error) {
// 只要判断 error === 0
if ($error === UPLOAD_ERR_OK) {
// 临时文件名
$tmpFileName = $_FILES['user_pic']['tmp_name'][$key];
// 原始文件名
$originalFileName = $_FILES['user_pic']['name'][$key];
// 目标文件名
$destFileName = 'images/'.md5(time().mt_rand(1,1000)).strstr($originalFileName, '.');
// 移动文件
move_uploaded_file($tmpFileName, $destFileName);
echo "<p>$originalFileName: 上传成功...</p>";
// 预览
echo "<img src='{$destFileName}' width='200'>";
}
}
} catch (MyException $er) {
echo $er;
}
?>
演示效果:
<input type="file" name="user_pic[]" multiple>
multiple
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>多文件逐个上传</legend>
<!-- 这个上传文件大小的限制字段,必须写到file字段的前面 -->
<input type="hidden" name="MAX_FILE_SIZE" value="3000000">
<input type="file" name="user_pic[]" multiple>
<button>上传</button>
</fieldset>
</form>
演示效果: