Laravel 5 Mime 验证 [英] Laravel 5 Mime validation

查看:33
本文介绍了Laravel 5 Mime 验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我正在尝试上传视频,并验证文件类型.

根据文档:

<块引用>

mimes:foo,bar,...

验证中的文件必须具有与所列扩展名之一对应的 MIME 类型.

MIME 规则的基本用法

'photo' => 'mimes:jpeg,bmp,png'

我正在上传 wmv 视频,我的规则是这样的:

返回 ['文件' =>['必需','mimes:video/x-ms-wmv']]

我在 Request::file('file') 上做了一个 print_r() 并且我得到以下数据:

SymfonyComponentHttpFoundationFileUploadedFile 对象([测试:SymfonyComponentHttpFoundationFileUploadedFile:private] =>[原始名称:SymfonyComponentHttpFoundationFileUploadedFile:private] =>示例视频.wmv[mimeType:SymfonyComponentHttpFoundationFileUploadedFile:private] =>视频/x-ms-wmv[大小:SymfonyComponentHttpFoundationFileUploadedFile:private] =>70982901[错误:SymfonyComponentHttpFoundationFileUploadedFile:private] =>0[路径名:SplFileInfo:private] =>C:wamp	mpphp6428.tmp[文件名:SplFileInfo:私有] =>php6428.tmp)

但是我收到错误:

{"file":["文件必须是一个文件类型:video/x-ms-wmv."]}

我尝试将mime 类型"更改为 video/*wmv(根据文档)以及 video/x-ms-wmv 但它们都没有正确验证文件.

正如您从 print_r() 中看到的,Symfony 的 mime 类型 is video/x-ms-wmv.

我做错了吗?或者 Laravel/Symfony 不能很好地验证文件?

感谢您的帮助

编辑好的,我打开了 validator.php 并将 echo $value->guessExtension(); 添加到 ValidateMimes() 方法,它输出asf.

为什么 Symfony 输出 videox-ms-wmv,文件扩展名为 wmv,我正在验证它们,但 Laravel 却在猜测 asf?!

视频验证对我来说太不可靠了.

解决方案

这是预期的行为.

Laravel 正在调用Symphony 上的 href="http://api.symfony.com/2.3/Symfony/Component/HttpFoundation/File/UploadedFile.html#method_guessExtension" rel="noreferrer">guessExtensionUploadedFile 对象,它将返回文件的预期扩展名,而不是 mimetype.

这就是为什么文档指出您应该使用上传的图像:

<块引用>

'photo' => 'mimes:jpeg,bmp,png'

Symfony 的 guessExtension 调用 getMimeType,它使用 PHP 的 Fileinfo Functions 去猜测给定文件的 mimetype.

一旦 getMimeType 猜测文件的 mimetype,Symfony 的 MimeTypeExtensionGuesser 开始从文件中检索的 mime 类型获取扩展名.

//... 截自 MimeTypeExtensionGuesser'视频/x-ms-asf' =>'asf','视频/x-ms-wmv' =>'wmv','视频/x-ms-wmx' =>'wmx','视频/x-ms-wvx' =>'wvx','视频/x-msvideo' =>'avi',

因此,您的规则应该是:

返回 ['文件' =>['必需', 'mimes:wmv,asf']]

应该包含asf 的原因主要是历史原因.引用维基百科:

<块引用>

ASF 文件中最常见的媒体是 Windows Media Audio (WMA) 和 Windows Media Video (WMV).ASF 文件最常见的文件扩展名是扩展名 .WMA(使用 Windows Media Audio 的纯音频文件,带有 MIME 类型audio/x-ms-wma")和 .WMV(包含视频的文件),使用 Windows Media 音频和视频编解码器,带有 MIME 类型video/x-ms-asf").这些文件与旧的 .ASF 文件相同,但扩展名和 MIME 类型不同.

Microsoft 的文档关于ASF 和 WMV/WMA 之间的区别文件状态:

<块引用>

ASF 文件与 WMV 或 WMA 文件之间的唯一区别是文件扩展名和 MIME 类型 [...] 文件的基本内部结构是相同的.

因为文件的内部结构是相同的(包括幻数为文件格式),wmv、wma和asf是一回事.三个扩展之间的唯一区别是资源管理器中显示的图标.

不仅仅是 Windows Media 文件会有这个问题,维基百科列出了许多不同的视频容器格式也会有同样的问题.如果您想找到容器中使用的视频编解码器,您将需要查看更多内容,而不仅仅是"魔法模式",由 fileinfo 函数使用.

