我试图将一个MP3文件上传到Laravel应用程序并遇到了一个问题,即使该文件的属性设置为" audio / mpeg"它被上传为" application / octet-stream" (.bin)文件。当我尝试死亡并将文件转储到服务器端代码时使用:
dd($request->file('file'));
我明白了:
UploadedFile {#187 ▼
-test: false
-originalName: "CUS12309821-20-AUG-2016-13-48-13.mp3"
-mimeType: "audio/mpeg"
-size: 47000471
-error: 0
path: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T"
filename: "phpyZCsbU"
basename: "phpyZCsbU"
pathname: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
extension: ""
realPath: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
aTime: 2016-09-20 12:56:00
mTime: 2016-09-20 12:56:00
cTime: 2016-09-20 12:56:00
inode: 4565593
size: 47000471
perms: 0100600
owner: 501
group: 20
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
}
看看当我使用这个方法时,确实说mimeType的文件属性是正确的" audio / mpeg"格式。但是当我上传文件后调用getMimeType()方法时,我得到:
"application/octet-stream"
这是路由方法中的代码:
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$file = $request->all();
$filePath = Storage::putFile('file', $request->file('files'));
dd($request->file('file')->getMimeType());
$file['path'] = Storage::url($filePath);
$file['size'] = Storage::size($filePath);
$file['type'] = $request->file('file')->getMimeType();
return $file;
}
这个问题看起来很独特,因为我使用的是Laravel框架,其他有这个问题的人使用的是vanilla PHP。此外,我们可能已经将excel文件报告为应用程序/八位字节流而不是excel文件。最后,我相信这可能是guess()方法的一个问题,它由getMethodType()调用。拥有更多Laravel经验的人可能会证实这一点。
答案 0 :(得分:13)
UploadedFile
对象最终从Symfony\Component\HttpFoundation\File\UploadedFile
扩展,从The type of the file as provided by PHP
获取/设置mimeType。
要访问该mimeType,您需要调用$file->getClientMimeType()
然而,在它建议的功能的Symfony docblock中:
客户端mime类型是从上传文件的请求中提取的,因此不应将其视为安全值。
对于受信任的mime类型,请改用getMimeType()(根据文件内容猜测mime类型)。
在你的情况下,$file->getMimeType()
应该是可信任的,并从内容中猜出mime类型,但它返回的东西好像无法确定mime类型,是“application / octet-stream”
其他信息
帮助您做出决定。基本上getClientMimeType()
将返回浏览器设置的mime类型。
getMimeType
调用使用我可以看到的两种不同技术猜测mime类型:
使用二进制mime类型技术查看以下命令file -b --mime %s 2>/dev/null
的输出(如果支持)。
第二种技术是使用finfo_open
命令,如果它存在于php中。
如果你的系统上存在1.和2.,从我看到2.将优先考虑,并且1.将成为后备。
我个人赞成getMimeType()
的安全性结果。然而,问题是“浏览器mime类型检测的可靠性以及使用的技术”将是另一个有趣的问题:-)
更新了示例
我为你提供了一个例子。
对于我对“DropboxInstalled.dmg”进行检查,以下是我的结果:
使用命令行(终端)中的file -b --mime DropboxInstaller.dmg
返回application/octet-stream
使用finfo_open
功能
$finfo = new \finfo(FILEINFO_MIME_TYPE);
echo $finfo->file('./DropboxInstaller.dmg');
返回application/x-iso9660-image
答案 1 :(得分:5)
我在Laravel 5.4中遇到过这个问题。我通过将post_max_size
中的upload_max_filesize
和php.ini
设置为更高的值来解决此问题。
之后,我实际上不得不重新启动OSX才能真正反映在应用程序中。