学习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. ...
随机推荐
- WPF基础:Dispatcher介绍
Disaptcher作用 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程,其余的是子线程.在WPF或WinForm应用程序中,主线程负 ...
- vim编辑文件时[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
出现这个问题是因为你上次编辑的时候在没有保存的情况下退出了(如:电脑关机等)也有可能是有其他人在和你同时进行编辑行为(不同会话中).这是因为在用vim编辑的时候,vim会在打开文件目录下 ...
- 微信小程序开发(二)——使用WeUI组件库
一.前言 因为小程序的api描述都比较简单,并没有wxml及wxss的描述,一定会想小程序有没有一个UI库,类似于前端中的Bootstrap,MD,Semantic UI这样的框架UI库.有的,它就是 ...
- STM32—串口通讯详解
串口通讯目录 物理层 协议层 USART简介 开发板与上位机的连接 代码讲解: 一.初始化结构体 二.NVIC配置中断优先级 三.USART配置函数讲解 四.传输数据的函数: 1.发送一个字节 2.发 ...
- L298N使用资料
L298N驱动连接arduino小车电机(代码和使用): https://www.cnblogs.com/fsong/p/12309911.htmlarduino UNO 连接L298N驱动两个电机转 ...
- Linux从头学08:Linux 是如何保护内核代码的?【从实模式到保护模式】
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...
- docker 安装部署 mysql(配置文件启动)
获取 mysql 镜像 docker pull mysql:5.6 docker images 创建容器 创建宿主机 redis 容器的数据和配置文件目录 # 创建宿主机 redis 容器的数据和配置 ...
- 在WPF中的ItemsControl中使用事件和命令(Using events and Commands within ItemsControl in WPF)
Say I have a standard WPF ItemsControl bound to an ObservableCollection of "Dog" objects l ...
- Walkthrough: Create and use your own Dynamic Link Library (C++)
参考网站:https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-librar ...
- .net core2.1 迁移.net core 3.1
1.解决方案->属性-->目标框架 .net core3.1 2.删除旧的Nuget包添加新的NuGet包 3.修改Startup.cs 修改ConfigureServices 修改Con ...