[TOC]
# 验证
`Phalcon\Validation` 是一个独立的验证组件,用于验证任意数据集。此组件可用于对不属于模型或集合的数据对象实现验证规则。
以下示例显示了其基本用法:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Validator\Email;
use Phalcon\Validation\Validator\PresenceOf;
$validation = new Validation();
$validation->add(
'name',
new PresenceOf(
[
'message' => 'The name is required',
]
)
);
$validation->add(
'email',
new PresenceOf(
[
'message' => 'The e-mail is required',
]
)
);
$validation->add(
'email',
new Email(
[
'message' => 'The e-mail is not valid',
]
)
);
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
```
此组件的松耦合设计允许您以框架提供的验证器创建自己的验证器。
## 初始化验证
只需在`Phalcon\Validation`对象中添加验证器,即可直接初始化验证链。您可以将验证放在单独的文件中,以便更好地重用代码和组织:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Validator\Email;
use Phalcon\Validation\Validator\PresenceOf;
class MyValidation extends Validation
{
public function initialize()
{
$this->add(
'name',
new PresenceOf(
[
'message' => 'The name is required',
]
)
);
$this->add(
'email',
new PresenceOf(
[
'message' => 'The e-mail is required',
]
)
);
$this->add(
'email',
new Email(
[
'message' => 'The e-mail is not valid',
]
)
);
}
}
```
然后初始化并使用您自己的验证器:
```php
<?php
$validation = new MyValidation();
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
```
## 验证器
Phalcon为此组件公开了一组内置验证器:
| 类 | 说明 |
| ---------------------------------------------- | ------------------------------------------------------------------ |
| `Phalcon\Validation\Validator\Alnum` | 验证字段的值仅为字母数字字符。 |
| `Phalcon\Validation\Validator\Alpha` | 验证字段的值是否仅为字母字符。 |
| `Phalcon\Validation\Validator\Date` | 验证字段的值是否为有效日期。 |
| `Phalcon\Validation\Validator\Digit` | 验证字段的值是否只是数字字符。 |
| `Phalcon\Validation\Validator\File` | 验证字段的值是否是正确的文件。 |
| `Phalcon\Validation\Validator\Uniqueness` | 验证字段的值在相关模型中是唯一的。 |
| `Phalcon\Validation\Validator\Numericality` | 验证字段的值是否为有效数值。 |
| `Phalcon\Validation\Validator\PresenceOf` | 验证字段的值不为null或空字符串。 |
| `Phalcon\Validation\Validator\Identical` | 验证字段的值是否与指定值相同。 |
| `Phalcon\Validation\Validator\Email` | 验证该字段是否包含有效的电子邮件格式。 |
| `Phalcon\Validation\Validator\ExclusionIn` | 验证值是否不在可能值列表中。 |
| `Phalcon\Validation\Validator\InclusionIn` | 验证值是否在可能值列表中。 |
| `Phalcon\Validation\Validator\Regex` | 验证字段的值是否与正则表达式匹配。 |
| `Phalcon\Validation\Validator\StringLength` | 验证字符串的长度。 |
| `Phalcon\Validation\Validator\Between` | 验证值是否在两个值之间。 |
| `Phalcon\Validation\Validator\Confirmation` | 验证值与数据中存在的另一个值相同。 |
| `Phalcon\Validation\Validator\Url` | 验证该字段是否包含有效的URL。 |
| `Phalcon\Validation\Validator\CreditCard` | 验证信用卡号。 |
| `Phalcon\Validation\Validator\Callback` | 使用回调函数进行验证。 |
以下示例说明如何为此组件创建其他验证器:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Message;
use Phalcon\Validation\Validator;
class IpValidator extends Validator
{
/**
* Executes the validation
*
* @param Validation $validator
* @param string $attribute
* @return boolean
*/
public function validate(Validation $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;
}
}
```
验证器返回有效的布尔值非常重要,该值指示验证是否成功。
## 回调验证器
通过使用`Phalcon\Validation\Validator\Callback`,您可以执行自定义函数,该函数必须返回将用于验证同一字段的布尔值或新验证器类。通过返回真正的验证将成功,返回`false`将意味着验证失败。执行此验证程序时,Phalcon将根据数据传递数据 - 如果它是实体,则将传递实体,否则传递数据。有例子:
```php
<?php
use \Phalcon\Validation;
use \Phalcon\Validation\Validator\Callback;
use \Phalcon\Validation\Validator\PresenceOf;
$validation = new Validation();
$validation->add(
'amount',
new Callback(
[
'callback' => function($data) {
return $data['amount'] % 2 == 0;
},
'message' => 'Only even number of products are accepted'
]
)
);
$validation->add(
'amount',
new Callback(
[
'callback' => function($data) {
if($data['amount'] % 2 == 0) {
return $data['amount'] != 2;
}
return true;
},
'message' => "You can't buy 2 products"
]
)
);
$validation->add(
'description',
new Callback(
[
'callback' => function($data) {
if($data['amount'] >= 10) {
return new PresenceOf(
[
'message' => 'You must write why you need so big amount.'
]
);
}
return true;
}
]
)
);
$messages = $validation->validate(['amount' => 1]); // will return message from first validator
$messages = $validation->validate(['amount' => 2]); // will return message from second validator
$messages = $validation->validate(['amount' => 10]); // will return message from validator returned by third validator
```
## 验证消息
`Phalcon\Validation` 有一个消息传递子系统,它提供了一种灵活的方法来输出或存储验证过程中生成的验证消息。
每条消息都包含`Phalcon\Validation\Message`类的实例。可以使用`getMessages()`方法获取生成的消息集。每条消息都提供扩展信息,例如生成消息的属性或消息类型:
```php
<?php
$messages = $validation->validate();
if (count($messages)) {
foreach ($messages as $message) {
echo 'Message: ', $message->getMessage(), "\n";
echo 'Field: ', $message->getField(), "\n";
echo 'Type: ', $message->getType(), "\n";
}
}
```
您可以传递`message`参数来更改/转换每个验证器中的默认消息,即使可以使用消息中的通配符`:field`替换为字段的标签:
```php
<?php
use Phalcon\Validation\Validator\Email;
$validation->add(
'email',
new Email(
[
'message' => 'The e-mail is not valid',
]
)
);
```
默认情况下, `getMessages()` 方法返回验证期间生成的所有消息。您可以使用`filter()`方法过滤特定字段的消息:
```php
<?php
$messages = $validation->validate();
if (count($messages)) {
// Filter only the messages generated for the field 'name'
$filteredMessages = $messages->filter('name');
foreach ($filteredMessages as $message) {
echo $message;
}
}
```
## 过滤数据
可以在验证之前过滤数据,确保未验证恶意或不正确的数据。
```php
<?php
use Phalcon\Validation;
$validation = new Validation();
$validation->add(
'name',
new PresenceOf(
[
'message' => 'The name is required',
]
)
);
$validation->add(
'email',
new PresenceOf(
[
'message' => 'The email is required',
]
)
);
// Filter any extra space
$validation->setFilters('name', 'trim');
$validation->setFilters('email', 'trim');
```
使用过滤器组件进行过滤和消毒。您可以向此组件添加更多过滤器或使用内置过滤器。
## 验证事件
在类中组织验证时,可以实现`beforeValidation()`和`afterValidation()`方法以执行其他检查,过滤,清理等。如果`beforeValidation()`方法返回`false`,则验证将自动取消:
```php
<?php
use Phalcon\Validation;
class LoginValidation extends Validation
{
public function initialize()
{
// ...
}
/**
* Executed before validation
*
* @param array $data
* @param object $entity
* @param Phalcon\Validation\Message\Group $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;
}
/**
* Executed after validation
*
* @param array $data
* @param object $entity
* @param Phalcon\Validation\Message\Group $messages
*/
public function afterValidation($data, $entity, $messages)
{
// ... Add additional messages or perform more validations
}
}
```
## 取消验证
默认情况下,将测试分配给某个字段的所有验证程序,无论其中一个验证程序是否已失败。您可以通过告知验证组件哪个验证程序可以停止验证来更改此行为:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Validator\Regex;
use Phalcon\Validation\Validator\PresenceOf;
$validation = new Validation();
$validation->add(
'telephone',
new PresenceOf(
[
'message' => 'The telephone is required',
'cancelOnFail' => true,
]
)
);
$validation->add(
'telephone',
new Regex(
[
'message' => 'The telephone is required',
'pattern' => '/\+44 [0-9]+/',
]
)
);
$validation->add(
'telephone',
new StringLength(
[
'messageMinimum' => 'The telephone is too short',
'min' => 2,
]
)
);
```
第一个验证器具有选项`cancelOnFail`,其值为`true`,因此如果该验证器失败,则不会执行链中的其余验证器。
如果要创建自定义验证器,可以通过设置`cancelOnFail`选项动态停止验证链:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Message;
use Phalcon\Validation\Validator;
class MyValidator extends Validator
{
/**
* Executes the validation
*
* @param Phalcon\Validation $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);
}
// ...
}
}
```
## 避免验证空值
您可以将选项`allowEmpty`传递给所有内置验证器,以避免在传递空值时执行验证:
```php
<?php
use Phalcon\Validation;
use Phalcon\Validation\Validator\Regex;
$validation = new Validation();
$validation->add(
'telephone',
new Regex(
[
'message' => 'The telephone is required',
'pattern' => '/\+44 [0-9]+/',
'allowEmpty' => true,
]
)
);
```
## 递归验证
您还可以通过`afterValidation()` 方法在另一个中运行`Validation`实例。在此示例中,验证`CompanyValidation`实例还将检查`PhoneValidation`实例:
```php
<?php
use Phalcon\Validation;
class CompanyValidation extends Validation
{
/**
* @var PhoneValidation
*/
protected $phoneValidation;
public function initialize()
{
$this->phoneValidation = new PhoneValidation();
}
public function afterValidation($data, $entity, $messages)
{
$phoneValidationMessages = $this->phoneValidation->validate(
$data['phone']
);
$messages->appendMessages(
$phoneValidationMessages
);
}
}
```
- 常规
- Welcome
- 贡献
- 生成回溯
- 测试重现
- 单元测试
- 入门
- 安装
- Web服务器设置
- WAMP
- XAMPP
- 教程
- 基础教程
- 教程:创建一个简单的REST API
- 教程:Vökuró
- 提升性能
- 教程:INVO
- 开发环境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 开发工具
- Phalcon开发者工具的安装
- Phalcon开发者工具的使用
- 调试应用程序
- 核心
- MVC应用
- 微应用
- 创建命令行(CLI)应用程序
- 依赖注入与服务定位
- MVC架构
- 服务
- 使用缓存提高性能
- 读取配置
- 上下文转义
- 类加载器
- 使用命名空间
- 日志
- 队列
- 数据库
- 数据库抽象层
- Phalcon查询语言(PHQL)
- ODM(对象文档映射器)
- 使用模型
- 模型行为
- ORM缓存
- 模型事件
- 模型元数据
- 模型关系
- 模型事务
- 验证模型
- 数据库迁移
- 分页
- 前端
- Assets管理
- 闪存消息
- 表单
- 图像
- 视图助手(标签)
- 使用视图
- Volt:模板引擎
- 业务逻辑
- 访问控制列表(ACL)
- 注解解析器
- 控制器
- 调度控制器
- 事件管理器
- 过滤与清理
- 路由
- 在session中存储数据
- 生成URL和路径
- 验证
- HTTP
- Cookies管理
- 请求环境
- 返回响应
- 安全
- 加密/解密
- 安全
- 国际化
- 国际化
- 多语言支持