使用 Laravel 4 进行文件上传 MIME 类型验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21564029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File upload mime-type validation with Laravel 4
提问by ryancey
When I upload a well-formed MP3 file, Laravel 4 tells me it's not audio/mp3
but application/octet-stream
, which makes this validation fails:
当我上传格式正确的 MP3 文件时,Laravel 4 告诉我它不是audio/mp3
but application/octet-stream
,这使得此验证失败:
$validator = Validator::make(
array('trackfile' => Input::file('trackfile')),
array('trackfile' => 'required|mimes:mp3')
);
if($validator->fails())
return 'doesn\'t works because mime type is '.Input::file('trackfile')->getMimeType();
else
return 'it works!';
Why doesn't it upload the file as an audio/mp3
file ?
为什么不将文件作为audio/mp3
文件上传?
(I already added 'files' => true
to the form declaration)
(我已经添加'files' => true
到表单声明中)
回答by ryancey
Edit
编辑
Built-in validator was still considering some mp3's as application/octet-stream, wether you converted the original file with this or that software.
内置验证器仍在考虑将某些 mp3 作为应用程序/八位字节流,无论您是使用此软件还是那个软件转换原始文件。
I finally used the MimeReaderclass by user Shane, which totally works. I'm still wondering why is it so hard to detect a right mime type though.
我终于使用了用户Shane的MimeReader类,它完全有效。我仍然想知道为什么很难检测到正确的 mime 类型。
I implemented it as a validator in Laravel:
我在 Laravel 中实现了它作为验证器:
- Move
MimeReader.phps
inapp/libraries/MimeReader.php
(watch the extension) Extend the Laravel
Validator
(I put it in myBaseController
constructor)Validator::extend('audio', function($attribute, $value, $parameters) { $allowed = array('audio/mpeg', 'application/ogg', 'audio/wave', 'audio/aiff'); $mime = new MimeReader($value->getRealPath()); return in_array($mime->get_type(), $allowed); });
- Add your error message in
app/lang/[whatever]/validation.php
(in my case, the key isaudio
) - I can now use
audio
as a rule ! Example:'file' => 'required|audio'
, wherefile
refers toInput::file('file')
- 移动
MimeReader.phps
中app/libraries/MimeReader.php
(看扩展) 扩展 Laravel
Validator
(我把它放在我的BaseController
构造函数中)Validator::extend('audio', function($attribute, $value, $parameters) { $allowed = array('audio/mpeg', 'application/ogg', 'audio/wave', 'audio/aiff'); $mime = new MimeReader($value->getRealPath()); return in_array($mime->get_type(), $allowed); });
- 添加您的错误消息
app/lang/[whatever]/validation.php
(在我的情况下,关键是audio
) - 我现在可以正常使用
audio
了!示例:'file' => 'required|audio'
,其中file
指的是Input::file('file')
Laravel was considering audio/mpeg
files to be .mpga
and not .mp3
. I corrected it in MimeTypeExtensionGuesser.php
(in the Symfony library), along with audio/ogg
that were considered as .oga
. Maybe the audio mime-type depends on what software encoder was used.
Laravel正在考虑audio/mpeg
的文件是.mpga
不.mp3
。我在MimeTypeExtensionGuesser.php
(在 Symfony 库中)更正了它,audio/ogg
并且被认为是.oga
. 也许音频 mime 类型取决于使用的软件编码器。
Other method is to bypass the validator and check the mime-type directly into the controller using Input::file('upload')->getMimeType()
like Sheikh Heera said.
另一种方法是绕过验证器并使用Input::file('upload')->getMimeType()
Sheikh Heera 所说的那样将 mime 类型直接检查到控制器中。
回答by The Alpha
It's probably because of mp3
file's mime type is audio/mpeg
or could be that, it fails to recognize the mime_content_type
and tells application/octet-stream
as a generic/fallback type. You may try this rule (example given below) instead (not tested/sure), because audio/mpeg
is the correct mime type for mp3
according to rfc3003:
这可能是因为mp3
文件的 mime 类型是audio/mpeg
或可能是那个,它无法识别mime_content_type
和告诉application/octet-stream
作为通用/回退类型。您可以尝试使用此规则(下面给出的示例)(未测试/确定),因为根据rfc3003audio/mpeg
是正确的 MIME 类型:mp3
array('trackfile' => 'required|mimes:audio/mpeg,mp3')
Also, you may manually check the mime
type using something like this:
此外,您可以使用以下内容手动检查mime
类型:
$file = Input::file('upload');
if($file->getMimeType() == 'audio/mpeg') {
// valid
}
else {
// invalid
}
Update:
更新:
Specially, for mp3
files, you may also use a library getID3which is similar to Php PECL extension id3, if you use it, you will be also able to use ID3 tag
of the file and can get information such as title
, artist
, album
, year
, genre
etc.
特别地,对于mp3
文件,你也可以使用一个库getID3这是类似PHP的PECL扩展,ID3,如果你使用它,你也将能够使用ID3 tag
的文件,并可以得到的信息,如title
,artist
,album
,year
,genre
等。
If you use it, you have to download it manually from the given link (getid3
) and put it in a folder inside app
, maybe app/libs/
and just put the getid3
folder from the extracted source into the libs
folder then in your composer.json
file add an entry inside classmap
of autoload
section like:
如果你使用它,你必须从给定链路(手动下载getid3
),并把它放在一个文件夹内app
,也许app/libs/
,只是把getid3
文件夹从提取的源到libs
文件夹,然后在composer.json
文件中添加一个条目内classmap
的autoload
类似部分:
// ...
"app/tests/TestCase.php",
"app/libs/getid3"
Then run composer dump-autoload
from terminal/command prompt and you are ready to use it. To use it symply try this:
然后composer dump-autoload
从终端/命令提示符运行,您就可以使用它了。要使用它 symply 试试这个:
$file = Input::file('upload'); // assumed name of the file input is upload
$path = $path = $file->getRealPath();
$id3 = new getID3();
$tags = $id3->analyze($path);
if(is_array($tags) && array_key_exists('audio', $tags)) {
// valid
dd($tag['tags']);
}
For a valid mp3
file You'll get an array like this:
对于一个有效的mp3
文件,你会得到一个这样的数组:
array (size=2) 'id3v1' =>
array (size=6)
'title' =>
array (size=1)
0 => string '46. Piya Basanti' (length=16)
'artist' =>
array (size=1)
0 => string '(Freshmaza.com)' (length=15)
'album' =>
...
If you have already installed or can install the PECL
extension using (from terminal) following command:
如果您已经安装或可以PECL
使用(从终端)以下命令安装扩展:
pear install pecl/id3
Then you may normally use
然后你可以正常使用
$tags = id3_get_tag( "path/to/example.mp3" );
print_r($tag);
The above example will output something similar to:
上面的例子将输出类似于:
Array
(
[title] => DN-38416
[artist] => Re:\Legion
[album] => Reflections
[year] => 2004
[genre] => 19
)
Check Php manual.
检查PHP 手册。