2011/07/04

PHPでpost_max_size以上のデータを投げても何とかハンドリングしたい

最近phpコードを書いているんですが、post_max_size以上のデータを受け取ると

PHP Warning: POST Content-Length of 9456137 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

なんてエラーを吐いてくれてエラーチェックができないんです。
対策はいくつか考えたんですが、
apacheのLimitRequestBodyを使う
コンテンツを配置するたびにapacheの設定を書くのが面倒だし確実に忘れる。AllowOverrideも環境依存だし。。
javascriptで制御
所詮クライアントサイドの気休めでしかないので信頼性低い。
MAX_UPLOAD_SIZEをhiddenで埋め込む
これも気休め。
と、どれもイマイチ決定打に欠けます。

実際にpost_max_size以上のデータを受け取ったとき、$_POSTのデータが破壊されるのか変数として提供することをあきらめるのかはわかりませんが、$_POSTの中身が空になるので、これを検知しちゃえばいいんじゃね?
ということで、意図的にエラーを発生させて観察してみました。その結果、post_max_size以上のデータを受け取ると、$_POST、$_FILESの両方とも、isset()にかけるとtrueが返されますがcount()で見ると空っぽなんですね。
これを受けて、下記のようなコードで逃げてみました。

// max_post_size越えのデータを受信した場合の対策
if(count($_POST) == 0 && count($_FILES) == 0)
{
死に際のエラー処理
exit();
}

本来はPHP側が正しくハンドリングしてくれればいいんですが、どうもこの辺のチェックが甘いようで、逃げの手法だということは知りつつもこの方法で決定。期待した動作になりました。

ちなみに、cent5系でふつうにインストールされるrpmなphpです。

# php -v
PHP 5.1.6 (cli) (built: Mar 31 2010 02:44:37)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies