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

[转载]PHP判断上传文件类型(防修改后缀)

程序员文章站 2024-01-10 14:27:58
...

原文地址:http://justcoding.iteye.com/blog/891241 网上流传着一种说法,用PHP读文件头部两个字节判断文件真实类型,其实这样判断也是不精确的,就拿office的文件类型来说。word以前的格式是storage方式存储,但是现在最新版本的docx是一个zip包。 即使是

原文地址:http://justcoding.iteye.com/blog/891241
网上流传着一种说法,用PHP读文件头部两个字节判断文件真实类型,其实这样判断也是不精确的,就拿office的文件类型来说。word以前的格式是storage方式存储,但是现在最新版本的docx是一个zip包。

即使是以前的storage方式存储的格式,也不能确定就是word文档,因为qq聊天记录也是采用这种方式存储的。所以,如果从文件格式分析的话,将会是很复杂的事情,但是可以实现精确的判断是不是word文档.比如,读取storage结构,判断里面的子节点名字,如果是docx格式,先用zlib解压,再判断里面的xml文件和目录名字,等等,其他office格式类似。

从上面一个简单的判断,我们可以得知,读文件头是不能真实判断文件类型的,判断文件类型,是一个很复杂的工作,下面是php读文件头判断文件类型的代码,但是不精准,可以作为参考。不过,除了office,其他还是挺准的。

function file_type($filename)  
{  
    $file = fopen($filename, "rb");  
    $bin = fread($file, 2); //只读2字节  
    fclose($file);  
    $strInfo = @unpack("C2chars", $bin);  
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);  
    $fileType = '';  
    switch ($typeCode)  
    {  
        case 7790:  
            $fileType = 'exe';  
            break;  
        case 7784:  
            $fileType = 'midi';  
            break;  
        case 8297:  
            $fileType = 'rar';  
            break;          
        case 8075:  
            $fileType = 'zip';  
            break;  
        case 255216:  
            $fileType = 'jpg';  
            break;  
        case 7173:  
            $fileType = 'gif';  
            break;  
        case 6677:  
            $fileType = 'bmp';  
            break;  
        case 13780:  
            $fileType = 'png';  
            break;  
        default:  
            $fileType = 'unknown: '.$typeCode;  
    }  
    //Fix  
    if ($strInfo['chars1']=='-1' AND $strInfo['chars2']=='-40' ) return 'jpg';  
    if ($strInfo['chars1']=='-119' AND $strInfo['chars2']=='80' ) return 'png';  
    return $fileType;  
}  
echo file_type('start.php');   // 6063 or 6033 

但是我不知道反过来定义 6063或者6033 就是指php的话 是不是不够严谨啊。

对于上传文件类型的判断,一直没有太好的办法,即使使用上面的代码,也有办法构造假的图片 的(如何构造不再传播),有人使用getimagesize来判断,不失为一种好办法:

if(in_array($attach['ext'], array('jpg', 'jpeg', 'gif', 'png', 'swf', 'bmp')) 
&& function_exists('getimagesize') 
&& !@getimagesize($target)){  
    unlink($target);  
    upload_error('post_attachment_ext_notallowed', $attacharray);  
}