[PHP] POSTで大量のkeyを渡す時はphp.iniのmax_input_varsに注意

2020/01/26

author

masyus

PHPで1つの画面から一度に大量のkeyをサーバーサイドへPOST時、

POSTしたデータをDBに保存しようとしたら途中までしか保存できていなかった

ということがありました。今回はその原因と解消方法について紹介いたします。対象となるPHPバージョンは5.3.9以降です。

一度のPOSTでサーバーサイドに渡せるkeyには上限値が設定されている

結論から言いますとPHPの設定を司るphp.inimax_input_varsという設定値がありまして、これがPOST時にサーバーサイドに渡せる入力変数の最大数を制御していたことで今回紹介した事象が発生していました。

max_input_varsの設定を超える量の入力変数を渡した場合、PHP処理は途中で止まることなく進んでいきますが、Apache側のエラーログに下記のようなWarningが吐き出されます。

[Sun Jan 26 h:i:s yyyy] [warn] [client X.X.X.X] PHP Warning: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0, referer: https://masyus.work/

このログは

「1000より大きい入力変数は対応できない(=超えた分は削ぎ落とされる)

ことを意味しています。これを解消するには

max_input_varsを適切な数字に設定し、Webサーバーを再起動(Apacheの場合はgraceful)する

ことで、入力変数が1000個以上でも対応できるようになります。もしmax_input_varsの設定をコメントアウトしていた場合、デフォルト値として1000が適用される点も注意です。

また、今回検証していませんがGETやCOOKIEに関しても同じ設定が適用されるようです。例えばURLに大量のクエリパラメータを使うような場合にも注意してみてください。(ただ、、そもそもそこまで多量の入力変数を取り扱う必要が本当にあるのかを先に見直すほうが適切かもしれません)

max_input_varsの上限に引っかかった実例

実際にmax_input_varsの上限に引っかかった実例としては

都道府県市区町村のチェックボックスに1つずつチェックを入れて、サーバーサイド側にPOSTする実装

がありました。全国の市区町村は1000を超えるからです。

「そもそも1000を超える都道府県のチェックボックスはUI/UXの観点でいかがなものか?」

と言われても仕方ないですが、実際にオペレーションが滞る事態でしたので取り急ぎmax_input_varsの値を変更して凌いだ経験があります。ですが、max_input_varsの存在理由は不用意に多数の入力変数を渡せないようにすることでセキュリティを高めることにあるため、そのような実装はそもそもしないようにするのがやはり良いです。

参考