PHP如何根据文件头检测文件类型实例代码
程序员文章站
2022-05-05 13:00:10
前言
什么是文件头部bom? 说白了,就是在保存文件的时候,文件前面会多出一串隐藏的字符,文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些...
前言
什么是文件头部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;
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
上一篇: Spring 事务全解析(转)
下一篇: php实现二叉树中和为某一值的路径方法