首先是一个包含表单的页面,这里只写一个表单
upload.php
<form action="doAction.php"method="post"enctype="multipart/form-data">
<--
这个是在客户端设置文件上传类型的方法
<input type="file" name="myFile" accept="image/jpeg,image/png,image/gif,image/jpg"/>
-->
<input type="file" name="myFile"/>
<input type="submit" value="上传"/>
</form>
上传文件步骤:
我们新建一个doAction.php
通过$_FIlES 接收传过来的文件,我们发现是一个2维数组
array
'myFile' =>
array
'name' => string 'css选择器权重.png' (length=22)
'type' => string 'image/png' (length=9)
'tmp_name' => string 'C:\wamp\tmp\phpB0C7.tmp' (length=23)
'error' => int 0
'size' => int 34464
这里面包含的几个参数 myFile 是我们设置的input标签里的name的值
name指的是传过来的那个文件本来的名称
type是指文件的类型,就是文件的后缀名
tmp_name 是指临时文件名称 检测是否为一个真实图片的时候要用到
error检测是否出错
size 指文件大小为多少个字节
分别定义这些变量去接收以上的数据
下面开始进行判断:
如果
$error == UPLOAD_ERR_OK;
则说明上传成功 否则根据error类型进行判断
switch ($error){
case 1://UPLOAD_ERR_INI_SIZE 超过配置文件中上传文件的大小
$mes = "超过了配置文件上传文件的大小";
break;
case 2://UPLOAD_ERR_FORM_SIZE 超过了表单中配置文件的大小
$mes = "超过了表单中配置文件的大小";
break;
case 3://UPLOAD_ERR_PARTIAL 文件部分被上传
$mes = "文件部分被上传";
break;
case 4://UPLOAD_ERR_NO_FILE 文件没有被上传
$mes = "文件没有被上传";
break;
case 6: //UPLOAD_ERR_NO_TMP_DIR 没有找到临时目录
$mes = "没有找到临时目录";
break;
case 7://UPLOAD_ERR_CANT_WRITE 文件不可写
$mes = "文件不可写";
break;
case 8://UPLOAD_ERR_EXTENSION php的扩展程序中断了程序上传
$mes = "php的扩展程序中断了程序上传";
break;
}
出现以上情况则说明上传失败
上传成功了我们才能进行各种判断
我们需要规定文件上传类型
我们先申明一个数组,根据’type’ => string ‘image/png’ (length=9)可得
数组:
$allowExt = array( "gif","jpg","jpeg","png","wbmp");
这个数组包含了可能的后缀名称
然后我们来进行验证
这里我们先封装了一个方法
function getExt($fileName){
return strtolower(end(explode('.',$fileName)));
/**
* strtolower() 函数把字符串转换为小写。
* end()输出数组中最后一个元素的值
* explode(),拆分字符串
*/
}
这个方法我们用来截取后缀名,我们把上面获取的name传进去,就能得出文件的后缀名
慕课视频里用了这个方法去验证,我试了下没有成功:
if(!in_array(getExt($name), $allowExt)){
$mes = "上传类型不合法";
exit();
}
php里确实提供了in_array()方法判断字符串是否存在数组中,但我这边没有试验成功,无奈我只有自己写了一个
for循环遍历数组进行比对,代码如下:
for($i=0;$i<count($allowExt);$i++){
$temp = $allowExt[$i];
if(getExt($name) == $temp){
$m = "上传类型合法";
$h = $m;
}else{
$m = "上传文件不合法";
}
}
if($h){
$mes = "上传类型合法";
}else{
alert($m, 'upload.php');
exit;
}
这样就能完美解决验证上传文件是否为图片的问题
这样还不够,如果大家新建一个文本文件,将后缀名修改为jpg/png之类的图片格式,那么我们这边就无法识别
所以我们还需要加一个判断:
$imgFlag = true;
if($imgFlag){
//如何检验图片是一个正真的图片类型 用getimagesize
$info = getimagesize($tmp_name);//如果是一个图片则返回的是一个数组,否则将返回false
// var_dump($info);
if(!$info){
$mes = "您传的不是一个真正的图片文件";
exit;
}
}
我们使用getimagesize()方法判断是否为一个真实的图片,将临时文件名称传入,如不是真实的图片则会
返回false;
然后限制一下图片上传的大小:
比如我们设置图片最大是1M
1M=1024*1024=1048516
$maxSize = 1048516;
所以:
if($size > $maxSize){
alert("上传文件过大", 'upload.php');
exit;
}
然后就是判断文件是不是通过http post方式提交上去的
已经设置下图片上传的路径,我们可以先在文件夹下新建一个upload文件夹存放图片
而后代码如下:
//使用 is_uploaded_file(临时文件名)判断文件是否上传成功
if(is_uploaded_file($tmp_name)){
$realname = getUniName() .".". getExt($name);
$path = "uploads";
if(!file_exists($path)){
mkdir($path,0777,true);
//mkdir() 函数创建目录.
//若成功,则返回 true,否则返回 false。
}
$destination = $path."/".$realname;
if(move_uploaded_file($tmp_name, $destination)){//文件移动
$mes = "文件移动成功";
}else{
$mes = "文件移动失败";
}
}else{
$mes = "文件不是通过http post上传的";
}
以上代码中
$path = "uploads";
if(!file_exists($path)){
mkdir($path,0777,true);
//mkdir() 函数创建目录.
//若成功,则返回 true,否则返回 false。
}
是用来判断upload文件夹是否存在,不存在则创建。
还有用到了getUniName()方法,这是我们之前封装好的一个方法,作用是产生唯一的名称,这个方法加上之前的getExt()方法,组成一个新的文件名称,且这个文件名是唯一的,这个封装好的代码如下,注释也很详细:
/**
* 生成唯一文件名
*/
function getUniName(){
return md5(uniqid(microtime(true),true));
//uniqid(prefix,more_entropy) 函数基于以微秒计的当前时间,生成一个唯一的 ID。
/**md5+uniqid+microtime生成唯一文件名效果特别好
* prefix 可选。为 ID 规定前缀。如果两个脚本恰好在相同的微秒生成 ID,该参数很有用。
*more_entropy 可选。规定位于返回值末尾的更多的熵。
*说明
*如果 prefix 参数为空,则返回的字符串有 13 个字符串长。如果 more_entropy 参数设置为 true,则是 23 个字符串长。
*如果 more_entropy 参数设置为 true,则在返回值的末尾添加额外的熵(使用组合线形同余数生成程序),这样可以结果的唯一性更好。
*microtime() 函数返回当前 Unix 时间戳的微秒数。
*里面的参数可选。当设置为 TRUE 时,规定函数应该返回浮点数,否则返回字符串。默认为 FALSE。
*/
}
注释里唯一没有说明的就是md5()这个函数,这个函数可以用来加密的,因为它的算法是不可逆的,
你就理解为把一个字符串换成另一个字符串就行
到这位置你就可以成功的在upload目录下看到你提交的图片了