# 驗證(Validation)
[Phalcon\\Validation](http://docs.iphalcon.cn/api/Phalcon_Validation.html)對Phalcon來說是一個相對獨立的組件,它可以對任意的數據進行驗證。 當然也可以用來對非模型內的數據進行驗證。
下面的例子展示了一些基本的使用方法:
~~~
<?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>";
}
}
~~~
由于此模型是松耦合設計的,故此我們也可以使用自己書寫的驗證工具:
## 初始化驗證(Initializing Validation)
我們可以直接在[Phalcon\\Validation](http://docs.iphalcon.cn/api/Phalcon_Validation.html)初始化時添加驗證鏈。我們可以把驗證器放在一個單獨的文件中以提高代碼的重用率及可組織性:
~~~
<?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",
]
)
);
}
}
~~~
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>";
}
}
~~~
## 驗證器(Validators)
Phalcon的驗證組件中內置了一些驗證器:
下面的例子中展示了如何創建自定義的驗證器:
~~~
<?php
use Phalcon\Validation;
use Phalcon\Validation\Message;
use Phalcon\Validation\Validator;
class IpValidator extends Validator
{
/**
* 執行驗證
*
* @param Phalcon\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;
}
}
~~~
最重要的一點即是難證器要返回一個布爾值以標識驗證是否成功:
## Callback Validator
By using[Phalcon\\Validation\\Validator\\Callback](http://docs.iphalcon.cn/api/Phalcon_Validation_Validator_Callback.html)you can execute custom function which must return boolean or new validator class which will be used to validate the same field. By returning`true`validation will be successful, returning`false`will mean validation failed. When executing this validator Phalcon will pass data depending what it is - if it’s an entity then entity will be passed, otherwise data. There is example:
~~~
<?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
~~~
## 驗證信息(Validation Messages)
[Phalcon\\Validation](http://docs.iphalcon.cn/api/Phalcon_Validation.html)內置了一個消息子系統,這提供了一個非常好的驗證消息回傳機制,以便在驗證結束后取得驗證信息,比如失敗原因等。
每個消息由一個[Phalcon\\Validation\\Message](http://docs.iphalcon.cn/api/Phalcon_Mvc_Model_Message.html)類的實例構成。 驗證過程產生的消息可以使用:code:[`](http://docs.iphalcon.cn/reference/validation.html#id1)getMessages()`方法取得。 每條消息都有一些擴展的信息組成比如產生錯誤的屬性或消息的類型等:
~~~
<?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參數以覆蓋驗證器中默認的信息:
~~~
<?php
use Phalcon\Validation\Validator\Email;
$validation->add(
"email",
new Email(
[
"message" => "The e-mail is not valid",
]
)
);
~~~
默認,:code:[`](http://docs.iphalcon.cn/reference/validation.html#id3)getMessages()`方法會返回在驗證過程中所產生的信息。 我們可以使用:code:[`](http://docs.iphalcon.cn/reference/validation.html#id5)filter()`方法來過濾我們感興趣的消息:
~~~
<?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;
}
}
~~~
## 過濾數據(Filtering of Data)
我們可以在數據被驗證之前對其先進行過濾,以確保那些惡意的或不正確的數據不被驗證。
~~~
<?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");
~~~
這里我們使用[filter](http://docs.iphalcon.cn/reference/filter.html)組件進行過濾。 我們還可以使用自定義的或內置的過濾器。
## 驗證事件(Validation Events)
當在類中執行驗證時, 我們可以在:code:[`](http://docs.iphalcon.cn/reference/validation.html#id7)beforeValidation()`或:code:[`](http://docs.iphalcon.cn/reference/validation.html#id9)afterValidation()`方法(事件)中執行額外的檢查,過濾,清理等工作。 如果:code:[`](http://docs.iphalcon.cn/reference/validation.html#id11)beforeValidation()`方法返回了false 則驗證會被中止:
~~~
<?php
use Phalcon\Validation;
class LoginValidation extends Validation
{
public function initialize()
{
// ...
}
/**
* 驗證執行之前執行
*
* @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;
}
/**
* 驗證之后執行
*
* @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
}
}
~~~
## 取消驗證(Cancelling Validations)
默認所有的驗證器都會被執行,不管驗證成功與否。 我們可以通過設置 cancelOnFail 參數為 true 來指定某個驗證器驗證失敗時中止以后的所有驗證:
~~~
<?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 為 true 來停止驗證鏈:
~~~
<?php
use Phalcon\Validation;
use Phalcon\Validation\Message;
use Phalcon\Validation\Validator;
class MyValidator extends Validator
{
/**
* 執行驗證
*
* @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);
}
// ...
}
}
~~~
## 避免驗證空值(Avoid validate empty values)
我們可以向所有內建的驗證器傳入選項 ‘allowEmpty’ 以避免在傳入的值為空時執行驗證。
~~~
<?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,
]
)
);
~~~
## 遞歸驗證(Recursive Validation)
我們可以通過`afterValidation()`方法,在一個驗證器中運行另一個驗證器。在本例中,CompanyValidation 驗證實例會同時執行 PhoneValidation 驗證器。
~~~
<?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
);
}
}
~~~
- 簡介
- 安裝
- 安裝(installlation)
- XAMPP下的安裝
- WAMP下安裝
- Nginx安裝說明
- Apache安裝說明
- Cherokee 安裝說明
- 使用 PHP 內置 web 服務器
- Phalcon 開發工具
- Linux 系統下使用 Phalcon 開發工具
- Mac OS X 系統下使用 Phalcon 開發工具
- Windows 系統下使用 Phalcon 開發工具
- 教程
- 教程 1:讓我們通過例子來學習
- 教程 2:INVO簡介
- 教程 3: 保護INVO
- 教程4: 使用CRUD
- 教程5: 定制INVO
- 教程 6: V?kuró
- 教程 7:創建簡單的 REST API
- 組件
- 依賴注入與服務定位器
- MVC架構
- 使用控制器
- 使用模型
- 模型關系
- 事件與事件管理器
- Behaviors
- 模型元數據
- 事務管理
- 驗證數據完整性
- Workingwith Models
- Phalcon查詢語言
- 緩存對象關系映射
- 對象文檔映射 ODM
- 使用視圖
- 視圖助手
- 資源文件管理
- Volt 模版引擎
- MVC 應用
- 路由
- 調度控制器
- Micro Applications
- 使用命名空間
- 事件管理器
- Request Environmen
- 返回響應
- Cookie 管理
- 生成 URL 和 路徑
- 閃存消息
- 使用 Session 存儲數據
- 過濾與清理
- 上下文編碼
- 驗證Validation
- 表單_Forms
- 讀取配置
- 分頁 Pagination
- 使用緩存提高性能
- 安全
- 加密與解密 Encryption/Decryption
- 訪問控制列表
- 多語言支持
- 類加載器 Class Autoloader
- 日志記錄_Logging
- 注釋解析器 Annotations Parser
- 命令行應用 Command Line Applications
- Images
- 隊列 Queueing
- 數據庫抽象層
- 國際化
- 數據庫遷移
- 調試應用程序
- 單元測試
- 進階技巧與延伸閱讀
- 提高性能:下一步該做什么?
- Dependency Injection Explained
- Understanding How Phalcon Applications Work
- Api
- Abstract class Phalcon\Acl