php Laravel Request::all() 不应静态调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28573860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:56:49  来源:igfitidea点击:

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

phplaravellaravel-5

提问by Moose

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

在 Laravel 中,我试图调用控制器中$input = Request::all();store()方法,但出现以下错误:

Non-static method Illuminate\Http\Request::all()should not be called statically, assuming $thisfrom incompatible context

Illuminate\Http\Request::all()假设$this来自不兼容的上下文,不应静态调用非静态方法

Any help figuring out the best way to correct this? (I'm following a Laracast)

任何帮助找出解决此问题的最佳方法?(我正在关注 Laracast)

回答by patricus

The error message is due to the call not going through the Requestfacade.

错误消息是由于调用没有通过Request门面。

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 Requesthas been aliased to the Illuminate\Support\Facades\Requestclass. Because of this, to use the Requestfacade in a namespaced file, you need to specify to use the base class: use Request;.

在 config/app.php 文件中,您可以找到类别名的列表。在那里,您将看到基类Request已成为类的别名Illuminate\Support\Facades\Request。因此,要Request在命名空间文件中使用外观,您需要指定使用基类: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.

由于这个问题似乎有点流量,所以我想在 Laravel 5 正式发布后稍微更新一下答案。

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.

虽然以上在技术上仍然是正确的并且可以工作,但该use Illuminate\Http\Request;语句包含在新的 Controller 模板中,以帮助推动开发人员朝着使用依赖注入而不是依赖 Facade 的方向发展。

When injecting the Request object into the constructor (or methods, as available in Laravel 5), it is the Illuminate\Http\Requestobject that should be injected, and not the Requestfacade.

当将 Request 对象注入构造函数(或 Laravel 5 中可用的方法)时,Illuminate\Http\Request应该注入的是对象,而不是Request外观。

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

回答by Jonathan Crowe

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

使用 Laravel 的魔法注入将请求对象注入控制器,然后非静态访问该函数。Laravel 会自动将具体的依赖注入到自动加载的类中

class MyController() 
{

   protected $request;

   public function __construct(\Illuminate\Http\Request $request)
   {
       $this->request = $request;
   }

   public function myFunc()
   {
       $input = $this->request->all();
   }

}

回答by lucidlogic

use the request()helper instead. You don't have to worry about usestatements and thus this sort of problem wont happen again.

改用request()助手。您不必担心use语句,因此此类问题不会再次发生。

$input = request()->all();

simple

简单的

回答by Luca C.

The facade is another Request class, access it with the full path:

Facade 是另一个 Request 类,使用完整路径访问它:

$input = \Request::all();

From laravel 5 you can also access it through the request()function:

从 Laravel 5 开始,您还可以通过以下request()功能访问它:

$input = request()->all();

回答by Jonathon

I thought it would be useful for future visitors to provide a bit of an explanation on what is happening here.

我认为对未来的访问者提供一些关于这里发生的事情的解释会很有用。

The Illuminate\Http\Requestclass

Illuminate\Http\Request

Laravel's Illuminate\Http\Requestclass has a method named all(in fact the allmethod is defined in a trait that the Requestclass uses, called Illuminate\Http\Concerns\InteractsWithInput). The signature of the allmethod at the time of writing looks like this:

Laravel 的Illuminate\Http\Request类有一个名为的方法all(实际上该all方法是在Request类使用的特性中定义的,称为Illuminate\Http\Concerns\InteractsWithInput)。all撰写本文时该方法的签名如下所示:

public function all($keys = null)

This method is not defined as staticand 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 allmethod is an instance method and deals with information that is present in an instance of the Requestclass, so calling it in this way makes no sense.

static当您尝试在静态上下文中调用该方法时,此方法未定义为等式,即Illuminate\Http\Request::all()您将收到 OP 问题中显示的错误。该all方法是一个实例方法,处理存在于Request类实例中的信息,因此以这种方式调用它是没有意义的。

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 realIlluminate\Http\Requestobject is notstatic.

Laravel 中的 Facade 为开发人员提供了一种方便的方式来访问 IoC 容器中的对象,并在这些对象上调用方法。开发人员可以在像 一样的外观上“静态地”调用方法Request::all(),但对真实Illuminate\Http\Request对象的实际方法调用不是静态的。

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\Requestfacade, this is what it looks like:

外观像代理一样工作 - 它引用 IoC 容器中的对象并将静态方法调用传递到该对象(非静态)。以Illuminate\Support\Facades\Request外观为例,它是这样的:

class Request extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'request';
    }
}

Under the hood, the base Illuminate\Support\Facades\Facadeclass uses some PHP magic, namely the __callStaticmethod to:

在幕后,基Illuminate\Support\Facades\Facade类使用了一些 PHP 魔法,即以下__callStatic方法:

  • Listen for a static method call, in this case allwith no parameters
  • Grab the underlying object from the IoC container using the key returned by getFacadeAccessor, in this case a Illuminate\Http\Requestobject
  • Dynamically call the method that it received statically on the object it has retrieved, in this case allis called non-statically on an instance of Illuminate\Http\Request.
  • 侦听静态方法调用,在本例all中没有参数
  • 使用 返回的键从 IoC 容器中获取底层对象getFacadeAccessor,在本例中为Illuminate\Http\Request对象
  • 在它检索到的对象上动态调用它静态接收的方法,在这种情况下,在all的实例上非静态调用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, allhas been correctly called on an instance of Illuminate\Http\Request.

这就是为什么,正如@patricus 在上面的回答中指出的那样,通过将use/import 语句更改为引用外观,错误不再存在,因为就 PHP 而言,all已在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.phpfile, under the aliaseskey, you will find a long list of mappings of strings to facade classes. For example:

别名是 Laravel 为方便起见而提供的另一个功能。它通过有效地创建指向根命名空间中的外观的别名类来工作。如果您查看您的config/app.php文件,在aliases键下,您会发现一长串字符串到外观类的映射。例如:

'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 aliasesconfig) as if you're using the facade itself:

Laravel 会根据您的配置为您创建这些别名类,这允许您使用根命名空间中可用的类(由aliases配置的字符串键引用),就像您正在使用外观本身一样:

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:

虽然 Laravel 中仍然提供了外观和别名,但可以并且通常鼓励沿着依赖注入路线走下去。例如,使用构造函数注入来实现相同的结果:

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.

这种方法有很多好处,但在我个人看来,依赖注入的最大优点是它使您的代码更易于测试。通过将类的依赖项声明为构造函数或方法参数,可以很容易地模拟出这些依赖项并单独对类进行单元测试。

回答by ghazyy

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 RouteClass.

当您将以下库导入 api.php 文件时也会发生这种情况。这是由某些 IDE 建议导入它以防止找不到路由类而发生的。

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;

回答by Ravi G

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

回答by dotNET

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.

即使use Illuminate\Http\Request;我的控制器顶部有一条线,我也面临这个问题。一直拉着我的头发,直到我意识到我在做$request::ip()而不是$request->ip()。如果您整晚没有睡觉并且在早上 6 点半睁着眼睛看代码,可能会发生在您身上。

Hope this helps someone down the road.

希望这可以帮助某人在路上。

回答by Julian Lanfranco

i make it work with a scope definition

我让它与范围定义一起工作

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

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