利用PHP实现智能文件类型检测的实现代码


Posted in PHP onAugust 02, 2011

使用文件后缀和MIME类型检测
通常我们想严格限制文件类型的时候,可以简单地用$_FILES['myFile']['type']  取得文件的 MIME类型然后来检测它是否是合法的类型。
或者我们可以取文件名的最后几个字符来获取文件后缀,不幸的是,这些方法并不足够,可以很容易地改变文件的扩展名绕过这个限制。此外,MIME类型信息是由浏览器发送的,而且,对于大多数浏览器,即使不是全部,是根据文件的扩展名的来给出MIME类型信息的!因此,MIME类型,就像扩展名一样,可以很容易地欺骗。
使用“魔术字节”
确定文件类型的最佳方法是通过检查文件的前几个字节 ? 称为“魔字节”。魔术字节本质上是文件头中不同长度在2到40个字节之间的,或在文件末尾的签名。有上百个类型的文件,他们中相当多的文件类型有好几个文件签名与它们相关联。在这里你可以看到一个文件签名列表。
偷懒的办法是使用fileinfo扩展,PHP 5.3.0 默认是启用的(根据官方MANUAL),如果没有启用,你可以自己启用
如在windows下面:

extension=php_fileinfo.dll

linux下面:

extension=fileinfo.so 
#如不能正常工作,再加上下面这条 
#mime_magic.magicfile=/usr/share/file/magic

windows下面如不能正常工作:
可参考:http://www.php.net/manual/en/fileinfo.installation.php#82570
下载file-5.03-bin.zip ,解压出来,在其中的share目录有magic.mgc 、magic 两个文件。
然后添加一个名为MAGIC的系统环境变量指向magic 文件。如D:\software\PHP\extras\misc\magic  

function getFileMimeType($file) { 
$buffer = file_get_contents($file); 
$finfo = new finfo(FILEINFO_MIME_TYPE); 
return $finfo->buffer($buffer); 
} 
$mime_type = getFileMimeType($file); 
switch($mime_type) { 
case "image/jpeg": 
// your actions go here... 
}

处理图像上传
如果你打算只允许图像上传,那么你可以使用内置的getimagesize()函数,以确保用户实际上是上传一个有效的图像文件。如果该文件不是有效的图像文件,这个函数返回false。
// 假设file input 域的name 属性为myfile 
$tempFile = $_FILES['myFile']['tmp_name']; // path of the temp file created by PHP during upload 
$imginfo_array = getimagesize($tempFile); // returns a false if not a valid image file 
if ($imginfo_array !== false) { 
$mime_type = $imginfo_array['mime']; 
switch($mime_type) { 
case "image/jpeg": 
// your actions go here... 
} 
} 
else { 
echo "This is not a valid image file"; 
}

手动读取和解释“魔法字节”
如果由于某种原因,你不能安装FileInfo扩展,那么你仍然可以手动确定,通过读取文件的前几个字节,并比较它们与已知的魔法与特定文件类型相关联的字节的文件类型。这个过程肯定少许的试验和错误,因为还有一种可能,有少数非法的魔法字节与合法文件格式关联了。
然而这不是不可能的,几年前,我被要求做一个只允许真正的 mp3 文件上传的脚本文件,并且,当时我们不能用 Fileinfo, 我们只能依靠这种手动检测的方式了.
我花了一段时间来解析一些mp3文件的非法魔法字节,但很快,我得到了一个稳定的上传脚本。
在本文结束前,我想给大家一个警告: 确保你永远没有调用一个 include() 来包含一个上传的文件,因为PHP代码很可能会巧妙地隐藏在图片里面,并且图片也可以成功的通过你的文件检测,当这样的脚本运行时,只可能给系统带来破坏。
译自:http://designshack.co.uk/articles/php-articles/smart-file-type-detection-using-php/
PHP 相关文章推荐
php下使用无限生命期Session的方法
Mar 16 PHP
Linux下实现PHP多进程的方法分享
Aug 16 PHP
php连接mssql的一些相关经验及注意事项
Feb 05 PHP
一个简单的php加密解密函数(动态加密)
Jun 19 PHP
ThinkPHP3.1新特性之命名范围的使用
Jun 19 PHP
PHP中常用的输出函数总结
Sep 22 PHP
thinkphp实现上一篇与下一篇的方法
Dec 08 PHP
PHP判断一个字符串是否是回文字符串的方法
Mar 23 PHP
php计划任务之验证是否有多个进程调用同一个job的方法
Dec 07 PHP
php 生成加密公钥加密私钥实例详解
Jun 16 PHP
php连接sftp的作用以及实例代码
Sep 23 PHP
Laravel实现通过blade模板引擎渲染视图
Oct 25 PHP
10条PHP高级技巧[修正版]
Aug 02 #PHP
PHP获取url的函数代码
Aug 02 #PHP
给初学者的30条PHP最佳实践(荒野无灯)
Aug 02 #PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
Aug 02 #PHP
linux下使用ThinkPHP需要注意大小写导致的问题
Aug 02 #PHP
理解和运用PHP中的多态性[译]
Aug 02 #PHP
应用开发中涉及到的css和php笔记分享
Aug 02 #PHP
You might like
如何突破PHP程序员的技术瓶颈分析
2011/07/17 PHP
php中定时计划任务的实现原理
2013/01/08 PHP
解析htaccess伪静态的规则
2013/06/18 PHP
浅析PHP绘图技术
2013/07/03 PHP
php+mysql数据库实现无限分类的方法
2014/12/12 PHP
php简单获取文件扩展名的方法
2015/03/24 PHP
php封装的mongodb操作类代码
2017/08/06 PHP
PHP闭包定义与使用简单示例
2018/04/13 PHP
laravel框架模板之公共模板、继承、包含实现方法分析
2019/08/30 PHP
jquery弹出框的用法示例(2)
2013/08/26 Javascript
三种取消选中单选框radio的方法
2014/09/09 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
2015/06/05 Javascript
手机端转盘抽奖代码分享
2015/09/10 Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
2016/01/26 Javascript
JavaScript中数组去除重复的三种方法
2016/04/22 Javascript
第一章之初识Bootstrap
2016/04/25 Javascript
14 个折磨人的 JavaScript 面试题
2016/08/08 Javascript
关于jquery中动态增加select,事件无效的快速解决方法
2016/08/29 Javascript
JS分页的实现(同步与异步)
2017/09/16 Javascript
详解element-ui表格中勾选checkbox,高亮当前行
2019/09/02 Javascript
python 判断一个进程是否存在
2009/04/09 Python
Python引用模块和查找模块路径
2016/03/17 Python
python数据类型_字符串常用操作(详解)
2017/05/30 Python
tensorboard 可以显示graph,却不能显示scalar的解决方式
2020/02/15 Python
详解用Python进行时间序列预测的7种方法
2020/03/13 Python
Python如何获取文件指定行的内容
2020/05/27 Python
解决tensorflow读取本地MNITS_data失败的原因
2020/06/22 Python
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
酒店员工检讨书
2014/02/18 职场文书
售前工程师职业生涯规划
2014/03/02 职场文书
电子商务专业求职信范文
2015/03/19 职场文书
出纳2015年度工作总结范文
2015/10/14 职场文书
导游词之山海关
2019/12/10 职场文书
Java反应式框架Reactor中的Mono和Flux
2021/07/25 Java/Android
Go语言并发编程 sync.Once
2021/10/16 Golang
Spring Cloud OAuth2实现自定义token返回格式
2022/06/25 Java/Android