Extend Request class in Laravel 5
Here is Official Document: Request Lifecycle
Content of app/Http/CustomRequest.php
<?php namespace App\Http;
use Illuminate\Http\Request as BaseRequest;
class CustomRequest extends BaseRequest {
// coding
}
add this line to public/index.php$app->alias('request', 'App\Http\CustomRequest');
afterapp = require_once __DIR__.'/../bootstrap/app.php';
change the code at public/index.phpIlluminate\Http\Request::capture()
toApp\Http\CustomRequest::capture()
How to extend validation form request in Laravel 5.2?
You can extend your CreateUserRequest class like this:
<?php
namespace App\Http\Requests;
use CreateUserRequest;
Class OtherCreateUserRequest extends CreateUserRequest {
public function rules()
{
return parent::rules() + [
'additional' => 'rule',
];
}
}
How to set custom response for selected Request class in Laravel 5.5
If you want to customize validation response only for selected Request class, you need to add failedValidation()
message to this class:
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$response = new JsonResponse(['data' => [],
'meta' => [
'message' => 'The given data is invalid',
'errors' => $validator->errors()
]], 422);
throw new \Illuminate\Validation\ValidationException($validator, $response);
}
This way you don't need to change anything in Handler and have this custom response only for this single class.And if you want to change format globally for all responses you should add to app\Exceptions\Handler.php
file the following method:
protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'data' => [],
'meta' => [
'message' => 'The given data is invalid',
'errors' => $exception->errors()
]
], $exception->status);
}
You can read about this also in Upgrade guide in Exception Format section Extended Request class's attributes are empty - Laravel
Found the solution:
You have to use FormRequest not Request
use Illuminate\Foundation\Http\FormRequest;
Extended Request missing data when reaching controller with type-hint
This is kind of tricky.
First of all, you need to be familiar with the service container and dependency injection. Here is the full doc: https://laravel.com/docs/8.x/container
When you type hint a class inside a controller method, Laravel will try to understand what it should do with it.
If nothing is registered inside the service container, it will try to make a new instance of it.
\Illuminate\Http\Request
is bound as a singleton (https://laravel.com/docs/8.x/container#binding-a-singleton).
While a simple bind will return a new instance at each call, a singleton will always return the exact same instance.
Here is a quick demo:
\App\Models\User::class
is a class that is not explicitly bound.
When you try to resolve it using the service container, it will not find it and will try to make a new instance:
$u1 = app(\App\Models\User::class);
// Searching \App\Models\User::class...
// Cannot find \App\Models\User::class...
// returning new \App\Models\User();
$u2 = app(\App\Models\User::class);
// same process again
$u3 = app(\App\Models\User::class);
// and again
// You can check these instances are indeed different by checking their hash:
dd(
spl_object_hash($u1), // 000000004af5213500000000220f0bc0 (52135)
spl_object_hash($u2), // 000000004af5213400000000220f0bc0 (52134)
spl_object_hash($u3) // 000000004af5213700000000220f0bc0 (52137)
);
But since \Illuminate\Http\Request::class
is bound by Laravel, it follows a different path:$r1 = app(\Illuminate\Http\Request::class);
// Searching \Illuminate\Http\Request::class...
// Found it! Bound as a singleton.
// returning new \Illuminate\Http\Request() and storing the
// instance in case it is required again later;
$r2 = app(\Illuminate\Http\Request::class);
// Searching \Illuminate\Http\Request::class...
// Found it and already called! Returning the stored instance ($r1)
$r3 = app(\Illuminate\Http\Request::class);
// Searching \Illuminate\Http\Request::class...
// Found it and already called! Returning the stored instance ($r1)
// Their hash are the same
dd(
spl_object_hash($u1), // 0000000011f522cf0000000077704cd1
spl_object_hash($u2), // 0000000011f522cf0000000077704cd1
spl_object_hash($u3) // 0000000011f522cf0000000077704cd1
);
Now, what's happening?Under the hood, when a new request is made to your app and before hitting the controller method, Laravel will do a lot of things to prepare the \Illuminate\Http\Request
instance.
For instance, it will setup the route resolver inside Illuminate\Routing\Router
:
/**
* Return the response for the given route.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Routing\Route $route
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function runRoute(Request $request, Route $route)
{
// here
$request->setRouteResolver(function () use ($route) {
return $route;
});
//
$this->events->dispatch(new RouteMatched($route, $request));
return $this->prepareResponse($request,
$this->runRouteWithinStack($route, $request)
);
}
Each time Laravel internally call a method like this:protected function method(Request $request){
// do something to $request
}
$request
is always the same instance, because it is bound as a singleton.We are now in your controller.
public function frontend1(\Illuminate\Http\Request $request){
// Searching \Illuminate\Http\Request::class...
// Found it and already called!
// Returning the stored instance that has been prepared through all
// Laravel core classes
dump($request);
dump($request->all()); //well prepared
dump($request->route('id')); //well setup
return Book::all();
}
public function frontend2(\App\Http\Request $request){
// Searching \App\Http\Request::class...
// Cannot find \App\Http\Request::class...
// returning new \App\Http\Request();
dump($request);
dump($request->all()); //nothing
dump($request->route('id')); //empty
return Book::all();
}
If you are still here, how to solve this problem?
The easiest way is to use aFormRequest
, initially designed to handle form validation, but if you return an empty rules array, you should be able to do everything you did with your custom \App\Http\Request
instance:<?php
namespace App\Http;
use Illuminate\Foundation\Http\FormRequest;
class Request extends FormRequest
{
public function rules()
{
return [];
}
}
Try again, everything should work fine, since this is a feature specially designed to replace the initial \Illuminate\Http\Request
object.The full doc is here: https://laravel.com/docs/8.x/validation#creating-form-requests
Related Topics
Doctrine2 - "Class" Is Not a Valid Entity or Mapped Super Class
Difference Between Buffered and Unbuffered Queries
Png Transparency Resize with Simpleimage.PHP Class
Find Windows 32 or 64 Bit Using PHP
How to Avoid Request Entity Too Large 413 Error
Unchecked Checkbox Returning Null Value
How to Retrieve Date from Table Cell Using PHPspreadsheet
Laravel 4 - Including a "Partial" View Within a View (Without Using Blade Template)
I Want to Find Current Location of User in PHP
Why Is Object Oriented PHP with MySQLi Better Than the Procedural Approach
Call to Undefined Function Curl_Init() - with Wamp
Php: $_Server Variables: $_Server['Http_Host'] VS $_Server['Server_Name']
How to Get an Array of Data from $_Post
Encoding Byte Data into Digits
Jquery Ajax Form Data Serialize Using PHP
Storing Leading Zeros of Integers in MySQL Database as Integer