Dev Notes

Software Development Resources by David Egan.

Laravel Form Validation Primer


Forms, Laravel, PHP
David Egan

Form validation logic can be held in an extension of the Request class.

The Request class allows your script to get an instance of the current HTTP request. This is achieved by type hinting the Request class on the controller method. Dependency injection of The HTTP request then happens automatically.

Fortunately, Laravel has a built-in Artisan command that facilitates the generation of custom requests.

Create a Custom Request

Create a new form request class using Artisan:

php artisan make:request ArticleRequest

This stubs out a form request class under /app/Http/Requests - in this case the new file is: app/Http/Requests/ArticleRequest.php.

The file contains a new ArticleRequest class, which extends FormRequest.

FormRequest in turn extends the basic Laravel Request class - which in turn extends the Symfony Request component.

It’s probably better to keep the class name a bit general - ArticleRequest is probably better than CreateArticleRequest - as the same validation logic can be used for forms used to create and edit resources.

Set Up Validation Rules

The new form request class has an authorize() and a rules() method stubbed out. The authorize() method can be used to check if the user is authorized to make the request - we might add a check for article ownership here.

The rules() method allows you to set rules which must be passed. The controller form processing method will receive an instance of the request class - and will not progress if any rules fail.

Example Rules with Custom Error Messages

<?php

// app/Http/Requests/CreateArticleRequest.php

...
  /**
   * Get the validation rules that apply to the request.
   *
   * This method should return an array of validation rules.
   *
   * @return array
   */
    public function rules()
    {
      return [
        // The 'title' field is required and must be at least 10 characters
        'title' => 'required|min:10',

        // The 'body' field is required
        'body' => 'required',

        // The 'published_at' field is required and must be a date
        'published_at' => 'required|date'
      ];

      // If necessary, create a $rules array to return (rather than returning
      // the array directly). This will allow conditional validation to be
      // built in - for example, a form that updates a record may require
      // additional (or relaxed) validation rules. These can be added
      // conditionally to the $rules array before it is returned.
    }

    /**
     * Override the built-in messages.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'title.required' => 'Er, you forgot to add a title!',
            'title.min' => 'Don\'t be stingy - make the title LONGER THAN 3 CHARACTERS!',
            'body.required' => 'No body, no article.'
        ];
    }

In the Controller

The new form request instance is passed into form processing methods on the Controller.

Dependency injection happens automatically by means of Laravel’s service container, but this can only take place if the request class is type-hinted on the controller method.

The store/update methods will not proceed until validation rules pass.

Example:

<?php
// app/Http/Controllers/ArticlesController.php
...
  /**
   * Store a newly created resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @return \Illuminate\Http\Response
   */
  public function store(Requests\ArticleRequest $request)
  {

      $request = $request->all();
      Article::create($request);

      return redirect('articles');
  }

...

References


comments powered by Disqus