Laravel Request::all() Should Not Be Called Statically

前端 未结 9 1505
迷失自我
迷失自我 2020-11-28 20:53

In Laravel, I\'m trying to call $input = Request::all(); on a store() method in my controller, but I\'m getting the following error:

相关标签:
9条回答
  • 2020-11-28 21:22

    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.

    0 讨论(0)
  • 2020-11-28 21:28

    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 讨论(0)
  • 2020-11-28 21:29

    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();
       }
    
    }
    
    0 讨论(0)
提交回复
热议问题