一、文件上传的原理
文件上传:文件从用户本地电脑通过传输的方式(web表单)保存到服务器所在电脑指定的目录下
1、文件上传的步骤
1.增加文件上传的表单:浏览器请求一个服务器的HTML脚本(包含文件上传表单)
2.用户从本地选择一个文件(点击上传框(按钮))
3.用户点击上传,文件会通过物联网传输到服务器上
4.服务器操作系统会将文件保存到临时目录下,是以临时文件的格式保存(windows下的tmp文件夹)
5.服务器脚本开始工作:判断文件有效
6.服务器脚本将有效文件从临时目录下移动到指定的目录下
二、HTML的表单要求
1.form标签的method属性必须是POST
2.form标签的enctype属性主要是规范表单数据的编码方式。在使用文件上传时,属性值必须时’multipart/form-data’
3.上传表单:file表单
三、PHP处理文件上传
在PHP中,有一个预定义变量$_FILES是专门用来存储用户上传的文件的
1、$_FILES变量
$_FILES变量是专门用来接收文件上传的。使用$_POST是接收不到文件信息的。
1.$_FILES变量是以一个数组的形式来接收文件的
name:文件在用户(浏览器端)电脑上实际存在的名字
tmp_name:文件上传到服务器端临时存放时的路径
type:MIME(多功能互联网邮件扩展)类型,用来在计算机中客户端识别文件的类型格式
error:文件上传的代号。用来告知PHP文件接收过程中出现了什么样的问题(PHP后期根据代码进行文件判断)
- size:文件大小(PHP根据实际需求来确定是否该保留)
2、移动临时文件到目标位置
文件上传之后会保存到$_FILES中,那么访问文件信息的形式就是$_FILES[表单name属性值][元素信息]
1.判断是否为上传的文件:临时文件
is_uploaded_file()
//取得文件信息
$file = $_FILES['image'];
//判断是否是上传文件:临时文件
if(is_uploaded_file($file['tmp_name'])){
//是上传文件
}else{
//不是上传文件
}
2.移动文件
move_uploaded_file(‘临时文件路径’,’要移动的目录下的文件名’)
//是上传文件
if(move_uploaded_file($file['tmp_name'],'uploads'.$file['name'])){
//文件保存成功
}else {
//文件保存失败
}
注意: 第二个参数要是一个有效的目录地址,目录必须存在;要带有文件名称,不能是纯路径。
3、多文件上传
1.当商品需要上传多个图片进行展示时,那么需要使用多文件上传。即针对一个内容进行多个文件上传:同名表单
2.当商品需要进行多维度图片说明时,需要使用多文件上传。即针对不同内容进行多个文件上传:批量解决问题
1.同名表单
HTML页面
input的name属性使用数组的形式。
<form action="" enctype="multipart/form-data">
文件上传:<input type="file" name="img[]"><br>
文件上传:<input type="file" name="img[]"><br>
文件上传:<input type="file" name="img[]"><br>
<button type="submit">提交</button>
</form>
PHP后台实现
将表单名字形成一个数组,同时将文件对应的五个要素都单独形成一个数组。每一个文件上传对用的数组元素的下标都是一样的
//判断元素存在而且是数组
if (isset($_FILES['image']['name']) && is_array($_FILES['image']['name'])) {
//遍历构造数组元素
$images = array(); //存放所有的文件信息,一个元素代表一个文件(数组)
foreach($_FILES['image']['name'] as $k=>$file){
$images[] = array(
'name'=>$file,
'tmp_name'=>$_FILES['image']['tmp_name'][$k],
'type'=>$_FILES['image']['type'][$k],
'error'=>$_FILES['image']['error'][$k],
'size'=>$_FILES['image']['size'][$k]
);
}
}
//此时的images数组就和不同name属性值的上传方式一样了
2.批量上传
HTML页面
input的name属性不同。
<form action="" enctype="multipart/form-data">
文件上传:<input type="file" name="body"><br>
文件上传:<input type="file" name="head"><br>
文件上传:<input type="file" name="foot"><br>
<button type="submit">提交</button>
</form>
PHP后台实现
每个文件都会形成一个属于自己独立的5个元素的数组
foreach($_FILES as $file){
//$file就是一个完整的上传文件信息:找到临时路径,指定存放路径
if(is_uploaded_file($file['tmp_name'])){
move_uploaded_file($file['tmp_name'],'upload/'.$file['name']);
}
}
3、封装成方法,并使用五个元素对文件的上传进行判断
$file = $_FILES['file_1'];
$path = 'img/';
$allow_type = array("image");
$allow_format = array("jpeg");
$max_size = 10000000;
if ($filename = upload_file($file, $path, $error, $allow_type, $allow_format, $max_size)) {
echo '文件保存成功!';
echo $filename . '.' . 'jpeg';
} else {
echo $error;
}
/**
* @param $file 通过$_FILES接受的文件数组
* @param $path 文件要保存的地址
* @param $error 方法返回的错误信息
* @param $allow_type 方法允许的文件类型
* @param $allow_format 方法允许的文件格式
* @param $max_size 方法允许的文件大小
* @return
*/
function upload_file($file, $path, &$error, $allow_type, $allow_format, $max_size)
{
//1.判断文件是否有效
if (!isset($file['name']) || !is_array($file)) {
$error = "不是一个有效文件!";
return false;
}
//判断保存文件路径是否有效
if (!is_dir($path)) {
$error = "文件存储路径不存在!";
return false;
}
//判断文件本身上传过程中是否有错误
switch ($file['error']) {
case 1:
case 2:
$error = "文件大小超过服务器允许大小!";
return false;
case 3:
$error = "文件上传有损,上传失败!";
return false;
case 4:
case 6:
$error = "没有找到文件!";
return false;
case 7:
$error = "文件写入失败!";
return false;
}
//判断MIME类型
$mime = strstr($file['type'], "/", TRUE);
if (!in_array($mime, $allow_type)) {
$error = "文件类型有误!";
return false;
}
//判断文件格式是否正确
$type = ltrim(strstr($file['type'], '/'), '/');
if (!in_array($type, $allow_format)) {
$error = "文件格式有误!";
return false;
}
//判断当前文件大小是否满足当前需求
if ($file["size"] > $max_size) {
$error = "文件过大!";
return false;
}
//构造文件名字:类型_年月日+随机字符串 .$ext
$filename = $mime . '_' . date("Ymd");
//移动到指定目录
if (is_uploaded_file($file["tmp_name"])) {
if (move_uploaded_file($file['tmp_name'], $path . "/" . $filename . '.' . $type)) {
return $filename;
}
} else {
$error = "文件保存失败!";
return false;
}
}