LoginSignup
3
1

More than 5 years have passed since last update.

PHPでパラメータのバリデートユーティリティを作ってみた

Last updated at Posted at 2017-02-01

コントローラのメソッド上部に並ぶパラメータのバリデーションの塊・・・嫌ですね。
なんとかスッキリさせたいと思い、試行錯誤した結果以下のようなものができました。

ターゲット

例えばこんなコード。ため息でる。
こんなコードそもそも書かない?それは素晴らしい!

$roomName      = isset($_GET["room_name"]) ? $_GET["room_name"] : null;
$remoconTypeId = isset($_GET["remocon_type_id"]) ? $_GET["remocon_type_id"] : null;
$operationId   = isset($_GET["operation_id"]) ? $_GET["operation_id"] : null;
$startTime     = isset($_GET["start_time"]) ? $_GET["start_time"] : null;
$endTime       = isset($_GET["end_time"]) ? $_GET["end_time"] : null;

// チェック処理
if($roomName == null) {

    echo "ルーム名 が未入力です。";
    return;
}
else if(!in_array($roomName, ['A', 'B', 'C'])) {

    echo "不正な ルーム名 です。";
    return;
}

if($remoconTypeId == null) {

    echo "リモコン種別 が未入力です。";
    return;
}
else if(!is_numeric($remoconTypeId)) {

    echo "不正な リモコン種別 です。";
    return;
}

if($operationId == null) {

    echo "操作種別 が未入力です。";
    return;
}
else if(!is_numeric($remoconTypeId)) {

    echo "不正な 操作種別 です。";
    return;
}

if($startTime != null && $startTime !== date("Y-m-d H:i:s", strtotime($startTime))) {

    echo "不正な 開始日付 です。";
    return;
}

if($endTime != null && $endTime !== date("Y-m-d H:i:s", strtotime($endTime))) {

    echo "不正な 終了日付 です。";
    return;
}

共通化する

パラメータの存在チェックと、任意のバリデートがかけられるような共通関数を作りました。
オプショナルなパラメータについては、パラメータが存在するときのみバリデートをかけます。
エラーメッセージのバリエーションについては一旦無視します。$validationListerrorとかってキーでエラーメッセージ持たせればできそうですが。

public function validateParams($params, $validationList) {

    foreach ( $validationList as $validation ) {

        // existance
        $key = $validation["key"];
        $optional = isset($validation["optional"]) ? $validation["optional"] : false;
        if ( !$optional && !isset($params[$key]) ) {
            $error = [
                "error" => "missing params",
            ];
            $this->response($error); // レスポンスを返す関数
            exit;
        }

        // other validations
        $validate = $validation["validate"];
        if ( $optional && !isset($params[$key]) ) {
            continue;
        }
        $param = $params[$key];
        if ( !$validate($param) ) {
            $error = [
                "error" => "invalid params",
            ];
            $this->response($error); // レスポンスを返す関数
            exit;
        }
    }
}

共通関数を呼び出す

第一引数にチェックしたいパラメータ、第二引数にチェックしたい条件をまとめた配列を作って渡します。

$params = $_GET;
$this->validateParams(
    $params,
    [
        [
            "key"      => 'room_name',
            "validate" => function($param) {return in_array($param, ['A', 'B', 'C']);},
        ],
        [
            "key"      => 'remocon_type_id',
            "validate" => function($param) {return is_numeric($param);},
        ],
        [
            "key"      => 'operation_id',
            "validate" => function($param) {return is_numeric($param);},
        ],
        [
            "key"      => 'start_time',
            "validate" => function($param) {return $param === date("Y-m-d H:i:s", strtotime($param));},
            "optional" => true,
        ],
        [
            "key"      => 'end_time',
            "validate" => function($param) {return $param === date("Y-m-d H:i:s", strtotime($param));},
            "optional" => true,
        ],
    ]
);

おわりに

多少良くはなったけど、筋がいい感じはしない。やっぱりフレームワークのバリデート使うのがいいんですかね。
そもそもターゲットのコードがひどすぎると言われたらその通りです。でもこの世には結構存在するんですよ。。。しかも色々な事情でリファクタリングしにくいってのが。。。

3
1
4

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
3
1