[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管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持