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

这篇文章主要给大家介绍了关于PHP如何根据文件头检测文件类型的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用php具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

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

php怎么样验证文件类型?

先来看一个简单的方法:

  1. <?php
  2. function checkFileType($fileName){
  3. $file = fopen($fileName, "rb");
  4. $bin = fread($file, 2); //只读2字节
  5. fclose($file);
  6. // C为无符号整数,网上搜到的都是c,为有符号整数,这样会产生负数判断不正常
  7. $strInfo = @unpack("C2chars", $bin);
  8. $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
  9. $fileType = '';
  10. switch( $typeCode )
  11. {
  12. case '255216':
  13. return $typeCode. ' : ' .'jpg';
  14. break;
  15. case '7173':
  16. return $typeCode. ' : ' .'gif';
  17. break;
  18. case '13780':
  19. return $typeCode. ' : ' .'png';
  20. break;
  21. case '6677':
  22. return $typeCode. ' : ' .'bmp';
  23. break;
  24. case '7790':
  25. return $typeCode. ' : ' .'exe';
  26. break;
  27. case '7784':
  28. return $typeCode. ' : ' .'midi';
  29. break;
  30. case '8297':
  31. return $typeCode. ' : ' .'rar';
  32. break;
  33. default:
  34. return $typeCode. ' : ' .'Unknown';
  35. break;
  36. }
  37. //return $typeCode;
  38. }
  39. $file_name = '11.doc';
  40. echo checkFileType($file_name);

下来提供一个类的实现:

  1. <?php
  2. /*通过文件名,获得文件类型*
  3. *@author chengmo QQ:8292669*
  4. *@copyright <a href="http://www.cnblogs.com/chengmo">http://www.cnblogs.com/chengmo</a> 2010-10-17
  5. *@version 0.1
  6. *$filename="d:/1.png";echo cFileTypeCheck::getFileType($filename); 打印:png
  7. */
  8. class cFileTypeCheck
  9. {
  10. private static $_TypeList=array();
  11. private static $CheckClass=null;
  12. private function __construct($filename)
  13. {
  14. self::$_TypeList=$this->getTypeList();
  15. }
  16. /**
  17. *处理文件类型映射关系表*
  18. *
  19. * @param string $filename 文件类型
  20. * @return string 文件类型,没有找到返回:other
  21. */
  22. private function _getFileType($filename)
  23. {
  24. $filetype="other";
  25. if(!file_exists($filename)) throw new Exception("no found file!");
  26. $file = @fopen($filename,"rb");
  27. if(!$file) throw new Exception("file refuse!");
  28. $bin = fread($file, 15); //只读15字节 各个不同文件类型,头信息不一样。
  29. fclose($file);
  30. $typelist=self::$_TypeList;
  31. foreach ($typelist as $v)
  32. {
  33. $blen=strlen(pack("H*",$v[0])); //得到文件头标记字节数
  34. $tbin=substr($bin,0,intval($blen)); ///需要比较文件头长度
  35. if(strtolower($v[0])==strtolower(array_shift(unpack("H*",$tbin))))
  36. {
  37. return $v[1];
  38. }
  39. }
  40. return $filetype;
  41. }
  42. /**
  43. *得到文件头与文件类型映射表*
  44. *
  45. * @return array array(array('key',value)...)
  46. */
  47. public function getTypeList()
  48. {
  49. return array(array("FFD8FFE1","jpg"),
  50. array("89504E47","png"),
  51. array("47494638","gif"),
  52. array("49492A00","tif"),
  53. array("424D","bmp"),
  54. array("41433130","dwg"),
  55. array("38425053","psd"),
  56. array("7B5C727466","rtf"),
  57. array("3C3F786D6C","xml"),
  58. array("68746D6C3E","html"),
  59. array("44656C69766572792D646174","eml"),
  60. array("CFAD12FEC5FD746F","dbx"),
  61. array("2142444E","pst"),
  62. array("D0CF11E0","xls/doc"),
  63. array("5374616E64617264204A","mdb"),
  64. array("FF575043","wpd"),
  65. array("252150532D41646F6265","eps/ps"),
  66. array("255044462D312E","pdf"),
  67. array("E3828596","pwl"),
  68. array("504B0304","zip"),
  69. array("52617221","rar"),
  70. array("57415645","wav"),
  71. array("41564920","avi"),
  72. array("2E7261FD","ram"),
  73. array("2E524D46","rm"),
  74. array("000001BA","mpg"),
  75. array("000001B3","mpg"),
  76. array("6D6F6F76","mov"),
  77. array("3026B2758E66CF11","asf"),
  78. array("4D546864","mid"));
  79. }
  80. public static function getFileType($filename)
  81. {
  82. if(!self::$CheckClass) self::$CheckClass=new self($filename);
  83. $class=self::$CheckClass;
  84. return $class->_getFileType($filename);
  85. }
  86. }
  87. $filename="22.jpg";
  88. echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn";
  89. $filename="11.doc";
  90. echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn";

