web-dev-qa-db-ja.com

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

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

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

これを修正するための最良の方法を考え出す助けはありますか? (私はLaracastをフォローしています)

72
Moose

エラーメッセージは、Requestファサードを通過しない呼び出しが原因です。

変化する

use Illuminate\Http\Request;

use Request;

動作を開始するはずです。

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

編集

この質問にはトラフィックがあるように見えるので、Laravel 5が正式にリリースされてから、少し答えを更新したかったのです。

上記はまだ技術的には正しく機能しますが、use Illuminate\Http\Request;ステートメントは新しいコントローラーテンプレートに含まれており、開発者がFacadeに依存するよりも依存性注入を使用する方向にプッシュするのに役立ちます。

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

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

class MyController() 
{

   protected $request;

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

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

}
6
Jonathan Crowe

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

$input = \Request::all();

laravel 5からは、request()関数を使用してアクセスすることもできます。

$input = request()->all();
3
Luca C.

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

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

シンプルな

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

文脈で同じです

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

ここで何が起こっているのかについて少し説明することは、将来の訪問者にとって有益だと思いました。

Illuminate\Http\Requestクラス

LaravelのIlluminate\Http\Requestクラスにはallという名前のメソッドがあります(実際、allメソッドはIlluminate\Http\Concerns\InteractsWithInputと呼ばれるRequestクラスが使用するトレイトで定義されています)。執筆時点でのallメソッドのシグネチャは次のようになります。

public function all($keys = null)

このメソッドはstaticとして定義されていないため、静的コンテキスト、つまりIlluminate\Http\Request::all()でメソッドを呼び出そうとすると、OPの質問にエラーが表示されます。 allメソッドはインスタンスメソッドであり、Requestクラスのインスタンスに存在する情報を処理するため、この方法で呼び出しても意味がありません。

ファサード

Laravelのファサードは、IoCコンテナー内のオブジェクトにアクセスし、それらのオブジェクトのメソッドを呼び出す便利な方法を開発者に提供します。開発者は、Request::all()のようなファサードでメソッドを「静的に」呼び出すことができますが、realIlluminate\Http\Requestオブジェクトの実際のメソッド呼び出しはnotstatic。

ファサードはプロキシのように機能します。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コンテナーから基になるオブジェクトを取得します。
  • 取得したオブジェクトで静的に受信したメソッドを動的に呼び出します。この場合、allIlluminate\Http\Requestのインスタンスで非静的に呼び出されます。

@patricusが上記の回答で指摘したように、use/importステートメントをファサードを参照するように変更することで指摘したのは、PHPに関する限り、allIlluminate\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 configの文字列キーで参照)で使用可能なクラスを利用できます。

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
Jonathon

コントローラーの一番上にあるuse Illuminate\Http\Request;行でもこの問題に直面していました。 $request::ip()ではなく$request->ip()を実行していることに気付くまで、髪を引っ張り続けました。一晩中寝ていなかったときに、午前6時にコードを半開眼で見ていると、あなたに起こることがあります。

これが将来誰かを助けることを願っています。

0
dotNET

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

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

0