>我正在尝试将 MP3 文件上传到 Laravel 应用程序,但遇到了一个问题,即使该文件的属性设置为"audio/mpeg",它也会作为"应用程序/八位字节流"(.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 的文件属性是正确的"音频/mpeg"格式。但是,当我在上传文件后对文件调用 getMimeType(( 方法时,我得到:
"application/octet-stream"
下面是路由方法中的代码:
/**
* Store a newly created resource in storage.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
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 文件。最后,我相信这可能是 guess(( 方法的问题,该方法由 getMethodType(( 调用。拥有更多Laravel经验的人可能会证实这一点。
UploadedFile
对象最终从SymfonyComponentHttpFoundationFileUploadedFile
扩展而来,从The type of the file as provided by PHP
获取/设置mimeType。
要访问该 mimeType,您需要调用$file->getClientMimeType()
然而,在Symfony文档块中,它建议:
客户端 mime 类型是从上传文件的请求中提取的,因此不应将其视为安全值。
对于受信任的 MIME 类型,请改用 getMimeType(((它根据文件内容猜测 MIME 类型(。
但是,在您的情况下$file->getMimeType()
应该信任哪个并从内容中猜测 mime 类型,但是它返回一些东西,就好像它无法确定 mime 类型一样,即"应用程序/八位字节流">
其他信息
帮助您做出决定。基本上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
我在 Laravel 5.4 中遇到了这个问题。我通过将php.ini
中的post_max_size
和upload_max_filesize
设置为更高的值来修复。
之后,我实际上必须硬重启OSX,然后才能真正反映在应用程序中。