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】$_POSTを扱いやすくする妄想設計

Posted at

妄想設計とは

妄想設計とは実装はしたことないが、こんな設計良さそう、という妄想の結果の設計である。
もちろん実用性などはない(キリ)。

$_POST の値

APIを書いていると$_POSTからデータを取ってくることがある。

$age = $_POST['age'];

だが、$_POSTに入っているデータはユーザーからの投稿データであり、基本的にデータは信用できない。
そのため、サニタイズやバリデーションが必要になる。
上記のageだったらサニタイズは

$age = intval($age);
if ($age === 0) {
    // 0歳児はサポート外
    throw new \Exception('invalid age value');
}

で可能だが、これをさっきのコードに書くと

$age = $_POST['age'];
$age = intval($age);
if ($age === 0) {
    // 0歳児はサポート外
    throw new \Exception('invalid age value');
}

となるわけだが、ageだけでなくweightも必要だとすると、

$age = $_POST['age'];
$age = intval($age);
if ($age === 0) {
    throw new \Exception('invalid age value');
}

$weight = $_POST['age'];
$weight = intval($age);
if ($weight === 0) {
    throw new \Exception('invalid weight value');
}

こんな感じでダラダラと書くことになってしまう。
はー、ダラダラするのは開発者だけでいいんですよ。コードはキリっとしてないとダメです。

APIごとにデータを検証するクラスを書く。

フレームワークなどはモデルというクラスがあって、そのモデルでデータを検証したりする。
フレームワークを使う場合は投稿データはモデルに突っ込んでデータ検証すればいい。
だが、なにも$_POSTのデータはすべてモデルに入れてデータベースに保存するわけではない。
保存しないデータもあるが、それももちろん検証と無害化はしないといけない。

よってAPIごとに$_POSTのデータを包むクラスを書くという妄想をする。

PostPersonData

class PostPersonData {
    function __construct($ary) {
        $this->age = $ary['age'];
        $this->weight = $ary['weight'];
    }

    function sunitize() {
        $this->age = intval($this->age);
        $this->weight = intval($this->weight);
    }

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

こんなクラスをAPIのURLごとに用意する。
するとさきほどのコードは以下のように書くことができる。

$data = new PostPersonData($_POST);
$data->sunitize();

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

うーん、エレガント!すき!だいしゅき!

フレームワークを使っていてモデルへデータを変換する場合は以下のようなメソッドも定義できるだろう。

$person = $data->to_model();
$person->save();

だが、データのバリデーションはモデルにも書くし、そうすると二度手間になる。
モデルにデータの検証を書いているのに、$_POSTのクラスにも検証方法を書かないといけないのかい! となる。たしかに~。

おわりに

今日の妄想はここまでとする。
妄想を現実にして実装する日は近い。かもしれない。

0
0
6

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?