<小时>

话虽如此,预期行为 != 正确行为.

我提交了一个 pull request 以添加一个名为 mimetypes 的新验证器.这与您预期的一样,并使用猜测的 mimetype 来验证上传的文件,而不是从 mimetype 猜测的扩展名.

Ok, I'm trying to upload a video, and validate the file type.

According to the documentation:

mimes:foo,bar,...

The file under validation must have a MIME type corresponding to one of the listed extensions.

Basic Usage Of MIME Rule

'photo' => 'mimes:jpeg,bmp,png'

I'm uploading a wmv video, and my rules are so:

return [
    'file' => ['required', 'mimes:video/x-ms-wmv']
]

I've done a print_r() on Request::file('file') and I get the following data:

SymfonyComponentHttpFoundationFileUploadedFile Object
(
    [test:SymfonyComponentHttpFoundationFileUploadedFile:private] => 
    [originalName:SymfonyComponentHttpFoundationFileUploadedFile:private] => SampleVideo.wmv
    [mimeType:SymfonyComponentHttpFoundationFileUploadedFile:private] => video/x-ms-wmv
    [size:SymfonyComponentHttpFoundationFileUploadedFile:private] => 70982901
    [error:SymfonyComponentHttpFoundationFileUploadedFile:private] => 0
    [pathName:SplFileInfo:private] => C:wamp	mpphp6428.tmp
    [fileName:SplFileInfo:private] => php6428.tmp
)

However I'm getting the error:

{"file":["The file must be a file of type: video/x-ms-wmv."]}

I've tried changing the "mime type" to video/*, wmv (as per the docs) and also video/x-ms-wmv yet none of them validate the file correctly.

As you can see from the print_r() the mime type Symfony is getting is video/x-ms-wmv.

Am I doing something wrong? Or can Laravel/Symfony just not validate files well?

I appreciate the help

Edit Ok, I opened validator.php and added echo $value->guessExtension(); to the ValidateMimes() method, and it outputs asf.

Why is Symfony outputting videox-ms-wmv, the file extension is wmv, I'm validating both of them, but Laravel is guessing asf?!

It's too unreliable for video validation for me.

解决方案

This is expected behaviour.

Laravel is calling guessExtension on Symphony's UploadedFile object, which will return the expected extension of the file, not the mimetype.

This is why the documenatation states that for an uploaded image you should use:

'photo' => 'mimes:jpeg,bmp,png'

Symfony's guessExtension calls getMimeType, which uses PHP's Fileinfo Functions to go and guess the mimetype of a given file.

Once getMimeType guesses the mimetype for the file, Symfony's MimeTypeExtensionGuesser kicks in to get the extension from the mime type retrieved from a file.

    // ... cut from MimeTypeExtensionGuesser
    'video/x-ms-asf' => 'asf',
    'video/x-ms-wmv' => 'wmv',
    'video/x-ms-wmx' => 'wmx',
    'video/x-ms-wvx' => 'wvx',
    'video/x-msvideo' => 'avi',

Therefore, your rules should be:

return [
    'file' => ['required', 'mimes:wmv,asf']
]

The reason that asf should be included is mainly historical. To quote Wikipedia:

The most common media contained within an ASF file are Windows Media Audio (WMA) and Windows Media Video (WMV). The most common file extensions for ASF files are extension .WMA (audio-only files using Windows Media Audio, with MIME-type 'audio/x-ms-wma') and .WMV (files containing video, using the Windows Media Audio and Video codecs, with MIME-type 'video/x-ms-asf'). These files are identical to the old .ASF files but for their extension and MIME-type.

Microsoft's documentation about the difference between ASF and WMV/WMA files states:

The only difference between ASF files and WMV or WMA files are the file extensions and the MIME types [...] The basic internal structure of the files is identical.

Because the internal structure of the file is identical (including the magic numbers for the file format), wmv, wma and asf are one and the same. The only difference between the three extensions is the icon that is shown inside Explorer.

It's not just Windows Media files that will have this issue, Wikipedia lists many different video container formats that will have the same problem. If you want to find the video codec that is being used in a container, you are going to need to look at more then just the "magic patterns" that are used by the fileinfo functions.


That being said, expected behaviour != correct behaviour.

I submitted a pull request to add a new validator, called mimetypes. This does as you would expect and uses the guessed mimetype to validate an uploaded file, instead of the extension that is guessed from the mimetype.

这篇关于Laravel 5 Mime 验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