Laravel Request :: all()は静的に呼び出されるべきではありません


90

Laravelでは、私が呼び出ししようとしている$input = Request::all();上でstore()、私のコントローラのメソッドが、私は次のエラーを取得しています:

互換性のないコンテキストからIlluminate\Http\Request::all()想定して$this、非静的メソッドを静的に呼び出すことはできません

これを修正するための最良の方法を見つける助けはありますか?(私はララキャストをフォローしています)


@patricus、申し訳ありませんが、私が言っている必要があります。5.
ムース

ファサードを使用していないようです。あなたは持っていますuse Illuminate\Http\Request;あなたのコントローラで文を?
patricus 2015

@patricus、私はʻuse Illuminate \ Http \ Request;を持っています。私のコントローラーの上部にあるステートメント。
ムース

1
@patricus私はIlluminate\Http\Request/ vendorにパッケージを持っていません。別途ダウンロードする必要がありますか?
ムース

Illuminateパッケージはlaravel /フレームワークパッケージの一部として含まれています。Laravelのソースコードのいずれかを見たい場合は、以下にあります/vendor/laravel/framework/src/Illuminate/...
patricus 2015

回答:


222

エラーメッセージは、コールがRequestファサードを通過していないことが原因です。

変化する

use Illuminate\Http\Request;

use Request;

そしてそれは働き始めるはずです。

config / app.phpファイルには、クラスエイリアスのリストがあります。ここで、基本クラスRequestがクラスにエイリアスされていることがわかりますIlluminate\Support\Facades\Request。このためRequest、名前空間ファイルでファサードを使用するには、基本クラスを使用するように指定する必要がありますuse Request;

編集

この質問はトラフィックが多いようですので、Laravel 5が正式にリリースされたので、答えを少し更新したいと思いました。

上記は技術的には正しく、機能しますが、このuse Illuminate\Http\Request;ステートメントは新しいコントローラーテンプレートに含まれており、開発者がファサードに依存するのではなく、依存性注入を使用する方向に進むのに役立ちます。

Requestオブジェクトをコンストラクター(またはLaravel 5で使用可能なメソッド)にIlluminate\Http\Request挿入する場合、挿入する必要があるのはオブジェクトであり、Requestファサードではありません。

したがって、リクエストファサードで動作するようにコントローラーテンプレートを変更する代わりに、特定のコントローラーテンプレートで動作し、依存性注入の使用に移行することをお勧めします(コンストラクターまたはメソッドを介して)。

メソッドによる例

<?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');
    }
}

3
答えは正しいですが、好みに応じてIlluminate \ Support \ Facades \ Requestを使用します。個人的には、すべてをルート名前空間にエイリアスするというLaravelの習慣は、そもそも名前空間を持つという点に反していると思うからです。また、apigen / phpdocが「Request」クラスを見つけることができないため、APIドキュメントの生成が難しくなります。
delatbabel 2015

4
実際、職人のmake:controllerのボイラープレートを変更する必要はありません。メソッドにリクエストを挿入せずにリクエストを使用する場合は、$ input = \ Request :: all()を使用します(\に注意してください)。public myFunction(Request $ request(){$ input = $ request-> all()}を使用するよりもインジェクションを使用する場合、またはコンストラクターに
インジェクション

2
使用Request::all();中に使用できないのはなぜuse Illuminate\Http\Request; ですか?
SA__ 2015

@SA__ Request :: all()はファサードの方法です。だからあなたはuse Illuminate\Support\Facades\Request; 代わりにしなければならない use Illuminate\Http\Request;
Thabung 2016年

@redAは、Request :: all()を(ファサードクラスを介さずに)直接的な方法を使用するように変換する方法はありますか?
cid 2016年

6

Laravelのマジックインジェクションを使用してリクエストオブジェクトをコントローラーにインジェクトしてから、非静的に関数にアクセスします。Laravelは、オートロードされたクラスに具体的な依存関係を自動的に挿入します

class MyController() 
{

   protected $request;

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

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

}

5

request()代わりにヘルパーを使用してください。useステートメントについて心配する必要がないため、この種の問題は二度と発生しません。

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

シンプル


4

ファサードは別のRequestクラスであり、フルパスでアクセスします。

$input = \Request::all();

laravel 5から、次のrequest()機能を使用してアクセスすることもできます。

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

3

ここで何が起こっているのか、将来の訪問者に少し説明しておくと便利だと思いました。

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オブジェクト)を使用して、IoCコンテナから基になるオブジェクトを取得します
  • 取得したオブジェクトで静的に受信したメソッドを動的に呼び出します。この場合all、のインスタンスで非静的に呼び出されますIlluminate\Http\Request

これが、@ patricusが上記の回答で指摘したようuseに、ファサードを参照するように/ importステートメントを変更することにより、PHPに関する限り、allのインスタンスで正しく呼び出されたため、エラーが発生しなくなった理由ですIlluminate\Http\Request

エイリアシング

エイリアシングは、Laravelが便利に提供するもう1つの機能です。これは、ルート名前空間のファサードを指すエイリアスクラスを効果的に作成することによって機能します。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();

        // ...
    }
}

このアプローチには多くの利点がありますが、私の個人的な意見では、依存性注入の最大の利点は、コードのテストがはるかに簡単になることです。クラスの依存関係をコンストラクターまたはメソッドの引数として宣言することにより、それらの依存関係をモックアウトし、クラスを分離して単体テストすることが非常に簡単になります。


1
use Illuminate\Http\Request;
public function store(Request $request){
   dd($request->all());
}

文脈上同じです

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

1

また、次のライブラリをapi.phpファイルにインポートするときにも発生します。これは、ルートクラスが見つからないためにインポートするというIDEの提案によって発生します。

それを取り除くだけで、すべてが正常に機能します。

use Illuminate\Routing\Route;

更新:

このライブラリを追加してもエラーは発生しないようです

use Illuminate\Support\Facades\Route;

これは私にとってはうまくいきましたが、プロジェクトを生成し、vscodeを使用する方法のため、IDEの理由が私に当てはまらない理由がまだわかりません。
AldoOkware19年

0

use Illuminate\Http\Request;コントローラーの上部に線がある場合でも、この問題に直面していました。の$request::ip()代わりにやっていることに気付くまで、髪を引っ張り続けました$request->ip()。あなたが一晩中眠らず、半分開いた目で午前6時にコードを見ている場合にあなたに起こる可能性があります。

これが将来の誰かに役立つことを願っています。


0

スコープ定義で動作させる

public function pagar(\ Illuminate \ Http \ Request $ request){//


2
どのコードが機能しているかを示すだけでなく、なぜこれを行ったのかを説明してください。
creyD
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.