Laravel Request::all() Should Not Be Called Statically
Asked Answered
B

9

102

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)

Ballesteros answered 18/2, 2015 at 0:31 Comment(5)
It looks like you're not using the facade. Do you have a use Illuminate\Http\Request; statement in your controller?Jempty
@patricus, I do have the `use Illuminate\Http\Request; statement at the top of my controller.Ballesteros
@Jempty I do not have the Illuminate\Http\Request package in /vendor though. Do I have to download that separately?Ballesteros
The Illuminate packages are included as part of the laravel/framework package. If you want to look at any of the Laravel source code, you'll find it under /vendor/laravel/framework/src/Illuminate/...Jempty
You should use constructor injection or Request object over static calls. There also set for instant migration of your code toward DI: tomasvotruba.cz/blog/2019/03/04/…Vani
J
258

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');
    }
}
Jempty answered 18/2, 2015 at 0:47 Comment(7)
Answer is correct, however out of preference I would use Illuminate\Support\Facades\Request; because personally I think that Laravel's habit of aliasing everything to the root namespace is against the point of having namespaces in the first place. It also makes API documentation harder to generate because apigen/phpdoc won't be able to find the "Request" class.Turaco
In fact, you don't need to change the Boilerplate of the artisan make:controller . If you want to use the Request without injecting it to the method just use $input = \Request::all() (Notice the \ ) . If you want to use injection than use public myFunction(Request $request() { $input = $request->all() } Or inject it in the constructor and assign it to a class variableAeronaut
Why i can't use Request::all(); while i use use Illuminate\Http\Request; ?Cadmann
@Cadmann Request::all() is a facade way. so you have to use Illuminate\Support\Facades\Request; instead of use Illuminate\Http\Request;Waylen
@redA is there a way to convert Request::all() to use the direct way (and not through the facade class)?Righthander
@Righthander That's what the "Edit" section of this answer addresses. The Request object injected into the controller is the actual object, not a facade. So, you would just use $input = $this->request->all();.Jempty
@Jempty - thanks for the Edit section, very helpful.Anabiosis
L
12

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

Lannie answered 21/12, 2017 at 12:47 Comment(0)
H
6

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();
   }

}
Howzell answered 18/2, 2015 at 0:53 Comment(0)
B
5

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();
Bamby answered 28/12, 2017 at 10:55 Comment(0)
P
4

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.

Paucker answered 9/2, 2019 at 18:48 Comment(1)
thanks for sharing internally how it works, this deserves more like!Loricate
P
1

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;
Perichondrium answered 13/12, 2019 at 7:12 Comment(1)
this worked for me, but I still don't get why the IDE reason would not apply to me, because the way I generated the project and I use vscode.Darbie
M
0
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());
}
Moores answered 24/2, 2017 at 6:19 Comment(0)
S
-1

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.

Shedd answered 19/8, 2018 at 1:28 Comment(0)
C
-1

i make it work with a scope definition

public function pagar(\Illuminate\Http\Request $request) { //

Clawson answered 7/3, 2019 at 23:38 Comment(1)
Please not only show what code is working but also explain why you did this.Horribly

© 2022 - 2024 — McMap. All rights reserved.