PHP如何根據(jù)文件頭檢測文件類型實例代碼
前言
什么是文件頭部Bom? 說白了,就是在保存文件的時候,文件前面會多出一串隱藏的字符,文件簽名一般都在文件的頭部,如果你用十六進(jìn)制方式查看文件,你就可以看到文件的一些簽名信息。如用uestudio以十六進(jìn)制方式查看zip格式的文件,其文件內(nèi)容頭部有50 4B 03 04這樣的十六進(jìn)制信息。同理jpg文件狀況有FF D8 FF E0 xx xx 4A 46這樣的十六進(jìn)制信息,其實這此十六進(jìn)制都是表示一些特殊字條。
php怎么樣驗證文件類型?
先來看一個簡單的方法:
<?php
function checkFileType($fileName){
$file = fopen($fileName, "rb");
$bin = fread($file, 2); //只讀2字節(jié)
fclose($file);
// C為無符號整數(shù),網(wǎng)上搜到的都是c,為有符號整數(shù),這樣會產(chǎn)生負(fù)數(shù)判斷不正常
$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);
下來提供一個類的實現(xiàn):
<?php
/*通過文件名,獲得文件類型*
*@author chengmo QQ:8292669*
*@copyright <a >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();
}
/**
*處理文件類型映射關(guān)系表*
*
* @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字節(jié) 各個不同文件類型,頭信息不一樣。
fclose($file);
$typelist=self::$_TypeList;
foreach ($typelist as $v)
{
$blen=strlen(pack("H*",$v[0])); //得到文件頭標(biāo)記字節(jié)數(shù)
$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 個字節(jié)
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;
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
php中操作memcached緩存進(jìn)行增刪改查數(shù)據(jù)的實現(xiàn)代碼
這篇文章主要介紹了php中操作memcached緩存進(jìn)行增刪改查數(shù)據(jù)的實現(xiàn)代碼,需要的朋友可以參考下2014-08-08
PHP下編碼轉(zhuǎn)換函數(shù)mb_convert_encoding與iconv的使用說明
mb_convert_encoding這個函數(shù)是用來轉(zhuǎn)換編碼的。原來一直對程序編碼這一概念不理解,不過現(xiàn)在好像有點開竅了。2009-12-12
php Illegal string offset 'name&apo
這篇文章主要介紹了php Illegal string offset 'name'問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
總結(jié)的一些PHP開發(fā)中的tips(必看篇)
下面小編就為大家?guī)硪黄偨Y(jié)的一些PHP開發(fā)中的tips(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
PHP采用get獲取url漢字出現(xiàn)亂碼的解決方法
這篇文章主要介紹了PHP采用get獲取url漢字出現(xiàn)亂碼的解決方法,是很多PHP程序員都曾遇到的問題,非常具有實用價值,需要的朋友可以參考下2014-11-11
解決PHP4.0 和 PHP5.0類構(gòu)造函數(shù)的兼容問題
以下是對解決PHP4.0和PHP5.0類構(gòu)造函數(shù)兼容問題的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考一下2013-08-08

