maidsphere

A quantization noise whispers through the net.

PHPでファイルをアップロードするときの設定

Apr 6, 2015 22:34:44 JST

PHPを用いてファイルのアップロードがあるWebサイトを運営する場合に,サイズの大きなファイルもアップロード可能にするために変更しないといけない設定のメモ. なおこの設定の一部はPHP_INI_PERDIRなので,.htaccessからPHPの設定変更を許可されているサーバの場合のみ有効です.

以下が.htaccessに書くべきコードになります.

<IfModule mod_php5.c>
  php_value post_max_size "32M"
  php_value upload_max_filesize "24M"

  php_value memory_limit "128M"

  php_value max_execution_time "120"
  php_value max_input_time "120"
</IfModule>

数値は私の環境で使ってる値なので,各自の環境に応じて適宜書き換えてください.

単純にupload_max_filesizeだけ変更すればいいわけではなくて,POSTの許容サイズも大きくしないといけません. PHPのマニュアルのpost_max_sizeの項を読む限り

To upload large files, this value must be larger than upload_max_filesize.

ということなので,post_max_size > upload_max_filesizeである必要があります.上述の例では,8MiBの余裕があります.

さらに

If memory limit is enabled by your configure script, memory_limit also affects file uploading. Generally speaking, memory_limit should be larger than post_max_size.

とのことなので,memory_limit > post_max_size > upload_max_filesizeである必要があります.


このほかに,忘れてはいけないのがスクリプト実行時間の設定で,max_input_timemax_execution_timeです.

max_input_timeはユーザからのアップロードを受け付ける秒数です. ユーザの上り帯域を200KiB/s(= 1,600kbps)と見積もると,20MiBのファイルのアップロードには1分以上かかります. ファイルサイズとアップロード速度を考えて,この値を設定する必要があります. あまり深く考えたくない人は-1を指定すれば無制限になります.

max_execution_timeはスクリプト実行時間の方で,この秒数以上動き続けてるスクリプトは止められます. 暴走したスクリプトがサーバの資源を食いつぶすのを防ぐ仕組みです.

スクリプトの動作しうる最大時間はmax_input_time + max_execution_timeです. ファイルをアップロードしている時間は,スクリプト実行時間の一部としてはカウントされません.

ちなみに,この設定ディレクティブはPHPが動いているWebサーバの設定値以上を指定しても意味がありません. たとえばApache HTTP Serverなら,デフォルトで300以上の値は暗黙的に300と解釈されます.

「あれ? じゃあmax_input_time300以上指定しても無意味?」と思う人がいるかもしれませんが,Apache HTTP Serverにおいてファイルアップロードのタイムアウトは,パケットの送られてくる最大間隔になります. つまり,通信が300秒以上全く行われなかったときにしかタイムアウトしません. 通信さえ行われていれば極端な話,100時間ぐらいアップロードにかかってても正常に処理は行われます.


最後にそもそもの部分ですが,ファイルアップロードを許可するかしないかを決めるfile_uploadsという設定があり,これがOFFになってる場合はファイルのアップロード自体ができません.

この設定はPHP_INI_SYSTEMなので,ユーザレベルではこれをONにすることはできません. サーバのphp.iniもしくはhttpd.confを弄る必要があるためです.