发布于 2015-08-21 15:17:16 | 387 次阅读 | 评论: 0 | 来源: 网络整理
PhalconValidation对Phalcon来说是一个相对独立的组件,它可以对任意的数据进行验证。 当然也可以用来对非模型内的数据进行验证。
下面的例子展示了一些基本的使用方法:
<?php
use PhalconValidation;
use PhalconValidationValidatorEmail;
use PhalconValidationValidatorPresenceOf;
$validation = new Validation();
$validation->add(
'name',
new PresenceOf(
array(
'message' => 'The name is required'
)
)
);
$validation->add(
'email',
new PresenceOf(
array(
'message' => 'The e-mail is required'
)
)
);
$validation->add(
'email',
new Email(
array(
'message' => 'The e-mail is not valid'
)
)
);
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
由于此模型是松耦合设计的,故此我们也可以使用自己书写的验证工具:
我们可以直接在PhalconValidation初始化时添加验证链。我们可以把验证器放在一个单独的文件中以提高代码的重用率及可组织性:
<?php
use PhalconValidation;
use PhalconValidationValidatorEmail;
use PhalconValidationValidatorPresenceOf;
class MyValidation extends Validation
{
public function initialize()
{
$this->add(
'name',
new PresenceOf(
array(
'message' => 'The name is required'
)
)
);
$this->add(
'email',
new PresenceOf(
array(
'message' => 'The e-mail is required'
)
)
);
$this->add(
'email',
new Email(
array(
'message' => 'The e-mail is not valid'
)
)
);
}
}
Then initialize and use your own validator:
<?php
$validation = new MyValidation();
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
Phalcon的验证组件中内置了一些验证器:
下面的例子中展示了如何创建自定义的验证器:
<?php
use PhalconValidationMessage;
use PhalconValidationValidator;
use PhalconValidationValidatorInterface;
class IpValidator extends Validator implements ValidatorInterface
{
/**
* 执行验证
*
* @param PhalconValidation $validator
* @param string $attribute
* @return boolean
*/
public function validate($validator, $attribute)
{
$value = $validator->getValue($attribute);
if (!filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
$message = $this->getOption('message');
if (!$message) {
$message = 'The IP is not valid';
}
$validator->appendMessage(new Message($message, $attribute, 'Ip'));
return false;
}
return true;
}
}
最重要的一点即是难证器要返回一个布尔值以标识验证是否成功:
PhalconValidation 内置了一个消息子系统,这提供了一个非常好的验证消息回传机制,以便在验证结束后取得验证信息,比如失败原因等。
每个消息由一个 PhalconValidationMessage 类的实例构成。 验证过程产生的消息可以使用getMessages()方法取得。 每条消息都有一些扩展的信息组成比如产生错误的属性或消息的类型等:
<?php
$messages = $validation->validate();
if (count($messages)) {
foreach ($validation->getMessages() as $message) {
echo "Message: ", $message->getMessage(), "n";
echo "Field: ", $message->getField(), "n";
echo "Type: ", $message->getType(), "n";
}
}
当然这里我们也可以对getMessages()方法进行重写, 以取得我们想要的信息:
<?php
use PhalconValidation;
class MyValidation extends Validation
{
public function initialize()
{
// ...
}
public function getMessages()
{
$messages = array();
foreach (parent::getMessages() as $message) {
switch ($message->getType()) {
case 'PresenceOf':
$messages[] = 'The field ' . $message->getField() . ' is mandatory';
break;
}
}
return $messages;
}
}
或我们也可以传送一个message参数以覆盖验证器中默认的信息:
<?php
use PhalconValidationValidatorEmail;
$validation->add(
'email',
new Email(
array(
'message' => 'The e-mail is not valid'
)
)
);
默认,getMessages()方法会返回在验证过程中所产生的信息。 我们可以使用filter()方法来过滤我们感兴趣的消息:
<?php
$messages = $validation->validate();
if (count($messages)) {
// Filter only the messages generated for the field 'name'
foreach ($validation->getMessages()->filter('name') as $message) {
echo $message;
}
}
我们可以在数据被验证之前对其先进行过滤,以确保那些恶意的或不正确的数据不被验证。
<?php
use PhalconValidation;
$validation = new Validation();
$validation
->add('name', new PresenceOf(array(
'message' => 'The name is required'
)))
->add('email', new PresenceOf(array(
'message' => 'The email is required'
)));
// Filter any extra space
$validation->setFilters('name', 'trim');
$validation->setFilters('email', 'trim');
这里我们使用 filter: 组件进行过滤。 我们还可以使用自定义的或内置的过滤器。
当在类中执行验证时, 我们可以在beforeValidation或afterValidation方法(事件)中执行额外的检查,过滤,清理等工作。 如果beforeValidation方法返回了false 则验证会被中止:
<?php
use PhalconValidation;
class LoginValidation extends Validation
{
public function initialize()
{
// ...
}
/**
* 验证执行之前执行
*
* @param array $data
* @param object $entity
* @param PhalconValidationMessageGroup $messages
* @return bool
*/
public function beforeValidation($data, $entity, $messages)
{
if ($this->request->getHttpHost() != 'admin.mydomain.com') {
$messages->appendMessage(new Message('Only users can log on in the administration domain'));
return false;
}
return true;
}
/**
* 验证之后执行
*
* @param array $data
* @param object $entity
* @param PhalconValidationMessageGroup $messages
*/
public function afterValidation($data, $entity, $messages)
{
// ... Add additional messages or perform more validations
}
}
默认所有的验证器都会被执行,不管验证成功与否。 我们可以通过设置 cancelOnFail 参数为 true 来指定某个验证器验证失败时中止以后的所有验证:
<?php
use PhalconValidation;
use PhalconValidationValidatorRegex;
use PhalconValidationValidatorPresenceOf;
$validation = new Validation();
$validation
->add('telephone', new PresenceOf(array(
'message' => 'The telephone is required',
'cancelOnFail' => true
)))
->add('telephone', new Regex(array(
'message' => 'The telephone is required',
'pattern' => '/+44 [0-9]+/'
)))
->add('telephone', new StringLength(array(
'messageMinimum' => 'The telephone is too short',
'min' => 2
)));
第一个验证器中 cancelOnFail 参数设置为 true 则表示如果此验证器验证失败则验证链中接下的验证不会被执行。
我们可以在自定义的验证器中设置 cancelOnFail 为 true 来停止验证链:
<?php
use PhalconValidation;
use PhalconValidationMessage;
use PhalconValidationValidator;
use PhalconValidationValidatorInterface;
class MyValidator extends Validator implements ValidatorInterface
{
/**
* 执行验证
*
* @param PhalconValidation $validator
* @param string $attribute
* @return boolean
*/
public function validate(Validation $validator, $attribute)
{
// If the attribute value is name we must stop the chain
if ($attribute == 'name') {
$validator->setOption('cancelOnFail', true);
}
// ...
}
}
You can pass the option ‘allowEmpty’ to all the built-in validators to avoid the validation to be performed if an empty value is passed:
<?php
use PhalconValidation;
use PhalconValidationValidatorRegex;
$validation = new Validation();
$validation
->add('telephone', new Regex(array(
'message' => 'The telephone is required',
'pattern' => '/+44 [0-9]+/',
'allowEmpty' => true
)));