或者可以这么检测:

  1. <?php
  2. $filename = '22.jpg';
  3. $extname = strtolower(substr($filename, strrpos($filename, '.') + 1));
  4. echo $extname.'<br />';
  5. $file = @fopen($filename, 'rb');
  6. if ($file)
  7. {
  8. $str = @fread($file, 0x400); // 读取前 1024 个字节
  9. echo substr($str, 0, 4);
  10. @fclose($file);
  11. }
  12. if (substr($str, 0, 4) == 'MThd' && $extname != 'txt')
  13. {
  14. $format = 'mid';
  15. }
  16. elseif (substr($str, 0, 4) == 'RIFF' && $extname == 'wav')
  17. {
  18. $format = 'wav';
  19. }
  20. elseif (substr($str ,0, 3) == "/xFF/xD8/xFF")
  21. {
  22. $format = 'jpg';
  23. }
  24. elseif (substr($str ,0, 4) == 'GIF8' && $extname != 'txt')
  25. {
  26. $format = 'gif';
  27. }
  28. elseif (substr($str ,0, 8 ) == "/x89/x50/x4E/x47/x0D/x0A/x1A/x0A")
  29. {
  30. $format = 'png';
  31. }
  32. elseif (substr($str ,0, 2) == 'BM' && $extname != 'txt')
  33. {
  34. $format = 'bmp';
  35. }
  36. elseif ((substr($str ,0, 3) == 'CWS' || substr($str ,0, 3) == 'FWS') && $extname != 'txt')
  37. {
  38. $format = 'swf';
  39. }
  40. elseif (substr($str ,0, 4) == "/xD0/xCF/x11/xE0")
  41. { // D0CF11E == DOCFILE == Microsoft Office Document
  42. if (substr($str,0x200,4) == "/xEC/xA5/xC1/x00" || $extname == 'doc')
  43. {
  44. $format = 'doc';
  45. }
  46. elseif (substr($str,0x200,2) == "/x09/x08" || $extname == 'xls')
  47. {
  48. $format = 'xls';
  49. } elseif (substr($str,0x200,4) == "/xFD/xFF/xFF/xFF" || $extname == 'ppt')
  50. {
  51. $format = 'ppt';
  52. }
  53. } elseif (substr($str ,0, 4) == "PK/x03/x04")
  54. {
  55. $format = 'zip';
  56. } elseif (substr($str ,0, 4) == 'Rar!' && $extname != 'txt')
  57. {
  58. $format = 'rar';
  59. } elseif (substr($str ,0, 4) == "/x25PDF")
  60. {
  61. $format = 'pdf';
  62. } elseif (substr($str ,0, 3) == "/x30/x82/x0A")
  63. {
  64. $format = 'cert';
  65. } elseif (substr($str ,0, 4) == 'ITSF' && $extname != 'txt')
  66. {
  67. $format = 'chm';
  68. } elseif (substr($str ,0, 4) == "/x2ERMF")
  69. {
  70. $format = 'rm';
  71. } elseif ($extname == 'sql')
  72. {
  73. $format = 'sql';
  74. } elseif ($extname == 'txt')
  75. {
  76. $format = 'txt';
  77. }
  78. echo $format;