欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-22 23:14:42
前言 什么是文件头部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;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。