Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Validator Laravel Package

symfony/validator

Symfony Validator component validates values and objects using a constraint-based system inspired by JSR-303 Bean Validation. Supports built-in and custom constraints, rich violation messages, and integration with Symfony forms and frameworks.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/validator
    

    For Laravel, use symfony/validator alongside symfony/property-access (if not already included via symfony/http-foundation).

  2. Basic Validation:

    use Symfony\Component\Validator\Validation;
    use Symfony\Component\Validator\Constraints as Assert;
    
    $validator = Validation::createValidator();
    $value = 'test@example.com';
    
    $constraint = new Assert\Email();
    $violations = $validator->validate($value, $constraint);
    
    if (count($violations) === 0) {
        // Valid
    }
    
  3. First Use Case: Validate a form request in Laravel:

    use Illuminate\Http\Request;
    use Symfony\Component\Validator\Validator\ValidatorInterface;
    
    public function __construct(ValidatorInterface $validator) {
        $this->validator = $validator;
    }
    
    public function store(Request $request) {
        $data = $request->validate([
            'email' => ['required', 'email'],
            'age' => ['integer', 'min' => 18, 'max' => 120],
        ]);
        // Proceed with valid data
    }
    

Where to Look First

  • Official Documentation (Constraints, Validation Groups, Custom Constraints).
  • Laravel Integration: Use ValidatorInterface from symfony/validator via Laravel’s service container.
  • Common Constraints: Email, NotBlank, Length, Unique, Callback.

Implementation Patterns

Core Workflows

  1. Form/Request Validation:

    use Symfony\Component\Validator\Constraints as Assert;
    
    $constraints = new Assert\Collection([
        'email' => new Assert\Email(),
        'password' => new Assert\Length(['min' => 8]),
    ]);
    $violations = $validator->validate($request->all(), $constraints);
    
  2. Domain Model Validation:

    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints as Assert;
    
    $metadata = new ClassMetadata(User::class);
    $metadata->addPropertyConstraint('email', new Assert\Email());
    $metadata->addPropertyConstraint('age', new Assert\Range(['min' => 18]));
    $validator->validate($user, $metadata);
    
  3. API Payload Validation:

    $payload = json_decode($request->getContent(), true);
    $constraints = new Assert\All([
        new Assert\Type('array'),
        new Assert\Callback(function ($item) {
            return strlen($item) <= 255;
        }),
    ]);
    $validator->validate($payload, $constraints);
    

Integration Tips

  • Laravel Forms: Use symfony/validator with Laravel’s FormRequest:

    public function rules() {
        return [
            'email' => 'required|email',
            'age' => 'integer|min:18',
        ];
    }
    
    public function withValidator($validator) {
        $validator->addConstraintTo('email', new Assert\NotBlank());
    }
    
  • Custom Constraints:

    namespace App\Validator\Constraints;
    
    use Symfony\Component\Validator\Constraint;
    
    class CustomConstraint extends Constraint {
        public $message = 'This value is invalid.';
    }
    
  • Validation Groups:

    $validator->validate($object, null, ['group1', 'group2']);
    
  • Dynamic Constraints:

    $constraint = new Assert\Callback(function ($value) use ($dynamicRule) {
        return $value === $dynamicRule;
    });
    
  • Cascading Failures: Use Assert\Valid to validate nested objects/collections recursively.


Gotchas and Tips

Pitfalls

  1. Performance:

    • Avoid validating large arrays/collections unnecessarily. Use Assert\All sparingly.
    • Cache metadata for reusable validation (e.g., domain models):
      $validator->validate($user, $metadata); // Reuse $metadata
      
  2. Constraint Options:

    • Deprecated Options: In Symfony 8+, avoid passing associative arrays to GroupSequence or using implicit constraint names in YAML/XML.
    • Null Handling: Constraints like NotBlank may not work as expected with null values. Use Assert\NotNull or Assert\Blank explicitly.
  3. Custom Constraints:

    • Option Validation: Ensure configureOptions() in custom constraints validates required options:
      public function configureOptions(OptionsResolver $resolver) {
          $resolver->setRequired(['param']);
          $resolver->setDefault('param', 'default');
      }
      
    • Expression Language: If using Expression, ensure the ExpressionLanguage component is installed:
      composer require symfony/expression-language
      
  4. Edge Cases:

    • Regex Bypass: Large inputs may bypass regex checks (fixed in v6.4.36+). Use Assert\Regex with caution on untrusted data.
    • Extreme Dates: Avoid comparing dates near PHP’s DateTime limits (e.g., 1901-12-31 vs. 1970-01-01). Use Assert\GreaterThan/LessThan with care.
  5. Laravel-Specific:

    • Service Binding: Laravel’s Validator facade wraps symfony/validator. For advanced use, inject ValidatorInterface directly:
      public function __construct(private ValidatorInterface $validator) {}
      
    • Form Requests: Laravel’s FormRequest uses symfony/validator under the hood. Override failedValidation() for custom responses:
      public function failedValidation(Validator $validator) {
          throw new \Exception('Custom error');
      }
      

Debugging Tips

  1. Violation Details:

    foreach ($violations as $violation) {
        echo $violation->getPropertyPath() . ': ' . $violation->getMessage();
    }
    
  2. Constraint Dumping: Use ValidatorBuilder to inspect constraints:

    $builder = Validation::createValidatorBuilder();
    $validator = $builder->getValidator();
    $metadata = $validator->getMetadataFactory()->getMetadataFor($class);
    
  3. Constraint Order: Validation stops at the first failure by default. Use Assert\Valid for nested validation or Validator::validate($value, $constraints, null, ['stop_on_first_error' => false]).

Extension Points

  1. Custom Validators:

    use Symfony\Component\Validator\ConstraintValidator;
    
    class CustomValidator extends ConstraintValidator {
        public function validate($value, Constraint $constraint) {
            if (!preg_match($constraint->pattern, $value)) {
                $this->context->buildViolation($constraint->message)
                    ->addViolation();
            }
        }
    }
    
  2. Metadata Customization: Override Loader\LoaderInterface to load constraints from custom sources (e.g., database).

  3. Validation Groups: Dynamically assign groups based on context:

    $validator->validate($object, null, ['group_' . $user->role]);
    
  4. Constraint Composition: Combine constraints using Assert\All, Assert\Collection, or Assert\Valid for complex rules.

  5. Event Listeners: Attach listeners to validation events (e.g., ConstraintViolatedEvent):

    $validator->addListener('constraint_violated', function ($event) {
        // Log or transform violations
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport