用户
 找回密码
 入住 CI 中国社区
搜索
查看: 8714|回复: 6
收起左侧

[分享][翻译]官方教程第五篇:Built-in Model Validation

[复制链接]
发表于 2008-1-12 12:19:10 | 显示全部楼层 |阅读模式
Built-in Model Validation
模型的内建验证
Make your models self-contained with built-in validation and database access.
使你的模型中包含内置验证机制和数据库访问权限。
Please note that this tutorial assumes that the user has a bit of experience setting up Kohana 2 websites.
请注意这个教程假设用户有一定的利用 Kohana2 建站的经验。
This tutorial level is Advanced.
这个教程的等级为高级。
Introduction
介绍
In this tutorial, we will set up a User Model, complete with "fake" ORM and built in validation. I have started moving all my validation needs into my models, so that I could clear up the clutter in my controllers and make everything more logical.
在这个教程中,我们将设置一个 User 模型,完全的使用伪 ORM[也没看懂] 并内建验证。我已经开始把所有的需要的验证都放入到我的模块中,因此我可以保持我的控制器清爽并使所有的事情都变得逻辑化。
When you hear the 'M' in MVC, the M stands for Model. It is meant to model actual "things" (usually stored in a database, although they could also model static objects, like circles and physics equations ;)). This should include performing sanity checks on it's input before it tries to modify itself. This is the reason you should put validation checks in your model. From a MVC architecture standpoint, it "just makes sense."
当你听到 MVC 中的 'M' ,这个 M 表示模型。意思是模型化具体的事物(通常被存储在数据库中,他们同样可以 模型化静态对象,比如[几何中的]圆和物理中的方程;))。这需要在处理“输入”之前对其进行检查。这就是为什么要把验证放到模型中。从 MVC 结构出发,这就是它的意义。
To start we will create a model with our basic variables. The variables will match our database columns.
首先,我们使用基础变量创建一个模块。这些变量和数据库的列相匹配。
PHP复制代码
<?php
class User_Model extends Model {
 protected $id;
 protected $username;
 protected $password;
 protected $email;
 protected $address;
 protected $city;
 protected $state;
 protected $zip;
 protected $last_login;
}
?>
复制代码

Since we want validation inside the model, let's declare a rules vairable to hold our rules, field names and if the field has been validated yet:
既然我们需要在模型内部验证,我们描述一下这些规则变量来设置规则,字段名和是否已验证[TRUE/FALSE]。

PHP复制代码
 
<?php
class User_Model extends Model {
 protected $id;
 protected $username;
 protected $password;
 protected $email;
 protected $address;
 protected $city;
 protected $state;
 protected $zip;
 protected $last_login;
 
 private $rules = array(
     'ad'       => array('name' => 'User ID', 'rules' => '', 'valid' => FALSE),
     'username' => array('name' => 'Username', 'rules' => 'required[3,35]', 'valid' => FALSE),
     'password' => array('name' => 'Password', 'rules' => 'required[3,25]', 'valid' => FALSE),
     'email'    => array('name' => 'Email', 'rules' => 'valid_email|required', 'valid' => FALSE),
     'zip'      => array('name' => 'ZIP Code', 'rules' => 'numeric|require'),'valid' => FALSE)
    );
 
 public $validation;
 private $validated = FALSE;
 
 //Magic function
 public function __construct() {
  $this->validation = new Validation();
 }
}
?>
复制代码

This will define our validation rules and fields.
这定义了我们验证的规则的字段名。
We want our model to have some psuedo ORM capabilities. This will include easily setting and fetching private fields, inserting/saving/fetching record sets, as well as deleting database rows. Next we will set up some magic php functions to get/set data in our model.
我们希望我们的模型拥有伪 ORM 性能。这将包括简单的存入、取出私有字段,插入/保存/取得 记录,同样也可以删除数据库中的行。下面我们在模型中设置一些php魔术函数来 取出/存入 数据。
PHP复制代码
<?php
 public function __set($key, $val) {
  // Make sure this key and value is valid
  // 确保 key 和 value 的值是合法的
  if (issent($this->$key)) {
   $this->validation->set_rules(array($key => $value),
       $this->rules[$key]['rules'],$this->rules[$key]['name']);
   
   if (!$this->validtaion->run()) {
    return FALSE;
   }
   
   // You win at life!
   // [认证成功]
   $this->$key = $var;
   $this->rules[$key]['valid'] = TRUE;
   
   // See if the whole thing is validated
   // 看看是否所有的都被验证了
   foreach ($this->rules as $key => $rule) {
    // If anything isn't validated, just return success
    // 如果还有未验证的,仅仅返回成功[$validated 仍然为 false]
    if ($rule['valid'] == FALSE) {
     return TRUE;
    }
   
    // Otherwise set validated and return
    // 否则设置 validate 并返回
    $this->validated = TRUE;
    return TRUE;
   }
  }
 }
 
 public function __get($key) {
  if (isset($this->$key))
   retrun $this->$key;
 
  return FALSE;
 }
?>
复制代码

