Validation in Yii

    Good day. Today I would like to make out such an interesting feature of the Yii Framework as the validation of these models. At the time of writing, the current version of the framework is 1.1.10 , we will actually consider validation on it.
    I want to say right away that I don’t want to retype manuals and APIs, so if possible I will refer to ready-made sources. In addition, I will not describe how to use validators. I will try to disclose the mechanism of validation of Yii models based on the rules of validation, so that using them you understand what actually happens and where in which case you can look for errors.

    Beginning of Understanding Validators



    So, on the wonderful site yiiframewrok.ru there is a section for recipes.
    This section has a Quick Guide to Validation . The original of this article is located at this address .
    After reading this article you will understand:
    1. How to set validation rules
    2. What is a specific rule?
    3. Find out a list of standard validators and their parameters

    Next, read the article Creating a Model ( Original ) from which you will learn:
    1. Something about the scripts. (I want to emphasize this point, it is poorly documented)
    2. How to create validators
    3. How to perform validation

    By the way, examples of creating your own validators are well described in the book: Yii 1.1 Application Development Cookbook
    Armed with the acquired knowledge, we can move on and figure out what happens when called:CModel::validate();

    Deep into CModel :: validate ();


    Method CModel::validate($attributes=null, $clearErrors=true);- takes 2 optional parameters as an input (a list of attributes for validation, and a clearErrors key, which clears the array with errors before calling the validators)
    It is important to understand this if you will expand the standard Yii models and use the method CModel::addError();for your purposes, because CModel::validate();returns true if the data was validated successfully and false if CModel::hasErrors();true.
    In addition, it should be noted here that vadilation will not work if you override the method CModel::beforeValidate();and it returns false.
    In order to dilute the text, let's take a look at the code and everything will become more or less clear:
    1. public function validate ($ attributes = null, $ clearErrors = true)
    2. {
    3.     if ($ clearErrors)
    4.         $ this-> clearErrors ();
    5.     if ($ this-> beforeValidate ())
    6.     {
    7.         foreach ($ this-> getValidators () as $ validator)
    8.             $ validator-> validate ($ this, $ attributes);
    9.         $ this-> afterValidate ();
    10.         return! $ this-> hasErrors ();
    11.     }
    12.     else
    13.         return false;
    14. }

    I think there are no more questions here, so let's better look at the method CModel::getValidator()
    foreach ($ this-> getValidators () as $ validator)

    to understand how Yii gets the list of validators based on the rules specified in the method CModel::rules()

    CModel :: getValidators ()


    1.     public function getValidators ($ attribute = null)
    2.     {
    3.         if ($ this -> _ validators === null)
    4.             $ this -> _ validators = $ this-> createValidators ();
    5.  
    6.         $ validators = array ();
    7.         $ scenario = $ this-> getScenario ();
    8.         foreach ($ this -> _ validators as $ validator)
    9.         {
    10.             if ($ validator-> applyTo ($ scenario)) {
    11.                 if ($ attribute === null || in_array ($ attribute, $ validator-> attributes, true))
    12.                     $ validators [] = $ validator;
    13.             }
    14.         }
    15.         return $ validators;
    16.     }

    The method returns an array of validators described by the rules in the model.
    An interesting point here begins with the 7th line. I mentioned scripts above. So, here we see that the validator is added to the chain only if the method CValidator::applyTo($scenario);
    returns true and true it returns either in the case when the “on” parameter is not set or in the case when the validator refers to the scenario in which the model is executed .
    Move on. Consider the methodCModel:createValidators();
    $ this -> _ validators = $ this-> createValidators ();

    which in essence will be the lower and last level of analysis of validation rules, and then we will summarize some of the results.

    Closer to completion: CModel :: createValidators ()


    1.     public function createValidators ()
    2.     {
    3.         $ validators = new CList;
    4.         foreach ($ this-> rules () as $ rule)
    5.         {
    6.             if (isset ($ rule [0], $ rule [1])) // attributes, validator name
    7.                 $ validators-> add (CValidator :: createValidator ($ rule [1], $ this, $ rule [0], array_slice ($ rule, 2)));
    8.             else
    9.                 throw new CException (Yii :: t ('yii', '{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.', array ('{class}' => get_class ($ this))));
    10.         }
    11.         return $ validators;
    12.     }

    So we have reached the lower level. This method just makes the analysis of the very validation rules described in CModel::rules()and using the static class method CValidator::createValidator()creates validator objects described by these rules.
    Seeing the API method CValidator::createValidator()and also remembering the standard parameters of the validation rule
    1. array (
    2.     'list of model fields',
    3.     'validator'
    4.     'on' => 'script name',
    5.     'message' => 'error message',
    6.     ... validation parameters ...
    7. );

    , everything immediately falls into place.

    To summarize


    As you can see, the algorithm for parsing validation rules is not such a complicated thing. The main thing is to have a desire to understand and understand the problem. Understanding how the code works, a lot of various questions arise during development, when something goes wrong and the program runs incorrectly.

    In conclusion, we can summarize some features that will help to understand why perhaps your validator does not work as we would like, or why some validation rule is not fulfilled.

    • When a method CModel::validate()is called , a check is made to see if the method is completed CModel::beforeValidate().
      If the method fails, validation is considered failed
    • If the method CModel::hasErrors()returns true, validation is considered failed
    • When the method is called CModel::getValidators(), only validators are added that relate to the current script, as well as validators for which the script is not specified in the validation rules

    Also popular now: