CakePHP Data Validation 数据检验
Data Validation 数据检验
Section 1 数据检验
创建自定义的检验规则可以确保model里的数据符合应用程序的业务规则(business rule),例如密码长度只能为8个字符,用户名只能包含字母,等等。 数据检验的第一步是在model里创建检验规则。我们在model的定义里通过Model::validate数组来实现这一规则,例如:
/app/models/user.php<?php
class User extends AppModel
{
var $name = 'User';
var $validate = array(
'login' => '/[a-z0-9\_\-]{3,}$/i',
'password' => VALID_NOT_EMPTY,
'email' => VALID_EMAIL,
'born' => VALID_NUMBER
);
}
?>
<?php
class User extends AppModel
{
var $name = 'User';
var $validate = array(
'login' => '/[a-z0-9\_\-]{3,}$/i',
'password' => VALID_NOT_EMPTY,
'email' => VALID_EMAIL,
'born' => VALID_NUMBER
);
}
?>
检验规则使用和Perl兼容的正则表达式来定义,其中一些常有的已被预定义了,位于/libs/validators.php。它们是:
VALID_NOT_EMPTY
VALID_NUMBER
VALID_MAIL
VALID_YEAR
如果在model定义里有任何检验规则出现(例如,在$validate数组里),它们将在执行保存操作的时候(例如,在执行Model::save()方法的时候)将被解析并检验数据。要验证数据也可以直接调用Model::validates()(返回false如果验证失败)和Model::invalidFields()(返回一个包含错误信息的数组)。
但是通常,数据都隐含在controller代码之中。下面的例子展示了怎样创建一个处理表单的action:
Form-handling Action in /app/controllers/blog_controller.php<?php
class BlogController extends AppController {
var $uses = array('Post');
function add ()
{
if (emptyempty($this->data))
{
$this->render();
}
else
{
if($this->Post->save($this->data))
{
//ok cool, the stuff is valid
}
else
{
//Danger, Will Robinson. Validation errors.
$this->set('errorMessage', 'Please correct errors below.');
$this->render();
}
}
}
}
?>
<?php
class BlogController extends AppController {
var $uses = array('Post');
function add ()
{
if (empty($this->data))
{
$this->render();
}
else
{
if($this->Post->save($this->data))
{
//ok cool, the stuff is valid
}
else
{
//Danger, Will Robinson. Validation errors.
$this->set('errorMessage', 'Please correct errors below.');
$this->render();
}
}
}
}
?>
这个action使用的view如下所示:
The add form view in /app/views/blog/add.thtml<h2>Add post to blog</h2>
<form action="<?php echo $html->url('/blog/add')?>" method="post">
<div class="blog_add">
<p>Title:
<?php echo $html->input('Post/title', array('size'=>'40'))?>
<?php echo $html->tagErrorMsg('Post/title', 'Title is required.')?>
</p>
<p>Body
<?php echo $html->textarea('Post/body') ?>
<?php echo $html->tagErrorMsg('Post/body', 'Body is required.')?>
</p>
<p><?=$html->submit('Save')?></p>
</div>
</form>
<h2>Add post to blog</h2>
<form action="<?php echo $html->url('/blog/add')?>" method="post">
<div class="blog_add">
<p>Title:
<?php echo $html->input('Post/title', array('size'=>'40'))?>
<?php echo $html->tagErrorMsg('Post/title', 'Title is required.')?>
</p>
<p>Body
<?php echo $html->textarea('Post/body') ?>
<?php echo $html->tagErrorMsg('Post/body', 'Body is required.')?>
</p>
<p><?=$html->submit('Save')?></p>
</div>
</form>
Controller::validates($model[, $model…])用来检查任何加到该model里的自定义检验。Controller::validationErrors()方法返回model抛出的任何错误信息,使得我们可以用tagErrorMsg()在view里显示它们。
如果你想执行一些不同于基于正则表达式的Cake验证的自定义验证规则,你可以用model的invalidate()方法来将一个字段(field)标价为不正确的。想象一下,当一个用户尝试创建一个已存在的用户名的时候,你需要在表单里显示一个错误信息。因为你无法让Cake用正则表达式来找出这个无效数据,你需要执行自己的检验,并且把该字段标记为无效来触发Cake对无效数据的通常处理流程。
这个controller也许和以下的代码类似:
<?php
class UsersController extends AppController
{
function create()
{
// Check to see if form data has been submitted
if (!emptyempty($this->data['User']))
{
//See if a user with that username exists
$user = $this->User->findByUsername($this->data['User']['username']);
// Invalidate the field to trigger the HTML Helper's error messages
if (!emptyempty($user['User']['username']))
{
$this->User->invalidate('username');//populates tagErrorMsg('User/username')
}
//Try to save as normal, shouldn't work if the field was invalidated.
if($this->User->save($this->data))
{
$this->redirect('/users/index/saved');
}
else
{
$this->render();
}
}
}
}
?>