9

[symfony]ログイン認証バリデータ(データベース接続)のサンプル

Tag: phpuechoco @ 20 : 42 : 29

symfony1.1で、メールアドレスとパスワードによるログインフォームを作りたい。

ログインフォーム

ログインフォーム

メンバー情報などが記録されたMemberテーブルは以下の仕様

TEXT:
  1. propel:
  2. member:
  3. _attributes: { idMethod: native }
  4. id: { type: INTEGER, required: true, autoIncrement: true, primaryKey: true }
  5. name: { type: VARCHAR, size: '255', required: true, default: '' }
  6. mail_pc: { type: VARCHAR, size: '255', required: true, default: '' }
  7. password: { type: VARCHAR, size: '255', required: true, default: '' }
  8. created_at: { type: TIMESTAMP }
  9. updated_at: { type: TIMESTAMP }
  10. last_logined_at: { type: TIMESTAMP }
  11. is_admin: { type: TINYINT, default: '0' }
  12. enabled: { type: TINYINT, required: true, default: '1' }

ログインフォームに必要なバリデータは、個々の項目(mail_pc、password)のバリデートと、データベースへの問い合わせの2つ。個々の項目のバリデートはバリデータを使えばすぐにできそう。以下のような感じ。

php:
  1. class LoginForm extends sfForm
  2. {
  3. public function configure()
  4. {
  5. $this->setWidgets(array(
  6. 'mail_pc'  => new sfWidgetFormInput(array(), array('size' => 50)),
  7. 'password' => new sfWidgetFormInputPassword(array(), array('size' => 32)),
  8. ));
  9.  
  10. $this->widgetSchema->setLabels(array(
  11. 'mail_pc'  => 'PCメールアドレス',
  12. 'password' => 'パスワード',
  13. ));
  14.  
  15. $this->widgetSchema->setNameFormat('login[%s]');
  16.  
  17. $this->setValidators(array(
  18. 'mail_pc'  => new sfValidatorEmail(
  19. 'required' => 'メールアドレスを入力してください。',
  20. 'invalid'  => 'メールアドレスが正しくありません。'
  21. )
  22. ),
  23. 'password' => new sfValidatorString(
  24. array('min_length' => 6, 'max_length' => 64),
  25. 'required'   => 'パスワードを入力してください。',
  26. 'min_length' => 'パスワードは%min_length%文字以上です。',
  27. 'max_length' => 'パスワードは%max_length%文字以下です。',
  28. )
  29. )
  30. ));
  31. }
  32.  
  33. }

エラー処理とかもバリデータが一括で請け負ってくれるので、データベースへの問い合わせもバリデータにすればすっきりすると思って、作ろうと思ったけど、ネット上に資料が少ない。どうやっていいかよくわからない。

とりあえず、複数項目のバリデートだから、validatorSchemaのsetPostValidator()に登録するんじゃないかと気づく。こんな感じでsfValidatorSchemaLoginクラスを作ってみた。

php:
  1. /**
  2. * sfValidatorSchemaLogin
  3. *
  4. * @package    Travi
  5. * @subpackage validator
  6. */
  7. class sfValidatorSchemaLogin extends sfValidatorBase
  8. {
  9. /**
  10. * @see sfValidatorBase
  11. */
  12. protected function doClean($values)
  13. {
  14. if ($values['mail_pc'] != '' && $values['password'] != '') {
  15. // 両パラメータが与えられたときだけ実行
  16. $encrypted_password = myUtil::encrypt($values['password']);
  17. if (MemberPeer::isValidUser($values['mail_pc'], $encrypted_password)) {
  18. return $values;
  19. } else {
  20. throw new sfValidatorError($this, 'invalid', array());
  21. }
  22. }
  23. return $values;
  24. }
  25. }

このクラスのミソは、必要なパラメータ(メールアドレスとパスワード)がそろったときだけ、データベースに問い合わせること。なぜかというと、メールアドレスかパスワードのバリデータが成功した時点でデータベースの問い合わせをした方が効率がいいので。

最後に、LoginFormのPostValidatorを登録

php:
  1. $this->validatorSchema->setPostValidator(
  2. new sfValidatorSchemaLogin(
  3. 'invalid'  => 'メールアドレスかパスワードが間違っています。'
  4. )
  5. )
  6. );

意外と簡単にいけたけど、もっとスマートな方法ないかなぁ。。。Propel系の標準Validatorがいまいちよくわからないんだな。

Leave a Reply