Quantcast
Channel: PHP7.4タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 113

【Laravel】getMimeTypeとgetClientMimeTypeの違いと取得できる値の比較

$
0
0

はじめに

 この記事では、getMimeTypeとgetClientMimeTypeのそれぞれの定義と取得できる値の違いをまとめました。

「あれ、このファイルをアップロードした時にどんな値がとれるんだっけ?」って時にさっと確認できるように比較表を記載してますので、結果だけ知りたい場合は下記の比較表をご覧ください。

背景

 Laravelを利用したWEBアプリケーションを開発中に、ユーザーがアップロードした画像に対してMIMEタイプ別に加工処理をする必要が出てきたのがきっかけです。

調べたところ、getMimeTypeとgetClientMimeTypeの2つがあり、どちらを使うのが正しいのか、それぞれ取得できる値に違いがあるのか気になったので、まとめてみやすいようにしてみました。

 また個人的な理由ですが、いままで「仕事が忙しい」を言い訳にいっさいアウトプットをしてこなかったため、今年こそはと一念発起して書き始めました。備忘録兼自分の理解を深める目的で書いてますので、内容に間違いがあったり、もっといいやり方や別のやり方等がありましたら、コメントいただけると嬉しいです!

環境

(Docker上でPHPの実行環境を作って試しています。)
Debian GNU/Linux: 10.6
PHP: 7.4.12
Laravel Framework: 8.13.0

getMimeTypeとgetClientMimeTypeについて

定義

getMimeType()

route_folder/vendor/symfony/http-foundation/Request.php
<?phpnamespaceSymfony\Component\HttpFoundation;useSymfony\Component\HttpFoundation\Exception\ConflictingHeadersException;useSymfony\Component\HttpFoundation\Exception\SuspiciousOperationException;useSymfony\Component\HttpFoundation\Session\SessionInterface;/* 〜〜〜〜省略〜〜〜〜〜 */classRequest{/* 〜〜〜〜省略〜〜〜〜〜 *//**
     * Gets the mime type associated with the format.
     *
     * @return string|null The associated mime type (null if not found)
     */publicfunctiongetMimeType(string$format){if(null===static::$formats){static::initializeFormats();}returnisset(static::$formats[$format])?static::$formats[$format][0]:null;}/* 〜〜〜〜省略〜〜〜〜〜 */}

getClientMimeType()

route_folder/vendor/symfony/http-foundation/File/UploadedFile.php
<?php/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */namespaceSymfony\Component\HttpFoundation\File;/* 〜〜〜〜省略〜〜〜〜〜 *//**
 * A file uploaded through a form.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
 * @author Fabien Potencier <fabien@symfony.com>
 */classUploadedFileextendsFile{/* 〜〜〜〜省略〜〜〜〜〜 *//**
     * Returns the file mime type.
     *
     * The client mime type is extracted from the request from which the file
     * was uploaded, so it should not be considered as a safe value.
     *
     * For a trusted mime type, use getMimeType() instead (which guesses the mime
     * type based on the file content).
     *
     * @return string The mime type
     *
     * @see getMimeType()
     */publicfunctiongetClientMimeType(){return$this->mimeType;}/* 〜〜〜〜省略〜〜〜〜〜 */}

違いと使い分け

getClientMimeType()のコメント部分にがっつり記載されてました。

Returns the file mime type.

The client mime type is extracted from the request from which the file
was uploaded, so it should not be considered as a safe value.

For a trusted mime type, use getMimeType() instead (which guesses the mime
type based on the file content).

getClientMimeType()はファイルをアップロードしたリクエストから抽出されたものなので正確なものではなく、信頼できるMIMEタイプを取得したい場合はgetMimeType()を使ってください。とのことでした。

またこちらにも同じような内容の質問で、とても分かりやすい回答が載ってました。
https://stackoverflow.com/questions/39594854/why-does-laravels-getmimetype-method-identify-a-file-as-application-octet-st

