96
votes

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)

9
@patricus, sorry, I should have said 5.Moose
It looks like you're not using the facade. Do you have a use Illuminate\Http\Request; statement in your controller?patricus
@patricus, I do have the `use Illuminate\Http\Request; statement at the top of my controller.Moose
@patricus I do not have the Illuminate\Http\Request package in /vendor though. Do I have to download that separately?Moose
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/...patricus

9 Answers

240
votes

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');
    }
}
8
votes

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

6
votes

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

}
5
votes

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();
4
votes

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.

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

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;
0
votes

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.

0
votes

i make it work with a scope definition

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