学习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. ...
随机推荐
- filter,interceptor,controllerAdvice,aspect,controller执行顺序
1.filter,这是java的过滤器,和框架无关的,是所有过滤组件中最外层的,从粒度来说是最大的. 配置方式,有直接实现Filter+@component,@Bean+@configuration( ...
- eclipse选中参数高亮显示设置
window - preference - java - Editor - Mark Occurrences
- Python语言系列-10-数据库
MySQL 基础环境准备 readme.txt 作者:Alnk(李成果) 版本:v1.0 安装mysql数据库 略 创建student库 # mysql> create database stu ...
- 把对象交给spring管理的3种方法及经典应用
背景 先说一说什么叫把对象交给spring管理.它区别于把类交给spring管理.在spring里采用注解方式@Service.@Component这些,实际上管理的是类,把这些类交给spring来负 ...
- 网络游戏逆向分析-4-分析喊话call参数来源
网络游戏逆向分析-4-分析喊话call参数来源 好久没更新了,去实习去了,大家见谅一下. 前面找到了喊话功能call函数,然后分析了它的参数有五个,分别的四个push的和一个ecx: 第一次edx = ...
- docker-compose部署mysql,redis,rabbitmq
version: '3' services: mysql: image: mysql:5.7.31 container_name: mysql restart: always command: --c ...
- SpringBoot集成Druid
maven <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-b ...
- .Net Core NPOI读取Excel 并转为数据实体类
创建应用程序 这里直接创建Console程序 引用NPOI的NuGet包 PM> Install-Package NPOI -Version 2.5.1 直接Nuget包管理器添加 导入Exce ...
- 使用TypeConverter类
3.2.2 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射注意本小节的例子对于初学者来说理解起来比较困难而且实用性不大,主要是为喜欢刨根问底的WPF ...
- Semaphore 类 的使用理解C#
示例 下面的代码示例创建一个信号量,其最大计数为3,初始计数为零. 该示例启动五个线程,这会阻止等待信号量. 主线程使用 Release(Int32) 方法重载将信号量计数增加到其最大值,从而允许三个 ...