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 相关文章推荐
php 截取字符串并以零补齐str_pad() 函数
May 07 PHP
php实现过滤表单提交中html标签的方法
Oct 17 PHP
页面利用渐进式JPEG来提升用户体验度
Dec 01 PHP
yii中widget的用法
Dec 03 PHP
PHP中捕获超时事件的方法实例
Feb 12 PHP
PHP IDE PHPStorm配置支持友好Laravel代码提示方法
May 12 PHP
使用Thinkphp框架开发移动端接口
Aug 05 PHP
在CentOS系统上从零开始搭建WordPress博客的全流程记录
Apr 21 PHP
yii插入数据库防并发的简单代码
May 27 PHP
php表单文件iframe异步上传实例讲解
Jul 26 PHP
PHP常见字符串操作函数与用法总结
Mar 04 PHP
laravel 去掉index.php伪静态的操作方法
Oct 12 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 接口类与抽象类的实际作用
2009/11/26 PHP
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
Codeigniter框架实现获取分页数据和总条数的方法
2014/12/05 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
PHP registerXPathNamespace()函数讲解
2019/02/03 PHP
juqery 学习之五 文档处理 插入
2011/02/11 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
深入理解JavaScript编程中的同步与异步机制
2015/06/24 Javascript
动态加载jQuery的两种方法实例分析
2015/07/17 Javascript
jQuery Validate初步体验(一)
2015/12/12 Javascript
AngularJS 避繁就简的路由
2016/07/01 Javascript
jQuery如何封装输入框插件
2016/08/19 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
Vue 路由切换时页面内容没有重新加载的解决方法
2018/09/01 Javascript
微信小程序实现录音时的麦克风动画效果实例
2019/05/18 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
2020/09/21 Javascript
Ant Design Pro 之 ProTable使用操作
2020/10/31 Javascript
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
Python输出带颜色的字符串实例
2017/10/10 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
Python confluent kafka客户端配置kerberos认证流程详解
2020/10/12 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
Crocs卡骆驰洞洞鞋日本官方网站:Crocs日本
2016/08/25 全球购物
全球在线商店:BerryLook
2019/04/14 全球购物
什么是命名空间(NameSpace)
2015/11/24 面试题
外国语学院毕业生自荐信
2013/10/28 职场文书
事假请假条范文
2014/04/11 职场文书
营销总监岗位职责
2014/09/16 职场文书
python实现高效的遗传算法
2021/04/07 Python
详解Java实践之适配器模式
2021/06/18 Java/Android
javascript的setTimeout()使用方法总结
2021/11/20 Javascript
漫改真人电影「萌系男友是燃燃的橘色」公开先导视觉图
2022/03/21 日漫
IDEA中sout快捷键无效问题的解决方法
2022/07/23 Java/Android