rougin/valla
Composer 安装命令:
composer require rougin/valla
包简介
A simple validation package in PHP.
README 文档
README
A simple validation package for PHP inspired by Valitron.
use Rougin\Valla\Valid; $data = array('name' => '', 'email' => 'not-an-email'); $valid = new Valid($data); $valid->addRule('name', 'required'); $valid->addRule('email', 'required|email'); if (! $valid->passed()) { // "Name is required" echo $valid->firstError(); }
Installation
Install the package using Composer:
$ composer require rougin/valla
Basic usage
The core of Valla is the Valid class. Create an instance with the data to validate, then add rules with addRule():
use Rougin\Valla\Valid; $data = array('age' => 'abc'); $data['email'] = 'not-an-email'; $data['name'] = ''; $valid = new Valid($data); $valid->addRule('age', 'required|numeric'); $valid->addRule('email', 'required|email'); $valid->addRule('name', 'required'); if (! $valid->passed()) { $errors = $valid->getErrors(); // "Age must be numeric" echo $valid->firstError(); }
Setting labels
Labels provide user-friendly field names in error messages:
use Rougin\Valla\Valid; $data = array('email' => 'not-an-email'); $valid = new Valid($data); $labels = array('email' => 'Email Address'); $valid->setLabels($labels); $valid->addRule('email', 'email'); if (! $valid->passed()) { // "Email Address is not a valid email address" echo $valid->firstError(); }
Adding custom rules
Custom rules can be added by implementing to RuleInterface:
namespace Rougin\Test\Rules; use Rougin\Valla\RuleInterface; use Rougin\Valla\Ruleset; class Uppercase implements RuleInterface { public function getError() { return 'must be uppercase'; } public function getName() { return 'uppercase'; } public function passed($value, array $data) { return strtoupper($value) === $value; } public function setValue(array $values) { return $this; } }
To register the custom rule, add it to a Ruleset class then set it to the Valid class:
use Rougin\Test\Rules\Uppercase; use Rougin\Valla\Valid; use Rougin\Valla\Ruleset; // Register the custom rule --- $rules = new Ruleset; $rules->addRule(new Uppercase); // ---------------------------- // Inject the ruleset to check --- $data = array('name' => 'Valla'); $valid = new Valid($data); $valid->setRuleset($rules); // ------------------------------- $valid->addRule('name', 'uppercase'); if (! $valid->passed()) { // "Name must be uppercase" echo $valid->firstError(); }
Using Check class
The Check class provides a declarative, class-based approach to validation by defining rules and labels as properties. It wraps a Valid instance internally.
Using labels, rules
The $labels property defines user-friendly names for the fields, while $rules specifies the validation rules:
use Rougin\Valla\Check; class UserCheck extends Check { protected $labels = array( 'age' => 'Age', 'email' => 'Email', 'name' => 'Name', ); protected $rules = array( 'age' => 'required|numeric', 'email' => 'required|email', 'name' => 'required', ); }
Validating data
Once the Check class is created, validate an array of data using valid():
$check = new UserCheck; $data = array('name' => 'John'); $data['age'] = 20; $data['email'] = 'john@example.com'; if (! $check->valid($data)) { echo $check->firstError(); }
Dynamic labels, rules
For more validation scenarios, the labels and rules methods can be overridden to define them dynamically:
use Rougin\Valla\Check; class UserCheck extends Check { /** * @return array<string, string> */ public function labels() { $labels = $this->labels; $labels['is_company'] = 'Is a Company?'; return $labels; } /** * @param array<string, mixed> $data * * @return array<string, string> */ public function rules(array $data) { $rules = $this->rules; if (array_key_exists('is_company', $data)) { $rules['company_name'] = 'required'; } return $rules; } }
Using PSR-7 requests
If using ServerRequestInterface from PSR-7, the Request class provides a convenient way to validate request data:
use Rougin\Valla\Request; class UserCheck extends Request { /** * @var array<string, string> */ protected $aliases = array( 'username' => 'name', 'email_add' => 'email', 'new_age' => 'age', ); // ... }
The Request class provides two methods for validation: isParamsValid for validating query parameters and isParsedValid for validating the parsed body:
$check = new UserCheck; // Returns the "ServerRequestInterface" --- $request = Http::getServerRequest(); // ---------------------------------------- // Checks against data from "getQueryParams" --- if ($check->isParamsValid($request)) { // Query parameters are valid } // --------------------------------------------- // Checks against data from "getParsedBody" --- if ($check->isParsedValid($request)) { // Parsed body is valid } // --------------------------------------------
When an alias is specified, it will be used to look for the field in the ServerRequestInterface data. For example, if the request data contains a username field, it will be validated against the rules defined for the name field.
Overriding valid
When extending the Request class and overriding the valid method, the setAlias method must be called to apply the defined aliases:
use Rougin\Valla\Request; class UserCheck extends Request { // ... public function valid($data) { // Always include this if aliases are defined --- $data = $this->setAlias($data); // ---------------------------------------------- if (! parent::valid($data)) { return count($this->errors) === 0; } // Add extra custom validation conditions here return count($this->errors) === 0; } }
Built-in rules
Valla ships with 43 built-in rules, each pre-loaded in the default Ruleset:
contains
Checks that the value contains the given substring with non-string values fail automatically:
use Rougin\Valla\Valid; $data = array('name' => 'Jane'); $valid = new Valid($data); $valid->addRule('name', 'contains:Doe'); if (! $valid->passed()) { // "Name must contain Doe" echo $valid->firstError(); }
creditCard
Validates a credit card number using the Luhn algorithm with dashes and spaces stripped before checking:
use Rougin\Valla\Valid; $data = array('card' => '123456789'); $valid = new Valid($data); $valid->addRule('card', 'creditCard'); if (! $valid->passed()) { // "Card must be a valid credit card number" echo $valid->firstError(); }
Validates a properly formatted email address with non-string values fail automatically:
use Rougin\Valla\Valid; $data = array('email' => 'not-an-email'); $valid = new Valid($data); $valid->addRule('email', 'email'); if (! $valid->passed()) { // "Email is not a valid email address" echo $valid->firstError(); }
in
Checks that the value matches one of the listed values:
use Rougin\Valla\Valid; $data = array('role' => 'guest'); $valid = new Valid($data); $valid->addRule('role', 'in:admin,editor'); if (! $valid->passed()) { // "Role contains invalid value" echo $valid->firstError(); }
instanceOf
Validates that the value is an instance of the given class with non-object values fail automatically:
use Rougin\Valla\Valid; $data = array('obj' => new \stdClass); $valid = new Valid($data); $valid->addRule('obj', 'instanceOf:\DateTime'); if (! $valid->passed()) { // "Obj must be an instance of 'DateTime'" echo $valid->firstError(); }
lengthMax
Checks that the value does not exceed the given character length with non-string values fail automatically:
use Rougin\Valla\Valid; $data = array('name' => 'too long'); $valid = new Valid($data); $valid->addRule('name', 'lengthMax:5'); if (! $valid->passed()) { // "Name must not exceed 5 characters" echo $valid->firstError(); }
lengthMin
Checks that the value meets the given minimum character length with non-string values fail automatically:
use Rougin\Valla\Valid; $data = array('name' => 'Jo'); $valid = new Valid($data); $valid->addRule('name', 'lengthMin:5'); if (! $valid->passed()) { // "Name must be at least 5 characters long" echo $valid->firstError(); }
notIn
Checks that the value does not match any of the listed values:
use Rougin\Valla\Valid; $data = array('role' => 'admin'); $valid = new Valid($data); $valid->addRule('role', 'notIn:admin,editor'); if (! $valid->passed()) { // "Role contains invalid value" echo $valid->firstError(); }
numeric
Checks that the value is numeric:
use Rougin\Valla\Valid; $data = array('age' => 'abc'); $valid = new Valid($data); $valid->addRule('age', 'numeric'); if (! $valid->passed()) { // "Age must be numeric" echo $valid->firstError(); }
required
Ensures the field is present and not empty with an optional strict mode rejecting only null:
use Rougin\Valla\Valid; $data = array('name' => ''); $valid = new Valid($data); $valid->addRule('name', 'required'); if (! $valid->passed()) { // "Name is required" echo $valid->firstError(); }
requiredWith
Makes the field required when at least one of the listed fields is present and non-empty:
use Rougin\Valla\Valid; $data = array('company_name' => '', 'is_company' => 'yes'); $valid = new Valid($data); $valid->addRule('company_name', 'requiredWith:is_company'); if (! $valid->passed()) { // "Company_name is required" echo $valid->firstError(); }
requiredWithout
Makes the field required when at least one of the listed fields is absent or empty:
use Rougin\Valla\Valid; $data = array('phone' => ''); $valid = new Valid($data); $valid->addRule('phone', 'requiredWithout:email'); if (! $valid->passed()) { // "Phone is required" echo $valid->firstError(); }
subset
Checks that every item in the array belongs to the listed set with non-array values fail automatically:
use Rougin\Valla\Valid; $data = array('options' => array('a', 'd')); $valid = new Valid($data); $valid->addRule('options', 'subset:a,b,c'); if (! $valid->passed()) { // "Options contains an item that is not in the list" echo $valid->firstError(); }
accepted
Checks that the value is one of yes, on, 1, or true:
use Rougin\Valla\Valid; $data = array('terms' => 'no'); $valid = new Valid($data); $valid->addRule('terms', 'accepted'); if (! $valid->passed()) { // "Terms is not accepted" echo $valid->firstError(); }
alpha
Checks that the value contains only alphabetic characters:
use Rougin\Valla\Valid; $data = array('name' => '123'); $valid = new Valid($data); $valid->addRule('name', 'alpha'); if (! $valid->passed()) { // "Name must contain only alphabetic characters" echo $valid->firstError(); }
alphaNum
Checks that the value contains only alpha-numeric characters:
use Rougin\Valla\Valid; $data = array('name' => 'test!@#'); $valid = new Valid($data); $valid->addRule('name', 'alphaNum'); if (! $valid->passed()) { // "Name must contain only alpha-numeric characters" echo $valid->firstError(); }
array
Checks that the value is an array:
use Rougin\Valla\Valid; $data = array('items' => 'string'); $valid = new Valid($data); $valid->addRule('items', 'array'); if (! $valid->passed()) { // "Items must be an array" echo $valid->firstError(); }
arrayHasKeys
Checks that the array value contains all of the specified keys:
use Rougin\Valla\Valid; $data = array('data' => array('a' => 1)); $valid = new Valid($data); $valid->addRule('data', 'arrayHasKeys:a,b'); if (! $valid->passed()) { // "Data must contain the required keys" echo $valid->firstError(); }
ascii
Checks that the value contains only ASCII characters:
use Rougin\Valla\Valid; $data = array('name' => "J\xC3\xA1ne"); $valid = new Valid($data); $valid->addRule('name', 'ascii'); if (! $valid->passed()) { // "Name must contain only ASCII characters" echo $valid->firstError(); }
between
Checks that the numeric value falls between the given minimum and maximum:
use Rougin\Valla\Valid; $data = array('age' => 25); $valid = new Valid($data); $valid->addRule('age', 'between:1,20'); if (! $valid->passed()) { // "Age must be between 1 and 20" echo $valid->firstError(); }
boolean
Checks that the value is a boolean:
use Rougin\Valla\Valid; $data = array('flag' => 'yes'); $valid = new Valid($data); $valid->addRule('flag', 'boolean'); if (! $valid->passed()) { // "Flag must be a boolean" echo $valid->firstError(); }
containsUnique
Checks that the array value contains only unique values:
use Rougin\Valla\Valid; $data = array('items' => array('a', 'b', 'a')); $valid = new Valid($data); $valid->addRule('items', 'containsUnique'); if (! $valid->passed()) { // "Items must contain unique values only" echo $valid->firstError(); }
date
Checks that the value is a valid date string:
use Rougin\Valla\Valid; $data = array('birthday' => 'not-a-date'); $valid = new Valid($data); $valid->addRule('birthday', 'date'); if (! $valid->passed()) { // "Birthday must be a valid date" echo $valid->firstError(); }
dateAfter
Checks that the value is a date after the specified date:
use Rougin\Valla\Valid; $data = array('date' => '2020-01-01'); $valid = new Valid($data); $valid->addRule('date', 'dateAfter:2023-01-01'); if (! $valid->passed()) { // "Date must be a date after 2023-01-01" echo $valid->firstError(); }
dateBefore
Checks that the value is a date before the specified date:
use Rougin\Valla\Valid; $data = array('date' => '2024-01-01'); $valid = new Valid($data); $valid->addRule('date', 'dateBefore:2023-01-01'); if (! $valid->passed()) { // "Date must be a date before 2023-01-01" echo $valid->firstError(); }
dateFormat
Checks that the value matches the specified date format (e.g., Y-m-d):
use Rougin\Valla\Valid; $data = array('date' => '01-01-2023'); $valid = new Valid($data); $valid->addRule('date', 'dateFormat:Y-m-d'); if (! $valid->passed()) { // "Date must be a valid date format" echo $valid->firstError(); }
different
Checks that the value is different from the value of another field:
use Rougin\Valla\Valid; $data = array('a' => 'hello', 'b' => 'hello'); $valid = new Valid($data); $valid->addRule('a', 'different:b'); if (! $valid->passed()) { // "A must be different from b" echo $valid->firstError(); }
emailDNS
Checks that the value is an email address with an active domain (MX record):
use Rougin\Valla\Valid; $data = array('email' => 'test@nonexistent-domain.invalid'); $valid = new Valid($data); $valid->addRule('email', 'emailDNS'); if (! $valid->passed()) { // "Email must be a valid email address with active domain" echo $valid->firstError(); }
equals
Checks that the value equals the value of another field:
use Rougin\Valla\Valid; $data = array('a' => 'hello', 'b' => 'world'); $valid = new Valid($data); $valid->addRule('a', 'equals:b'); if (! $valid->passed()) { // "A must be equal to b" echo $valid->firstError(); }
integer
Checks that the value is an integer with an optional strict mode:
use Rougin\Valla\Valid; $data = array('age' => 'abc'); $valid = new Valid($data); $valid->addRule('age', 'integer'); if (! $valid->passed()) { // "Age must be an integer" echo $valid->firstError(); }
ip
Checks that the value is a valid IP address:
use Rougin\Valla\Valid; $data = array('ip' => 'not-an-ip'); $valid = new Valid($data); $valid->addRule('ip', 'ip'); if (! $valid->passed()) { // "Ip must be a valid IP address" echo $valid->firstError(); }
ipv4
Checks that the value is a valid IPv4 address:
use Rougin\Valla\Valid; $data = array('ip' => '::1'); $valid = new Valid($data); $valid->addRule('ip', 'ipv4'); if (! $valid->passed()) { // "Ip must be a valid IPv4 address" echo $valid->firstError(); }
ipv6
Checks that the value is a valid IPv6 address:
use Rougin\Valla\Valid; $data = array('ip' => '192.168.1.1'); $valid = new Valid($data); $valid->addRule('ip', 'ipv6'); if (! $valid->passed()) { // "Ip must be a valid IPv6 address" echo $valid->firstError(); }
length
Checks that the string length matches an exact value or falls between min and max:
use Rougin\Valla\Valid; $data = array('name' => 'Jo'); $valid = new Valid($data); $valid->addRule('name', 'length:5'); if (! $valid->passed()) { // "Name must be exactly 5 characters" echo $valid->firstError(); }
lengthBetween
Checks that the string length falls between the given min and max:
use Rougin\Valla\Valid; $data = array('name' => 'too long'); $valid = new Valid($data); $valid->addRule('name', 'lengthBetween:1,5'); if (! $valid->passed()) { // "Name must be between 1 and 5 characters" echo $valid->firstError(); }
listContains
Checks that the array value contains the specified item:
use Rougin\Valla\Valid; $data = array('items' => array('a', 'b')); $valid = new Valid($data); $valid->addRule('items', 'listContains:c'); if (! $valid->passed()) { // "Items must contain the specified value" echo $valid->firstError(); }
max
Checks that the numeric value does not exceed the given maximum:
use Rougin\Valla\Valid; $data = array('age' => 25); $valid = new Valid($data); $valid->addRule('age', 'max:20'); if (! $valid->passed()) { // "Age must not exceed 20" echo $valid->firstError(); }
min
Checks that the numeric value is at least the given minimum:
use Rougin\Valla\Valid; $data = array('age' => 5); $valid = new Valid($data); $valid->addRule('age', 'min:10'); if (! $valid->passed()) { // "Age must be at least 10" echo $valid->firstError(); }
optional
Always passes regardless of the value, allowing a field to be optional:
use Rougin\Valla\Valid; $data = array('field' => ''); $valid = new Valid($data); $valid->addRule('field', 'optional'); // [NOTE] Optional rules always pass $valid->passed();
regex
Checks that the value matches the given regular expression:
use Rougin\Valla\Valid; $data = array('name' => 'hello'); $valid = new Valid($data); $valid->addRule('name', 'regex:/^[0-9]+$/'); if (! $valid->passed()) { // "Name does not match the required pattern" echo $valid->firstError(); }
slug
Checks that the value is a valid slug (alpha-numeric, dashes, underscores):
use Rougin\Valla\Valid; $data = array('slug' => 'not a slug!'); $valid = new Valid($data); $valid->addRule('slug', 'slug'); if (! $valid->passed()) { // "Slug must be a valid slug" echo $valid->firstError(); }
url
Checks that the value is a valid URL starting with http, https, or ftp:
use Rougin\Valla\Valid; $data = array('link' => 'not-a-url'); $valid = new Valid($data); $valid->addRule('link', 'url'); if (! $valid->passed()) { // "Link must be a valid URL" echo $valid->firstError(); }
urlActive
Checks that the value is a valid URL with an active domain (DNS record):
use Rougin\Valla\Valid; $data = array('link' => 'http://nonexistent-domain.invalid'); $valid = new Valid($data); $valid->addRule('link', 'urlActive'); if (! $valid->passed()) { // "Link must be a valid URL with active domain" echo $valid->firstError(); }
Migrating from Valitron
As this was inspired from Valitron, migrating to Valla is simple as changing its namespace and the class name. Valla provides the same rule method for mirroring Valitron's:
-use Valitron\Validator; +use Rougin\Valla\Valid; -$valid = new Validator($data); +$valid = new Valid($data); $valid->rule('required', 'name'); $valid->rule('min', 'age', 5); $valid->rule('required', array('name', 'email')); if (! $valid->validate()) { print_r($valid->errors()); }
Once migrated, update the said method to addRule with its required parameters:
-$valid->rule('required', 'name'); +$valid->addRule('name', 'required'); -$valid->rule('min', 'age', 5); +$valid->addRule('age', 'min:5'); -$valid->rule('required', array('name', 'email')); +$valid->addRule('name', 'required'); +$valid->addRule('email', 'required');
Warning
The rule method only accepts string rule names (e.g. 'required', 'min:5'). Callable rules will not be supported. Kindly see Adding custom rules for how to create one.
Changelog
Please see CHANGELOG for more recent changes and latest updates.
Contributing
See CONTRIBUTING on how to contribute to the project.
License
The MIT License (MIT). Please see LICENSE for more information.
rougin/valla 适用场景与选型建议
rougin/valla 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.07k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 10 月 26 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php-validation」 「php-validator」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 rougin/valla 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 rougin/valla 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 rougin/valla 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A validator featuring rule objects, string rule mapping, wildcard validation and more
WordPress Validation and Sanitization Library
The Vection Validator provides validation of data and schemas. A number of different validators are already included and can be applied in a chained manner.
PHP validation & sanitizer library
PHP Validation class inspired by the jQuery Validation Plugin
Validates and sanitizes structured data arrays with configurable constraints (size, depth, nesting, key/value types).
统计信息
- 总下载量: 1.07k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 5
- 依赖项目数: 3
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-26