Table Of Contents

Previous topic

< Contextual Escaping

Next topic

Forms >

This Page

Validation

Phalcon\Validation is an independent validation component to validate an arbitrary set of data. This component can be used to implement validation rules that does 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 loose-coupled design of this component allows you to create your own validators together with the ones provided by the framework.

Initializing validation

As seen before, Validation chains can be initialized in a direct manner by just adding validators to the Phalcon\Validation object. You can re-use code or organize better your validations implementing them in a separated file:

<?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:

Name Explanation Example
PresenceOf Validates that a field’s value isn’t null or empty string. Example
Identical Validates that a field’s value is the same as a specified value Example
Email Validates that field contains a valid email format Example
ExclusionIn Validates that a value is not within a list of possible values Example
InclusionIn Validates that a value is within a list of possible values Example
Regex Validates that the value of a field matches a regular expression Example
StringLength Validates the length of a string Example
Between Validates that a value is between two values Example
Confirmation Validates that a value be the same as as other present in the data Example

Additional validators can be created by the developer. The following example explains how to create a validator 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_URL, FILTER_FLAG_PATH_REQUIRED)) {

            $message = $this->getOption('message');
            if (!$message) {
                $message = 'The IP is not valid';
            }

            $validator->appendMessage(new Message($message, $attribute, 'Ip'));

            return false;
        }

        return true;
    }

}

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 method getMessages(). 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 method getMessages() can be overriden in a validation class to replace/translate the default messages generated automatically 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 parameter ‘message’ 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 in the validation, you can filter messages for a specific field using ‘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;
    }
}

Filtering of Data

Data can be filtering prior to the validation ensuring that malicious data or wrong is not going to be validated as a proper one.

<?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/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 methods ‘beforeValidation’ and ‘afterValidation’ to perform additional checks/clean-up etc. If ‘beforeValidation’ 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
     */
    public function beforeValidation($data, $entity, $messages)
    {
        if ($this->request->getHttpHost() != 'admin.mydomain.com') {
            $messages->appendMessage(new Message('Users only 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
    }

}

Validation Cancelling

By default, all validators assigned to a field are validated regardless if one of them have failed or not. You can change this behavior by telling the validation component which validator must 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’ => true, therefore if that validator fails the next validator in the chain is not executed.

If you’re 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 is name we must stop the chain
        if ($attribute == 'name') {
            $validator->setOption('cancelOnFail', true);
        }

        //...
    }

}