laminas/laminas-validator
Validation component for PHP and Laminas applications. Provides a wide range of ready-to-use validators (strings, numbers, dates, files, and more), consistent error messages, and an extensible API to create custom validators and input filtering rules.
Installation:
composer require laminas/laminas-validator
Add to composer.json under require if not using global install.
First Use Case: Validate a user input (e.g., email, file upload) in a Laravel controller:
use Laminas\Validator\EmailAddress;
$validator = new EmailAddress();
$isValid = $validator->isValid($request->input('email'));
Where to Look First:
EmailAddress, NotEmpty, File\MimeType) in Laminas\Validator\.laminas-inputfilter or laminas-form integration if using forms.Basic Validation:
$validator = new \Laminas\Validator\NotEmpty();
if (!$validator->isValid($value)) {
return redirect()->back()->withErrors(['field' => $validator->getMessages()]);
}
Chaining Validators:
$validator = new \Laminas\Validator\Composite([
new \Laminas\Validator\NotEmpty(),
new \Laminas\Validator\EmailAddress(),
]);
Custom Validation Logic:
$validator = new \Laminas\Validator\Callback(function ($value) {
return strlen($value) >= 8;
}, ['message' => 'Password must be at least 8 characters.']);
File Validation (e.g., uploads):
$validator = new \Laminas\Validator\File\MimeType([
'mimeType' => 'image/jpeg,image/png',
]);
$isValid = $validator->isValid($request->file('avatar'));
Integration with Laravel Forms:
Use laravel-form (if installed) or manually bind to Laravel’s FormRequest:
public function rules()
{
return [
'email' => ['required', 'email'],
'avatar' => ['required', 'mimes:jpeg,png'],
];
}
Laravel Service Providers: Bind validators to Laravel’s IoC container for reuse:
$this->app->bind(\Laminas\Validator\EmailAddress::class, function () {
return new \Laminas\Validator\EmailAddress();
});
Form Request Validation:
Extend FormRequest and use Laminas validators in rules() or withValidator():
public function withValidator($validator, $data, $messages)
{
$validator->add(new \Laminas\Validator\Callback(function ($value) {
return $value === 'secret';
}));
}
API Responses: Return validator messages in JSON:
return response()->json([
'errors' => $validator->getMessages()
], 422);
File Validation Quirks:
File\MimeType requires the fileinfo PHP extension. Check with:
if (!extension_loaded('fileinfo')) {
throw new \RuntimeException('FileInfo extension is required.');
}
$file = $request->file('avatar');
$file->store('avatars'); // Store first, then validate
Callback Scope Issues:
bind: false) cannot access validator methods (e.g., setMessage()). Use bind: true for dynamic messages:
$validator = new \Laminas\Validator\Callback([...], ['bind' => true]);
Performance:
File\Hash on large files) in loops. Cache results if reused.Message Localization:
resources/lang or set custom messages:
$validator->setMessage('isInvalid', 'Custom error message.');
Validator Messages: Dump messages for debugging:
dd($validator->getMessages());
Context in Callbacks:
Ensure the $context array is passed when using standalone validators (not via laminas-inputfilter):
$validator->isValid($value, $request->all());
Exception Handling:
Use throwExceptions: true in Callback for development:
$validator = new \Laminas\Validator\Callback([...], ['throwExceptions' => true]);
Custom Validators:
Extend \Laminas\Validator\AbstractValidator:
class CustomValidator extends \Laminas\Validator\AbstractValidator
{
public function isValid($value)
{
return $value === 'custom';
}
}
Validator Factories:
Use Laravel’s Validator facade to create instances dynamically:
$validator = \Validator::make($data, [
'field' => ['custom_validator'],
]);
PSR-7 Uploads:
For PSR-7 apps (e.g., Lumen), use UploadedFileInterface:
$validator = new \Laminas\Validator\File\MimeType([...]);
$isValid = $validator->isValid($psr7UploadedFile);
Testing: Mock validators in PHPUnit:
$validator = $this->createMock(\Laminas\Validator\EmailAddress::class);
$validator->method('isValid')->willReturn(true);
How can I help you explore Laravel packages today?