Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change request input values from empty string to null in Laravel

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

like image 759
ira Avatar asked Aug 03 '16 13:08

ira


2 Answers

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);
like image 169
Jari Pekkala Avatar answered Sep 28 '22 08:09

Jari Pekkala


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

 protected $middleware = [
    


    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,

];
like image 33
Rahul Jat Avatar answered Sep 28 '22 06:09

Rahul Jat