前端页面
需要一个表单<form></form>
,必须具有
method="post" enctype="multipart/form-data"
两者缺一不可,再通过表单里面的
<input type="file" name="myFile" />
对文件进行传输。
接收页面
通过$_FILES['myFile']
接收(返回的是一个数组,进行相应的分配得到相应的值)
$a = $_FILES['myFile'];
$filename = $a['name'];
$type = $a['type'];
$tmp_name = $a['tmp_name'];
$error = $a['error'];
$size = $a['size'];
根据相应的顺序进行判断。
1. 对$error
进行判断
错误代号 | 英文码 | 内容 |
---|---|---|
0 | UPLOAD_ERR_OK | 其值为 0,没有错误发生,文件上传成功。 |
1 | UPLOAD_ERR_INI_SIZE | 其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。 |
2 | UPLOAD_ERR_FORM_SIZE | 其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。 |
3 | UPLOAD_ERR_PARTIAL | 其值为 3,文件只有部分被上传。 |
4 | UPLOAD_ERR_NO_TMP_DIR | 其值为 4,没有文件被上传。 |
6 | UPLOAD_ERR_NO_TMP_DIR | 其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。 |
7 | UPLOAD_ERR_CANT_WRITE | 其值为 7,文件写入失败。PHP 5.1.0 引进。 |
8 | UPLOAD_ERR_EXTENSION | 其值为8,文件由于PHP的扩展程序导致文件上传失败 |
2.用is_uploaded_file($tmp_name)
函数判断是否是通过POST
方式上传
3.可以用pathinfo($filename,PATHINFO_EXTENSION)
函数来获得上传文件的后缀类型
4.可以用md5(uniqid(microtime(true),true))
来生成唯一标识的文件名称,加上3.
的后缀就可以组成保存的文件名。
5.这两个代码可以生成希望存储的文件夹,在文件夹不存在的情况下使用(判断文件夹不存在的代码 file_exists($destination)
)
mkdir("uploads",0777,true);
chmod("uploads",0777);
6.move_uploaded_file($tmp_name, $destination)
这代码是将临时文件移动到指定文件夹,并保存。$destination
的内容是 指定文件夹+文件名+.后缀
。而保存的$tmp_name
是文件传输过来的临时文件。
文件上传代码封装
function uploadMonoFile($a)
{
$filename = $a['name'];
@$type = $a['type'];
$tmp_name = $a['tmp_name'];
$error = $a['error'];
@$size = $a['size'];
$allowExt = array("gif", "jpeg", "jpg", "png", "wbmp");
$maxSize = 1048576;
//对上传文件判断是否成功还是出错
if ($error == UPLOAD_ERR_OK) {
$postfix = pathinfo($filename, PATHINFO_EXTENSION);
//限制文件上传类型
if (!in_array($postfix, $allowExt)) {
exit("非法文件类型");
}
//限制文件上传大小
if ($size > $maxSize) {
exit("文件过大");
}
//是否是用POST的方式判断
if (is_uploaded_file($tmp_name)) {
//获得唯一的文件名,getUniName()是封装的一个方法--md5加密的
$filename = getUniName($filename);
$destination = "uploads/";
//判断文件夹是否存在
if (!file_exists($destination)) {
mkdir("uploads", 0777, true);
chmod("uploads", 0777);
}
$destination = "uploads/" . $filename . "." . $postfix;
//将临时文件进行存储到指定文件夹
if (move_uploaded_file($tmp_name, $destination)) {
$mes = "文件上传成功";
} else {
$mes = "文件上传失败";
}
} else {
$mes = "文件不是通过post方式上传的";
}
return $mes;
} else {
switch ($error) {
case 1:
$mes = "超过配置文件的大小";
break;
case 2:
$mes = "超过表单限制的大小";
break;
case 3:
$mes = "文件部分被上传";
break;
case 4:
$mes = "没有文件被上传";
break;
case 6:
$mes = "没有找到临时目录";
break;
case 7:
$mes = "文件不可写";
break;
case 8:
$mes = "由于PHP的扩展程序导致文件上传失败";
break;
}
}
return $mes;
}
多文件上传代码封装
多文件上传是基于name传递的参数是数组还是多个不同的文件参数
- 无论是多个不同的文件参数还是数组参数上传,接受的参数都会被纳入同一个数组中。
-
对于要区分两种不同的数组的关键在于查找其中的不同点,数组参数中,文件的数据都被统一分配在了同一个数组当中,而单个文件上传是文件的所有数据都分配在一个数组里面。
-
从上一点即可得知,name是数组参数的文件上传,其为一个二维数组,而多个单文件上传其为一个一维数组。于是判断其中的文件名
['name']
是字符串还是数组极客判断是以数组形式上传还是单文件形式上传。步骤:
- 将接收的参数
$a
遍历成单个数组$a_sm
。 - 判断数组里面的某项值是否是字符串还是数组,这里判断的是文件名
['name']
。 - 如果是字符串,则确定为单文件上传,如果是数组,则是多文件上传。
['name']是字符串》》单文件上传
- 判断
['error']
是否是UPLOAD_ERR_OK
,文件是否上传成功。 - 然后使用之前封装的函数对文件进行相应的处理。
['name']是数组》》多文件上传
- 通过
foreach
函数对二维数组进行遍历分割成单文件数组的形式,然后用单文件数组的方法对文件进行相应的处理。
这两个是判断成功数和失败数,忽视空文件。代码未完善
$success_num=0; $fail_num=0;
function uploadMultiFile($a)
{
$success_num=0;
$fail_num=0;
foreach ($a as $a_sm) {
if (is_string($a_sm['name'])) {
if ($a_sm['error'] == UPLOAD_ERR_OK) {
$res = uploadMonoFile($a_sm);
if ($res=="文件上传成功"){
$success_num++;
}
} elseif ($a_sm['error'] != 4) {
echo "文件出错";
}
} else {
$i = 0;
foreach ($a_sm as $key => $value) {
$files[$i]['name'] = $a_sm['name'][$i];
$files[$i]['tmp_name'] = $a_sm['tmp_name'][$i];
$files[$i]['error'] = $a_sm['error'][$i];
$i++;
}
foreach ($files as $file) {
$res = uploadMonoFile($file);
if ($res=="文件上传成功") {
$success_num++;
}
}
}
}
return $success_num."个文件上传成功".",有".$fail_num."个上传失败。";
}