使用 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/mp3but application/octet-stream, which makes this validation fails:
当我上传格式正确的 MP3 文件时,Laravel 4 告诉我它不是audio/mp3but 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/mp3file ?
为什么不将文件作为audio/mp3文件上传?
(I already added 'files' => trueto 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.phpsinapp/libraries/MimeReader.php(watch the extension) Extend the Laravel
Validator(I put it in myBaseControllerconstructor)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
audioas a rule ! Example:'file' => 'required|audio', wherefilerefers 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/mpegfiles to be .mpgaand not .mp3. I corrected it in MimeTypeExtensionGuesser.php(in the Symfony library), along with audio/oggthat 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 mp3file's mime type is audio/mpegor could be that, it fails to recognize the mime_content_typeand tells application/octet-streamas a generic/fallback type. You may try this rule (example given below) instead (not tested/sure), because audio/mpegis the correct mime type for mp3according 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 mimetype using something like this:
此外,您可以使用以下内容手动检查mime类型:
$file = Input::file('upload');
if($file->getMimeType() == 'audio/mpeg') {
// valid
}
else {
// invalid
}
Update:
更新:
Specially, for mp3files, 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 tagof the file and can get information such as title, artist, album, year, genreetc.
特别地,对于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 getid3folder from the extracted source into the libsfolder then in your composer.jsonfile add an entry inside classmapof autoloadsection like:
如果你使用它,你必须从给定链路(手动下载getid3),并把它放在一个文件夹内app,也许app/libs/,只是把getid3文件夹从提取的源到libs文件夹,然后在composer.json文件中添加一个条目内classmap的autoload类似部分:
// ...
"app/tests/TestCase.php",
"app/libs/getid3"
Then run composer dump-autoloadfrom 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 mp3file 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 PECLextension 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 手册。

