此篇文章主要讲解如何封装一个php的用于文件上传下载的函数,可以用于本demo中的头像上传功能,顺便讲解一下多文件上传的方式。如果对于文件上传特别熟悉可以跳过此节。
还是使用之前那个界面。
addUser.php:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<H3>添加管理员</H3>
<FORM action="doAdminAction.php?act=addUser" method="post">
<TABLE width="60%" border="1" cellpadding="5" cellspacing="0" bgcolor="#cccccc">
<tr>
<TD align="right">用户名称</TD>
<TD><input type="text" name="username" placeholder="请输入用户名称"/></TD>
</tr>
<tr>
<TD align="right">用户密码</TD>
<TD><input type="text" name="password" placeholder="请输入用户名称"/></TD>
</tr>
<tr>
<TD align="right">用户邮箱</TD>
<TD><input type="text" name="email" placeholder="请输入用户名称"/></TD>
</tr>
<tr>
<td align="right">性别</td>
<td><input type="radio" name="sex" value="1" checked="checked"/>男
<input type="radio" name="sex" value="2" />女
<input type="radio" name="sex" value="3" />保密
</td>
</tr>
<tr>
<td align="right">头像</td>
<td><input type="file" name="face" /></td>
</tr>
<tr>
<TD colspan="2"><input type="submit" value="添加用户"/></TD>
</tr>
</FORM>
</body>
</html>
这里是文件目录:
在表单提交的doAdminAction.php中,只需要增 加move_uploaded_file($_FILES["face"]["tmp_name"],
这一行代码,即可把客户端上传的文件放在服务器中的对应的地方。但是这样的代码有一些问题
"upload/" . $_FILES["face"]["name"]);
(1)如果在admin不存在upload的文件夹,文件上传不上去。
(2)对于上传的文件的类型没有进行检验,如果出现病毒文件会比较危险。
(3)如果上传了与upload文件夹中的文件名称相同的文件,原来的文件就会被替换掉。
(4)对于文件上传可能会出现的一些错误没有进行处理,例如文件大小超过了2M,(php ini 文件中默认规定的上传限制大小为2M)
下面是解决方案:
(1)首先判断upload的文件夹是否存在,如果不存在则建立
$path="upload/";
//如果路径不存在就建立的路径上
if(!file_exists($path))
{
mkdir($path,0777,true);
}
(2)使用strtolower(end(explode(“.”, $filename)));获得文件的拓展名
然后判断拓展名是否在所需要的文件类型中。
(3)使用md5(uniqid(microtime(true),true));得到一个唯一的字符串与之前得到的文件拓展名连接在一起,作为上传文件的文件名。
(4)现在开始编写doAdminAction的代码,第四个问题将在代码中讲解。
<?php
require_once '../include.php';
//print_r($_FILES["face"]);
$path="upload/";
//如果路径不存在就建立的路径上
if(!file_exists($path))
{
mkdir($path,0777,true);
}
//允许的类型
$allowExt=array("gif","jpeg","png","jpg","wbmp");
$filename=$_FILES["face"]["name"];
$ext=getExt($filename);
if(!in_array($ext,$allowExt)){
exit("非法文件类型");
}
//得到了唯一的文件名的文件
$filename=getUniName().".".$ext;
if(move_uploaded_file($_FILES["face"]["tmp_name"],
$path.$filename))
{
echo "文件上传成功";
}
else
{
switch($_FILES["face"]['error']){
case 1:
$mes="超过了配置文件上传文件的大小";//UPLOAD_ERR_INI_SIZE
break;
case 2:
$mes="超过了表单设置上传文件的大小"; //UPLOAD_ERR_FORM_SIZE
break;
case 3:
$mes="文件部分被上传";//UPLOAD_ERR_PARTIAL
break;
case 4:
$mes="没有文件被上传";//UPLOAD_ERR_NO_FILE
break;
case 6:
$mes="没有找到临时目录";//UPLOAD_ERR_NO_TMP_DIR
break;
case 7:
$mes="文件不可写";//UPLOAD_ERR_CANT_WRITE;
break;
case 8:
$mes="由于PHP的扩展程序中断了文件上传";//UPLOAD_ERR_EXTENSION
break;
}
echo $mes;
}
?>
如果发生了出现的错误,则这些错误会被打印出来。至此单文件上传的内容讲解完毕,现在将上述的代码封装为函数。
<?php
function uploadFile($path="upload/",$allowExt=array("gif","jpeg","png","jpg","wbmp"),$imgFlag=true)
{
//如果路径不存在就建立的路径上
if(!file_exists($path))
{
mkdir($path,0777,true);
}
//允许的类型
$filename=$_FILES["face"]["name"];
$ext=getExt($filename);
if(!in_array($ext,$allowExt)){
exit("非法文件类型");
}
if($imgFlag){
//如何验证图片是否是一个真正的图片类型
//getimagesize($filename):验证文件是否是图片类型 正确返回数组错误返回false
$info=getimagesize($tmp_name);
//var_dump($info);exit;
if(!$info){
exit("不是真正的图片类型");
}
}
//得到了唯一的文件名的文件
$filename=getUniName().".".$ext;
if(move_uploaded_file($_FILES["face"]["tmp_name"],
$path.$filename))
{
echo "文件上传成功";
}
else
{
switch($_FILES["face"]['error']){
case 1:
$mes="超过了配置文件上传文件的大小";//UPLOAD_ERR_INI_SIZE
break;
case 2:
$mes="超过了表单设置上传文件的大小"; //UPLOAD_ERR_FORM_SIZE
break;
case 3:
$mes="文件部分被上传";//UPLOAD_ERR_PARTIAL
break;
case 4:
$mes="没有文件被上传";//UPLOAD_ERR_NO_FILE
break;
case 6:
$mes="没有找到临时目录";//UPLOAD_ERR_NO_TMP_DIR
break;
case 7:
$mes="文件不可写";//UPLOAD_ERR_CANT_WRITE;
break;
case 8:
$mes="由于PHP的扩展程序中断了文件上传";//UPLOAD_ERR_EXTENSION
break;
}
echo $mes;
}
}
多文件上传分为两种情况
(1)多个单文件上传
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
-->
<FORM action="doAction2.php" method="post" enctype="multipart/form-data">
<INPUT type="hidden" name="MAX_FILE_SIZE" value="1048576"/>
请选择上传文件:<INPUT type="file" name="myFile1"/><br/>
请选择上传文件:<INPUT type="file" name="myFile2"/><br/>
请选择上传文件:<INPUT type="file" name="myFile3"/><br/>
<input type="submit" value="上传"/>
</FORM>
</body>
</html>
这种形式相当于上传了多个单文件,在doAction2.php中print_r($_FILES);得到
Array
(
[myFile1] => Array
(
[name] => touxiang.jpg
[type] => image/jpeg
[tmp_name] => D:\xampp\tmp\php79E3.tmp
[error] => 0
[size] => 28747
)
[myFile2] => Array
(
[name] => 文章.png
[type] => image/png
[tmp_name] => D:\xampp\tmp\php7A03.tmp
[error] => 0
[size] => 11655
)
[myFile3] => Array
(
[name] => 增加.png
[type] => image/png
[tmp_name] => D:\xampp\tmp\php7A04.tmp
[error] => 0
[size] => 7439
)
)
(2)多文件上传
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
-->
<FORM action="doAction2.php" method="post" enctype="multipart/form-data">
<INPUT type="hidden" name="MAX_FILE_SIZE" value="1048576"/>
请选择上传文件:<INPUT type="file" name="myFile[]"/><br/>
请选择上传文件:<INPUT type="file" name="myFile[]"/><br/>
请选择上传文件:<INPUT type="file" name="myFile[]"/><br/>
<input type="submit" value="上传"/>
</FORM>
</body>
</html>
同样print_r($_files)一下
Array
(
[myFile] => Array
(
[name] => Array
(
[0] => touxiang.jpg
[1] => 文章.png
[2] => 增加.png
)
[type] => Array
(
[0] => image/jpeg
[1] => image/png
[2] => image/png
)
[tmp_name] => Array
(
[0] => D:\xampp\tmp\php1EC.tmp
[1] => D:\xampp\tmp\php1ED.tmp
[2] => D:\xampp\tmp\php1EE.tmp
)
[error] => Array
(
[0] => 0
[1] => 0
[2] => 0
)
[size] => Array
(
[0] => 28747
[1] => 11655
[2] => 7439
)
)
)
发现两种方式得到的数组有很多的不同。
对于第一种的情况(相当于一个文件数组)我们可以
foreach ($_FILES as $var)
{
//对于每一个文件进行了文件上传操作
$info=uploadFile($var);
echo $info;
}
对于第二种情况我们可以将所示的三维数组转换为第一种情况所示的二维数组即可。
foreach($_FILES[myFile][name] as $key=>$var )
{
$files[$key][name]=$_FILES[myFile][name][$key];
$files[$key][type]=$_FILES[myFile][type][$key];
$files[$key][tmp_name]=$_FILES[myFile][tmp_name][$key];
$files[$key][error]=$_FILES[myFile][error][$key];
$files[$key][size]=$_FILES[myFile][size][$key];
}
print_r($files);
结果
Array
(
[0] => Array
(
[name] => touxiang.jpg
[type] => image/jpeg
[tmp_name] => D:\xampp\tmp\php3227.tmp
[error] => 0
[size] => 28747
)
[1] => Array
(
[name] => 文章.png
[type] => image/png
[tmp_name] => D:\xampp\tmp\php3228.tmp
[error] => 0
[size] => 11655
)
[2] => Array
(
[name] => 增加.png
[type] => image/png
[tmp_name] => D:\xampp\tmp\php3229.tmp
[error] => 0
[size] => 7439
)
)
成功了,现在我们开始封装一个文件上传函数,这个函数呢既可以处理单文件上传又可以处理多文件上传。然后我们只需要编写数组处理的这部分,然后调用upload()函数即可。
<?php
require_once "../include.php";
//用于转换数组
function buildInfo()
{
foreach($_FILES as $file)
{
$i=0;
if(is_string($file['name']))
{
$files[$i]=$file;
$i++;
}
else
{
foreach($file[name] as $key=>$var)
{
$files[$key][name]=$file[name][$key];
$files[$key][type]=$file[type][$key];
$files[$key][tmp_name]=$file[tmp_name][$key];
$files[$key][error]=$file[error][$key];
$files[$key][size]=$file[size][$key];
}
}
}
return $files;
}
//用于上传
function uploadFile($path="upload/",$allowExt=array("gif","jpeg","png","jpg","wbmp"))
{
//如果路径不存在就建立的路径上
if(!file_exists($path))
{
mkdir($path,0777,true);
}
$files=buildInfo();
foreach($files as $file)
{
//允许的类型
$filename=$file["name"];
$ext=getExt($filename);
if(!in_array($ext,$allowExt)){
exit("非法文件类型");
}
//校验是否是一个真正的图片类型
if($imgFlag){
if(!getimagesize($file['tmp_name'])){
exit("不是真正的图片类型");
}
}
//得到了唯一的文件名的文件
$filename=getUniName().".".$ext;
if(move_uploaded_file($file["tmp_name"],
$path.$filename))
{
echo "文件上传成功";
}
else
{
switch($file['error']){
case 1:
$mes="超过了配置文件上传文件的大小";//UPLOAD_ERR_INI_SIZE
break;
case 2:
$mes="超过了表单设置上传文件的大小"; //UPLOAD_ERR_FORM_SIZE
break;
case 3:
$mes="文件部分被上传";//UPLOAD_ERR_PARTIAL
break;
case 4:
$mes="没有文件被上传";//UPLOAD_ERR_NO_FILE
break;
case 6:
$mes="没有找到临时目录";//UPLOAD_ERR_NO_TMP_DIR
break;
case 7:
$mes="文件不可写";//UPLOAD_ERR_CANT_WRITE;
break;
case 8:
$mes="由于PHP的扩展程序中断了文件上传";//UPLOAD_ERR_EXTENSION
break;
}
echo $mes;
}
}
}
这段代码中还增加了对于上传图片是否为图片格式的检验,以及对于图片大小的检验,因为有些病毒文件会伪装为图片文件。