【PHP】filter_input_array で送信されたデータをまとめて処理する

PHP

前の記事で filter_input をまとめたので、今回は filter_input_array をまとめます。ただ使い方はほとんどかわらず、まとめて処理したい時に役立つみたい。基本的にはこっち使って処理した方が設定値などがまとめて確認できるからいいと思ってます。
【PHP】filter_input を使って、文字列、論理値、配列を受け取ってみる

filter_input_array とは

filter_input と同じように送信されたデータをバリデーション混みで取得、変数に格納してくれます。これもバリデーションに失敗したら false で、空のデータの場合は null にしてくれるため、if などの条件分岐を作る手間が減ります。
filter_input と filter_input_array の違いはまとめてデータを取得するか、ひとつひとつ取得するかの違いで、いちいち filter_input を呼ぶ必要がなくなります。

マニュアルの記述

mixed filter_input_array ( int $type [, mixed $definition [, bool $add_empty = true ]] )

使用方法

試しにひとつだけ受け取って動作を確認してみます。

$filter = [
    "title" => FILTER_DEFAULT
];
$post_datas = filter_input_array(INPUT_POST, $filter);
var_dump($post_datas);
=> array (size=1)
    'title' => string 'タイトル' (length=12)
var_dump($post_datas["title"]);
=> string 'タイトル' (length=12)

これで $post_datas から添字で値を取得することができました。ちなみに filter_input と違って、デフォルトのフィルタはないみたいなので、連想配列で FILTER_DEFAULT などを設定しないと false になりました。省略したいのであれば別に関数を作る必要があります。
また特にバリデーションとか必要ないという場合は、第二引数自体を省略できますが、それだと特にこの関数を使う意味がなくなります。

共通のフィルタを使用する

全て同じフィルタで構わない場合は、第二引数にフィルタを指定してあげれば同じフィルタが適用されます。

$post_datas = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
var_dump($post_datas);
// $_POST = [
//   "title" => "<p>タイトル</p>"
//   "name" => "<p>ネーム</p>"
//   ];
array (size=2)
  'title' => string 'タイトル' (length=12)
  'name' => string 'ネーム' (length=9)

このようにどちらのタグもサニタイズしてくれます。

POST以外

第一引数の取得できる値は filter_input 同様に以下の種類があります。

  • INPUT_GET
  • INPUT_POST
  • INPUT_COOKIE
  • INPUT_SERVER
  • INPUT_ENV

バリデート、サニタイズ

こちらも filter_input と全く同じものが使えます。
詳しくは以下の記事か公式のマニュアルを確認してください。
【PHP】filter_input を使って、文字列、論理値、配列を受け取ってみる
フィルタの型

使い方は簡単なので、これ以上説明は必要ないかと思います。せっかくなのでもう少し多く値を取得する例をあげたいと思います。

<form action="" method="post">
  <div class="form-group">
    <label for="">String</label>
    <input class="form-control" type="text" name="str">
  </div>
  <label for="">Array</label>
  <div class="form-check">
    <input type="checkbox" name="arr[]" value="1" class="form-check-input" id="Check_1">
    <label class="form-check-label" for="Check_1">Check_1</label>
    <input type="checkbox" name="arr[]" value="2" class="form-check-input" id="Check_2">
    <label class="form-check-label" for="Check_2">Check_2</label>
  </div>
  <div class="form-group">
    <label for="">Boolean</label>
    <input class="form-control" type="text" name="bool">
  </div>
  <div class="form-group">
    <label for="">Integer</label>
    <input class="form-control" type="text" name="int">
  </div>
  <div class="form-group">
    <input class="btn btn-primary" type="submit" value="Add">
  </div>
</form>
$filter = [
    "str" => [
      "filter" => FILTER_SANITIZE_STRING,
      "flags" => FILTER_FLAG_STRIP_BACKTICK | FILTER_FLAG_ENCODE_HIGH
    ],
    "arr" => [
      "flags" => FILTER_REQUIRE_ARRAY
    ],
    "bool" => FILTER_VALIDATE_BOOLEAN,
    "int" => [
      "filter" => FILTER_VALIDATE_INT,
      "options" => [
        "max_range" => 10,
        "min_range" => 5
      ]
    ]
];
$post_datas = filter_input_array(INPUT_POST, $filter);
var_dump($post_datas);

この設定に対して、以下のようにデータを送信すると

//$_POST = [
//  "str" => "`タイトル`",
//  "arr" => [1,2],
//  "bool" => "true",
//  "int" => "5"
//];
array (size=4)
  'str' => string '&#227;&#8218;&#191;&#227;&#8218;&#164;&#227;&#402;&#710;&#227;&#402;&#171;' (length=72)
  'arr' => 
    array (size=2)
      0 => string '1' (length=1)
      1 => string '2' (length=1)
  'bool' => boolean true
  'int' => int 5

このようにオプション通りに str の部分がエンコードされていますね。このフォームだとバリデートで false になるのは bool と int になります。試しにデータを送信してみます。

//$_POST = [
//  "str" => "example",
//  "arr" => [],
//  "bool" => "example",
//  "int" => "1"
//];
array (size=4)
  'str' => string 'example' (length=7)
  'arr' => null
  'bool' => boolean false
  'int' => boolean false

FILTER_VALIDATE_BOOLEAN はデフォルトで “1”, “true”, “on”, “yes” 以外のものが入っている場合には false になります。false 以外を null にしたい場合は flags に FILTER_NULL_ON_FAILURE を指定します。
また送信された int はオプションで max_range, min_range が指定されているため、範囲外の数値が false になっています。
上記のように変数に配列で指定されているので、まとめてフィルタなどが確認できる点が filter_input_array の利点の一つだと思います。

問題点

filter_input_array は多次元配列だと指定することができません。その場合はちまちま ffilter_input で設定していくしかありません。ただ qiita で以下の記事を見つけました。これを使えば、多次元配列であっても対応することが可能です。
filter_input_array_recursive
こういうバリデート関係はやっぱりライブラリに頼ったほうが楽なんだろうな。。

まとめ

filter_input に続いて、 filter_input_array に関してまとめてみました。
ただ結局エラーメッセージとかもまとめて設定したいし。。ってなるとライブラリに落ち着きますよね。
ただそういうものに頼る前に内部の仕組みを知ることが大事!ということで。

コメント