PHP 7.2 finfo魔术文件

时间:2018-10-25 01:23:42

标签: php mime-types libmagic

我有一个Laravel 5项目,我们让用户下载.ai(插图文件)。问题是Laravel将.ai文件检测为application / pdf。

我正在使用此功能检测哑剧类型

$type = File::mimeType( $_path );

我也尝试使用这种方法,但是得到了相同的结果

$finfo = finfo_open(FILEINFO_MIME);
$mimetype = $finfo->file($_path);
finfo_close($finfo);

我认为,这仅仅是PHP的问题,根本不知道什么是.ai文件。我对finfo进行了更深入的研究,我了解到默认的mime定义已编译到PHP中,但我看到finfo_open具有第二个参数“ magic_file”,我认为这是您可以将路径插入到另一个mime定义文件的地方。

我尝试使用Ubuntu的/etc/magic.mime文件,但finfo给了我

ErrorException: finfo_open(): Warning: offset `application\/activemessage' invalid in

错误。我认为是因为magic.mime文件的格式不正确。

在线上的大多数主题都创建了一个自定义PHP函数或一些其他技巧来检测mime类型,但我觉得这不是这里的正确解决方案。

在哪里可以找到最新的mime定义文件,如何将它们加载到PHP或finfo中?

我的环境:

Ubuntu 16.04
PHP 7.2

1 个答案:

答案 0 :(得分:4)

  

我认为,这肯定是PHP的问题,根本不知道   .ai文件是。我对finfo进行了更深入的研究,我了解默认   mime定义被编译成PHP,但是我看到finfo_open具有   第二个参数“ magic_file”,我认为这是一个您可以放置​​的地方   将路径插入另一个mime定义文件。

fileinfo extension尝试通过在文件中的特定位置查找某些 magic 序列来猜测mime类型。魔术文件是一个存储了多达已知魔术序列的数据库。

  

我有一个Laravel 5项目,我们让用户下载.ai   (插图文件)。问题是Laravel将.ai文件检测为   应用程序/ pdf。

按照上述说明进行操作,可以查找魔术文件以将.ai个文件检测为pdf。因为Adobe Illustrator Artwork是可以保存为EPS或PDF格式的文件。

我几乎没有做任何研究来区分一般的pdf文件和以pdf格式保存的ai文件。首先,我已经从互联网上下载了免费的AI文件,通过同时使用命令hexdumpfile查找magic number来识别文件。

$ hexdump -C 7_full_ai_vi_template_vector_8.ai | head
00000000  25 50 44 46 2d 31 2e 34  0d 25 e2 e3 cf d3 0d 0a  |%PDF-1.4.%......|
00000010  31 20 30 20 6f 62 6a 0d  3c 3c 20 0d 2f 54 79 70  |1 0 obj.<< ./Typ|
00000020  65 20 2f 43 61 74 61 6c  6f 67 20 0d 2f 50 61 67  |e /Catalog ./Pag|
00000030  65 73 20 32 20 30 20 52  20 0d 2f 4d 65 74 61 64  |es 2 0 R ./Metad|
00000040  61 74 61 20 38 38 20 30  20 52 20 0d 3e 3e 20 0d  |ata 88 0 R .>> .|
00000050  65 6e 64 6f 62 6a 0d 32  20 30 20 6f 62 6a 0d 3c  |endobj.2 0 obj.<|
00000060  3c 20 0d 2f 54 79 70 65  20 2f 50 61 67 65 73 20  |< ./Type /Pages |
00000070  0d 2f 4b 69 64 73 20 5b  20 35 20 30 20 52 20 5d  |./Kids [ 5 0 R ]|
00000080  20 0d 2f 43 6f 75 6e 74  20 31 20 0d 3e 3e 20 0d  | ./Count 1 .>> .|
00000090  65 6e 64 6f 62 6a 0d 33  20 30 20 6f 62 6a 0d 3c  |endobj.3 0 obj.<|
$ file 7_full_ai_vi_template_vector_8.ai
7_full_ai_vi_template_vector_8.ai: PDF document, version 1.4

查看文件的前几个字节,正如您所看到的,它是扩展名为.ai的PDF文件。

之后,我在Mac上使用“预览”将其打开,它知道此文件是由Adobe Illustrator在“检查器”对话框中创建的。因此,它必须具有某种方法来找出以PDF格式保存的AI文件。

Inspector Dialog

  

大多数在线主题创建自定义PHP函数或其他一些函数   hack来检测mime类型,但是我觉得那是不正确的   解决方案在这里。

     

在哪里可以找到最新的mime定义文件以及如何加载   它们变成PHP还是finfo?

我没有运气就用谷歌搜索解决方案,所以我自己创建了它,在Adobe Illustrator File Format Specification的第15页中说:

  

%% Creator注释标识了生成   PostScript语言文档。版本号(版本6.0   图1)是任意文本,以换行符结尾。

我认为包含pdf魔术字节和文件开头的字符串%%Creator Adobe Illustrator的文件应标识为.ai

让我们写一些magic rule

$ cat ai
0       string          %PDF-           PDF document
!:mime  application/pdf
>5      byte            x               \b, version %c
>7      byte            x               \b.%c
>7      search/1000     %%Creator:\ Adobe\ Illustrator  Adobe Illustrator Document

PHP脚本为.ai使用自定义魔术文件

$ cat fileinfo.php
<?php

$magic_file = __DIR__ . '/ai';

$finfo = new finfo(FILEINFO_NONE, $magic_file);
echo $finfo->file($argv[1]) . PHP_EOL;

将输出

$ php fileinfo.php ./7_full_ai_vi_template_vector_8.ai
PDF document, version 1.4 Adobe Illustrator Document

它有效,但是我认为维护自己的魔术文件不是一个好主意。也许您可以为其编写简单的功能,在.ai说它是pdf文件之后,检测$type = File::mimeType( $_path );