1、文件上传基本信息
朱老师整理资料,便于记忆
1.1、 php 关于文件上传的配置
文件上传项目项在php.ini
中设置,常用的配置项有:
序号 |
配置项 |
默认值 |
描述 |
1 |
file_uploads |
On |
使 PHP 支持文件上传 |
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 |
允许的尽可能最大的文件上传(以字节为单位) |
1.2、 $_FILE
- 上传文件的描述信息,全部保存在系统全局变量
$_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 |
文件写入失败 |
2、单文件上传实战
// $_FILES: 文件上传变量,超全局的变量数组, 保存着所有与文件上传的相关信息
printf('<pre>%s</pre>', print_r($_FILES, true));
// 1、获取Post上传参数
// 原始文件名
$fileName=$_FILES['my_pic']['name'] ?? null;
// 临时文件名
$tmpFileName=$_FILES['my_pic']['tmp_name'] ?? null;
// 获取文件类型(取后缀名前面字符:image/png -> image)
$fileType = strstr(($_FILES['my_pic']['type'] ?? null),'/',true);
// 获取上传错误的代码
$errorCode = $_FILES['my_pic']['error'] ?? null;
// 目标文件名
$saveFileName = 'uploads/' . md5(time(). mt_rand(1,1000)) .strstr($fileName, '.');
// 查看php.ini中的关于上传文件大小的配置项
// echo ini_get('upload_max_filesize');
// 2、对上传文件进行判断
// 首先临时文件名是存在,并且必须是通过POST上传的
if (!$tmpFileName && is_uploaded_file($tmpFileName)) $errorCode=100;
// 判断文件类型是否为'image'
if ($fileType !== 'image') $errorCode=110;
// 自定义文件上传的异常处理类
class UpExt extends Exception
{
public function __toString()
{
return <<< UPLOAD
<table>
<tr>
<td>编号</td>
<td>信息</td>
<td>文件</td>
<td>行号</td>
</tr>
<tr>
<td>$this->code</td>
<td>$this->message</td>
<td>$this->file</td>
<td>$this->line</td>
</tr>
</table>
<style>
table {border-collapse: collapse;border:1px solid black;text-align: center;}
td {border:1px solid black;padding: 5px;}
tr:first-of-type {background-color:#eee;}
tr:last-of-type td {color: red;}
</style>
UPLOAD;
}
}
try {
// 使用系统常量判断错误代码
if ($_FILES && $errorCode > UPLOAD_ERR_OK) {
switch ($errorCode) {
case 100:
throw new UpExt('上传参数不正确', 100);
break;
case 110:
throw new UpExt('文件类型错误', 110);
break;
case UPLOAD_ERR_INI_SIZE:
throw new UpExt('上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UpExt('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值', 2);
break;
case UPLOAD_ERR_PARTIAL:
throw new UpExt('文件只有部分被上传', 3);
break;
case UPLOAD_ERR_NO_FILE:
throw new UpExt('没有文件被上传', 4);
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new UpExt('找不到临时文件夹', 5);
break;
case UPLOAD_ERR_CANT_WRITE:
throw new UpExt('文件写入失败', 6);
break;
default:
// 测试时建议关掉default: 避免误报影响
throw new UpExt('未知类型错误', 7);
}
}
if (move_uploaded_file($tmpFileName, $saveFileName)) {
echo '<p>'. $_FILES['my_pic']['name'].': 上传成功</p>';
// 预览图片
echo "<img src='{$saveFileName}' width='200'>";
}
} catch (UpExt $e) {
echo $e;
}
?>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单文件上传</title>
</head>
<body>
<!-- 上传文件表单的属性设置:
methods="POST"
enctype="multipart/form-data" -->
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>单文件上传</legend>
<!-- 前端设置上传文件的大小:字节 -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value=" 380"> -->
<input type="file" name="my_pic" id="my_pic" >
<button>上传</button>
</fieldset>
</form>
</body>
</html>
3、多文件上传实战
try {
$total =count((array)$_FILES['my_pic']['name']);
for($i=0; $i<$total; $i++) {
// 1、获取Post上传参数
// 原始文件名
$fileName=$_FILES['my_pic']['name'][$i] ?? null;
// 临时文件名
$tmpFileName=$_FILES['my_pic']['tmp_name'][$i] ?? null;
// 获取文件类型(取后缀名前面字符:image/png -> image)
$fileType = strstr(($_FILES['my_pic']['type'][$i] ?? null),'/',true);
// 获取上传错误的代码
$errorCode = $_FILES['my_pic']['error'][$i] ?? null;
// 目标文件名
$saveFileName = 'uploads/' . md5(time(). mt_rand(1,1000)) .strstr($fileName, '.');
// 2、对上传文件进行判断
// 首先临时文件名是存在,并且必须是通过POST上传的
if (!$tmpFileName && is_uploaded_file($tmpFileName)) $errorCode=100;
// 判断文件类型是否为'image'
if ($fileType !== 'image') $errorCode=110;
if ($_FILES && $errorCode > UPLOAD_ERR_OK) {
switch ($errorCode) {
case 100:
throw new UpExt('上传参数不正确', 100);
break;
case 110:
throw new UpExt('文件类型错误', 110);
break;
case UPLOAD_ERR_INI_SIZE:
throw new UpExt('上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值', 1);
break;
case UPLOAD_ERR_FORM_SIZE:
throw new UpExt('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值', 2);
break;
case UPLOAD_ERR_PARTIAL:
throw new UpExt('文件只有部分被上传', 3);
break;
case UPLOAD_ERR_NO_FILE:
throw new UpExt('没有文件被上传', 4);
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new UpExt('找不到临时文件夹', 5);
break;
case UPLOAD_ERR_CANT_WRITE:
throw new UpExt('文件写入失败', 6);
break;
default:
// 测试时建议关掉default: 避免误报影响
throw new UpExt('未知类型错误', 7);
}
}
if (move_uploaded_file($tmpFileName, $saveFileName)) {
echo '<p>'. $fileName.': 上传成功</p>';
// 预览图片
echo "<img src='{$saveFileName}' width='200'>";
}
}
} catch (UpExt $e) {
echo $e;
}
class UpExt extends Exception
{
public function __toString()
{
return <<< UPLOAD
<table>
<tr>
<td>编号</td>
<td>信息</td>
<td>文件</td>
<td>行号</td>
</tr>
<tr>
<td>$this->code</td>
<td>$this->message</td>
<td>$this->file</td>
<td>$this->line</td>
</tr>
</table>
<style>
table {border-collapse: collapse;border:1px solid black;text-align: center;}
td {border:1px solid black;padding: 5px;}
tr:first-of-type {background-color:#eee;}
tr:last-of-type td {color: red;}
</style>
UPLOAD;
}
}
?>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多文件上传</title>
</head>
<body>
<!-- 上传文件表单的属性设置:
methods="POST"
enctype="multipart/form-data" -->
<form action="" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>多文件上传</legend>
<!-- 前端设置上传文件的大小:字节 -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value=" 380"> -->
<input type="file" name="my_pic[]" id="my_pic" multiple>
<button>上传</button>
</fieldset>
</form>
</body>
</html>
总结
- 做个上传研究了半天,多文件上传没有思路,最终通过
for
循环实现了多维数组文件输出。 - 上传封装没有研究,眼睛痛,交作业休息了。