Validation Example

验证实例

本实例将会创建用户帐号并演示如何操作模型和控制器进行验证。我们首先创建一个处理后的form表单,并提示部分错误给用户。我们假定 Model_User 类已经包含一个名为 hash_password 的用于将明文转为密文的方法。如果您欲使明文加密方法超出该该实例中的加密范围,您可考虑使用Authentication库。 原文

SQL schema

  1. CREATE TABLE IF NOT EXISTS `members` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `username` varchar(32) NOT NULL,
  4. `password` varchar(100) NOT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

Model

  1. <?php defined('SYSPATH') or die('No direct access allowed.');
  2. class Model_Member extends ORM {
  3. public function rules()
  4. {
  5. return array(
  6. 'username' => array(
  7. array('not_empty'),
  8. array('min_length', array(':value', 4)),
  9. array('max_length', array(':value', 32)),
  10. array(array($this, 'username_available')),
  11. ),
  12. 'password' => array(
  13. array('not_empty'),
  14. ),
  15. );
  16. }
  17. public function filters()
  18. {
  19. return array(
  20. 'password' => array(
  21. array(array($this, 'hash_password')),
  22. ),
  23. );
  24. }
  25. public function username_available($username)
  26. {
  27. // There are simpler ways to do this, but I will use ORM for the sake of the example
  28. return ORM::factory('member', array('username' => $username))->loaded();
  29. }
  30. public function hash_password($password)
  31. {
  32. // Do something to hash the password
  33. }
  34. }

HTML Form

请忽略我这简陋的form表单,我只是不想尝试使用任何模块和不相干的方法。 :) 原文

  1. <form action="<?= URL::site('/members'); ?>" method="post" accept-charset="utf-8">
  2. <label for="username">Username:</label>
  3. <input id="username" type="text" name="username" value="<?= Arr::get($values, 'username'); ?>" />
  4. <label for="username" class="error"><?= Arr::get($errors, 'username'); ?>
  5. <label for="password">Password:</label>
  6. <input id="password" type="password" name="password" value="<?= Arr::get($values, 'password'); ?>" />
  7. <label for="password" class="error"><?= Arr::get($errors, 'password'); ?>
  8. <label for="password_confirm">Repeat Password:</label>
  9. <input id="password_confirm" type="password" name="_external[password_confirm]" value="<?= Arr::path($values, '_external.password_confirm'); ?>" />
  10. <label for="password_confirm" class="error"><?= Arr::path($errors, '_external.password_confirm'); ?>
  11. <button type="submit">Create</button>
  12. </form>

Controller

[!!] 切忌, password 会在被模型赋值时候进行加密,由于此原因,有必要进字符长度、 password_confirm 匹配的验证。由于模型不进行 password_confirm 列的验证,因此我们需要在controller中增加简单逻辑,并将错误信息存入一个数组。阅读 filters 文档,了解如何工作。 原文

  1. public function action_create()
  2. {
  3. $view = View::factory('members/create')
  4. ->set('values', $_POST)
  5. ->bind('errors', $errors);
  6. if ($_POST)
  7. {
  8. $member = ORM::factory('member')
  9. // The ORM::values() method is a shortcut to assign many values at once
  10. ->values($_POST, array('username', 'password'));
  11. $external_values = array(
  12. // The unhashed password is needed for comparing to the password_confirm field
  13. 'password' => Arr::get($_POST, 'password'),
  14. // Add all external values
  15. ) + Arr::get($_POST, '_external', array());
  16. $extra = Validation::factory($external_values)
  17. ->rule('password_confirm', 'matches', array(':validation', ':field', 'password'));
  18. try
  19. {
  20. $member->save($extra);
  21. // Redirect the user to his page
  22. $this->request->redirect('members/'.$member->id);
  23. }
  24. catch (ORM_Validation_Exception $e)
  25. {
  26. $errors = $e->errors('models');
  27. }
  28. }
  29. $this->response->body($view);
  30. }

Messages

application/messages/models/member.php

  1. return array(
  2. 'username' => array(
  3. 'not_empty' => 'You must provide a username.',
  4. 'min_length' => 'The username must be at least :param2 characters long.',
  5. 'max_length' => 'The username must be less than :param2 characters long.',
  6. 'username_available' => 'This username is not available.',
  7. ),
  8. 'password' => array(
  9. 'not_empty' => 'You must provide a password.',
  10. ),
  11. );

application/messages/models/member/_external.php

  1. return array(
  2. 'password_confirm' => array(
  3. 'matches' => 'The password fields did not match.',
  4. ),
  5. );