// tutorial

Writing rules() in a Form Request

The rules() method looks like a plain array of pipe-delimited strings, but each entry can just as easily be an array, a Rule object, or a closure. Here's what's available once the basic required|string|max:255 stops being enough.

php laravel validation 6 min read
  1. String syntax vs array syntax

    A pipe-delimited string and an array of rules mean exactly the same thing — the array form just avoids escaping when a rule's parameter contains a pipe or comma itself, like a regex.

    php
    public function rules(): array
    {
        return [
            'email' => 'required|email|max:255',
    
            // equivalent, array form
            'email' => ['required', 'email', 'max:255'],
        ];
    }
  2. Rule objects for anything dynamic

    The Rule facade builds rules that need runtime values — like ignoring the current record's own row on an unique check during an update.

    php
    use Illuminate\Validation\Rule;
    
    public function rules(): array
    {
        return [
            'email' => [
                'required',
                'email',
                Rule::unique('users')->ignore($this->user),
            ],
            'status' => ['required', Rule::in(['draft', 'published', 'archived'])],
        ];
    }
  3. Conditional rules

    Some fields only need validating depending on other input. sometimes skips a rule entirely when the field is absent from the request; Rule::when() and reading $this->input() handle everything more conditional than that, since rules() is just a regular method.

    php
    public function rules(): array
    {
        return [
            'promo_code' => 'sometimes|string|max:20',
    
            'shipping_address' => [
                Rule::requiredIf($this->input('delivery_method') === 'courier'),
                'string',
            ],
        ];
    }
  4. Custom messages and attribute names

    Override messages() to replace the default English copy for specific rule.field combinations, and attributes() to control the field name that gets substituted into the :attribute placeholder.

    php
    public function messages(): array
    {
        return [
            'price.min' => 'The price can\'t be negative.',
        ];
    }
    
    public function attributes(): array
    {
        return [
            'sku' => 'SKU',
        ];
    }
  5. Validating nested and array input

    Dot notation reaches into nested arrays, and * applies the same rule to every item in a list — handy for a request with a repeated group of fields, like order line items.

    php
    public function rules(): array
    {
        return [
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|integer|exists:products,id',
            'items.*.quantity' => 'required|integer|min:1',
        ];
    }