php上传图片,解决in_array无效的问题,以及判断图片格式类型

首先是一个包含表单的页面,这里只写一个表单
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目录下看到你提交的图片了

猜你喜欢

转载自blog.csdn.net/wry_developer/article/details/75332373