質問の概要
今PHPでバリデーションする処理を書いています。
バリデーションの内容としては、コンストラクタで受け取った配列の中身をチェックするような処理です。
そこで、バリデーション処理をリファクタリングしていてふと疑問に思いました。
PHPでバリデーションを書く際の最適な方法などはあるのでしょうか。
こんな感じの処理
既存のコードでは、このように1つでもエラーになったらすぐに return false
してました。
が、これだと複数のバリデーションに該当してても、どこでエラーになったかわかりづらく、テストも書きづらいという課題を感じました。
php
1class Hoge 2{ 3 private $hoge = array(); 4 private $logger = null; 5 6 public function __construct($hoge, $logger) 7 { 8 $this->hoge = $hoge; 9 $this->loger = $logger; 10 } 11 12 /** 13 * hogeのバリデーション 14 * 15 * @return boolean 16 */ 17 public function isValid() 18 { 19 if (!isset($this->hoge['id']) || !is_numeric($this->hoge['id'])) { 20 $this->logger->error('invalid_id'); 21 return false; 22 } 23 24 if (!isset($this->hoge['address']) || (strlen($this->hoge['address']) > 10)) { 25 $this->logger->error(sprintf('invalid_id id=%s', $this->hoge['id'])); 26 return false; 27 } 28 } 29} 30
こんな感じに修正してみた・・
そこで、クラスのプロパティに、 errors
というものを用意して、バリデーションに引っかかったらこのプロパティに内容を追加していこうと考えました。
そうすれば、ログも全部吐かれるし、テストも、 getErrors
のようなゲッターを用意して、エラーの配列が意図したものと一致してるかも確認できます。
ただ、1つ問題に遭遇しました。
これまで「この $hoge
の一意なキーとなる id
が存在していない」というエラー以外では、この id
をログに吐く事でログチェックをやりやすくしていました。
しかし、今回からは id
が存在しなくても他のバリデーションはするようにしたため、
最初のバリデーションでエラーになると、それ以降のバリデーションでエラーが起きた時にはログに吐く際の id
が定義されていないため、 undefined id
となってしまいます。
こういう問題ってどう解決したら良いのでしょうか。
最初の id
キーの存在チェックだけ return false
をしても良いかと思ったのですが、
ほかの部分との処理が異なっていてあまりすっきりしません。
php
1class Hoge 2{ 3 private $hoge = array(); 4 private $errors = array(); 5 private $logger = null; 6 7 public function __construct($hoge, $logger) 8 { 9 $this->hoge = $hoge; 10 $this->logger = $logger; 11 } 12 13 /** 14 * hogeのバリデーション 15 * 16 * @return boolean 17 */ 18 public function isValid() 19 { 20 if (!isset($this->hoge['id']) || !is_numeric($this->hoge['id'])) { 21 $this->errors[] = 'invalid_id'; 22 $this->logger->error('invalid_id'); 23 } 24 25 if (!isset($this->hoge['address']) || (strlen($this->hoge['address']) > 10)) { 26 $this->errors[] = 'invalid_address'; 27 $this->logger->error(sprintf('invalid_id id=%s', $this->hoge['id'])); 28 } 29 30 return count($this->errors) < 1; 31 } 32}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。