Laravelでは、コントローラーの$input = Request::all();
メソッドでstore()
を呼び出そうとしていますが、次のエラーが発生しています:
互換性のないコンテキストから
$this
を想定して、非静的メソッドIlluminate\Http\Request::all()
を静的に呼び出すべきではありません
これを修正するための最良の方法を考え出す助けはありますか? (私はLaracastをフォローしています)
エラーメッセージは、Request
ファサードを通過しない呼び出しが原因です。
変化する
use Illuminate\Http\Request;
に
use Request;
動作を開始するはずです。
Config/app.phpファイルで、クラスエイリアスのリストを見つけることができます。ここで、基本クラスRequest
がIlluminate\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');
}
}
Laravelのマジックインジェクションを使用してリクエストオブジェクトをコントローラーにインジェクトし、関数に非静的にアクセスします。 Laravelは、自動ロードされたクラスに具体的な依存関係を自動的に挿入します
class MyController()
{
protected $request;
public function __construct(\Illuminate\Http\Request $request)
{
$this->request = $request;
}
public function myFunc()
{
$input = $this->request->all();
}
}
ファサードは別のリクエストクラスであり、フルパスでアクセスします。
$input = \Request::all();
laravel 5からは、request()
関数を使用してアクセスすることもできます。
$input = request()->all();
代わりにrequest()
ヘルパーを使用してください。 use
ステートメントについて心配する必要はありません。したがって、この種の問題は二度と起こりません。
$input = request()->all();
シンプルな
use Illuminate\Http\Request;
public function store(Request $request){
dd($request->all());
}
文脈で同じです
use Request;
public function store(){
dd(Request::all());
}
ここで何が起こっているのかについて少し説明することは、将来の訪問者にとって有益だと思いました。
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コンテナーから基になるオブジェクトを取得します。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
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();
// ...
}
}
このアプローチには多くの利点がありますが、私の個人的な意見では、依存性注入の最大の長所は、コードをテストしやすくすることです。クラスの依存関係をコンストラクターまたはメソッドの引数として宣言することにより、それらの依存関係を模擬し、クラスを分離して単体テストすることが非常に簡単になります。
コントローラーの一番上にあるuse Illuminate\Http\Request;
行でもこの問題に直面していました。 $request::ip()
ではなく$request->ip()
を実行していることに気付くまで、髪を引っ張り続けました。一晩中寝ていなかったときに、午前6時にコードを半開眼で見ていると、あなたに起こることがあります。
これが将来誰かを助けることを願っています。
スコープ定義で動作させる
public function pagar(\ Illuminate\Http\Request $ request){//