teonord/validator
最新稳定版本:0.1.2
Composer 安装命令:
composer require teonord/validator
包简介
Advanced validation library with multiple API styles including JSON templates, inline rules, builder pattern, and functional composition. Features 50+ built-in validators, dot notation for nested objects, field reference resolution, and internationalization support. Zero dependencies, fully synchron
关键字:
README 文档
README
Advanced validation library for PHP with multiple API styles including JSON templates, inline rules, builder pattern, and functional composition. Features 50+ built-in validators, dot notation for nested objects, field reference resolution, and internationalization support. Zero dependencies, fully synchronous, and designed for maximum developer experience with extensible custom rule system.
Features
- 🎯 Multiple Validation APIs: JSON templates, inline rules, builder pattern, functional composition
- 🏷️ PHP 8.2+: Modern PHP with strict types and full type safety
- 🌍 Internationalization: Multi-language error messages
- 🔧 Extensible: Custom rules and validators
- 🧪 Comprehensive Rule Set: 50+ built-in validation rules
- 🚀 Lightweight: Zero dependencies, only PHP extensions
📚 Table of Contents
- Installation
- Quick Start
- JSON Template Validation
- Validation APIs
- Rule Reference
- Error Handling
- Internationalization
- Custom Rules
- API Reference
Installation
composer require teonord/validator
Examples
Quick Start
use Teonord\Validator\Validator;
use Teonord\Validator\Parser\InlineParser;
$data = [
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => 25
];
$validator = new Validator($data);
$result = $validator->validateRules([
'name' => InlineParser::parse('required|minLength:2'),
'email' => InlineParser::parse('required|email'),
'age' => [['rule' => 'numeric'], ['rule' => 'min', 'value' => 18]]
]);
var_dump($result->isValid); // bool(true)
var_dump($result->errors); // []
JSON Template Validation
use Teonord\Validator\Validator;
$data = [
'username' => 'john_doe'
];
$validator = new Validator($data);
$template = [
[
'name' => 'username',
'validation' => [
[
'rule' => 'required',
'message' => [
'en' => 'Username is required',
'fr' => 'Nom d\'utilisateur est requis'
]
],
[
'rule' => 'minLength',
'value' => 3,
'message' => [
'en' => 'Username must be at least 3 characters',
'fr' => 'Le nom d\'utilisateur doit contenir au moins 3 caractères'
]
]
]
]
];
$result = $validator->validateTemplate($template);
Validation APIs
JSON Template API
Structured validation with field definitions and custom messages:
use Teonord\Validator\Validator;
$data = [
'email' => 'john@example.com',
'password' => 'pass123'
];
$validator = new Validator($data);
$template = [
[
'name' => 'email',
'validation' => [
[
'rule' => 'required',
'message' => ['en' => 'Email is required', 'es' => 'El email es requerido']
],
[
'rule' => 'email',
'message' => ['en' => 'Invalid email format', 'es' => 'Formato de email inválido']
]
]
],
[
'name' => 'password',
'validation' => [
[
'rule' => 'required',
'message' => ['en' => 'Password is required', 'es' => 'La contraseña es requerida']
],
[
'rule' => 'minLength',
'value' => 8,
'message' => ['en' => 'Password must be 8+ characters', 'es' => 'La contraseña debe tener 8+ caracteres']
]
]
]
];
$result = $validator->validateTemplate($template);
Inline Rules API
use Teonord\Validator\Validator;
use Teonord\Validator\Parser\InlineParser;
$data = [
'username' => 'john',
'email' => 'john@example.com',
'age' => 25,
'tags' => ['js', 'php'],
'website' => 'https://example.com'
];
$validator = new Validator($data);
$result = $validator->validateRules([
'username' => InlineParser::parse('required|minLength:3|maxLength:20|alphaDash'),
'email' => InlineParser::parse('required|email'),
'age' => InlineParser::parse('required|numeric|min:18|max:100'),
'tags' => InlineParser::parse('array|minItems:1|maxItems:5'),
'website' => InlineParser::parse('url')
]);
Builder Pattern API
Fluent interface for building validation rules:
use Teonord\Validator\ValidatorBuilder;
$result = (new ValidatorBuilder())
->setData(['username' => 'john_doe', 'email' => 'john@example.com'])
->addField('username', [
['rule' => 'required'],
['rule' => 'minLength', 'value' => 3],
['rule' => 'alphaDash']
])
->addField('email', [
['rule' => 'required'],
['rule' => 'email']
])
->setLanguage('en')
->validate();
Functional Composition API
Composable validation pipelines:
use Teonord\Validator\Functional\Composition;
use Teonord\Validator\Functional\ValidatorPipes;
use Teonord\Validator\Types\ValidationError;
// Individual validation pipes
$userValidation = ValidatorPipes::createPipe([
'name' => [['rule' => 'required'], ['rule' => 'minLength', 'value' => 2]],
'email' => [['rule' => 'required'], ['rule' => 'email']]
]);
$addressValidation = ValidatorPipes::createPipe([
'street' => [['rule' => 'required']],
'city' => [['rule' => 'required']],
'country' => [['rule' => 'required'], ['rule' => 'in', 'value' => ['US', 'CA', 'UK']]]
]);
$paymentValidation = ValidatorPipes::createPipe([
'payment_method' => [['rule' => 'required']],
'amount' => [['rule' => 'required'], ['rule' => 'numeric'], ['rule' => 'min', 'value' => 1]]
]);
// Data transformation
$sanitizeData = function(array $data): array {
return [
...$data,
'name' => isset($data['name']) ? strtolower(trim($data['name'])) : null,
'email' => isset($data['email']) ? strtolower(trim($data['email'])) : null,
'street' => isset($data['street']) ? trim($data['street']) : null
];
};
// Error formatting
$formatErrors = function(array $errors): array {
return array_map(function(ValidationError $error) {
return new ValidationError(
$error->field,
$error->rule,
"{$error->field}: {$error->message}",
$error->value,
[...$error->params, 'code' => "VALIDATION_" . strtoupper($error->rule)]
);
}, $errors);
};
// Complete validation pipeline
$completeValidation = Composition::pipe(
Composition::transformData($userValidation, $sanitizeData),
$addressValidation,
Composition::conditional(
fn(array $data) => $data['requires_payment'] ?? false,
$paymentValidation
)
);
$validationPipe = Composition::mapErrors($completeValidation, $formatErrors);
// Usage
$userData = [
'name' => ' JOHN DOE ',
'email' => 'JOHN@EXAMPLE.COM',
'street' => '123 Main St',
'city' => 'New York',
'country' => 'US',
'requires_payment' => true,
'payment_method' => 'credit_card',
'amount' => 50
];
$result = $validationPipe($userData);
Rule Reference
String Rules
required- Field is requiredminLength:value- Minimum string lengthmaxLength:value- Maximum string lengthlength:value- Exact string lengthemail- Valid email formaturl- Valid URL formatip- Valid IP address (IPv4, IPv6 compressed/uncompressed, IPv4-mapped)uuid- Valid UUID formatalpha- Only lettersalphaNumeric- Letters and numbers onlyalphaDash- Letters, numbers, dashes and underscoresregex:pattern- Matches regex patternstartsWith:value- Starts with valueendsWith:value- Ends with valuecontains:value- Contains valuenotContains:value- Does not contain valuein:value1,value2,...- Value is in listnotIn:value1,value2,...- Value is not in list
Number Rules
numeric- Is a numberinteger- Is an integerfloat- Is a floatmin:value- Minimum valuemax:value- Maximum valuebetween:min,max- Between min and maxpositive- Positive numbernegative- Negative numbermultipleOf:value- Multiple of value
Array Rules
array- Is an arrayminItems:value- Minimum array lengthmaxItems:value- Maximum array lengthlengthItems:value- Exact array lengthincludes:value- Array includes valueexcludes:value- Array excludes valueunique- Array has unique values
Date Rules
date- Valid datebefore:date- Date is beforeafter:date- Date is afterbetweenDates:start,end- Date is between
File Rules
file- Is a file objectmime:type1,type2,...- File MIME typemaxSize:bytes- Maximum file sizeminSize:bytes- Minimum file size
Boolean Rules
boolean- Is booleanaccepted- Is accepted (true, 'true', 1, '1', 'yes', 'on')
Conditional Rules
requiredIf:field,value- Required if field equals valuerequiredUnless:field,value- Required unless field equals valuerequiredWith:field- Required when field is presentrequiredWithAll:field1,field2,...- Required when all fields presentrequiredWithout:field- Required when field is not presentrequiredWithoutAll:field1,field2,...- Required when none of fields presentsame:field- Same as another fielddifferent:field- Different from another fieldgt:field- Greater than another fieldgte:field- Greater than or equal to another fieldlt:field- Less than another fieldlte:field- Less than or equal to another fieldwhen:condition- Apply rules when condition is truerequiredIfAny:conditions- Required if any condition is metrequiredIfAll:conditions- Required if all conditions are met
Error Handling
use Teonord\Validator\Validator;
$validator = new Validator($data);
$result = $validator->validateRules([
'email' => [['rule' => 'required'], ['rule' => 'email']]
]);
if (!$result->isValid) {
foreach ($result->errors as $error) {
echo "Field: " . $error->field . "\n";
echo "Rule: " . $error->rule . "\n";
echo "Message: " . $error->message . "\n";
echo "Value: " . ($error->value ?? 'null') . "\n";
}
$apiErrors = array_map(function($error) {
return [
'field' => $error->field,
'message' => $error->message,
'code' => $error->rule
];
}, $result->errors);
}
Internationalization
use Teonord\Validator\Validator;
use Teonord\Validator\Types\ValidatorOptions;
$validator = new Validator($data, new ValidatorOptions(
'fr', // language
[
'email.required' => [
'en' => 'Email address is required',
'fr' => 'L\'adresse email est requise',
'es' => 'La dirección de correo electrónico es obligatoria'
],
'email.email' => [
'en' => 'Must be a valid email address',
'fr' => 'Doit être une adresse email valide',
'es' => 'Debe ser una dirección de correo electrónico válida'
]
]
));
Custom Rules
use Teonord\Validator\Validator;
$validator = new Validator($data);
$customRule = function(mixed $value, array $params, array $data): bool|string {
if ($value === 'custom') {
return true;
}
return false; // or return error message string
};
$validator->addCustomRule('customRule', $customRule);
$validator->addCustomRule('even', fn($value) => is_numeric($value) && $value % 2 === 0);
$result = $validator->validateRules([
'field' => [['rule' => 'customRule']],
'number' => [['rule' => 'even']]
]);
API Reference
Main Classes and Functions
Validator- Main validation classValidatorBuilder- Fluent builder for validation rulesInlineParser::parse()- Parse inline rule string
Validator Class
Constructor
new Validator(array $data, ?ValidatorOptions $options = null)
Methods
validateTemplate(array $template): ValidationResultvalidateRules(array $rules): ValidationResultaddCustomRule(string $name, callable $rule): void
ValidatorBuilder Class
Methods
setData(array $data): selfaddField(string $field, array $rules): selfsetOptions(ValidatorOptions $options): selfsetLanguage(string $language): selfbuild(): Validatorvalidate(): ValidationResult
Functional API
Composition::pipe(callable ...$pipes): callableComposition::mapErrors(callable $pipe, callable $mapper): callableComposition::transformData(callable $pipe, callable $transformer): callableComposition::conditional(callable $condition, callable $truePipe, ?callable $falsePipe = null): callableComposition::mergePipes(callable ...$pipes): callableValidatorPipes::createPipe(array $rules, ?ValidatorOptions $options = null): callableValidatorPipes::createTemplatePipe(array $template, ?ValidatorOptions $options = null): callableValidatorPipes::validateField(string $field, array $rules, ?ValidatorOptions $options = null): callableComposition::tap(callable $pipe, callable $callback): callableComposition::catchError(callable $pipe, callable $handler): callableComposition::withDefault(callable $pipe, array $defaultData): callable
Types
class ValidationResult {
public bool $isValid;
/** @var ValidationError[] */
public array $errors;
public array $data;
}
class ValidationError {
public string $field;
public string $rule;
public string $message;
public mixed $value;
public array $params;
}
class ValidatorOptions {
public string $language = 'en';
/** @var array<string, array<string, string>> */
public array $customMessages = [];
/** @var array<string, callable> */
public array $customRules = [];
}
License
MIT
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-06