こちらのサイトの答えをお借りすると、

getMimeType() -> ファイルの内容をみてMIMEタイプを判断

getClientMimeType() -> ブラウザが判定した情報を元にMIMEタイプを判断

なので、正確にMIMEタイプを撮りたい場合はgetMimeType()を使うと良さそうでした。
ただ、上記の質問者の方のようにmp3をあげたはずなのにgetMimeType()だと別の値になってしまうとのことで、取得できる値を整理してみました。

準備

今回は実際に取得できる値を確認するだけなので、DBへの保存等はせず、ログに吐き出すだけの処理を実装しました。

route_folder/routes/web.php
Route::get('/file/upload','LectureController@index');Route::post('/file/upload','LectureController@upload');
route_folder/app/Http/Controllers/FileUploadController.php
<?phpnamespaceApp\Http\Controllers;useIlluminate\Http\Request;classFileUploadControllerextendsController{publicfunctionindex(){returnview('file.upload');}publicfunctionupload(Request$request){$images=$request->file('images');foreach($imagesas$image){logger('拡張子: '.$image->getClientOriginalExtension());logger('getMimeType(): '.$image->getMimeType());logger('getClientMimeType(): '.$image->getClientMimeType());}returnredirect('/file/upload');}}
route_folder/resources/views/file/upload.blade.php
<div><formaction="/file/upload"method="POST"enctype='multipart/form-data'>
        @csrf
        <h2>画像アップロード</h2><div><inputtype="file"name="images[]"multiple="multiple"></div><buttontype="submit">更新</button></form></div>

出力結果

route_folder/storage/logs/laravel-2021-02-23.log
[2021-02-23 12:58:26] stack-channel.DEBUG: 拡張子: pdf  
[2021-02-23 12:58:26] stack-channel.DEBUG: getMimeType(): application/pdf  
[2021-02-23 12:58:26] stack-channel.DEBUG: getClientMimeType(): application/pdf  

結果

基本的にはどちらも取得結果は同じでしたが、画像系のファイルだとsvg,テキスト系のファイルだとcsv,txt,log,nfo,srt、動画系のファイルだとwav, aiffが違ってたので、テキストファイルや動画ファイルあたりを扱うときにはをつけた方が良さそうでした。

またこちらに載ってない拡張子も随時追記していこうと思います。

拡張子getMimeType()getClientMimeType()
.jpeg,jpg,jpe,jfifimage/jpegimage/jpeg
.pngimage/pngimage/png
.gifimage/gifimage/gif
.HEICimage/heicimage/heic
.aiapplication/postscriptapplication/postscript
.psdimage/vnd.adobe.photoshopimage/vnd.adobe.photoshop
.tifimage/tiffimage/tiff
.svgtext/htmlimage/svg+xml
.csvtext/plaintext/csv
.txttext/plaintext/plain
.logtext/plainapplication/octet-stream
.nfotext/plainapplication/octet-stream
.srttext/plainapplication/octet-stream
.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.docapplication/mswordapplication/msword
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.pptxapplication/vnd.openxmlformats-officedocument.presentationml.presentationapplication/vnd.openxmlformats-officedocument.presentationml.presentation
.mp3audio/mpegaudio/mpeg
.midaudio/midiaudio/midi
.wavaudio/x-wavaudio/wav
.aiffaudio/x-aiffaudio/aiff
.oggaudio/oggaudio/ogg
.movvideo/quicktimevideo/quicktime
.zipapplication/zipapplication/zip
.rarapplication/x-rarapplication/x-rar

引用

https://stackoverflow.com/questions/39594854/why-does-laravels-getmimetype-method-identify-a-file-as-application-octet-st

https://qiita.com/mashirou_yuguchi/items/14d3614173c114c30f02

http://www.tohoho-web.com/ex/draft/extension.htm


Viewing all articles
Browse latest Browse all 113

Trending Articles