▼ 2008/02/24(日) VALID_NOT_EMPTYの思わぬ動作。CakePHP1.2bバリデーション
CakePHP1.2は1.1に比べて、バリデーション(varidation,varidate)の大幅な機能強化が図られている。
ここでは、NOT EMPTY についてはまった点があったので覚書として書いておきます。
1.2bの話であって、1.1については知りません。
関数が true を返すか、false を返すか。
全部、当てられる人がいたら、それはそれで恐ろしい。
2つの場合で、 パラメータがセットされていない場合に、 true になっています。なぜかと調べると、この2つの場合は、
'allowEmpty'=>false と 'required'=>true のチェックをした後に、
array_key_exists($fieldName, $data)
というチェックで、unset の場合(キーが存在しない場合) には、そのまま 正規表現のループに入る前に、tureで処理を抜けてしまいます。
変数がセットされていれば、バリデーションの個々のルーチンに入るか、正規表現チェックを行います。
なるほど他の言語のバリデーションも、値の要求 と 値が空かどうか、 は全く別のものとして、考えられているようです。
私は、空でない値が欲しい = 値が空かどうか、 だけしか考えないことがはまった原因です。はい。
本当は
(通常は、未定義の変数はフォームからはこない、という前提であるならば)
でも、悪意をもった人がPOSTしてきたり、chekboxの値*2などを取得するときは注意が必要かと思います。
その場合は、'required'=>trueは、なくても大丈夫かと思います。
チェックボックスにチェックがない場合でもデータを送信する
Sun Limited Mt-CakePHP1.2 のバリデーション
ここでは、NOT EMPTY についてはまった点があったので覚書として書いておきます。
1.2bの話であって、1.1については知りません。
結論
値の要求 と 値が空かどうか のバリデーションは別個のものである。
通常、値が欲しいフィールドについて、
VALID_NOT_EMPTY を使う時には、必ず、'required'=>true を使用すること
(データベースのdefault値を設定していて、かつ、$this->Model->create($this->data);をバリデーションの前に実施している場合は、'required'=>trueはなくてもいいかも)
検証
$this->Model->validates()関数が true を返すか、false を返すか。
全部、当てられる人がいたら、それはそれで恐ろしい。
'rule'=> VALID_NOT_EMPTYが前提です。
| 他パラメータなし | 'required'=>true | 'allowEmpty'=>false, | (参考) 'required'=>true の理論上の動作 | |
| unset | true ←attention | false | true ←attention | false |
| null | false | false | false | false |
| '' | false | false | false | true |
| \n(LF) | false | false | false | true |
| \r(CR) | true | true | true | true |
| 半角空白 | true | true | true | true |
| 全角空白 | true | true | true | true |
| ゼロ | true | true | true | true |
| '00' | ture | true | true | true |
| false(論理型) | false | false | false | true |
| 'false'(文字列型) | true | true | true | true |
| 判別法 | 正規表現'/.+/' | ! isset+正規表現 | isset+empty &not numeric+ 正規表現 | |
| false になるもの | 正規表現'/.+/'と同等 | null値 | 値がnullでなく、 emptyと評価される、 数値以外のもの。 |
留意点
'rule'=>VALID_NOT_EMPTY の場合の VALID_NOT_EMPTY は、定数で、「/.+/」と定義されていますので、要は正規表現だけで判別しているということです。混乱した点
attentionの部分をみてください。2つの場合で、 パラメータがセットされていない場合に、 true になっています。なぜかと調べると、この2つの場合は、
'allowEmpty'=>false と 'required'=>true のチェックをした後に、
array_key_exists($fieldName, $data)
というチェックで、unset の場合(キーが存在しない場合) には、そのまま 正規表現のループに入る前に、tureで処理を抜けてしまいます。
変数がセットされていれば、バリデーションの個々のルーチンに入るか、正規表現チェックを行います。
変数がセットされていない場合(キーが存在しない、unsetな場合)という仕様になっています。
'required'=>true の時には、 unset な変数は false となるのに、
'allowEmpty'=>false と VALID_NOT_EMPTY (&ただの正規表現だけの時も妥当する)
の時は、そのフィールドに設定された他のバリデーションルールを実行せずに、true を返す*1
なるほど他の言語のバリデーションも、値の要求 と 値が空かどうか、 は全く別のものとして、考えられているようです。
私は、空でない値が欲しい = 値が空かどうか、 だけしか考えないことがはまった原因です。はい。
本当は
空でない値が欲しい = 値の要求 + 値が空でないとなるわけですね。
留意点
CakePHPのバリデーションの書き方はさまざまな書き方があって、それは、cakePHP 1.2のバリデーションを理解するが詳しいのですが、unset値も確実にerrorにしたい場合は、下記の簡便的な指定は避けた方がいいかと思います。×
var $varidate = array(
' fieldname ' => VALID_NOT_EMPTY
);
留意点の留意点
通常、HTMLのフォームから入力された場合( input type="text" )、ユーザーが何も入力しなくても、空文字列'' はセットされますので、必ずしも、'required'=>true がなくても、通常の使用の範囲でなら、問題がでないことも多いかと思います。(通常は、未定義の変数はフォームからはこない、という前提であるならば)
でも、悪意をもった人がPOSTしてきたり、chekboxの値*2などを取得するときは注意が必要かと思います。
留意点の留意点2
データベースのdefault値を設定していて、かつ、$this->Model->create($this->data);をバリデーションの前に実施している場合は、当該デフォルト値が、$this->Model->dataにセットされるので、変数が未定義のままバリデーションに突入する、ということはないかと思います。その場合は、'required'=>trueは、なくても大丈夫かと思います。
参考にさせていただいたサイト
cakePHP 1.2のバリデーションを理解するチェックボックスにチェックがない場合でもデータを送信する
Sun Limited Mt-CakePHP1.2 のバリデーション
▼ コメント(0件)
- TB-URL http://www.cpa-lab.com/tech/096/tb/