Filter User Input Before Validation in Laravel

Jun 6, 2019 laravel php
This post is more than 18 months old. Since technology changes too rapidly, this content may be out of date (but that's not always the case). Please remember to verify any technical or programming information with the current release.

Sometimes it makes sense to filter user input before it goes to validation. If you’re using controller-based validation in Laravel, this is pretty easy. But, if you’re doing your validation in request classes, your approach needs to be different.

In this example, I have an item coming in as an array. The item is an array as well. Sometimes, because of the UI, the user can send in a blank item, followed by a filled item. So, I don’t want to give them errors for the blank one - I just want it removed.

To give a better idea, here’s an example of what the form fields look like.

<div>
  <input name="items[0][id]">
  <input name="items[0][label]">
</div>
<div>
  <input name="items[1][id]">
  <input name="items[1][label]">
</div>

This markup is obviously programmatically generated, but this gives you an idea. The user could not fill in the first row, which is ok. It should be ignored.

To do this, you can use the method prepareForValidation on your request class.

<?php
class ItemStoreRequest extends FormRequest
{
  /**
   * get rid of empty items before validation
   */
  protected function prepareForValidation()
  {
    if (is_array($items = $this->get('items', []))) {
      $this->merge(['items' => array_filter($items)]);
    }
  }

  public function rules(): array
  // snip

And, obviously the controller looks like this:

<?php
MyController extends Controller
{
  public function store(ItemStoreRequest $request)
  {
    $validated = $request->validated();
    // snip

The prepareForValidation() method runs before the rules are retrieved and validated. In this example, I’m retrieving the items array. If the item is an array, we filter out any empty ones, then merge it back into the request. Simple! This way we can keep our request-based logic in the same class and we don’t have to make lax validation rules.

Looking for more Laravel Tips & Tricks? Join Joel and I on the No Compromises bi-weekly podcast; around 15 minutes of thoughtful real-world advice and helpful info.
Go to All Posts