ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

看起来你没有使用外观。您的控制器中有 use Illuminate\Http\Request; 语句吗?
@patricus,我确实有 `use Illuminate\Http\Request;我的控制器顶部的声明。
@patricus 我在 /vendor 中没有 Illuminate\Http\Request 包。我必须单独下载吗?
Illuminate 包作为 laravel/framework 包的一部分包含在内。如果您想查看任何 Laravel 源代码,您可以在 /vendor/laravel/framework/src/Illuminate/... 下找到它
您应该使用构造函数注入或 Request 对象而不是静态调用。还设置了将您的代码即时迁移到 DI:tomasvotruba.cz/blog/2019/03/04/…

p
patricus

错误消息是由于调用未通过 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');
    }
}

答案是正确的,但是出于偏好,我会使用 Illuminate\Support\Facades\Request;因为我个人认为 Laravel 将所有内容都别名为根命名空间的习惯是与首先拥有命名空间的观点背道而驰的。它还使 API 文档更难生成,因为 apigen/phpdoc 将无法找到“请求”类。
实际上,您不需要更改工匠 make:controller 的 Boilerplate。如果您想使用 Request 而不将其注入方法,只需使用 $input = \Request::all() (注意 \ )。如果您想使用注入而不是使用 public myFunction(Request $request() { $input = $request->all() } 或者将其注入构造函数并将其分配给类变量
为什么我在使用 use Illuminate\Http\Request; 时不能使用 Request::all();
@SA__ Request::all() 是一种门面方式。所以你必须 use Illuminate\Support\Facades\Request; 而不是 use Illuminate\Http\Request;
@redA 有没有办法将 Request::all() 转换为使用直接方式(而不是通过外观类)?
l
lucidlogic

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

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

简单的


J
Jonathan Crowe

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

class MyController() 
{

   protected $request;

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

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

}

L
Luca C.

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

$input = \Request::all();

在 laravel 5 中,您还可以通过 request() 函数访问它:

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

J
Jonathon

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

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

        // ...
    }
}

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


感谢您在内部分享它是如何工作的,这值得更多喜欢!
g
ghazyy

当您将以下库导入 api.php 文件时也会发生这种情况。这发生在一些 IDE 的建议中,因为找不到路由类而将其导入。

只需删除它,一切都会正常工作。

use Illuminate\Routing\Route;

更新:

似乎如果你添加这个库它不会导致错误

use Illuminate\Support\Facades\Route;

这对我有用,但我仍然不明白为什么 IDE 原因不适用于我,因为我生成项目的方式和我使用 vscode。
g
goto
use Illuminate\Http\Request;
public function store(Request $request){
   dd($request->all());
}

在上下文中是相同的

use Request;
public function store(){
   dd(Request::all());
}

d
dotNET

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

希望这对未来的人有所帮助。


J
Julian Lanfranco

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

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


请不仅显示哪些代码有效,还要解释您为什么这样做。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