fuelPHP Validation::forge()の名前付けについて
前の記事を書いたときに、forge()の()内には名前を入れられる、と言う風に書きました。
自分は全然気にしてなかったのですが、なぜ名前を入れられるのか、名前を入れる意味は?ということで先輩が妙な考えを言っていました。
今回たまたま名前が必要な場面が見つかったので書いておきます。
このバリデーションの名前付け、どんな時に必要かというとループ処理で1つ1つ連番フォームになっているSQLを実行する時に役立ちました。
name=num1
name=num2
name=num3
name=num4
name=num5
name=num6
name=num7
name=num8
name=num9
name=num10
例えばこんなフォームがあったとします
送信を押したとき、上から一つずつバリデーションをチェックしてinsertをしようとなったとき
$validation = Validation::forge();
$validation->add_callable( 'myvalidation' );
for($i = 1 ; $i <= 10 ; $i++)
{
$validation->add( 'num'.$i , '数字欄' )->add_rule('num')->add_rule('required');
if( $validation->run() )
{
DB::insert('test_table')->column('num')->values( Input::post('num'.$i) )->execute();
}
else
{
echo '半角数字以外が入っています。';
}
}
こんな感じに書きます。
Validation::forge();はループ内に入れると「このバリデーションは既にインスタンス作ってるよ」と怒られるので外に置いてます。
ルールはフォームの中身が数値かどうか、値は入っているかの2つ。
数値かどうかだけだと未入力はtrueになるらしいのでadd_rule('required')も入れてます。
このまま順当に処理を進めていくとABCが入ってるnum6の部分と空欄のnum7の二ヶ所でelseに入りますね。
その下のnum8~num10はちゃんとした数字が入っていますが・・・この部分もelseになります。
何故かというと一つのバリデーションにルールを1個ずつ追加してしまっているからです。
つまり初回は num1 が数値かどうかのバリデーション。
2周目は num1とnum2 が数値かどうかのバリデーション。
3周目は num1とnum2とnum3 が数値かどうかのバリデーション。
4周目は・・・とどんどんルールが追加されていきます。
なので num8~num10 は num6とnum7のバリデーションが通らないのでちゃんとした数字が入っていてもダメになるわけです。
正確にはバリデーションは追加した順から見ていって、通らなかった部分で処理を止めるのでnum6でダメだったから後はいいやって感じです。
ループする度ルールを初期化する方法は無いのかと探してみたのですが見当たりませんでした・・・
ループの数だけvalidation用の変数とか配列を作るのも何かやだ・・・そんな時に名前付けが役立ちます。
for($i = 1 ; $i <= 10 ; $i++)
{
$validation = Validation::forge($i);
$validation->add_callable( 'myvalidation' );
$validation->add( 'num'.$i , '数字欄' )->add_rule('num')->add_rule('required');
if( $validation->run() )
{
DB::insert('test_table')->column('num')->values( Input::post('num'.$i) )->execute();
}
else
{
echo '半角数字以外が入っています。';
}
}
Validation::forge();をループ内にいれ、毎回数値がカウントアップする名前を入れておけばループする度新しい名前のバリデーションが追加され、ループする度個別のルールを入れることができます。