2012-04-08 69 views
6

我工作在PHP上传表单必须只允许将MP3文件。是MIME类型检测最好的方法来检测一种文件?

上传完成后,我分析文件,以检查它是否真的是一个MP3 ..第一步是检测MIME类型为“audio/mpeg”,我使用库finfo_file()测试一些MP3被拒绝,因为他们的MIME类型结果为:应用/八位字节流

我的问题是: - 我的应用程序应该拒绝绝对那些MP3?他们实际上播放音频 - 是否有任何理由为什么这种MIME类型是一个MP3? - MIME类型是检测文件类型的最可靠方法吗?

回答

0

如果你想检测的文件类型,而不只是信任客户提供正确的MIME类型一个非常强大的方式,在UNIX上使用file效用。

$ file Black\ Sands\ 01\ Prelude.mp3 
Black Sands 01 Prelude.mp3: Audio file with ID3 version 2.2.0, contains: MPEG ADTS, layer III, v1, 320 kbps, 44.1 kHz, Stereo 

$ file homework/math475-hw8.docx 
homework/math475-hw8.docx: Microsoft Word 2007+ 

在PHP中,您可以使用exec函数来调用它。

+0

这是一个选项,我没有考虑..我无法测试,因为我赢了 – enkore 2012-04-08 05:32:14

+0

有一个为win32编译的版本[这里](http://gnuwin32.sourceforge.net/packages/ file.htm)。 – 2012-04-09 00:31:51

+0

'file'命令和PHP的'finfo_file'函数使用相同的方法来确定MIME类型(通常通过引用'/ usr/share/misc/magic')。当你有一个内置函数时,对'exec file'没有用处。然而,我有一种情况,当我期望它返回'audio/mpeg'时,'finfo_file'和'file -I'都会检测到'.mp3'作为'application/octet-stream'。两者都失败了。不过,我认为这可以通过将路径传递给改进的'magic'文件作为finfo_open的第二个参数来解决。 – 2015-09-17 18:33:37

0

文件检测的最好的方法是使用“魔字节”或“幻数”方案中,除了MIME。 Unix的file(以及finfo_file)实际使用“魔术字节”做这个文件检测。所以,简而言之:是的。

不要太在乎你的文件看起来像,以及更多关于你可以用它做什么。只要它起作用,文件应该没问题。

如果你真的做多,你可以检查魔术字节自己。有a list of them here

+0

这就是为什么与getid3()类我得到“音频/ MPEG”,但与finfo_filei获得“应用程序/八位字节流”在同一个文件上。 这有点奇怪.. 但即使该文件是可播放的,如果结果与不同的MIME类型,它会因为安全原因而被拒绝(除非我找到更好的方法)..我想知道有多少MP3没有正确的MIME .. – enkore 2012-04-08 05:31:21

+1

@enkore“我想知道有多少MP3没有正确的MIME “MIME类型由客户端提供。这不是MP3文件本身固有的。 – 2012-04-09 00:33:10

2

在我需要上传的大多数应用程序中,我有时会根据预定义的MIME类型列表来解决验证浏览器(客户端)传递的MIME的问题。这种方法使得一般的假设:如果可疑的东西是在哪里浏览器是无法沟通的上传MIME类型的文件中去,我可能不想理会在这个时候处理它。

<?php 

$valid_mp3_mimes = array(
    'audio/mpeg', 
    'audio/x-mpeg', 
    'audio/mp3', 
    'audio/x-mp3', 
    'audio/mpeg3', 
    'audio/x-mpeg3', 
    'audio/x-mpeg-3', 
    'audio/mpg', 
    'audio/x-mpg', 
    'audio/x-mpegaudio', 
    'video/mpeg', 
    'video/x-mpeg', 
); 

$uploaded_file_mime = $_FILES['upload_field_name']['type']; 

if(!in_array($uploaded_file_mime, $valid_mp3_mimes)) 
{ 
    die('Upload is not a valid MP3 file.'); 
} 

您可能会也可能不会觉得这是您的目的足够的方法。 PHP手册明确指出,如果浏览器提供了这个信息,并且在服务器端不检查MIME类型,则此信息可用,因此不应被视为理所当然。

需要考虑的一件事是服务器上的资源的可用性,它允许您验证文件的真实MIME类型。作为PHP开发人员,我们非常喜欢大部分创建平台无关代码的灵活性(例如,构建在运行XAMPP的Windows系统上的我们的Web应用程序可以通过很少的修改部署到Linux主机环境中)。但是,在验证MIME类型时,我们开始引入平台相关的方法,这些方法需要验证这些工具的存在(如“file”或“finfo_file”)。

这可能是一个实现值得研究(从笨GitHub的仓库取),利用这些工具,并即将为彻底的工作示例作为你将PHP的范围内得到:

如果可能,文件MIME类型会检测上载文件的(实际)MIME类型。 https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Upload.php#L983


来源

PHP手册 POST方法上传 - http://www.php.net/manual/en/features.file-upload.post-method.php

网站管理员工具包 MIME类型 - http://www.webmaster-toolkit.com/mime-types.shtml

FILExt .MP3文件 - http://filext.com/file-extension/MP3