Laravelでファイルアップロード上限を変更するには?

Laravel

Laravelでアップロード上限に達した時の挙動

まず、Laravelでファイルアップロードの上限サイズを越えたら、どのようになるのかをまとめます。

例えば、画像をアップロードするフォームがあり、アップロードされたファイルをControllerでファイルとして保存する処理を考えます。

よくあるのは、次のように $request->file() で取得されるオブジェクトに対してstore()関数を呼び出します。

$request->file('image')->store();

ここで、アップロード上限を超える画像ファイルがアップロードされると、状況に応じて、2種類のエラーが出力されます。

ケース① The “” file does not exist or is not readable

2MB~8MBのファイルをアップロードすると、ファイルが読み込めないというような例外が発生します。

スタックトレースを見ると、SymfonyでMIMEタイプを取得する処理で例外が発生しています。

[2021-04-26 15:10:38] local.ERROR: The "" file does not exist or is not readable. {"exception":"[object] (Symfony\\Component\\Mime\\Exception\\InvalidArgumentException(code: 0): The \"\" file does not exist or is not readable. at /var/www/laravel/vendor/symfony/mime/FileinfoMimeTypeGuesser.php:50)
[stacktrace]
#0 /var/www/laravel/vendor/symfony/mime/MimeTypes.php(134): Symfony\\Component\\Mime\\FileinfoMimeTypeGuesser->guessMimeType()
#1 /var/www/laravel/vendor/symfony/http-foundation/File/File.php(81): Symfony\\Component\\Mime\\MimeTypes->guessMimeType()
#2 /var/www/laravel/vendor/symfony/http-foundation/File/File.php(61): Symfony\\Component\\HttpFoundation\\File\\File->getMimeType()
#3 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Http/FileHelpers.php(50): Symfony\\Component\\HttpFoundation\\File\\File->guessExtension()
#4 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Http/UploadedFile.php(36): Illuminate\\Http\\UploadedFile->hashName()
#5 /var/www/laravel/app/Http/Controllers/UploadController.php(40): Illuminate\\Http\\UploadedFile->store()

ログだけを見ても、アップロード上限に達したエラーとは気づきませんよね。

ケース② PostTooLargeException

8MB以上のファイルをアップロードすると、PostTooLargeExceptionが発生します。

PostTooLargeException

Laravelには、Postデータの長さをチェックするミドルウェア\Illuminate\Foundation\Http\Middleware\ValidatePostSizeがあり、8MBを越えた場合に例外を発生します。

Laravel固有のアップロード上限設定はない

Laravelには、ファイルアップロードの上限サイズを設定する項目はありません。

2MBと8MBの上限値は、PHPの設定ファイルphp.iniで設定します。

ミドルウェアValidatePostSizeでも、php.iniの設定post_max_sizeを参照しています。

php.iniでupload_max_filesizeとpost_max_sizeを変更する

php.iniには、アップロードサイズ上限に関する設定が2つあり、2つの設定値を変更します。

upload_max_size

upload_max_sizeは、アップロードするファイルの上限サイズ(バイト)です。

初期値は 2MB です。

upload_max_filesize = 2M

例えば上限値を10MBに変更する場合は、次のようにphp.iniを設定します。

upload_max_filesize = 10M

upload_max_filesizeは、単一ファイルの最大サイズを指定します。複数のファイルをアップロードする場合には、すべてのファイルの合計最大値ではなく、アップロードするファイルの中で最大のファイルサイズのみを指定します。

ただし、次に説明するpost_max_sizeも、upload_max_sizeより大きな値に設定する必要があります

post_max_size

post_max_sizeは、ファイルアップロードに限らず、POST時のリクエストボディの最大サイズを指定します。

初期値は 8MB です。

post_max_size = 8M

例えば上限値を10MBに変更する場合は、次のようにphp.iniを設定します。

post_max_size = 10M

post_max_sizeは、upload_max_filesizeよりも大きな値に設定する必要があります。

また、複数のファイルをアップロードする場合は、合計最大値を設定します

たとえば、最大10MBのファイルを5つアップロードできるようにするには、post_max_sizeは50MB以上に設定します。

php.iniの設定変更を適用する

FastCGI Process Manager(php-fpm)の場合

PHPをFastCGIで動作させている時は、FastCGI Process Manager(php-fpm)を再起動します。

# systemctl restart php-fpm

FastCGIを使っている場合、Apacheの再起動ではphp.iniの変更は適用されません。

RHEL 8/CentOS 8では、Apache上のPHPはデフォルトでFastCGIモードで動作します。

FastCGIモードで動作しているかどうかを確認するには、プロセス一覧を見るのが良いでしょう。FastCGIで動作しているときは、以下のようにphp-fpmプロセスがあることが分かります。

[root@laravel-study-web laravel]# ps -ef|grep php
root       471     1  0 04:49 ?        00:00:00 php-fpm: master process (/etc/php-fpm.conf)
apache     472   471  0 04:49 ?        00:00:00 php-fpm: pool www
apache     473   471  0 04:49 ?        00:00:00 php-fpm: pool www
apache     474   471  0 04:49 ?        00:00:00 php-fpm: pool www
apache     475   471  0 04:49 ?        00:00:00 php-fpm: pool www
apache     476   471  0 04:49 ?        00:00:00 php-fpm: pool www
apache     477   471  0 04:49 ?        00:00:00 php-fpm: pool www

Apacheモジュール(libphp.so)の場合

Apacheを再起動すれば、php.iniの変更が反映されます。

# systemctl restart httpd

RHEL 7/CentOS 7では、Apache上のPHPはデフォルトでApacheモジュールとして動作します。

まとめ

/etc/php.iniには、ファイルアップロードの上限値設定が2か所あることと、変更の適用方法にも2種類ある点に注意しましょう。