PHP如何根据文件头检测文件类型实例代码


Posted in PHP onOctober 14, 2018

前言

什么是文件头部Bom? 说白了,就是在保存文件的时候,文件前面会多出一串隐藏的字符,文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些签名信息。如用uestudio以十六进制方式查看zip格式的文件,其文件内容头部有50 4B 03 04这样的十六进制信息。同理jpg文件状况有FF D8 FF E0 xx xx 4A 46这样的十六进制信息,其实这此十六进制都是表示一些特殊字条。

php怎么样验证文件类型?

先来看一个简单的方法:

<?php
function checkFileType($fileName){ 
  $file = fopen($fileName, "rb"); 
  $bin = fread($file, 2); //只读2字节 
  fclose($file); 
 // C为无符号整数,网上搜到的都是c,为有符号整数,这样会产生负数判断不正常
  $strInfo = @unpack("C2chars", $bin);
  $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); 
  $fileType = ''; 

 switch( $typeCode )
 {
 case '255216':
 return $typeCode. ' : ' .'jpg';
 break;
 case '7173':
 return $typeCode. ' : ' .'gif';
 break;
 case '13780':
 return $typeCode. ' : ' .'png';
 break;
 case '6677':
 return $typeCode. ' : ' .'bmp';
 break;
 case '7790':
 return $typeCode. ' : ' .'exe';
 break;
 case '7784':
 return $typeCode. ' : ' .'midi';
 break;
 case '8297':
 return $typeCode. ' : ' .'rar';
 break;
 default:
 return $typeCode. ' : ' .'Unknown';
 break;
 }
 //return $typeCode;
 }

$file_name = '11.doc';
echo checkFileType($file_name);

下来提供一个类的实现:

<?php
/*通过文件名,获得文件类型*
 *@author chengmo QQ:8292669*
 *@copyright <a href="http://www.cnblogs.com/chengmo">http://www.cnblogs.com/chengmo</a> 2010-10-17
 *@version 0.1
 *$filename="d:/1.png";echo cFileTypeCheck::getFileType($filename); 打印:png
 */
class cFileTypeCheck
{
  private static $_TypeList=array();
  private static $CheckClass=null;
  private function __construct($filename)
  {
    self::$_TypeList=$this->getTypeList();
  }

  /**
   *处理文件类型映射关系表*
   *
   * @param string $filename 文件类型
   * @return string 文件类型,没有找到返回:other
   */
  private function _getFileType($filename)
  {
    $filetype="other";
    if(!file_exists($filename)) throw new Exception("no found file!");
    $file = @fopen($filename,"rb");
    if(!$file) throw new Exception("file refuse!");
    $bin = fread($file, 15); //只读15字节 各个不同文件类型,头信息不一样。
    fclose($file);

    $typelist=self::$_TypeList;
    foreach ($typelist as $v)
    {
      $blen=strlen(pack("H*",$v[0])); //得到文件头标记字节数
      $tbin=substr($bin,0,intval($blen)); ///需要比较文件头长度

      if(strtolower($v[0])==strtolower(array_shift(unpack("H*",$tbin))))
      {
        return $v[1];
      }
    }
    return $filetype;
  }

  /**
   *得到文件头与文件类型映射表*
   *
   * @return array array(array('key',value)...)
   */
  public function getTypeList()
  {
    return array(array("FFD8FFE1","jpg"),
    array("89504E47","png"),
    array("47494638","gif"),
    array("49492A00","tif"),
    array("424D","bmp"),
    array("41433130","dwg"),
    array("38425053","psd"),
    array("7B5C727466","rtf"),
    array("3C3F786D6C","xml"),
    array("68746D6C3E","html"),
    array("44656C69766572792D646174","eml"),
    array("CFAD12FEC5FD746F","dbx"),
    array("2142444E","pst"),
    array("D0CF11E0","xls/doc"),
    array("5374616E64617264204A","mdb"),
    array("FF575043","wpd"),
    array("252150532D41646F6265","eps/ps"),
    array("255044462D312E","pdf"),
    array("E3828596","pwl"),
    array("504B0304","zip"),
    array("52617221","rar"),
    array("57415645","wav"),
    array("41564920","avi"),
    array("2E7261FD","ram"),
    array("2E524D46","rm"),
    array("000001BA","mpg"),
    array("000001B3","mpg"),
    array("6D6F6F76","mov"),
    array("3026B2758E66CF11","asf"),
    array("4D546864","mid"));
  }


  public static function getFileType($filename)
  {
    if(!self::$CheckClass) self::$CheckClass=new self($filename);
    $class=self::$CheckClass;
    return $class->_getFileType($filename);
  }

}

$filename="22.jpg";
echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn";
$filename="11.doc";
echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn";

或者可以这么检测:

<?php
$filename = '22.jpg';

