PHP – アップロードのファイルサイズについて
POSTメソッドを使用した、クライアントからサーバーへのファイルアップロードについての注意書き。
1. アップロードファイルの最大サイズ
PHPの設定ファイル「php.ini」の以下の項目で設定
1 |
upload_max_filesize = 2M |
単位はバイトのようです。
このupload_max_filesizeが指定するファイルサイズとは、以下の「upfile」で示したファイルの最大許容サイズの事。
1 2 3 4 |
<form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="upfile" id="upfile"/> <input type="submit" value="アップロード" /> </form> |
現状の設定だと、2MB(デフォルト値)以上のファイルをアップロードすると、PHP側はそれらサイズオーバーしたファイルを破棄する。
この場合、$_FILESで取得できるエラー情報に「UPLOAD_ERR_INI_SIZE」(int型で1)が返る。
1 2 |
$error = $_FILES['upfile']['error']; echo $error; |
エラーコードに関してはPHPの公式を参照してください。http://php.net/manual/ja/features.file-upload.errors.php
2MB以上のファイルをアップロードしたい場合は、upload_max_filesizeの値を大きくすればよし。
2. POSTメソッドにてPOSTできる全体の最大サイズ
若干分かり辛い日本語ですね。
ファイルアップロードでサーバーに送信されるデータは何もファイルだけではありません。
<form>でくくっている中にいろいろな情報がありますね。「enctype=”multipart/form-data”」とかありますね。
これら全部を含めた「POSTできる最大サイズ」ってのんがあります。
1 |
post_max_size = 8M |
例のごとくphp.iniに上記の項目があります。デフォルト値は8M(PHP5だとこのはず)です。
upload_max_sizeでどんなに大きくしても上記のpost_max_sizeに設定した以上のデータは送信できないです。
もし設定サイズをオーバーするデータをPOSTすると、PHPは全て無かった事にします。
もとい、$_POSTと$FILESを空にしちゃいます。
この状態で「$_FILES[“upfile”][“size”]」とか使っちゃうと「そんなもんねぇよ」って怒られます。
大きいなサイズのファイルをアップロードする場合、この値も大きくしなければいけません。
注意して欲しいのは「upload_max_filesize < post_max_size」です
「<=」ではなく「<」でなければいけないです。(多分きっとおそらくメイビー)
3. PHPを実行する時の確保メモリ量
PHPもメモリ確保します。当たり前ですね。
あまり良くわからないので設定項目だけ。
1 |
memory_limit = 128M |
php.ini に上記の項目があります。(デフォルトは128Mだったはず)
メモリの最大確保サイズを指定しています。
基本的に
「upload_max_filesize < post_max_size < memory_limit」
となるようにしましょう。
4. php.ini以外で設定してみる .conf
php.iniはいわば元となる設定ファイル。
大容量アップロードに対応して、あらかじめ大きな値を設定したりすると、目的のコード以外のところでもその設定が反映されちゃいます。
別にいいよっていうならばここは読み飛ばしてください。
上で説明した1〜3の項目はApacheのconfファイルでも設定可能です。
CentOSなら「httpd.conf」
Ubuntuなら・・・いろいろ設定があるので調べて見てください。とりあえず.confに書けばいいと。
そしてディレクティブに以下のような記述をするとおkなわけです。
1 2 3 |
php_value memory_limit 128M php_value post_max_size 8M php_value upload_max_filesize 2M |
5. php.ini以外で設定してみる .htaccess
ディレクトリ毎の設定を変更できる.htaccessでも1〜3を変更できます。
反映させたいphpファイルがあるフォルダと同じ場所に以下の内容の.htaccessを作ればよろし
1 2 3 4 5 |
<IfModule mod_php5.c> php_value memory_limit 128M php_value post_max_size 8M php_value upload_max_filesize 2M </IfModule> |
6. ファイルサイズの制限
まぁ設定でどんな大きくしたって、それを越えるファイルを上げてくる奴がいるかもしれませんね。
いっそ無限にできないの?無限は無理だけど無制限なら可能です。
「memory_limit = -1」とかにすると制限なしという意味になります。
ただし、無制限はちょっとオススメしたくないなぁ。
てことでファイルサイズのチェック方法を書きます。(チェックできれば制限できるはず)
以下、memory_limit,post_max_size,upload_max_filesizeはデフォルト値の128M,8M,2Mとします。
そもそも1~3の設定で制限できてるのでは?という疑問があるかもしれません。
が、問題は項目2の「post_max_size」なんですよ。
これを越えてくるデータをPOSTされると、POSTデータ全部なくなっちゃうわけで。
1 2 3 4 |
$max_filesize = 1024*1024*2; //2Mの意味 if( $_FILES["upfile"]["size"] < $max_filesize) echo "OK"; else echo "NG"; |
とかあったら残念な事になる。
2MB以下のファイルをアップロードすると、OKが表示されますね。
2MB以上のファイルだとNGが表示されますが、が、が、
「8MB以上のファイル」だと事情が変わってきます。
この例であれば、8MB以上のファイルでOKが表示されてしまうかもしれません。
上の項目2でも書いてますが、そもそも$_FILESが空になってしまうからです。
じゃぁどうするかというと、
お手軽ということで以下のコードで
1 2 3 4 |
$size = 1024*1024*2 //2MBの意味 if( $_SERVER['CONTENT_LENGTH'] < $size ) echo "OK"; else echo "NG"; |
このようにすればいいかな。ヘッダーの情報を見ています。
この値はクライアントが書き換え可能ですが、やましい事ない人は書き換えたりとかしませんよね。
書き換えたりしてきたら全部エラーページもなにもなしに処理中断でいいかと。
7. テストするに当たって・・・(テスト工程ではありません)
今回やたらつまったんですよ。
get_cfg_var()でテストしてたんですよ。
.htaccessとかでいじっても値が変更されないなぁとか思ってたんですよ。
get_cfg_var()がphp.iniの値しか見ないとか思ってなかったんですよ。
phpinfo()かini_get()使わないといけないって思わなかったんですよ。
・・・誠に残念である。
phpinfo()使いましょうね。はい。
(・ω・)