Table Of ContentsPrevious topicNext topic |
Validation¶Phalcon\Validation is an independent validation component that validates an arbitrary set of data. This component can be used to implement validation rules on data objects that do not belong to a model or collection. The following example shows its basic usage: <?php
use Phalcon\Validation\Validator\PresenceOf,
Phalcon\Validation\Validator\Email;
$validation = new Phalcon\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>';
}
}
The loosely-coupled design of this component allows you to create your own validators along with the ones provided by the framework. Initializing Validation¶Validation chains can be initialized in a direct manner by just adding validators to the Phalcon\Validation object. You can put your validations in a separate file for better re-use code and organization: <?php
use Phalcon\Validation,
Phalcon\Validation\Validator\PresenceOf,
Phalcon\Validation\Validator\Email;
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'
)));
}
}
<?php
$validation = new MyValidation();
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
Validators¶Phalcon exposes a set of built-in validators for this component:
The following example explains how to create additional validators for this component: <?php
use Phalcon\Validation\Validator,
Phalcon\Validation\ValidatorInterface,
Phalcon\Validation\Message;
class IpValidator extends Validator implements ValidatorInterface
{
/**
* Executes the validation
*
* @param Phalcon\Validation $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;
}
}
It is important that validators return a valid boolean value indicating if the validation was successful or not. Validation Messages¶Phalcon\Validation has a messaging subsystem that provides a flexible way to output or store the validation messages generated during the validation processes. Each message consists of an instance of the class Phalcon\Validation\Message. The set of messages generated can be retrieved with the getMessages() method. Each message provides extended information like the attribute that generated the message or the message type: <?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";
}
}
The getMessages() method can be overridden in a validation class to replace/translate the default messages generated by the validators: <?php
class MyValidation extends Phalcon\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;
}
}
Or you can pass a ‘message’ parameter to change the default message in each validator: <?php
use Phalcon\Validation\Validator\Email;
$validation->add('email', new Email(array(
'message' => 'The e-mail is not valid'
)));
By default, ‘getMessages’ returns all the messages generated during validation. You can filter messages for a specific field using the ‘filter’ method: <?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;
}
}
Filtering of Data¶Data can be filtered prior to the validation ensuring that malicious or incorrect data is not validated. <?php
$validation = new Phalcon\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');
Filtering and sanitizing is performed using the filter: component. You can add more filters to this component or use the built-in ones. Validation Events¶When validations are organized in classes, you can implement the ‘beforeValidation’ and ‘afterValidation’ methods to perform additional checks, filters, clean-up, etc. If ‘beforeValidation’ method returns false the validation is automatically cancelled: <?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
}
}
Cancelling Validations¶By default all validators assigned to a field are tested regardless if one of them have failed or not. You can change this behavior by telling the validation component which validator may stop the validation: <?php
use Phalcon\Validation\Validator\PresenceOf,
Phalcon\Validation\Validator\Regex;
$validation = new Phalcon\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(
'minimumMessage' => 'The telephone is too short',
'min' => 2
)));
The first validator has the option ‘cancelOnFail’ with a value of true, therefore if that validator fails the remaining validators in the chain are not executed. If you are creating custom validators you can dynamically stop the validation chain by setting the ‘cancelOnFail’ option: <?php
use Phalcon\Validation\Validator,
Phalcon\Validation\ValidatorInterface,
Phalcon\Validation\Message;
class MyValidator extends Validator implements ValidatorInterface
{
/**
* Executes the validation
*
* @param Phalcon\Validation $validator
* @param string $attribute
* @return boolean
*/
public function validate($validator, $attribute)
{
// If the attribute value is name we must stop the chain
if ($attribute == 'name') {
$validator->setOption('cancelOnFail', true);
}
//...
}
}
|