PHP
HTTP
post
アップロード
PHPDay 4

ファイルのPOSTに立ちはだかる壁(PHP編)

More than 1 year has passed since last update.

PHPでファイルアップロードを行うこともありますが、あちこちの設定が「扱えるファイルの最大サイズ」に影響するので、抜けや漏れが発生しやすいかもしれません。

第一の壁 HTTPサーバ

まず、POSTリクエストはHTTPサーバに届きますが、このHTTPサーバの段階で「最大のリクエストサイズ」や「最大のPOSTサイズ」で容量を制限してあることがあります。

Apacheではデフォルト無制限なので、意図して設定していない限り問題にはなりませんが、nginxの場合はもともと「静的ファイルの配信」を意図して作られていた加減か、最大1MBというかなり低めの設定がデフォルトになっています。PHP側をいくら設定しても、nginxで設定した場合にはPHPまで大きなデータが届かないので、注意が必要です。

第二の壁 PHPの最大POSTサイズ

そして、PHP側でもpost_max_sizeとして、POST可能なデータ量の最大値が決まっています。これはデフォルトで8MBという値になっていますので、本格的にファイルアップロードを運用するなら設定は必要です。なお、性質上ini_setでの設定はできず、php.ini.htaccessなどで切り替える必要があります。

第三の壁 アップロードの最大ファイルサイズ

さらに、POSTでファイルを送る場合、1ファイルあたりの最大サイズも決まっています(upload_max_filesize)。デフォルトが2MBなので、少し大きな画像でも超えてしまうレベルの設定となっています。これまた(PHPプログラムが動く前に走るものなので)ini_setは使えません。

また、「一度に受け取れるファイルの数」にも制限がありますが、デフォルトで20個となっているので、実用上問題となることはあまりないと思います。

第四の壁 最大メモリ容量

ここまででファイルのデータは通るようになりますが、それを「受け取った後」の処理も問題となります。具体的には、普通の処理をしていると、POSTデータをメモリに乗っける必要が出てくるということです。memory_limitはプログラムで調整もできますが、POSTデータが大きすぎる場合ini_setに辿り着く前にメモリ不足で落ちてしまうので、php.iniなどで設定しておく必要があります。