コントローラのメソッド上部に並ぶパラメータのバリデーションの塊・・・嫌ですね。
なんとかスッキリさせたいと思い、試行錯誤した結果以下のようなものができました。
ターゲット
例えばこんなコード。ため息でる。
こんなコードそもそも書かない?それは素晴らしい!
$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;
}
共通化する
パラメータの存在チェックと、任意のバリデートがかけられるような共通関数を作りました。
オプショナルなパラメータについては、パラメータが存在するときのみバリデートをかけます。
エラーメッセージのバリエーションについては一旦無視します。$validationList
にerror
とかってキーでエラーメッセージ持たせればできそうですが。
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,
],
]
);
おわりに
多少良くはなったけど、筋がいい感じはしない。やっぱりフレームワークのバリデート使うのがいいんですかね。
そもそもターゲットのコードがひどすぎると言われたらその通りです。でもこの世には結構存在するんですよ。。。しかも色々な事情でリファクタリングしにくいってのが。。。