0

Rules in Yii2 models look like this:

[
    // checks if "level" is 1, 2 or 3
    ['level', 'in', 'range' => [1, 2, 3]],
]

Wouldn't it be better if they were objects like this?

[
  new RangeRule('level', [1, 2, 3])
]
11
  • 1
    For performance optimization I guess. Commented Feb 7, 2017 at 13:56
  • AFAIK, the performance difference is very minor between arrays and objects. Commented Feb 7, 2017 at 14:01
  • See stackoverflow.com/questions/2193049/php-objects-vs-arrays and gist.github.com/Thinkscape/1136563 - PHP is getting better at array optimization with every version. Commented Feb 7, 2017 at 14:06
  • 1
    Those benchmarks are still old. One for PHP 7 is needed, I think. Commented Feb 7, 2017 at 14:15
  • 1
    Loading the class file is only done once. I think the arrays make the rules much harder to read, but if it's possible to use the objects instead if you want to, then no problem. Commented Feb 8, 2017 at 9:09

1 Answer 1

1

You can use validator objects like this:

use yii\validators\Validator;
use yii\validators\NumberValidator;
use yii\validators\StringValidator;

class TestModel extends \yii\base\Model
{
    public $firstProperty;
    public $secondProperty;

    public function rules()
    {
        return [
            new NumberValidator(['attributes' => ['firstProperty'], 'integerOnly' => true, 'min' => 0, 'max' => 100]),
            new StringValidator(['attributes' => ['secondProperty'], 'max' => 5]),
        ];
    }
}

Moreover, you can decorate these objects as you want (using additional classes and methods):

class TestModel extends \yii\base\Model
{
    public $firstProperty;
    public $secondProperty;

    public function rules()
    {
        // Prepare Int validator
        $validatorInt              = new NumberValidator();
        $validatorInt->integerOnly = true;
        $validatorInt->min         = 0;
        $validatorInt->max         = 100;

        // Prepare String validator
        $validatorString      = new StringValidator();
        $validatorString->max = 5;

        // Make rules
        return [
            static::_makeRule(['firstProperty'], $validatorInt),
            static::_makeRule(['secondProperty'], $validatorString),
        ];
    }

    protected function _makeRule($attrName, Validator $validatorObj)
    {
        $validatorObj = clone $validatorObj;

        $validatorObj->attributes = (array)$attrName;

        $validatorObj->init();                          // Initializes validator and normalizes values

        return $validatorObj;
    }

}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.