学习PHP中Fileinfo扩展的使用
今天来学习的这个扩展其实现在也已经是标配的一个扩展了,为什么呢?因为 Laravel 框架在安装的时候它就是必须的一个扩展,没有打开它的话,连 Laravel 框架都是无法使用的。
Fileinfo 介绍
Fileinfo 是通过给定的 magic 字节序列库来获得文件的内容类型及编码。它所获取的序列库是根据操作系统来定的,比如在 Linux 系统中默认使用的就是 /usr/share/misc/magic 这个文件。其实我们就是可以用这个扩展的函数来获得文件的 MIME 信息,就像我们常见的 image/png 、 text/html 这些内容。
Fileinfo 这个扩展也是为了兼容新老开发模式,所以提供了面向过程和面向对象的两种形式,我们先来看看面向对象的形式如何使用。
面向对象使用
$finfo = new finfo(FILEINFO_MIME);
echo $finfo->file("./1.PHP中的日期相关函数(三).php"), PHP_EOL;
// text/x-php; charset=us-ascii
echo $finfo->buffer(file_get_contents("https://www.baidu.com")) . "\n";
// text/html; charset=utf-8
$finfo->set_flags(FILEINFO_EXTENSION);
echo $finfo->file('timg.jpeg') . "\n";
// jpeg/jpg/jpe/jfif
首先,我们通过 new 一个 finfo 类来获得文件操作对象,参数中的常量是可选的,默认情况下是 FILEINFO_NONE ,代表无特殊处理,这里我们使用的是 FILEINFO_MIME 表明按照 RFC2045 定义的格式返回文件 mime 类型和编码。
然后使用 file() 方法,就可以获得指定文件的 mime 信息了。buffer() 方法则是返回字符串内容的信息,比如我们获取一个网页信息的内容,就能够得到它的字符串代表的文件编码格式为 text/hmtl 。set_flags() 方法是可以在实例化对象之后修改它的构造参数属性,也就是我们在实例化时设置的那个参数信息,在这里我们将它修改为 FILEINFO_EXTENSION ,也就是让 finfo 对象返回文件可能的扩展名。我们使用一张图片进行测试,返回的可能扩展名就包括注释中展示的这些。
面向过程
针对上面面向对象的代码,我们也展示一下相同的操作使用面向过程的函数是如何运行的。
$finfo = finfo_open(FILEINFO_MIME);
echo finfo_file($finfo,"./1.PHP中的日期相关函数(三).php"), PHP_EOL;
// text/x-php; charset=us-ascii
echo finfo_buffer($finfo, file_get_contents("https://www.baidu.com")), PHP_EOL;
// text/html; charset=utf-8
finfo_set_flags($finfo, FILEINFO_EXTENSION);
echo finfo_file($finfo, 'timg.jpeg') . "\n";
// jpeg/jpg/jpe/jfif
finfo_close($finfo);
可以看出,这里就是将 finfo 对象换成了 finfo_open() 方法来获得一个 finfo 操作句柄。之后使用类似的 finfo_file() 、 finfo_buffer() 、 finfo_set_flags() 函数来进行操作,实现的效果和上面的面向对象的结果是一样的。
需要注意的,面向过程的写法是有一个 finfo_close() 方法的,一般对于句柄类型的操作都会有一个关闭的函数来释放句柄资源。就像 mysqli 之类的扩展一样,finfo 中也是包含一个这样的函数的,并且只提供面向过程的这个函数,上面的 finfo 类中是没有这样一个 close() 方法的。
快速返回 mime
当然,Fileinfo 扩展也为我们提供了一个快速地返回文件 mime 信息的函数。我们可以不用使用 finfo 对象或者打开一个 finfo 句柄就可以方便快捷地获得一个文件的 mime 信息。
echo mime_content_type('./1.PHP中的日期相关函数(三).php'), PHP_EOL;
// text/x-php
echo mime_content_type('./timg.jpeg'), PHP_EOL;
// image/jpeg
不过 PHP 官方似乎废弃过这个函数,但现在又恢复了它,也就是说并不是特别的推荐使用这个函数。在正式的开发过程中,我们还是不要嫌麻烦,使用 finfo 对象或者 finfo 相关的函数来获得 mime 信息会更靠谱一些。
如果我们确定要判断的文件只是图片类型的话,那么我们还可以用另外一个函数来进行图片文件的 mime 获取。
$image = exif_imagetype("./timg.jpeg");
echo image_type_to_mime_type($image), PHP_EOL;
// image/jpeg
总结
非常简单但是很实用的函数,为什么说它实用呢?上传文件的安全性问题就可以靠它来解决。我们在上传文件的时候,通常会判断文件的后缀名及上传数组中的文件 MIME 类型。不过很多工具是可以在上传过程中修改文件的 MIME 类型的,也就是通过一些抓包工具修改 Content-Type 。而通过 Fileinfo 扩展获得必须是本地或远程已经存在的文件,也就是说不会有上传过程中因为修改传输信息而产生的安全检查绕过问题。
因此,在 Lavarl 框架中,vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php 类中的 mimeType() 方法使用的正是 finfo_file() 这个函数来获取文件的 mime 信息。在它的上传组件中,Laravel 的底层 symfony 框架中,对于上传文件的 MIME 判断也是使用的 finfo_file() 函数,(vendor/symfony/mime/FileinfoMimeTypeGuesser.php) 并没有直接使用正常的上传后的 $_FILES 中的 type 字段。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/5.学习PHP中Fileinfo扩展的使用.php
参考文档:
https://www.php.net/manual/zh/book.fileinfo.php
===============
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
学习PHP中Fileinfo扩展的使用的更多相关文章
- 学习PHP中好玩的Gmagick图像操作扩展的使用
在 PHP 的图像处理领域,要说最出名的 GD 库为什么好,那就是因为它不需要额外安装的别的什么图像处理工具,而且是随 PHP 源码一起发布的,只需要在安装 PHP 的时候添加上编译参数就可以了. G ...
- 学习PHP中的iconv扩展相关函数
想必 iconv 这个扩展的相关函数大家多少都接触过,做为 PHP 的默认扩展它已经存在了很久,也是我们在操作字符编码时经常会使用的函数.不过除了 iconv() 这个函数外,你还知道它的其它函数吗? ...
- 学习PHP中的高精度计时器HRTime扩展
不知道大家还记得在学校的时候体育测试时老师带的秒表吗?当枪声想起时,我们开始跑步,这时秒表启动,当我们跑过终点后,老师会按下按扭记录我们的成绩,这就是一个典型的定时器的应用.今天我们要学习的内容其实就 ...
- 【转发】NPAPI学习(Firefox和Chrome扩展开发 )
NPAPI学习(Firefox和Chrome扩展开发 ) 2011-11-08 14:41:02 by [6yang], 1172 visits, 收藏 | 返回 Firefox和Chrome扩展开发 ...
- lnmp安装fileinfo扩展
1.错误: PHP Fileinfo extension must be installed/enabled to use Intervention Image. 2.原因: 缺少 fileinfo扩 ...
- LINQ学习系列-----1.3 扩展方法
这篇内容继续接着昨天的Lambda表达式的源码继续下去.昨天讲了Lambda表达式,此篇讲扩展方法,这两点都是Linq带来的新特性. 一.扩展方法介绍 废话不多说,先上源码截图: 上图中Ge ...
- Android学习开发中如何保持API的兼容
Android学习开发中如何保持API的兼容: 1,采用良好的设计思路 在设计过程中,如果能按照下面的方式来进行设计,会让这个API生命更长久 面向用例的设计,收集用户建议,把自己模拟成用户,保证AP ...
- AutoCAD中的扩展字典及扩展记录(C#)
在学习CAD扩展记录的过程中,遇到了一些问题,也积累了一些经验,现在给大家分享一些我的学习心得.在学习扩展字典之前需要读者了解cad的组码,也就是DxfCode.感兴趣的也可以了解一下扩展数据的相关内 ...
- linux 安装 PHP fileinfo 扩展
将windows解压Linux服务器 1.错误: PHP Fileinfo extension must be installed/enabled to use Intervention Image. ...
随机推荐
- Java 常用类库与技巧【笔记】
Java 常用类库与技巧[笔记] Java异常体系 Java异常相关知识 Java在其创立的时候就设置了比较有效的处理机制,其异常处理机制主要回答了三个问题:what,where,why what表示 ...
- Visio2013安装报错 1935 问题解决
最近安装Visio2013,奈何一直报错,出现1935的错误并且回滚 试了试网上的方法,无论是安装.netframework4.0也好,下载.net修复工具也好,都不行 最后尝试删除一个注册表路径 H ...
- S3C2440—1.熟悉裸机开发板
文章目录 一.板载资源介绍 二.安装驱动及上位机 1.USB的驱动及上位机 2.eop驱动安装 3.安装烧录软件oflash 三.烧写开发板 1.预备知识 2.烧写裸板 3.使用u-boot烧写程序 ...
- 题解—P2898 [USACO08JAN]Haybale Guessing G
pre 首先注意一下翻译里面并没有提到的一点,也是让我没看懂样例的一点,就是这个长度为 \(n\) 的数组里面的数各不相同. 有很多人用并查集写的这道题,题解里面也有一些用线段树写的,不过我认为我的做 ...
- HBuilder mui 手机app开发 Android手机app开发 ios手机app开发 打开新页面 预加载页面 关闭页面
创建子页面 在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题: mui的解决思路是:将需要滚动的区域通过单独的webview实 ...
- 05.SpringMVC之请求映射
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. @RequestMapping注解有六个属性,下面进 ...
- BeanUtils实现对象拷贝(三)
package beanutil; import java.lang.reflect.InvocationTargetException; import java.util.Date; import ...
- ProjectEuler 009题
题目: A Pythagorean triplet is a set of three natural numbers, a b c, for which, a2 + b2 = c2 For exam ...
- 转:JAVA 参数传递
转自:http://blog.sina.com.cn/s/blog_5dd380b90100bvel.html 网络上有太多关于JAVA参数传递是传值还是传引用的讨论,其实大多是概念不清,混淆视听.从 ...
- 工具库用久了,你还会原生操作 Cookie 吗?
用得好了,工具库和框架确实是一大助力,但就怕我们会因此习惯了走捷径,而忘了自己的根本依靠是什么. 前言 前端技术的飞速发展,给从业人员不可避免地带来了"疲劳"感,我们常常会感叹学不 ...