2013-04-24 85 views
4

我有以下PHP代码,显示上传文件的MIME类型。检测MIME类型失败php

<?php 

if ($_POST) { 

    var_dump($_FILES); 

    $finfo = new finfo(FILEINFO_MIME_TYPE); 

    var_dump($finfo->file($_FILES['file']['tmp_name'])); 

} else{ 
    ?> 
    <form method="POST" enctype="multipart/form-data"><input name="file" type="file"><input name="submit" value="send" type="submit"/></form> 
    <?php 
} 

用这个脚本上传somefile.csv的结果如下。

array (size=1) 
    'file' => 
    array (size=5) 
     'name' => string 'somefile.csv' (length=12) 
     'type' => string 'text/csv' (length=8) 
     'tmp_name' => string '/tmp/phpKiwqtu' (length=14) 
     'error' => int 0 
     'size' => int 3561 
string 'text/x-fortran' (length=14) 

所以当然MIME类型应该是文本/ csv。但是我使用的框架(Symfony 1.4)使用fileinfo方法。

而且我测试远一点似乎file --mime-type somefile.csv返回somefile.csv: text/x-fortran命令(在Ubuntu)和命令mimetype somefile.csv返回somefile.csv: text/csv。 somefile.csv是用MSOffice创建的(我不知道这是否重要)。 显然mimetype使用了一些很棒的mime数据库(http://freedesktop.org/wiki/Software/shared-mime-info),而file没有。

  1. PHP是否使用filemimetype或两者皆不?
  2. 此外,我不确定这里要做什么;我上传的文件格式错误?我必须使用不同的mime数据库吗? PHP是否被窃听?这里发生了什么?

编辑:

为什么它被检测为Fortran程序的原因是因为somefile.csv只包含以下内容:

somecolumn; 
C F; 

相信的上述内容CSV文件有效吗?如果一个字段包含空格,则该字段不必放在引号内,对吗?

回答

0

PHP Mimetype introduction

本扩展已被弃用在一个更清洁的方式PECL扩展Fileinfo的提供相同的功能(和更多)。

该模块中的函数尝试通过在文件中的特定位置查找某些魔术字节序列来猜测文件的内容类型和编码。虽然这不是一个防弹的方法,但所使用的启发式方法做得非常好。

此扩展名来自Apache mod_mime_magic,它本身是基于由Ian F. Darwin维护的文件命令。查看源代码以获取更多历史和版权信息。

PHP Fileinfo introduction

此模块中的功能,试图通过寻找在文件中的特定位置的某些魔术字节序列来猜测文件的内容类型和编码。 虽然这不是防弹的方法,但所用的启发式方法做得很好

下面是关于同一主题的一些答案的问题:Detecting MIME type in PHP

+0

http://pear.php.net/package/MIME_Type给出了相同的结果als file_info。我不明白为什么一个CSV文件看起来像一个fortran文件。 – meijuh 2013-04-24 11:57:30

+0

看看Fortran代码示例,我无法弄清楚为什么发生这种情况,它们完全不同。 如果您在简单的文本编辑器中打开该特定的CSV文件,它看起来像纯CSV还是其他元素可能导致混淆结果? – 2013-04-24 13:15:10

+0

另外5美分,我搜索了很好的基于PHP的网络应用程序,这里有其他方法:Drupal 8似乎使用Guzzle PHP框架来完成这项工作,在https://github.com/guzzle/guzzle上查看他们的代码。 /blob/master/src/Guzzle/Http/Mimetypes.php。 他们只是对预先定义的已知MIME类型列表进行简单的扩展检查。不是我要说的。 – 2013-04-24 13:21:13

5

我没有Unix机器在这里考察一个真正的“神奇”的文件(用来猜测MIME类型库),但快速谷歌搜索发现这一点:

# $File: fortran,v 1.6 2009/09/19 16:28:09 christos Exp $ 
# FORTRAN source 
0  regex/100  \^[Cc][\ \t] FORTRAN program 
!:mime text/x-fortran 

显然,它会扫描该文件的开头寻找以单个C字母加空格开头的行,这些行似乎是Fortran style comment。因此,误报:

somecolumn; 
C F; 
+0

因此,我应该如何处理误报?我知道解决方案是在每个单元格周围加引号,但这并不是我想要的,因为我的web应用程序的用户上载了这些CSV文件,并且示例显示的是一个有效的CSV文件 – meijuh 2013-04-24 15:47:10

+0

In取决于您的确切需求,但是,在这种情况下,最好使用文件扩展名。你也可以为你的mime文件移除Fortran。 (不知道为什么你在这里使用启发式,如果你已经知道它是CSV;猜测MIME类型将不验证文件) – 2013-04-24 15:49:21

+0

那么CSV文件是由应用程序的用户上传。如果误报是猜测MIME类型的结果,那么使用MIME类型猜测没有任何意义。我只会确保该文件在公用文件夹中不可执行,用户应该知道他们正在下载的内容。此外,由于我仅使用CSV文件,并且CSV文件的语法必须正确,所以我还可以使用BNF语法检查CSV文件的内容。 – meijuh 2013-04-24 18:00:04