宜昌本地软件开发与弱电工程服务商
项目咨询 · 快速响应

[PHP]用PHP程序判断上传文件类型的方法

2016-10-13 00:16:48 点击量:57 标签: 收藏本文

     网上流传着一种说法,用PHP读文件头部两个字节判断文件真实类型,其实这样判断也是不精确的,就拿office的文件类型来说。

      word以前的格式是storage方式存储,但是现在最新版本的docx是一个zip包。

      即使是以前的storage方式存储的格式,也不能确定就是word文档,因为qq聊天记录也是采用这种方式存储的。所以,如果从文件格式分析的话,将会是很复杂的事情,但是可以实现精确的判断是不是word文档

      比如,读取storage结构,判断里面的子节点名字,如果是docx格式,先用zlib解压,再判断里面的xml文件和目录名字,等等,其他office格式类似。

      从上面一个简单的判断,我们可以得知,读文件头是不能真实判断文件类型的,判断文件类型,是一个很复杂的工作,下面是php读文件头判断文件类型的代码,但是不精准,可以作为参考。不过,除了office,其他还是挺准的。

  1. <?php    
  2. function file_type($filename) 
  3. { 
  4.     $file = fopen($filename, "rb"); 
  5.     $bin = fread($file, 2); //CuPlauyer.com提示:只读2字节 
  6.     fclose($file); 
  7.     $strInfo = @unpack("C2chars", $bin); 
  8.     $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); 
  9.     $fileType = ''; 
  10.     switch ($typeCode) 
  11.     { 
  12.         case 7790: 
  13.             $fileType = 'exe'; 
  14.             break; 
  15.         case 7784: 
  16.             $fileType = 'midi'; 
  17.             break; 
  18.         case 8297: 
  19.             $fileType = 'rar'; 
  20.             break;         
  21.         case 8075: 
  22.             $fileType = 'zip'; 
  23.             break; 
  24.         case 255216: 
  25.             $fileType = 'jpg'; 
  26.             break; 
  27.         case 7173: 
  28.             $fileType = 'gif'; 
  29.             break; 
  30.         case 6677: 
  31.             $fileType = 'bmp'; 
  32.             break; 
  33.         case 13780: 
  34.             $fileType = 'png'; 
  35.             break; 
  36.         default: 
  37.             $fileType = 'unknown: '.$typeCode; 
  38.     } 
  39.  
  40.     //CuPlauyer.com提示:Fix 
  41.     if ($strInfo['chars1']=='-1' AND $strInfo['chars2']=='-40' ) return 'jpg'; 
  42.     if ($strInfo['chars1']=='-119' AND $strInfo['chars2']=='80' ) return 'png'; 
  43.  
  44.     return $fileType; 
  45. } 
  46.  
  47. echo file_type('start.php');   // 6063 or 6033 

但是我不知道反过来定义 6063或者6033 就是指php的话 是不是不够严谨啊。

对于上传文件类型的判断,一直没有太好的办法,即使使用上面的代码,也有办法构造假的图片 的(如何构造不再传播),有人使用getimagesize来判断,不失为一种好办法:

  1. if(in_array($attach['ext'], array('jpg', 'jpeg', 'gif', 'png', 'swf', 'bmp')) && function_exists('getimagesize') && !@getimagesize($target))  
  2. { 
  3.     unlink($target); 
  4.     upload_error('post_attachment_ext_notallowed', $attacharray); 
  5. }