Change request input values from empty string to null in Laravel
Asked Answered
S

3

5

In my controller I receive an Illuminate\Http\Request Request that contains some data with values equal to an empty string:

dd($request->input())

//output
array:5 [▼
  "_token" => "K43q88mR5zQRqVPAuYX5IWtQ1khQ24JTsuxl8mz4"
  "param1" => "1"
  "param2" => "2"
  "param3" => ""
  "param4" => ""
]

(basically that happens when the user had made no selections in the create form BUT due to frontend restrictions see here, I am not able to change the form of the Request so that to exclude the empty string values from being sent to the server)

The request input data is used to attach a relationships to models. For example:

$book->authors()->attach($request->input('param1'));

The problem is that when the input value is equal to the empty string "" the above line throws a QueryException, since it tries to add a foreign key equal to "" to the pivot table.

On the other hand, I noticed that if the value is null instead of "", the attach() method is not executed and, thus, does not throws an Exception, neither updates the database, which is exactly the behavior I want, when the user made no selection in the input form.

My question is how can I change the request values from "" to null? My first thought was to make a helper function that iterates over the request input array and replace "" with null and use it in the controller BUT it does not seems like a good idea for me, because this would not prevent possible unwanted validation errors, when using Form Request Validation.

Any ideas please ???

Thank you in advance

Smitten answered 3/8, 2016 at 13:51 Comment(0)
E
7

NOTE: Laravel 5.4 now ships with this feature

https://laravel.com/docs/5.4/requests#input-trimming-and-normalization

For versions > 5.4 see answer below or just copy the official middlewares.


HTTP middleware provide a convenient mechanism for filtering HTTP requests entering your application.

Make a middleware and assign it to the routes or controller's methods you want it to take place.

Example:

class SanitizeMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        foreach ($request->input() as $key => $value) {
            if (empty($value)) {
                $request->request->set($key, null);
            }
        }

        return $next($request);
    }
}
Route::post('/users', function (Request $request) {

    dd($request->input());

})->middleware(SanitizeMiddleware::class);
Edva answered 3/8, 2016 at 16:46 Comment(1)
Thanks for this, however anyone using it may want to explicity check for string '0' which is perfectly valid.. if ($value !== '0' && empty($value)) {Solmization
S
3

This being said you can solve your problem as follows: Comment out or put this in middleware in the App\Http\Kernel.php file.

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
Sika answered 10/2, 2021 at 11:56 Comment(0)
I
-1

Can't you just check before you add an item to your pivot table?

if(!empty($request->input('paramX'))){
    $book->authors()->attach($request->input('paramX'));
}
Insured answered 3/8, 2016 at 14:15 Comment(1)
Thank you for your reply I am acctualy using if ($request->input('paramX') != "") for every single input parameter. What I am asking is for a more "global" without the need to include the if statement everytime for every single request input parameter.Smitten

© 2022 - 2024 — McMap. All rights reserved.