PHP:封装文件上传函数
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 |
允许的尽可能最大的文件上传 |
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 |
文件写入失败 |
3.封装单文件上传
文件大小不超过5M
后缀只能是[‘jpg’,’jpeg’,’png’,’wbmp’,’gif’]
检查图片合法性
为每一张图片处理散列名称
目标目录不存在,创建目录 6.设置错误日志接收系统错误,而不是将错误显示到页面上
①普通单文件上传,没有封装成为函数
html代码块
- form文件上传新属性:
enctype="multipart/form-data"
<?php
/**
* 文件上传 :客户端上传文件到服务器, 首先存在临时文件夹下,
* 做一些严格的验证(大小, 后缀,合法文件,),通过以后,移动文件到指定的文件夹
*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
</head>
<body>
<form action="index.php" method="post" enctype="multipart/form-data">
<fieldset>
<legend>单文件上传</legend>
<label for="myFile">
<input type="file" name="myFile" id="myFile">
</label>
<button>上传</button>
</fieldset>
</form>
</body>
</html>
PHP代码块
<?php
//开启错误日志
ini_set('error_log','./error.log');
//打印接收的文件格式
printf("<pre>%s</pre>",print_r($_FILES,true));
//接受的文件属性进行变量赋值
$FilesName = $_FILES['myFile']['name'];
$FilesType = $_FILES['myFile']['type'];
$FilesTmp_name = $_FILES['myFile']['tmp_name'];
$FilesError = $_FILES['myFile']['error'];
$FilesSize = $_FILES['myFile']['size'];
//判断用户上传的文件类型/检测是否合法文件
if ($FilesError == 0) {
//设置上传文件的类型
$allowExt = ['jpg','jpeg','png','wbmp','gif'];
//拆分文件名称的前后缀
$arr = explode('.',$FilesName);
//获取文件名称的前缀
$prefix = array_shift($arr);
//获取文件名称的后缀
$ext = array_pop($arr);
//in_array — 检查数组中是否存在某个值 则返回 true,否则返回 false。
if (!in_array($ext,$allowExt)) {
//检查文件类型
die('非法的文件类型');
}
//限制文件上传大小
$MaxSize = 2097152;
if ($MaxSize < $FilesSize) {
die('文件大小超过限制的最大值');
}
//检测上传的文件是否合法
//getimagesize — 取得图像大小
if (!getimagesize($FilesTmp_name)) {
die('不是真实图片');
}
//检测文件上传是否用 http post 上传
//is_uploaded_file — 判断文件是否是通过 HTTP POST 上传的
if (!is_uploaded_file($FilesTmp_name)) {
die('上传方式错误:请用HTTP post方式上传');
}
//如果文件正确则移动此文件
$action = 'uploads/';
//file_exists指定的文件或目录存在则返回 true,否则返回 false。
if (!file_exists($action)) {
//mkdir — 新建目录
mkdir($action,0777,true);
//chmod — 改变文件模式
chmod($action,0777);
}
//move_uploaded_file — 将上传的文件移动到新位置
move_uploaded_file($FilesTmp_name,$action.$FilesName);
echo "文件上传成功";
}else {
//switch 循环出 error 错误的信息
switch ($FilesError) {
case 1:
echo '文件超过`php.ini`中`upload_max_filesize`值<br>';
break;
case 2:
echo '文件大小超过表单中`MAX_FILE_SIZE`指定的值<br>';
break;
case 3:
echo '文件只有部分被上传<br>';
break;
case 4:
echo '没有文件被上传<br>';
break;
case 6:
echo '找不到临时文件夹<br>';
break;
case 7:
echo '文件写入失败<br>';
break;
default:
echo "文件写入失败";
break;
}
}
②单文件上传,封装成为函数
公共函数代码块
<?php
//封装文件上传函数
/*
* 第一个值:用户上传的文件/后端接收的文件
* 第二个值:设置默认上传文件的路径
* 第三个值:判断是否检测文件合法
* 第四个值:设置默认文件格式
* 第五个值:设置默认允许用户上传文件大小
*/
function UploadedFile(array $fileInfo,$uploadPath = "./uploads",$flag = true,array $allowExt = ['jpg','JPG','jpeg','png','wbmp','gif'],$MaxSize = 5242880)
{
//判断用户上传的文件/后端接收的文件错误信息是否=0
if ($fileInfo['error'] != 0)
{
switch ($error) {
case 1:
$res['mess'] = '文件超过`php.ini`中`upload_max_filesize`值<br>';
break;
case 2:
$res['mess'] = '文件大小超过表单中`MAX_FILE_SIZE`指定的值<br>';
break;
case 3:
$res['mess'] = '文件只有部分被上传<br>';
break;
case 4:
$res['mess'] = '没有文件被上传<br>';
break;
case 6:
$res['mess'] = '找不到临时文件夹<br>';
break;
case 7:
$res['mess'] = '文件写入失败<br>';
break;
default:
$res['mess'] = "文件写入失败";
break;
}
return $res['mess'];
}
//后端设置文件的类型
//设置上传文件的类型
//拆分文件名称的前后缀
$arr = explode('.',$fileInfo['name']);
//获取文件名称的前缀
$prefix = array_shift($arr);
//获取文件名称的后缀
$ext = array_pop($arr);
//in_array — 检查数组中是否存在某个值 则返回 true,否则返回 false。
if (!in_array($ext,$allowExt))
{
//检查文件类型
$res['mess'] =('非法的文件类型');
}
//限制文件上传大小
if ($MaxSize < $fileInfo['size'])
{
$res['mess'] =('文件大小超过限制的最大值');
}
//检测上传的文件是否合法
//getimagesize — 取得图像大小
if ($flag)
{
if (!getimagesize($fileInfo['tmp_name'])) {
$res['mess'] =('不是真实图片');
}
}
//检测文件上传是否用 http post 上传
//is_uploaded_file — 判断文件是否是通过 HTTP POST 上传的
if (!is_uploaded_file($fileInfo['tmp_name'])) {
$res['mess'] =('上传方式错误:请用HTTP post方式上传');
}
if (!empty($res)) {
return $res;
}
//-------------------------------------------
//如果文件正确则移动此文件
//file_exists指定的文件或目录存在则返回 true,否则返回 false。
if (!file_exists($uploadPath)) {
//mkdir — 新建目录
mkdir($uploadPath,0777,true);
//chmod — 改变文件模式
chmod($uploadPath,0777);
}
//文件名称md5+时间戳 加密
$fileRealPath = $uploadPath.'/'.md5($prefix.time()).'.'.$ext;
//move_uploaded_file — 将上传的文件移动到新位置
if (!move_uploaded_file($fileInfo['tmp_name'],$fileRealPath))
{
$res['mess'] = '文件移动失败';
}else
{
$res['mess'] = $fileInfo['name'].'文件上传成功';
$res['fileRealPath'] = $fileRealPath;
return $res;
}
}
INDEX3调用函数代码块
<?php
require 'common.php';
ini_set('error_log','./error.log');
//文件大小超出 post_max_size的值 $_FILES,$_POST全部为空
$post_max_size = ini_get('post_max_size');
$fileInfo = $_FILES['myFile'];
$res = isset($fileInfo) ? UploadedFile($fileInfo) : NULL;
echo "<p>{$res['mess']}</p>"."<br>";
echo "<p>{$res['fileRealpath']}</p>"."<br>";
4.封装多文件上传
- 多文件上传:
<input type="file" name="myFile[]" id="myFile" multiple>
input 需要加上multiple
多文件上传需要遍历上传的文件,因为多个文件是三维数组
多文件上传,三维数组遍历,接下来把这个方法封装到函数中
文件上传成功
多文件上传封装函数代码块
//多文件上传方法
function upload()
{
$file = [];
$i = 0;
foreach ($_FILES as $key => $file) {
//因为是三维数组 还得遍历一次
foreach ($file['name'] as $key => $value) {
$file[$i]['name'] = $file['name'][$key];
$file[$i]['type'] = $file['type'][$key];
$file[$i]['tmp_name'] = $file['tmp_name'][$key];
$file[$i]['error'] = $file['error'][$key];
$file[$i]['size'] = $file['size'][$key];
$i++;
}
}
return $file;
}
多文件上传客户端代码块
<?php
require 'common.php';
ini_set('error_log','./error.log');
//文件大小超出 post_max_size的值 $_FILES,$_POST全部为空
$post_max_size = ini_get('post_max_size');
//多文件上传需要遍历上传的文件,因为多个文件是三维数组
printf('<pre>%s</pre>',print_r($_FILES,true));
//多文件上传三维数组遍历成二维数组,二维数组遍历成一维数组
$file = upload();
foreach ($file as $key => $fileInfo) {
$res = UploadedFile($fileInfo);
echo '<p style="color:green">'.$res['mess'].'</p>';
//获取文件真实路径 转成js格式上传到数据库
$uploadFiles[] = $res['fileRealPath'];
}
// var_dump(json_encode($uploadFiles));