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が発生します。
Laravelには、Postデータの長さをチェックするミドルウェア\Illuminate\Foundation\Http\Middleware\ValidatePostSizeがあり、8MBを越えた場合に例外を発生します。
Laravel固有のアップロード上限設定はない
Laravelには、ファイルアップロードの上限サイズを設定する項目はありません。
2MBと8MBの上限値は、PHPの設定ファイルphp.iniで設定します。
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モードで動作しているかどうかを確認するには、プロセス一覧を見るのが良いでしょう。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
まとめ
/etc/php.iniには、ファイルアップロードの上限値設定が2か所あることと、変更の適用方法にも2種類ある点に注意しましょう。