I'm using Laravel 9 and I want to redirect user to same page url, so I tried this:
if(!$status){
alert()->error('Wrong code!');
return redirect(Request::url());
}
And I have included as well the Request but don't know why get this error:
Non-static method Illuminate\Http\Request::url() cannot be called statically
So what's going wrong here? How can I solve this issue?
You can use
return redirect()->back()->withInput();
Or
use Illuminate\Http\Request;
public function yourMethod(Request $request) # inject $request here
{
return redirect($request->url());
}
I've been reading and following jetstream's documentation and I wanted to create a custom class for the authentication process:
If you prefer to encapsulate your custom authentication process within
a class instead of a closure, you may pass a PHP "callable" array to
the authenticateUsing method:
use App\Actions\AuthenticateLoginAttempt;
use Laravel\Fortify\Fortify;
Fortify::authenticateUsing([new AuthenticateLoginAttempt, '__invoke']);
I have already created the file AuthenticateLoginAttempt in App/Actions folder:
<?php
namespace App\Actions;
class AuthenticateLoginAttempt
{
public function __invoke()
{
}
}
What I wanted is also to pass the Request $request as an argument that will be used later in the __invoke magic method:
Fortify::authenticateUsing([new AuthenticateLoginAttempt, '__invoke', ...Request $request...]);
public function __invoke(Request $request)
{
}
How to achieve this one? It seems to me that their documentation is unclear to me. Thank you.
class SomeController extends Controller {
public function doALot(Request $request) {
$this -> doOne($someOtherVariable);
// Type error: Argument 1 passed to App\Http\Controllers\SomeController::doOne() must be an instance of Illuminate\Http\Request
$this -> doOne($request, $someOtherVariable);
// Bad practice?
...
}
public function doOne(Request $request, $someOtherVariable) {}
...
}
So how do one call doOne() from doALot() without passing injected resource, yet having Request in doOne()? It feels like bad practice to pass $request all over the place.
Solution tl;dr not possible, but there are other ways – read short answer from Alexey Mezenin
Long version (probably not the best yet suffice).
$ php artisan make:provider SomeServiceProvider
Then in created provider edit register() call to something along the lines:
public
function register() {
$this -> app -> bind('App\Services\SomeService', function ($app) {
return new SomeService();
});
}
Then proceed to create service class which will have injected resource as attribute.
<?php
namespace App\Services;
use \Illuminate\Support\Facades\Request;
class SomeService {
private $request;
/**
* SomeService constructor.
*/
public
function __construct(Request $request) {
$this -> request = $request;
}
public function doOne($someOtherVariable) {}
}
Then move your methods from controller to service and inject service into controller instead.
Tradeoffs: (-) two useless files to perform basic functionality, (+) detaches logic implementation from controller, (~) probably cleaner code.
It's not a good idea to call controller actions manually. The business logic should be in the service class. You can see an example of that in my Laravel best practices repo. If you don't want to pass $request object every time, you can inject Request class in service class' or controller constructor.
Another way to use Request data is to use request() helper:
request('key')
request()->has('key')
Or Request facade:
Request::has('key')
Or you can manually inject it inside the method:
$request = app('Illuminate\Http\Request');
Is it possible to transform Illuminate\Http\Request to custom validation request you made with php artisan make:request MyRequest?
I would like validation to take place in a method down the road so that I have:
protected function register(Request $request)
{
...
$this->userRepository->signup($request)
...
}
User repository:
public function signup(MyRequest $request)
{
...
}
Is this possible? I am getting an error now because one class is expected. Only thing that comes to mind is to make an interface, but I'm not sure if that could function.
Error I get
Type error: Argument 1 passed to UserRepository::signup() must be an
instance of App\Http\Requests\MyRequest, instance of
Illuminate\Http\Request given
Well, you can convert any request to any other request, as long as it extends from Illuminate\Http\Request.
There are basically two methods Laravel uses to convert one request to another. The problem here is that it will never get a validation object or trigger the validation automatically, as part of the injection when MyRequest was passed as an argument. It might also miss a message bag and the error handler, but nothing you can fix by initializing the request just like Laravel does when injecting it.
So you still have to trigger all the sequences the FormRequest (if it extends FromRequest rather than Request) normally does when booting the trait, but still, it's entirely possible and with some little extra work, you could convert any request to any other request.
For example; I'm using this setup to call just one route profile/{section}/save for saving my profile settings. Depending on $section's value, I convert the given $Request to any of my custom form requests for that particular $section.
use App\Http\Requests\MyRequest;
use Illuminate\Http\Request;
...
public function someControllerMethod(Request $Request) {
$MyRequest = MyRequest::createFrom($Request);
// .. or
$MyRequest = MyRequest::createFromBase($Request);
}
...
So to get people started with using a FormRequest as an example, it basically comes to this.
Instead of extending all your custom requests from the default Illuminate\Foundation\Http\FormRequest, use a base class which extends from FormRequest and add a custom method to transform and boot the request as if it were passed as an argument.
namespace App\Http\Requests;
use Illuminate\Routing\Redirector;
use Illuminate\Foundation\Http\FormRequest;
class BaseFormRequest extends FormRequest {
public function convertRequest(string $request_class) : BaseFormRequest {
$Request = $request_class::createFrom($this);
$app = app();
$Request
->setContainer($app)
->setRedirector($app->make(Redirector::class));
$Request->prepareForValidation();
$Request->getValidatorInstance();
return $Request;
}
public function authorize() {
return true;
}
public function rules() {
return [];
}
}
Let all your custom FormRequest extend your BaseFormRequest
namespace App\Http\Requests;
class MyRequest extends BaseFormRequest {
...
}
Now anywhere you want to convert a request, use the base class in your controller method and convert it using convertRequest with the custom request class you wish to convert.
public function someControllerMethod(BaseFormRequest $Request) {
$MyRequest = $Request->convertRequest(MyRequest::class);
}
like #dbf answer but with automatic validation
use App\Http\Requests\MyRequest;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
public function someControllerMethod(Request $Request) {
//this make your request class do validation
try{
app(MyRequest::class);
} catch (ValidationException $ex){
throw $ex;
}
//if no error you can continue to convert the request
$MyRequest = MyRequest::createFrom($Request);
// .. or
$MyRequest = MyRequest::createFromBase($Request);
}
Yes, there is no problem with that, you should create:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyRequest extends FormRequest
{
public function rules() {
// here you put rules
}
}
and in your controller:
public function signup(\App\Http\Requests\MyRequest $request)
{
...
}
Be aware you should also adjust authorize method in your request class (to return true or false depending on user access)
EDIT
After update - you should type hint your custom class in controller and in repository - it's up to you - I often use generic Illuminate\Http\Request, so you should do:
in controller:
public function controllerMethod(\App\Http\Requests\MyRequest $request)
in repository:
public function signup(\App\Http\Requests\MyRequest $request)
or
public function signup(\Illuminate\Http\Request $request)
So to sum up you should use Form request classes in controller - this is the place where validation will be made and later you can use either same class or generic \Illuminate\Http\Request - I personally often use in repositories or services just \Illuminate\Http\Request because they usually don't care about other things put into MyRequest class - they just want to get data from request class and that's it.
I didn't find it was possible to do what I wanted even with my custom class extending the Request because naturally one method expects an instance of one class while getting another one.
Maybe it would be possible to extract an interface out and wrap and bind it but that would be in my opinion a quickfix.
My opinion is that concept I had was wrong from the start, and it was more of an architecture problem so I transformed my app to a different approach and manage to avoid such issues in the first place.
In Laravel, I'm trying to call $input = Request::all(); on a store() method in my controller, but I'm getting the following error:
Non-static method Illuminate\Http\Request::all() should not be called statically, assuming $this from incompatible context
Any help figuring out the best way to correct this? (I'm following a Laracast)
The error message is due to the call not going through the Request facade.
Change
use Illuminate\Http\Request;
To
use Request;
and it should start working.
In the config/app.php file, you can find a list of the class aliases. There, you will see that the base class Request has been aliased to the Illuminate\Support\Facades\Request class. Because of this, to use the Request facade in a namespaced file, you need to specify to use the base class: use Request;.
Edit
Since this question seems to get some traffic, I wanted to update the answer a little bit since Laravel 5 was officially released.
While the above is still technically correct and will work, the use Illuminate\Http\Request; statement is included in the new Controller template to help push developers in the direction of using dependency injection versus relying on the Facade.
When injecting the Request object into the constructor (or methods, as available in Laravel 5), it is the Illuminate\Http\Request object that should be injected, and not the Request facade.
So, instead of changing the Controller template to work with the Request facade, it is better recommended to work with the given Controller template and move towards using dependency injection (via constructor or methods).
Example via method
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class UserController extends Controller {
/**
* Store a newly created resource in storage.
*
* #param Illuminate\Http\Request $request
* #return Response
*/
public function store(Request $request) {
$name = $request->input('name');
}
}
Example via constructor
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class UserController extends Controller {
protected $request;
public function __construct(Request $request) {
$this->request = $request;
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store() {
$name = $this->request->input('name');
}
}
use the request() helper instead. You don't have to worry about use statements and thus this sort of problem wont happen again.
$input = request()->all();
simple
Inject the request object into the controller using Laravel's magic injection and then access the function non-statically. Laravel will automatically inject concrete dependencies into autoloaded classes
class MyController()
{
protected $request;
public function __construct(\Illuminate\Http\Request $request)
{
$this->request = $request;
}
public function myFunc()
{
$input = $this->request->all();
}
}
The facade is another Request class, access it with the full path:
$input = \Request::all();
From laravel 5 you can also access it through the request() function:
$input = request()->all();
I thought it would be useful for future visitors to provide a bit of an explanation on what is happening here.
The Illuminate\Http\Request class
Laravel's Illuminate\Http\Request class has a method named all (in fact the all method is defined in a trait that the Request class uses, called Illuminate\Http\Concerns\InteractsWithInput). The signature of the all method at the time of writing looks like this:
public function all($keys = null)
This method is not defined as static and so when you try to call the method in a static context, i.e. Illuminate\Http\Request::all() you will get the error displayed in OP's question. The all method is an instance method and deals with information that is present in an instance of the Request class, so calling it in this way makes no sense.
Facades
A facade in Laravel provides developers with a convenient way of accessing objects in the IoC container, and calling methods on those objects. A developer can call a method "statically" on a facade like Request::all(), but the actual method call on the real Illuminate\Http\Request object is not static.
A facade works like a proxy - it refers to an object in the IoC container and passes the static method call onto that object (non-statically). For instance, take the Illuminate\Support\Facades\Request facade, this is what it looks like:
class Request extends Facade
{
protected static function getFacadeAccessor()
{
return 'request';
}
}
Under the hood, the base Illuminate\Support\Facades\Facade class uses some PHP magic, namely the __callStatic method to:
Listen for a static method call, in this case all with no parameters
Grab the underlying object from the IoC container using the key returned by getFacadeAccessor, in this case a Illuminate\Http\Request object
Dynamically call the method that it received statically on the object it has retrieved, in this case all is called non-statically on an instance of Illuminate\Http\Request.
This is why, as #patricus pointed out in his answer above, by changing the use/import statement to refer to the facade, the error is no longer there, because as far as PHP is concerned, all has been correctly called on an instance of Illuminate\Http\Request.
Aliasing
Aliasing is another feature that Laravel provides for convenience. It works by effectively creating alias classes that point to facades in the root namespace. If you take a look at your config/app.php file, under the aliases key, you will find a long list of mappings of strings to facade classes. For example:
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
// ...
'Request' => Illuminate\Support\Facades\Request::class,
Laravel creates these alias classes for you, based on your configuration and this allows you to utilise classes available in the root namespace (as referred to by the string keys of the aliases config) as if you're using the facade itself:
use Request:
class YourController extends Controller
{
public function yourMethod()
{
$input = Request::all();
// ...
}
}
A note on dependency injection
While facades and aliasing are still provided in Laravel, it is possible and usually encouraged to go down the dependency injection route. For example, using constructor injection to achieve the same result:
use Illuminate\Http\Request;
class YourController extends Controller
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function yourMethod()
{
$input = $this->request->all();
// ...
}
}
There are a number of benefits to this approach but in my personal opinion the greatest pro for dependency injection is that it makes your code way easier to test. By declaring the dependencies of your classes as constructor or method arguments, it becomes very easy to mock out those dependencies and unit test your class in isolation.
also it happens when you import following library to api.php file.
this happens by some IDE's suggestion to import it for not finding the Route Class.
just remove it and everything going to work fine.
use Illuminate\Routing\Route;
update:
seems if you add this library it wont lead to error
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
public function store(Request $request){
dd($request->all());
}
is same in context saying
use Request;
public function store(){
dd(Request::all());
}
I was facing this problem even with use Illuminate\Http\Request; line at the top of my controller. Kept pulling my hair till I realized that I was doing $request::ip() instead of $request->ip(). Can happen to you if you didn't sleep all night and are looking at the code at 6am with half-opened eyes.
Hope this helps someone down the road.
i make it work with a scope definition
public function pagar(\Illuminate\Http\Request $request)
{
//