LoginSignup
2
4

More than 5 years have passed since last update.

大量のPOST配列をJSONにしてPHPに送信することでPOST数を削減する

Last updated at Posted at 2019-02-07

概要

大量の配列をPOSTするページがあり、
PHPのmax_input_varsで設定された上限(デフォルト1,000個)に引っかかってしまい、
POSTデータがPHPで受け取れないという現象が起きていた。
(配列のPOSTでも1件ずつカウントされるんだ…)

そのため、FormをJSON形式にシリアライズしてPOSTし、
CakePHPでアンシリアライズするようにした。

環境

PHP5.6
CakePHP2

POSTしたいデータ

FormHelperでinputタグを出力している

echo $this->Form->hidden('Param1.' . $idx . '.id');
echo $this->Form->hidden('Param1.' . $idx . '.name');

結果のHTMLではname属性に以下のようにセットされる

<input type="hidden" name="data[Param1][1][id]" value="value1"/>
<input type="hidden" name="data[Param1][1][name]" value="value2"/>
<input type="hidden" name="data[Param1][2][id]" value="value3"/>
<input type="hidden" name="data[Param1][2][name]" value="value4"/>

JSでシリアライズ

submitイベントで以下の処理を発火させる。

var form = $('#form');

//formの全要素をJSON化してサブミット
var $fields = form.serializeArray();
for (var i = 0; i < $fields.length; i++) {
    //name属性の配列表記をドット記法に変換
    $fields[i].name = $fields[i].name.replace('data[', 'data.').split('][').join('.').replace(']', '');
}
form.after('<form id="formJson" action="" method="post"><input type="hidden" name="json" value="' + h($fields ? JSON.stringify($fields) : "") + '"></form>');
form = $('#formJson');

form.submit();

CakePHPでアンシリアライズ

とにかくdataに突っ込んでいるので '_method' もdataに入るようになったけど動いてるからいいか。

IshigurosController.php
if ($this->request->is('post') && $this->request->data('json')) {
    //Json形式のプロパティデータを連想配列形式へ変換する
    //Json形式でなければ何もしない
    $decoded = json_decode($this->request->data('json'), true);
    if ($decoded && json_last_error() === JSON_ERROR_NONE) {
        $request = Hash::expand(Hash::combine($decoded, '{n}.name', '{n}.value'));

        //'data'のみ特別処理する
        $requestData = [];
        if (isset($request['data'])) {
            $requestData = $request['data'];
            unset($request['data']);
        }

        foreach($request as $k => $v) {
            $this->request->data($k, $v);
        }

        foreach($requestData as $k => $v) {
            $this->request->data($k, $v);
        }
    }
}
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4