Laravel 4 中 File::mime() 的替换(从文件扩展名中获取 mime 类型)
Posted
技术标签:
【中文标题】Laravel 4 中 File::mime() 的替换(从文件扩展名中获取 mime 类型)【英文标题】:Replacement for File::mime() in Laravel 4 (to get mime type from file extension) 【发布时间】:2013-11-10 00:04:23 【问题描述】:Laravel 3 有一个 File::mime() 方法,可以很容易地从扩展名中获取文件的 mime 类型:
$extension = File::extension($path);
$mime = File::mime($extension);
升级到 Laravel 4 时出现错误:
调用未定义的方法 Illuminate\Filesystem\Filesystem::mime()
我在Filesystem API docs 中也看不到任何提及 mime 类型的内容。
在 Laravel 4 中获取文件 mime 类型的推荐方法是什么(请注意这不是用户上传的文件)?
【问题讨论】:
【参考方案1】:我发现的一个解决方案是使用Symfony HttpFoundation File class(它已经作为依赖项包含在 Laravel 4 中):
$file = new Symfony\Component\HttpFoundation\File\File($path);
$mime = $file->getMimeType();
事实上 File 类使用 Symfony MimeTypeGuesser 类所以这也有效:
$guesser = Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser::getInstance();
echo $guesser->guess($path);
但不幸的是,我得到了意想不到的结果:将路径传递给 css 文件时,我得到的是 text/plain 而不是 text/css。
【讨论】:
从relatedquestions看来,这不是一个可靠的方法。 文本/纯文本而不是大量其他格式也存在同样的问题。 js、txt、xls、po 等 - 都得到文本/纯 mimes【参考方案2】:如果您刚刚上传了可以使用的文件:
Input::file('field_name')->getMimeType();
你可以看到更多here!我希望它会有所帮助! :D
编辑:Input::file
是File
的某种扩展,因此您也可以使用File::get('file')->getMimeType();
。未测试,但必须有效。
【讨论】:
谢谢,但如前所述,我想将其用于任何常规文件,而不是刚刚上传的文件。 谢谢。但是 File::get() 返回一个字符串,所以不能调用 getMimeType()。此外,Symfony 的 getMimeType() 对于我需要它工作的 CSS 文件类型并不可靠(请参阅我自己的答案)。 是的,我猜这似乎是 Laravel 的一个错误。你看过 Laravel 的 GitHub 仓库吗?你应该看看问题跟踪,看看你是否发现了什么! 那个方法不可靠。结果毫无用处。【参考方案3】:看完之后:
php mime_content_type() 已弃用 它的替代品FileInfo不可靠 Symfony 的 getMimeType() 使用 FileInfo(请参阅我的其他答案)我决定将 Laravel 3 的 File::mime() 实现移植到我的 Laravel 4 应用程序中的帮助程序库中。 Laravel 3 实现只是根据文件扩展名从配置查找数组中读取 MIME 类型。
解决方案:
将 application/config/mimes.php 从我的 L3 项目复制到 app/config/mimes.php 在我的 L4 项目中 使用 Laravel 3 File class 中的 File::mime() 函数代码制作了一个 FileHelper 库。【讨论】:
【参考方案4】:原来 Symfony ExtensionGuesser
和 MimeTypeGuesser
使用了不可靠的 FileInfo
类。因此,对 mime 的验证会返回不可预测的结果,并且不能以正确的方式用于文件上传(它会返回 text/plain
mime for js
、xls
、po
等)。
我已经为这个问题找到了非常简单的解决方案。
代替
'attachment' => 'required|mimes:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt|max:10000',
我把它分成两个不同的部分,现在我的验证看起来像这样:
private function createFileAttachmentValidator($file)
return Validator::make(
[
'attachment' => $file,
'extension' => \Str::lower($file->getClientOriginalExtension()),
],
[
'attachment' => 'required|max:10000',
'extension' => 'required|in:jpg,jpeg,bmp,png,doc,docx,zip,rar,pdf,rtf,xlsx,xls,txt',
],
$this->validationMessages()
);
我只是尝试验证文件的扩展名是否存在以及它是否列在我的in
规则中。这行得通,但是,解决方案并不完美。
【讨论】:
将其与内置的 mime 验证一起使用是解决此问题的最佳方法。【参考方案5】:public function mimeType($path)
return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
参考:https://github.com/illuminate/filesystem/blob/master/Filesystem.php#L194
【讨论】:
以上是关于Laravel 4 中 File::mime() 的替换(从文件扩展名中获取 mime 类型)的主要内容,如果未能解决你的问题,请参考以下文章
如何更改文件 mime 类型以绕过 php shell 上传? [关闭]