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

时间:2015-02-18 00:31:45

标签: php laravel laravel-5

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

  

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

有任何帮助找出解决这个问题的最佳方法吗? (我跟随拉拉查斯)

8 个答案:

答案 0 :(得分:187)

错误消息是由于呼叫未通过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 facade,而是建议使用给定的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');
    }
}

答案 1 :(得分:6)

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

class MyController() 
{

   protected $request;

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

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

}

答案 2 :(得分:3)

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

$input = \Request::all();

从laravel 5您也可以通过request()功能访问它:

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

答案 3 :(得分:2)

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

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

简单

答案 4 :(得分:1)

我认为这对将来的访问者提供一些有关此处发生情况的解释很有用。

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对象上的实际方法调用不是静态

Facade就像代理一样工作-它引用IoC容器中的一个对象,并将静态方法调用传递给该对象(非静态)。例如,以Illuminate\Support\Facades\Request门面为例,

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

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

  • 监听静态方法调用,在这种情况下为all,不带参数
  • 使用getFacadeAccessor返回的键从IoC容器中获取基础对象,在本例中为Illuminate\Http\Request对象
  • 动态地调用它已检索到的对象上静态接收的方法,在这种情况下,allIlluminate\Http\Request的实例上被非静态调用。

这就是为什么,正如@patricus在上面的回答中指出的那样,通过更改use / import语句以引用外观,该错误不再存在,因为就PHP而言,{已在all的实例上正确调用{1}}。

别名

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

aliases

Laravel根据您的配置为您创建这些别名类,这使您可以利用根名称空间中可用的类(由'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, 配置的字符串键指代),就好像您在使用外墙本身:

aliases

有关依赖项注入的说明

尽管Laravel中仍然提供了外观和别名,但通常可以鼓励沿着依赖注入路径进行。例如,使用构造函数注入获得相同的结果:

use Request:

class YourController extends Controller
{
    public function yourMethod()
    {
        $input = Request::all();

        // ...
    }
}

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

答案 5 :(得分:1)

在将以下库导入api.php文件时也会发生。 这是由于某些IDE建议导入而导致的,因为它没有找到 Route 类。

只需将其删除,一切都会正常进行。

use Illuminate\Routing\Route;

更新:

如果您添加此库,似乎不会导致错误

use Illuminate\Support\Facades\Route;

答案 6 :(得分:0)

即使在控制器顶部的use Illuminate\Http\Request;行中,我也遇到了这个问题。一直拉着头发,直到我意识到自己在做$request::ip()而不是$request->ip()。如果您整夜没有睡觉,半睁着眼睛看着代码,可能会发生这种情况。

希望这可以帮助某人。

答案 7 :(得分:0)

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

公共函数pagar(\ Illuminate \ Http \ Request $ request)     {         //