PHP根据文件头检测文件类型
http://www.nowamagic.net/librarys/veda/detail/836
文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些签名信息。如用uestudio以十六进制方式查看zip格式的文件,其文件内容头部有50 4B 03 04这样的十六进制信息。同理jpg文件状况有FF D8 FF E0 xx xx 4A 46这样的十六进制信息,其实这此十六进制都是表示一些特殊字条。
php怎么样验证文件类型?先来看一个简单的方法:
01 |
function checkFileType( $fileName ){
|
02 |
$file
= fopen ( $fileName ,
"rb" ); |
03 |
$bin
= fread ( $file , 2);
//只读2字节 |
04 |
fclose( $file );
|
05 |
// C为无符号整数,网上搜到的都是c,为有符号整数,这样会产生负数判断不正常
|
06 |
$strInfo
= @unpack( "C2chars" ,
$bin ); |
07 |
$typeCode
= intval ( $strInfo [ "chars1" ]. $strInfo [ "chars2" ]);
|
08 |
$fileType
= "" ;
|
09 |
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 |
40 |
$file_name
= "11.doc" ; |
41 |
echo checkFileType( $file_name ); |
下来提供一个类的实现:
01 |
/*通过文件名,获得文件类型* |
02 |
*@author chengmo QQ:8292669* |
03 |
*@copyright <a href="http://www.cnblogs.com/chengmo">http://www.cnblogs.com/chengmo</a> 2010-10-17 |
04 |
*@version 0.1 |
05 |
*$filename="d:/1.png";echo cFileTypeCheck::getFileType($filename); 打印:png |
06 |
*/ |
07 |
class cFileTypeCheck |
08 |
{ |
09 |
private
static $_TypeList = array (); |
10 |
private
static $CheckClass =null; |
11 |
private
function __construct( $filename ) |
12 |
{ |
13 |
self:: $_TypeList = $this ->getTypeList(); |
14 |
} |
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 |
|
31 |
$typelist =self:: $_TypeList ; |
32 |
foreach
( $typelist
as $v ) |
33 |
{ |
34 |
$blen = strlen (pack( "H*" , $v [0]));
//得到文件头标记字节数 |
35 |
$tbin = substr ( $bin ,0, intval ( $blen ));
///需要比较文件头长度 |
36 |
|
37 |
if ( strtolower ( $v [0])== strtolower ( array_shift (unpack( "H*" , $tbin ))))
|
38 |
{ |
39 |
return
$v [1]; |
40 |
} |
41 |
} |
42 |
return
$filetype ; |
43 |
} |
44 |
|
45 |
/** |
46 |
*得到文件头与文件类型映射表* |
47 |
* |
48 |
* @return array array(array("key",value)...) |
49 |
*/ |
50 |
public
function getTypeList() |
51 |
{ |
52 |
return
array ( array ( "FFD8FFE1" , "jpg" ), |
53 |
array ( "89504E47" , "png" ), |
54 |
array ( "47494638" , "gif" ), |
55 |
array ( "49492A00" , "tif" ), |
56 |
array ( "424D" , "bmp" ), |
57 |
array ( "41433130" , "dwg" ), |
58 |
array ( "38425053" , "psd" ), |
59 |
array ( "7B5C727466" , "rtf" ), |
60 |
array ( "3C3F786D6C" , "xml" ), |
61 |
array ( "68746D6C3E" , "html" ), |
62 |
array ( "44656C69766572792D646174" , "eml" ), |
63 |
array ( "CFAD12FEC5FD746F" , "dbx" ), |
64 |
array ( "2142444E" , "pst" ), |
65 |
array ( "D0CF11E0" , "xls/doc" ), |
66 |
array ( "5374616E64617264204A" , "mdb" ), |
67 |
array ( "FF575043" , "wpd" ), |
68 |
array ( "252150532D41646F6265" , "eps/ps" ), |
69 |
array ( "255044462D312E" , "pdf" ), |
70 |
array ( "E3828596" , "pwl" ), |
71 |
array ( "504B0304" , "zip" ), |
72 |
array ( "52617221" , "rar" ), |
73 |
array ( "57415645" , "wav" ), |
74 |
array ( "41564920" , "avi" ), |
75 |
array ( "2E7261FD" , "ram" ), |
76 |
array ( "2E524D46" , "rm" ), |
77 |
array ( "000001BA" , "mpg" ), |
78 |
array ( "000001B3" , "mpg" ), |
79 |
array ( "6D6F6F76" , "mov" ), |
80 |
array ( "3026B2758E66CF11" , "asf" ), |
81 |
array ( "4D546864" , "mid" )); |
82 |
} |
83 |
|
84 |
|
85 |
public
static function
getFileType( $filename ) |
86 |
{ |
87 |
if (!self:: $CheckClass ) self:: $CheckClass = new
self( $filename ); |
88 |
$class =self:: $CheckClass ; |
89 |
return
$class ->_getFileType( $filename ); |
90 |
} |
91 |
|
92 |
} |
93 |
94 |
$filename = "22.jpg" ; |
95 |
echo $filename , "t" ,cFileTypeCheck::getFileType( $filename ), "rn" ; |
96 |
$filename = "11.doc" ; |
97 |
echo $filename , "t" ,cFileTypeCheck::getFileType( $filename ), "rn" ; |
或者可以这么检测:
01 |
$filename =
"22.jpg" ; |
02 |
|
03 |
$extname =
strtolower ( substr ( $filename ,
strrpos ( $filename ,
"." ) + 1)); |
04 |
echo $extname . "<br />" ; |
05 |
$file = @ fopen ( $filename ,
"rb" ); |
06 |
if
( $file ) |
07 |
{ |
08 |
$str
= @ fread ( $file , 0x400);
// 读取前 1024 个字节 |
09 |
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 |
|
79 |
echo
$format ; |
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。