As you can see in our __set() function, we are using our validation rules we defined above to make sure any data that is being set is actually sane data. We are also checking to see if all the keys have been validated, and if so, set our global validated check to TRUE.
正如你所看到的我们的  __set() 函数,我们使用前面定义的验证规则来确保所有被存入的值都是正确的。我们同样检查是否所有的键值都被验证过,如果都被验证过就将全局变量 $validated 设为 TRUE。
It might also be nice if we could set object properties with a big array instead of one at a time with __set(). Wil will make a set_fields() method for this:
如果我们能设置对象的属性为一个大的数组来取代一次只能通过 __set() 验证一个就爽了。我们将提供 set_fields() 方法来完成:
PHP复制代码
<?php
 public function set_fields($input) {
  $data      = array();
  $rules     = array();
  $fields    = array();
  $new_input = array();
 
  foreach ($this->rules as $key =>$value) {
   // Silently ignore invalid fields
   // 忽略非法字段
   $data[$key] = @$input[$key];
   $rules[$key] = $this->rules[$key]['rules'];
   $fields[$key] = $this->rules[$key]['name'];
   
   if (isset($data[$key]) and isset($input[$key])) {
    $new_input[$key] = $data[$key];
   }
  }
 
  $this->validation->set_rules($data, $rules, $fields);
 
  if ($this->validation->run()) {
   // Only set valid the keys that were
   // 仅将合法的 keys 设为 input
   foreach ($new_input as $key => $value) {
    $this->$key = $value;
    $this->rules[$key]['valid'] = TRUE;
   }
   
   // Check to see if everything is validated
   // 检查是否所有的都被验证了
   foreach ($this->rules as $key => $rule) {
    // If anything isn't validated, just return success
    if ($rule['rule'] == FALSE)
     return TRUE;
   }
   
   // Otherwise set validated and retrun
   // 然后设置 validated 并返回
   $ths->validated = TRUE;
   return TRUE;
  }
 
  return FALSE;
 }
?>
复制代码

Here you will see that it is basically a catch-all version of __set(), with some additional checks.
这里你看到的是一个基础的一揽子处理版的 __set(),增加了一些设置。

评分

参与人数 1威望 +5 收起 理由
Hex + 5 精品文章

查看全部评分

 楼主| 发表于 2008-1-12 12:21:55 | 显示全部楼层
<续>

Controller Code example
控制器代码示例
To use this model, we can write some code like this:
我们写如下代码来使用这个模型:
PHP复制代码
<?php
 $this->user = new User_Model();
 
 $this->user->set_fields($this->input->post());
 if ($rows = $this->user->save()) {
  // Display some succes page
 } else {
  // Display the form again with some error
  $view = $this->load->view('form', array('validation' => $this->user->validation));
 }
?>
复制代码

In addition, you can create new database rows:
另外,你可以创建新的数据库条目:
PHP复制代码
<?php
 $user = new User_Model();
 $user->username = 'test';
 $user->password = 'test';
 
 $user-save();
?>
复制代码

and delete rows:
删除条目:
PHP复制代码
<?php
 $user = new User_Model();
 
 $user->fetch(array('username' => 'test'));
 
 $user->delete();
?>
复制代码

You need to be careful when using the fetch method, as it has special behavior. If only one row is returned, it assigns the returned results to itself (as above), otherwise, it returns an array of User objects. Therefore, you need to test the result to see what kind of results you are getting back. If you aren't sure how many results are you are going to get back, use count().
你在使用 fetch 方法的时候要小心,因为它有特殊的行为。如果只有一个条目返回,它制定返回的结果给自己(如上),否则它会返回一个用户对象的属组。因此,你需要检侧这个结果判断你获得的返回是什么类型。如果你不去订有多少结果需要获取,请使用 count()。
Here we will delete all user accounts that are from Chicago.
这里我们删除所有来自芝加哥的的用户帐号.
PHP复制代码
<?php
 $user = new User_Model();
 
 // This might return more than one row
 // 这里可能返回多于 1 的条目
 $users = $user->fetch(array('city' => 'Chicago'));
 
 if (count($users) > 1) {
  forech ($users as $user) {
   if ($user->delete())
    continue;
   trow new Kohana_Exception('user.delete');
  }
 } else {
  $users->delete();
 }
?>
复制代码

Conclusion
总结
As you can see in this brief tutorial, putting your validation into your model can clean up your controller code in great ways.
如你在这个简单教程中所看到的,把验证放到模型中能够很好简化你的控制器。
I have also shown how to use models in true MVC fashion: to model and behave like real objects.
我还展示了在 MVC 方式中使用模型: 模型化和行为表现像一个对象。
I have provided a whole example class for you to play around with, and you can always email me at jeremy.bush@kohanaphp.com.
我提供了一个完整的类给你玩,你可以随时email我jeremy.bush@kohanaphp.com
I always appreciate any and all feedback!
我想来重视任何、所有的回馈!

[本篇完,下次再回:)]
发表于 2008-1-13 05:48:06 | 显示全部楼层
看贴不回贴是不道德的!楼主辛苦了!加分!!
 楼主| 发表于 2008-1-13 09:21:04 | 显示全部楼层

Hex 早啊~

看你的回复时间 “发表于 2008-1-13 05:48 ”
比我想象中早,也可以说比我想象中晚
注意休息啊~~哈哈
发表于 2008-1-14 09:36:32 | 显示全部楼层
多谢关心。。。。。。。。。哈哈。。。。。
发表于 2013-12-19 15:18:22 | 显示全部楼层
支持一下
发表于 2013-12-19 15:21:51 | 显示全部楼层
代码不完整啊,前面的都很好,最后没有完整的代码

本版积分规则