在 Laravel 中,我试图在控制器中的 store()
方法上调用 $input = Request::all();
,但出现以下错误:
不应静态调用非静态方法 Illuminate\Http\Request::all(),假设 $this 来自不兼容的上下文
任何帮助找出纠正此问题的最佳方法? (我正在关注 Laracast)
use Illuminate\Http\Request;
语句吗?
Illuminate\Http\Request
包。我必须单独下载吗?
Illuminate
包作为 laravel/framework 包的一部分包含在内。如果您想查看任何 Laravel 源代码,您可以在 /vendor/laravel/framework/src/Illuminate/...
下找到它
错误消息是由于调用未通过 Request
外观。
改变
use Illuminate\Http\Request;
至
use Request;
它应该开始工作。
在 config/app.php 文件中,您可以找到类别名列表。在那里,您将看到基类 Request
已别名为 Illuminate\Support\Facades\Request
类。因此,要在命名空间文件中使用 Request
外观,您需要指定使用基类:use Request;
。
编辑
由于这个问题似乎得到了一些流量,所以我想在 Laravel 5 正式发布后稍微更新一下答案。
虽然上述内容在技术上仍然正确并且可以工作,但 use Illuminate\Http\Request;
语句包含在新的 Controller 模板中,以帮助将开发人员推向使用依赖注入而不是依赖 Facade 的方向。
将 Request 对象注入构造函数(或 Laravel 5 中可用的方法)时,应该注入的是 Illuminate\Http\Request
对象,而不是 Request
外观。
因此,与其将 Controller 模板更改为使用 Request 门面,不如建议使用给定的 Controller 模板并转向使用依赖注入(通过构造函数或方法)。
通过方法示例
<?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');
}
}
通过构造函数的示例
<?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');
}
}
请改用 request()
帮助程序。您不必担心 use
语句,因此此类问题不会再次发生。
$input = request()->all();
简单的
使用 Laravel 的魔法注入将请求对象注入控制器,然后非静态访问该函数。 Laravel 会自动将具体的依赖注入到自动加载的类中
class MyController()
{
protected $request;
public function __construct(\Illuminate\Http\Request $request)
{
$this->request = $request;
}
public function myFunc()
{
$input = $this->request->all();
}
}
外观是另一个 Request 类,使用完整路径访问它:
$input = \Request::all();
在 laravel 5 中,您还可以通过 request()
函数访问它:
$input = request()->all();
我认为对未来的访问者提供一些关于这里发生的事情的解释会很有用。
Illuminate\Http\Request 类
Laravel 的 Illuminate\Http\Request
类有一个名为 all
的方法(实际上 all
方法是在 Request
类使用的特征中定义的,称为 Illuminate\Http\Concerns\InteractsWithInput
)。在撰写本文时,all
方法的签名如下所示:
public function all($keys = null)
此方法未定义为 static
,因此当您尝试在静态上下文(即 Illuminate\Http\Request::all()
)中调用该方法时,您将收到 OP 问题中显示的错误。 all
方法是一个实例方法,它处理存在于 Request
类实例中的信息,因此以这种方式调用它是没有意义的。
外墙
Laravel 中的外观为开发人员提供了一种方便的方式来访问 IoC 容器中的对象,并在这些对象上调用方法。开发人员可以在 Request::all()
之类的外观上“静态地”调用方法,但对 real Illuminate\Http\Request
对象的实际方法调用不是静态的。
外观像代理一样工作 - 它引用 IoC 容器中的对象并将静态方法调用传递给该对象(非静态)。例如,以 Illuminate\Support\Facades\Request
外观为例,它是这样的:
class Request extends Facade
{
protected static function getFacadeAccessor()
{
return 'request';
}
}
在底层,基础 Illuminate\Support\Facades\Facade
类使用了一些 PHP 魔法,即 __callStatic
方法:
监听一个静态方法调用,在这种情况下都是没有参数的
使用 getFacadeAccessor 返回的键从 IoC 容器中获取底层对象,在本例中为 Illuminate\Http\Request 对象
动态调用它在检索到的对象上静态接收的方法,在这种情况下,所有方法都在 Illuminate\Http\Request 的实例上被非静态调用。
这就是为什么正如@patricus 在上面的回答中指出的那样,通过更改 use
/import 语句来引用外观,错误不再存在,因为就 PHP 而言,all
已经正确在 Illuminate\Http\Request
的实例上调用。
别名
别名是 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 根据您的配置为您创建这些别名类,这允许您使用根命名空间中可用的类(由 aliases
配置的字符串键引用),就像您使用外观本身一样:
use Request:
class YourController extends Controller
{
public function yourMethod()
{
$input = Request::all();
// ...
}
}
依赖注入注意事项
虽然 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();
// ...
}
}
这种方法有很多好处,但在我个人看来,依赖注入的最大优点是它使您的代码更容易测试。通过将类的依赖关系声明为构造函数或方法参数,模拟这些依赖关系并单独对类进行单元测试变得非常容易。
当您将以下库导入 api.php 文件时也会发生这种情况。这发生在一些 IDE 的建议中,因为找不到路由类而将其导入。
只需删除它,一切都会正常工作。
use Illuminate\Routing\Route;
更新:
似乎如果你添加这个库它不会导致错误
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
public function store(Request $request){
dd($request->all());
}
在上下文中是相同的
use Request;
public function store(){
dd(Request::all());
}
即使我的控制器顶部有 use Illuminate\Http\Request;
行,我也遇到了这个问题。一直拉扯我的头发,直到我意识到我在做 $request::ip()
而不是 $request->ip()
。如果您整晚没有睡觉并且在早上 6 点半睁着眼睛看代码,那么您可能会发生这种情况。
希望这对未来的人有所帮助。
我让它与范围定义一起工作
公共函数 pagar(\Illuminate\Http\Request $request) { //
不定期副业成功案例分享
use Illuminate\Http\Request;
时不能使用Request::all();
?use Illuminate\Support\Facades\Request;
而不是use Illuminate\Http\Request;