$extname = strtolower(substr($filename, strrpos($filename, '.') + 1));
echo $extname.'<br />';
$file = @fopen($filename, 'rb');
  if ($file)
  {
    $str = @fread($file, 0x400); // 读取前 1024 个字节
 echo substr($str, 0, 4);
    @fclose($file);
  }
 if (substr($str, 0, 4) == 'MThd' && $extname != 'txt')
    {
      $format = 'mid';
    }
    elseif (substr($str, 0, 4) == 'RIFF' && $extname == 'wav')
    {
      $format = 'wav';
    }
    elseif (substr($str ,0, 3) == "/xFF/xD8/xFF")
    {
      $format = 'jpg';
    }
    elseif (substr($str ,0, 4) == 'GIF8' && $extname != 'txt')
    {
      $format = 'gif';
    }
    elseif (substr($str ,0, 8 ) == "/x89/x50/x4E/x47/x0D/x0A/x1A/x0A")
    {
      $format = 'png';
    }
    elseif (substr($str ,0, 2) == 'BM' && $extname != 'txt')
    {
      $format = 'bmp';
    }
    elseif ((substr($str ,0, 3) == 'CWS' || substr($str ,0, 3) == 'FWS') && $extname != 'txt')
    {
      $format = 'swf';
    }
    elseif (substr($str ,0, 4) == "/xD0/xCF/x11/xE0")
    {  // D0CF11E == DOCFILE == Microsoft Office Document
      if (substr($str,0x200,4) == "/xEC/xA5/xC1/x00" || $extname == 'doc')
      {
        $format = 'doc';
      }
      elseif (substr($str,0x200,2) == "/x09/x08" || $extname == 'xls')
      {
        $format = 'xls';
      } elseif (substr($str,0x200,4) == "/xFD/xFF/xFF/xFF" || $extname == 'ppt')
      {
        $format = 'ppt';
      }
    } elseif (substr($str ,0, 4) == "PK/x03/x04")
    {
      $format = 'zip';
    } elseif (substr($str ,0, 4) == 'Rar!' && $extname != 'txt')
    {
      $format = 'rar';
    } elseif (substr($str ,0, 4) == "/x25PDF")
    {
      $format = 'pdf';
    } elseif (substr($str ,0, 3) == "/x30/x82/x0A")
    {
      $format = 'cert';
    } elseif (substr($str ,0, 4) == 'ITSF' && $extname != 'txt')
    {
      $format = 'chm';
    } elseif (substr($str ,0, 4) == "/x2ERMF")
    {
      $format = 'rm';
    } elseif ($extname == 'sql')
    {
      $format = 'sql';
    } elseif ($extname == 'txt')
    {
      $format = 'txt';
    }

 echo $format;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
为php4加入动态flash文件的生成的支持
Oct 09 PHP
基于mysql的bbs设计(一)
Oct 09 PHP
别人整理的服务器变量:$_SERVER
Oct 20 PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 PHP
php实现微信公众号主动推送消息
Dec 31 PHP
PHP使用trim函数去除字符串左右空格及特殊字符实例
Jan 07 PHP
PHP的mysqli_set_charset()函数讲解
Jan 23 PHP
Laravel框架查询构造器 CURD操作示例
Sep 04 PHP
Laravel中正确地返回HTTP状态码方法示例
Sep 10 PHP
Laravel 模型使用软删除-左连接查询-表起别名示例
Oct 24 PHP
PHP高并发和大流量解决方案整理
Dec 24 PHP
PHP时间类完整代码实例
Feb 26 PHP
PHP5.0 TIDY_PARSE_FILE缓冲区溢出漏洞的解决方案
Oct 14 #PHP
PHP按一定比例压缩图片的方法
Oct 12 #PHP
PHP实现图片压缩
Sep 09 #PHP
PHP获取数据库表中的数据插入新的表再原删除数据方法
Oct 12 #PHP
thinkphp5.0整合phpsocketio完整攻略(绕坑)
Oct 12 #PHP
PHP解析url并得到url参数方法总结
Oct 11 #PHP
详细对比php中类继承和接口继承
Oct 11 #PHP
You might like
php实现用户在线时间统计详解
2011/10/08 PHP
php配合jquery实现增删操作具体实例
2013/12/12 PHP
php实现分页显示
2015/11/03 PHP
Javascript实例教程(19) 使用HoTMetal(4)
2006/12/23 Javascript
javascript flash下fromCharCode和charCodeAt方法使用说明
2008/01/12 Javascript
javascript定义函数的方法
2010/12/06 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
2013/11/22 Javascript
css3元素简单的闪烁效果实现(html5 jquery)
2013/12/28 Javascript
让checkbox不选中即将选中的checkbox不选中
2014/07/11 Javascript
Javascript实现字数统计
2015/07/03 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
2016/05/25 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
实例详解display:none与visible:hidden的区别
2017/03/30 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
Js利用Canvas实现图片压缩功能
2017/09/13 Javascript
浅谈webpack 自动刷新与解析
2018/04/09 Javascript
koa大型web项目中使用路由装饰器的方法示例
2019/04/02 Javascript
VSCode使用之Vue工程配置eslint
2019/04/30 Javascript
策略模式实现 Vue 动态表单验证的方法
2019/09/16 Javascript
layui-tree实现Ajax异步请求后动态添加节点的方法
2019/09/23 Javascript
Vue3.x源码调试的实现方法
2019/10/13 Javascript
pyqt4教程之实现半透明的天气预报界面示例
2014/03/02 Python
深入浅析python定时杀进程
2016/06/06 Python
Python 多线程的实例详解
2017/09/07 Python
python实现识别手写数字 python图像识别算法
2020/03/23 Python
Python读取Word(.docx)正文信息的方法
2018/03/15 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
2018/04/02 Python
浅谈matplotlib 绘制梯度下降求解过程
2020/07/12 Python
工商学院毕业生个人自我评价
2013/09/19 职场文书
最新销售员个人自荐信
2013/09/21 职场文书
幼儿园保教管理制度
2014/02/03 职场文书
彩色的非洲教学反思
2014/02/18 职场文书
师德师风演讲稿
2014/05/05 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
捐资助学感谢信
2015/01/21 职场文书
python使用tkinter实现透明窗体上绘制随机出现的小球(实例代码)
2021/05/17 Python