在Laravel中,我试图在控制器中调用$input = Request::all();
一个store()
方法,但是出现以下错误:
从不兼容的上下文中
Illuminate\Http\Request::all()
假设$this
,非静态方法不应静态调用
是否有帮助找出纠正此问题的最佳方法?(我正在观看Laracast)
在Laravel中,我试图在控制器中调用$input = Request::all();
一个store()
方法,但是出现以下错误:
从不兼容的上下文中
Illuminate\Http\Request::all()
假设$this
,非静态方法不应静态调用
是否有帮助找出纠正此问题的最佳方法?(我正在观看Laracast)
use Illuminate\Http\Request;
您的控制人中有陈述吗?
Illuminate\Http\Request
在/ vendor中没有软件包。我需要单独下载吗?
Illuminate
软件包是laravel / framework软件包的一部分。如果您想查看任何Laravel源代码,可以在/vendor/laravel/framework/src/Illuminate/...
Answers:
该错误消息是由于呼叫未通过Request
立面而导致的。
更改
use Illuminate\Http\Request;
至
use Request;
它应该开始工作。
在config / app.php文件中,您可以找到类别名的列表。在那里,您将看到基类Request
已被别名为Illuminate\Support\Facades\Request
该类。因此,要Request
在命名空间文件中使用Facade,需要指定使用基类: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::all();
时不能使用use Illuminate\Http\Request;
?
use Illuminate\Support\Facades\Request;
代替use Illuminate\Http\Request;
我认为这对将来的访问者提供一些有关此处发生情况的解释会很有用。
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()
,但在实际的方法调用真正的 Illuminate\Http\Request
对象是不是静态的。
外观就像代理一样工作-它引用IoC容器中的对象,并将静态方法调用传递给该对象(非静态)。例如,以Illuminate\Support\Facades\Request
外观为例:
class Request extends Facade
{
protected static function getFacadeAccessor()
{
return 'request';
}
}
在底层,基Illuminate\Support\Facades\Facade
类使用了一些PHP魔术,即__callStatic
:
all
没有参数getFacadeAccessor
,在本例中为Illuminate\Http\Request
objectall
的实例上非静态调用该方法Illuminate\Http\Request
。这就是为什么,正如@patricus在上面的回答中指出的那样,通过更改use
/ import语句以引用外观,该错误不再存在,因为就PHP而言,all
已正确地调用了PHP的实例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
配置的字符串键指代),就像您使用的是Facade本身一样:
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;