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
Laravel Request::all() Should Not Be Called Statically
提问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$this
from 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 Request
facade.
错误消息是由于调用没有通过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 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;
.
在 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\Request
object that should be injected, and not the Request
facade.
当将 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 use
statements 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\Request
class
该Illuminate\Http\Request
班
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:
Laravel 的Illuminate\Http\Request
类有一个名为的方法all
(实际上该all
方法是在Request
类使用的特性中定义的,称为Illuminate\Http\Concerns\InteractsWithInput
)。all
撰写本文时该方法的签名如下所示:
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.
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\Request
object 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\Request
facade, 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\Facade
class uses some PHP magic, namely the __callStatic
method to:
在幕后,基Illuminate\Support\Facades\Facade
类使用了一些 PHP 魔法,即以下__callStatic
方法:
- 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 aIlluminate\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 ofIlluminate\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, all
has 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.php
file, under the aliases
key, 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 aliases
config) 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) { //