Я пытаюсь загрузить файл 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, где другие с этой проблемой используют ванильный PHP. Кроме того, файл Excel, который могут быть использованы другими, возможно, сообщил о себе как о приложении / октет-потоке вместо файла Excel. Наконец, я полагаю, что это может быть проблемой с методом предположения (), который вызывается методом getMethodType (). Кто-то с большим опытом Laravel мог бы это подтвердить.
UploadedFile
объект в конечном итоге расширяется от Symfony\Component\HttpFoundation\File\UploadedFile
который получает / устанавливает mimeType из The type of the file as provided by PHP
,
Для доступа к этому mimeType вам нужно будет позвонить $file->getClientMimeType()
Однако в докблоке Symfony для этой функции предлагается:
Тип MIME клиента извлекается из запроса, из которого был загружен файл, поэтому его не следует рассматривать как безопасное значение.
Для доверенного типа MIME используйте взамен getMimeType () (который угадывает тип MIME на основе содержимого файла).
В вашем случае однако $file->getMimeType()
который должен быть доверенным и угадывает тип MIME из содержимого, однако он возвращает что-то, как будто он не может определить тип MIME, будучи «application / octet-stream»
Дополнительная информация
Чтобы помочь вам решить. В принципе getClientMimeType()
вернет тип MIME, который был установлен браузером.
getMimeType
Call угадывает 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. Я исправил установкой post_max_size
а также upload_max_filesize
в моем php.ini
на более высокое значение.
После этого мне пришлось сделать жесткий перезапуск OSX, прежде чем он действительно отразится в приложении должным образом.