📜 ⬆️ ⬇️

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 this writing, the current version of the framework is 1.1.10 , and we’ll actually consider validation on it.
I want to say right away that I don’t want to reprint manuals and APIs, so I will refer to ready sources whenever possible. In addition, I will not describe how to use validators. I will try to reveal the mechanism of validation of Yii models based on validation rules, so that using them you understand what is actually happening and where, if anything happens, you can look for errors.

Beginning of understanding validators



So, on the wonderful site yiiframewrok.ru there is a recipe section.
This section has a Quick Reference 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. Learn the list of standard validators and their parameters

Next is to read the article Creating a Model ( Original ) from which you will learn:
  1. Something about the scenarios. (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 validators are well described in the book: Yii 1.1 Application Development Cookbook
Armed with the knowledge gained, we can go ahead and figure out what happens when we call: CModel::validate();

Depth CModel :: validate ();


CModel::validate($attributes=null, $clearErrors=true); method CModel::validate($attributes=null, $clearErrors=true); - takes as input 2 optional parameters (a list of attributes for valdation, and the clearErrors key, which clears the array with errors before calling validators)
This is important to understand if you will extend the standard Yii models and use the CModel::addError(); method CModel::addError(); for their own purposes, because CModel::validate(); returns true in case of successful data validation and false if CModel::hasErrors(); returns true.
In addition, it should be noted here that vadilation will not work if you override the CModel::beforeValidate(); method CModel::beforeValidate(); and it returned 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 that there are no more questions here, so let's take a look at the CModel::getValidator() method CModel::getValidator()
foreach ( $ this -> getValidators ( ) as $ validator )

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

CModel :: getValidators ()


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

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

which in essence will be the lower and last level of parsing validation rules, and then we will summarize some 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. and the array's name.' , array ( '{class}' => get_class ( $ this ) ) ) ) ;
  10. }
  11. return $ validators ;
  12. }

So we got to the bottom level. This method performs the same validation rules described in CModel::rules() and using the static method of the class CValidator::createValidator() creates objects of validators described by these rules.
CValidator::createValidator() method API and also recalling the standard parameters of the validation rule
  1. array (
  2. 'model field list' ,
  3. 'validator' ,
  4. 'on' => 'script name' ,
  5. 'message' => 'error message' ,
  6. ... validation parameters ...
  7. ) ;

, everything will immediately fall into place.

Let's sum up


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 eliminates a lot of various questions arising during development, when something goes wrong and the program is not executed as it should.

In conclusion, we can summarize some features that will allow us to understand why your validator may not work as it would like, or why some validation rule is not executed.

Source: https://habr.com/ru/post/140275/


All Articles