0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PHP】モデルデータのクリーニングと検証

Posted at

モデルのデータの検証

フレームワークを使えないレンタルサーバーで、生の$_POSTを検証する場合。
$_POSTはユーザーからの投稿データであり信用できないものである。
そのため検証やサニタイズが必要になる。

intデータのバリデーション

intのデータはコメントで教えてもらったfilter_varで検証できそう。

$valid = filter_var($_POST['age'], FILTER_VALIDATE_INT);
if ($valid === false) {
    die("invalid age");
}

この関数はパースに失敗するとfalseを返す。
$_POST['age']が整数でない場合はパースに失敗し、$validfalseになる。

floatデータのバリデーション

floatの場合はFILTER_VALIDATE_FLOATを使う。

モデル

データモデルのクラスを作る。
フレームワークは使えないので自前で作る。

class PersonModel {
    function __construct() {
        $this->age = null;
        $this->weight = null;
    }

    function clean() {
        $this->age = filter_var($this->age, FILTER_VALIDATE_INT);
        $this->weight = filter_var($this->weight, FILTER_VALIDATE_FLOAT);
    }

    function validate() {
        $this->clean();
        if ($this->age === false || $this->age < 0 || $this->age >= 200) {
            throw new \Exception('invalid age value');
        }
        if ($this->weight === false || $this->weight < 0 || $this->weight >= 500) {
            throw new \Exception('invalid weight value');
        }
    }
}

こんなクラスを作ったらPOSTデータを突っ込んでクリーニングと検証を行う。

$person = new PersonModel();
$person->age = $_POST['age'];
$person->weight = $_POST['weight'];

try {
    $person->validate();
} catch (\Exception $e) {
    die($e->getMessage());
}

try {
    $person->save();
} catch (\Exception $e) {
    die($e->getMessage());
}

クリーニングとバリデーションは分けてやるべきなのか?

このPersonModelではデータのクリーニングと検証を分けて行っている。
validate()内ではclean()を呼び出しているので、検証の時はデータのクリーニングを必ずやるようになる。

filter_var()の性質上、値をフィルタしてその返り値で検証するというものなので、検証とクリーニングを切り離すのは2度手間になりそう。

またクリーニングではメンバ変数に直接クリーンした値を入れているが、これは別のcleaned_dataなどを作ってそこに入れた方が、元のデータを損失しないで済む。これはDjangoなどの設計ではそうなっている。

しかしこういうのを突き詰めていくと・・・

しかしこういうことを考えると、今度はIntFieldクラスとかFloatFieldクラスとかが欲しくなる。
そうなるとフレームワーク作り始めてしまうのだが、こわいので手は出さず・・・。
うーん、プログラミングは時間泥棒、はまるとどこまでも吸い取られる!

おわりに

今まで整数の検証はintvalでやっていたが、filter_varなるものを教えてもらったのでよかった。
おわり。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?