PHPackages                             jin2chen/yii-validator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. jin2chen/yii-validator

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

jin2chen/yii-validator
======================

validators from nest validation.

00[1 PRs](https://github.com/jin2chen/yii-validator/pulls)PHP

Since Jun 24Pushed 3y ago1 watchersCompare

[ Source](https://github.com/jin2chen/yii-validator)[ Packagist](https://packagist.org/packages/jin2chen/yii-validator)[ RSS](/packages/jin2chen-yii-validator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Yii Nest Validator
==================

[](#yii-nest-validator)

[![Latest Stable Version](https://camo.githubusercontent.com/b5b3d1b9ef5f3e026d2ed4fc08dd58b62464a3a1c22a1a3f0af6c4df668f682e/68747470733a2f2f706f7365722e707567782e6f72672f6a696e326368656e2f7969692d76616c696461746f722f76)](https://packagist.org/packages/jin2chen/yii-validator)[![Total Downloads](https://camo.githubusercontent.com/566236fb4b1dc3bc21bb5d06fb7ad746c2c50f08cc65a66fd67ae614402cb2f1/68747470733a2f2f706f7365722e707567782e6f72672f6a696e326368656e2f7969692d76616c696461746f722f646f776e6c6f616473)](https://packagist.org/packages/jin2chen/yii-validator)[![License](https://camo.githubusercontent.com/0fd75d30ee10ed199eb30e321dfbafbfac7c7afb44335875f642dfb7c226d6f1/68747470733a2f2f706f7365722e707567782e6f72672f6a696e326368656e2f7969692d76616c696461746f722f6c6963656e7365)](https://packagist.org/packages/jin2chen/yii-validator)[![Build status](https://github.com/jin2chen/yii-validator/workflows/build/badge.svg)](https://github.com/jin2chen/yii-validator/actions?query=workflow%3Abuild)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/bfc1a30214fdc04651a1751904cb3e00737afab7cc5d9608ccb57cce8b32b49b/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a696e326368656e2f7969692d76616c696461746f722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jin2chen/yii-validator/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/a7d0c6165c58cef04c882d28550ba5b3e35889579755ea20c9b1b437920a7f5a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a696e326368656e2f7969692d76616c696461746f722f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jin2chen/yii-validator/?branch=master)[![static analysis](https://github.com/jin2chen/yii-validator/workflows/static%20analysis/badge.svg)](https://github.com/jin2chen/yii-validator/actions?query=workflow%3A%22static+analysis%22)

Validator for nest validation.

Requirements
------------

[](#requirements)

- PHP 7.4 or higher.

Installation
------------

[](#installation)

The package could be installed with composer:

```
composer require jin2chen/yii-validator --prefer-dist
```

General usage
-------------

[](#general-usage)

### 1. Use `DataSetInterface` and `RulesProviderInterface`

[](#1-use-datasetinterface-and-rulesproviderinterface)

```
use jin2chen\YiiValidator\Rule\Many;
use jin2chen\YiiValidator\Rule\One;
use jin2chen\YiiValidator\Validator;
use Yiisoft\Validator\DataSetInterface;
use Yiisoft\Validator\Rule;
use Yiisoft\Validator\RulesProviderInterface;

abstract class Model implements DataSetInterface, RulesProviderInterface
{
    public function getAttributeValue(string $attribute)
    {
        return $this->{$attribute};
    }

    public function hasAttribute(string $attribute): bool
    {
        return property_exists($this, $attribute);
    }
}

/**
 * @internal
 */
final class UserForm extends Model
{
    /**
     * @var string
     */
    public $firstname;
    /**
     * @var string
     */
    public $lastname;
    /**
     * @var string
     */
    public $email;
    /**
     * @var Profile
     */
    public $profile;
    /**
     * @var Address[]
     */
    public $addresses;

    public function getRules(): array
    {
        return [
            'firstname' => $this->firstnameRules(),
            'lastname' => $this->lastnameRules(),
            'email' => $this->emailRules(),
            'profile' => $this->profileRules(),
            'addresses' => $this->addressesRules(),
        ];
    }

    private function firstnameRules(): array
    {
        return [
            Rule\Required::rule(),
            Rule\MatchRegularExpression::rule('/[a-z]+\s*[a-z]+/i'),
        ];
    }

    private function lastnameRules(): array
    {
        return [
            Rule\Required::rule(),
            Rule\MatchRegularExpression::rule('/[a-z]+\s*[a-z]+/i'),
        ];
    }

    private function emailRules(): array
    {
        return [
            Rule\Required::rule(),
            Rule\Email::rule(),
        ];
    }

    private function profileRules(): array
    {
        return [
            Rule\Required::rule(),
            One::rule(),
        ];
    }

    private function addressesRules(): array
    {
        return [
            Many::rule()->skipOnEmpty(true),
        ];
    }
}

final class Profile extends Model
{
    /**
     * @var string
     */
    public $website;
    /**
     * @var string
     */
    public $title;

    public function getRules(): array
    {
        return [
            'website' => $this->websiteRules(),
            'title' => $this->titleRules(),
        ];
    }

    private function websiteRules(): array
    {
        return [
            Rule\Url::rule()->skipOnEmpty(true),
        ];
    }

    private function titleRules(): array
    {
        return [
            Rule\InRange::rule(['CEO', 'COO', 'CFO'])->skipOnEmpty(true),
        ];
    }
}

final class Address extends Model
{
    /**
     * @var string
     */
    public $street;
    /**
     * @var string
     */
    public $city;
    /**
     * @var string
     */
    public $state;
    /**
     * @var string
     */
    public $zipcode;

    public function getRules(): array
    {
        return [
            'street' => $this->streetRules(),
            'city' => $this->cityRules(),
            'state' => $this->stateRules(),
            'zipcode' => $this->zipcodeRules(),
        ];
    }

    private function streetRules(): array
    {
        return [
            Rule\Required::rule(),
        ];
    }

    private function cityRules(): array
    {
        return [
            Rule\Required::rule(),
        ];
    }

    private function stateRules(): array
    {
        return [
            Rule\Required::rule(),
            Rule\MatchRegularExpression::rule('/^[A-Z]{2}$/')
        ];
    }

    private function zipcodeRules(): array
    {
        return [
            Rule\MatchRegularExpression::rule('/\d{6}/')->skipOnEmpty(true),
        ];
    }
}

$form = new UserForm();
$validator = new Validator();

$form->profile = new Profile();
$form->profile->website = 'www.jinchen.me';

$address1 = new Address();
$address2 = new Address();
$address2->state = 'ABC';
$addresses = [
    $address1,
    $address2,
];
$form->addresses = $addresses;

$results = $validator->validate($form);
print_r($results->getErrors());

//[
//    'firstname' => ['Value cannot be blank.'],
//    'lastname' => ['Value cannot be blank.'],
//    'email' => ['Value cannot be blank.'],
//    'profile.website' => ['This value is not a valid URL.'],
//    'addresses.0.street' => ['Value cannot be blank.'],
//    'addresses.0.city' => ['Value cannot be blank.'],
//    'addresses.0.state' => ['Value cannot be blank.'],
//    'addresses.1.street' => ['Value cannot be blank.'],
//    'addresses.1.city' => ['Value cannot be blank.'],
//    'addresses.1.state' => ['Value is invalid.'],
//];
```

### 2. Use array data

[](#2-use-array-data)

```
use jin2chen\YiiValidator\Rule\Many;
use jin2chen\YiiValidator\Rule\One;
use jin2chen\YiiValidator\Validator;
use Yiisoft\Validator\Rule;

$data = [
    'email' => 'abc.com',
    'profile' => [
        'website' => 'www.jinchen.me',
    ],
    'addresses' => [
        [
            'id' => 22,
            'state' => 'AAA',
        ],
        [
            'id' => 32,
            'state' => 'BBB',
        ],
    ],
];

$rules = [
    'email' => [
        Rule\Email::rule(),
    ],
    'profile' => [
        One::rule()->withRules(
            [
                'website' => [
                    Rule\Url::rule(),
                ],
            ]
        ),
    ],
    'addresses' => [
        Many::rule()->withRules(
            [
                'state' => [
                    Rule\MatchRegularExpression::rule('/^[A-Z]{2}$/'),
                ],
            ]
        )->withIndexKey('id'),
    ],
];

$validator = new Validator();
$results = $validator->validate($data, $rules);
print_r($results->getErrors());
//[
//    'email' => ['This value is not a valid email address.'],
//    'profile.website' => ['This value is not a valid URL.'],
//    'addresses.22.state' => ['Value is invalid.'],
//    'addresses.32.state' => ['Value is invalid.'],
//]
```

Testing
-------

[](#testing)

### Unit testing

[](#unit-testing)

The package is tested with [PHPUnit](https://phpunit.de/). To run tests:

```
./vendor/bin/phpunit
```

### Static analysis

[](#static-analysis)

The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis:

```
./vendor/bin/psalm
```

###  Health Score

15

—

LowBetter than 3% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity31

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4353268?v=4)[Jin Chen](/maintainers/jin2chen)[@jin2chen](https://github.com/jin2chen)

---

Top Contributors

[![jin2chen](https://avatars.githubusercontent.com/u/4353268?v=4)](https://github.com/jin2chen "jin2chen (7 commits)")

---

Tags

nestvalidators

### Embed Badge

![Health badge](/badges/jin2chen-yii-validator/health.svg)

```
[![Health](https://phpackages.com/badges/jin2chen-yii-validator/health.svg)](https://phpackages.com/packages/jin2chen-yii-validator)
```

###  Alternatives

[webmozart/assert

Assertions to validate method input/output with nice error messages.

7.6k894.0M1.2k](/packages/webmozart-assert)[bensampo/laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.

2.0k15.9M104](/packages/bensampo-laravel-enum)[swaggest/json-schema

High definition PHP structures with JSON-schema based validation

48612.5M73](/packages/swaggest-json-schema)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[ashallendesign/laravel-config-validator

A package for validating your Laravel app's config.

217905.3k5](/packages/ashallendesign-laravel-config-validator)[crazybooot/base64-validation

Laravel validators for base64 encoded files

1341.9M8](/packages/crazybooot-base64-validation)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
