Laravel İsteği :: all () Statik Olarak Çağrılmamalıdır


95

Laravel'de, denetleyicimdeki $input = Request::all();bir store()yöntemi çağırmaya çalışıyorum , ancak aşağıdaki hatayı alıyorum:

Uyumsuz bağlam Illuminate\Http\Request::all()varsayılarak statik olmayan yöntem statik olarak çağrılmamalıdır$this

Bunu düzeltmenin en iyi yolunu bulmak için herhangi bir yardım var mı? (Bir Laracast'ı takip ediyorum)


@patricus, üzgünüm, 5 demeliydim.
Moose

Görünüşe göre cepheyi kullanmıyorsun. use Illuminate\Http\Request;Denetleyicinizde bir ifade var mı?
patricus

@patricus, `Illuminate \ Http \ Request kullan; denetleyicimin üstündeki ifade.
Moose

1
@patricus Yine Illuminate\Http\Requestde / vendor içinde paketim yok . Bunu ayrıca indirmem gerekiyor mu?
Moose

IlluminatePaketler laravel / çerçeve paketinin parçası olarak dahil edilmiştir. Laravel kaynak kodlarından herhangi birine bakmak isterseniz, altında bulabilirsiniz/vendor/laravel/framework/src/Illuminate/...
patricus

Yanıtlar:


232

Hata mesajı, çağrının Requestcepheden geçmemesinden kaynaklanmaktadır .

Değişiklik

use Illuminate\Http\Request;

İçin

use Request;

ve çalışmaya başlamalıdır.

Config / app.php dosyasında, sınıf takma adlarının bir listesini bulabilirsiniz. Orada, temel sınıfın sınıfa diğer Requestadının verildiğini göreceksiniz Illuminate\Support\Facades\Request. Bu nedenle, kullanmak Çünkü Requestbir isim alanlı dosyada cephe, temel sınıf kullanmak belirtmek gerekir: use Request;.

Düzenle

Bu soru biraz trafik alıyor gibi göründüğünden, Laravel 5 resmi olarak piyasaya sürüldüğü için cevabı biraz güncellemek istedim.

Yukarıdakiler teknik olarak hala doğru olsa ve işe yarayacak olsa da use Illuminate\Http\Request;ifade, geliştiricileri Facade'e güvenmek yerine bağımlılık enjeksiyonu kullanma yönünde ilerletmeye yardımcı olmak için yeni Denetleyici şablonuna dahil edilmiştir.

Yapıcıya Request nesnesini (veya Laravel 5'te mevcut olan yöntemler) Illuminate\Http\Requestenjekte ederken, Requestcephe değil, enjekte edilmesi gereken nesnedir .

Bu nedenle, Kontrolör şablonunu Talep cephesiyle çalışacak şekilde değiştirmek yerine, verilen Kontrolör şablonuyla çalışmanız ve bağımlılık enjeksiyonunu (yapıcı veya yöntemler aracılığıyla) kullanmaya doğru ilerlemeniz daha iyi olur.

Yöntem yoluyla örnek

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

Yapıcı aracılığıyla örnek

<?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
Cevap doğru, ancak tercihim dışında Illuminate \ Support \ Facades \ Request'i kullanırdım; çünkü kişisel olarak, Laravel'in her şeyi kök ad alanına takma alışkanlığının ilk etapta ad alanlarına sahip olma noktasına aykırı olduğunu düşünüyorum. Apigen / phpdoc "İstek" sınıfını bulamayacağı için API belgelerinin oluşturulmasını da zorlaştırır.
delatbabel

4
Aslında, zanaatkar make: controller'ın Boilerplate'ini değiştirmenize gerek yoktur. Talebi metoda enjekte etmeden kullanmak istiyorsanız, sadece $ input = \ Request :: all () kullanın (\ 'ye dikkat edin). Genel myFunction kullanmak yerine enjeksiyon kullanmak istiyorsanız (Request $ request () {$ input = $ request-> all ()} Veya
kurucuya

2
Kullanırken neden Request::all();kullanamıyorum use Illuminate\Http\Request; ?
SA__

@SA__ Request :: all () bir cephe yoludur. böylece zorunda use Illuminate\Support\Facades\Request; yerineuse Illuminate\Http\Request;
Thabung

@redA, Request :: all () 'ı doğrudan (cephe sınıfı üzerinden değil) kullanmak için dönüştürmenin bir yolu var mı?
cid

7

kullanmak request()yerine yardımcısı. useİfadeler için endişelenmenize gerek yok ve bu nedenle bu tür bir sorun bir daha olmayacak.

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

basit


6

Laravel'in sihirli enjeksiyonunu kullanarak istek nesnesini denetleyiciye enjekte edin ve ardından işleve statik olmayan bir şekilde erişin. Laravel, otomatik olarak otomatik yüklenen sınıflara somut bağımlılıkları enjekte edecektir.

class MyController() 
{

   protected $request;

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

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

}

4

Cephe, başka bir İstek sınıfıdır, ona tam yolla erişin:

$input = \Request::all();

Laravel 5'ten request()fonksiyon aracılığıyla da erişebilirsiniz :

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

3

Gelecekteki ziyaretçiler için burada neler olduğuna dair biraz açıklama yapmanın yararlı olacağını düşündüm.

Illuminate\Http\Requestsınıf

Laravel'in Illuminate\Http\Requestsınıfının adlandırılmış bir yöntemi vardır all(aslında allyöntem, Requestsınıfın kullandığı, çağrılan bir özellikte tanımlanmıştır Illuminate\Http\Concerns\InteractsWithInput). allYöntemin yazım sırasındaki imzası şu şekildedir:

public function all($keys = null)

Bu yöntem olarak tanımlanmamıştır staticve bu nedenle yöntemi statik bir bağlamda çağırmaya çalıştığınızda, yani Illuminate\Http\Request::all()OP'nin sorusunda görüntülenen hatayı alırsınız. allBir örnek metot ve bir örneği mevcuttur bilgilerle fırsatlar olduğunu Requesthiç mantıklı bu şekilde çağırmak yüzden, sınıf.

Cepheler

Laravel'deki bir cephe, geliştiricilere IoC konteynerindeki nesnelere erişmenin ve bu nesnelerdeki yöntemlerin çağrılmasının uygun bir yolunu sağlar. Bir geliştirici, benzer bir cephede bir yöntemi "durağan" olarak Request::all()çağırabilir, ancak gerçek Illuminate\Http\Request nesnedeki gerçek yöntem çağrısı statik değildir .

Bir cephe, bir proxy gibi çalışır - IoC konteynerindeki bir nesneyi ifade eder ve statik yöntem çağrısını bu nesneye (statik olmayan olarak) iletir. Örneğin Illuminate\Support\Facades\Requestcepheyi ele alalım, göründüğü gibi:

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

Temel olarak, temel Illuminate\Support\Facades\Facadesınıf bazı PHP sihrini kullanır, yani şu __callStaticyöntemi kullanır:

  • Bu durumda allparametre olmadan statik bir yöntem çağrısını dinleyin
  • getFacadeAccessorBu durumda bir Illuminate\Http\Requestnesne tarafından döndürülen anahtarı kullanarak IoC konteynerinden temeldeki nesneyi alın
  • Geri getirdiği nesnede statik olarak aldığı yöntemi dinamik olarak çağırın, bu durumda allbir örneğinde statik olmayan olarak çağrılır Illuminate\Http\Request.

Bu nedenle, @patricus'un yukarıdaki cevabında belirttiği gibi, use/ import ifadesini cepheye atıfta bulunacak şekilde değiştirerek, hata artık orada değildir, çünkü PHP söz konusu olduğunda, allbir örneğinde doğru şekilde çağrılmıştır Illuminate\Http\Request.

Aliasing

Aliasing, Laravel'in kolaylık sağladığı bir başka özelliktir. Kök ad alanında cephelere işaret eden takma ad sınıflarını etkili bir şekilde oluşturarak çalışır. config/app.phpDosyanıza bir göz atarsanız , aliasesanahtarın altında, cephe sınıfları için uzun bir dizi eşleştirmeleri bulacaksınız. Örneğin:

'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, yapılandırmanıza bağlı olarak bu takma ad sınıflarını sizin için oluşturur ve bu, kök ad alanında bulunan sınıfları ( aliasesyapılandırmanın dize anahtarları tarafından anılır ) cephenin kendisini kullanıyormuş gibi kullanmanıza olanak tanır :

use Request:

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

        // ...
    }
}

Bağımlılık ekleme hakkında bir not

Laravel'de cepheler ve örtüşme hala sağlansa da, bağımlılık enjeksiyon yoluna gitmek mümkündür ve genellikle teşvik edilir. Örneğin, aynı sonucu elde etmek için yapıcı enjeksiyonu kullanmak:

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

        // ...
    }
}

Bu yaklaşımın birçok faydası vardır, ancak kişisel görüşüme göre bağımlılık enjeksiyonunun en büyük yanlısı, kodunuzun test edilmesini kolaylaştırmasıdır. Sınıflarınızın bağımlılıklarını yapıcı veya yöntem argümanları olarak bildirerek, bu bağımlılıkları alay etmek ve sınıfınızı tek başına test etmek çok kolay hale gelir.


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

bağlamda aynıdır söylemek

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

1

ayrıca aşağıdaki kitaplığı api.php dosyasına aktardığınızda da olur. bu, bazı IDE'lerin Rota Sınıfını bulamamak için içeri aktarma önerisiyle olur .

sadece onu kaldırın ve her şey yoluna girecek.

use Illuminate\Routing\Route;

Güncelleme:

Bu kitaplığı eklerseniz hataya neden olmayacak

use Illuminate\Support\Facades\Route;

bu benim için çalıştı, ancak projeyi oluşturduğum ve vscode kullandığım için IDE nedeninin neden benim için geçerli olmadığını hala anlamıyorum.
Aldo Okware

0

use Illuminate\Http\Request;Denetleyicimin üstündeki satırda bile bu sorunla karşılaşıyordum . Onun $request::ip()yerine yaptığımı anlayana kadar saçımı çekmeye devam ettim $request->ip(). Bütün gece uyumadıysanız ve sabah 6'da koda yarı açık gözlerle bakıyorsanız, başınıza gelebilir.

Umarım bu yolun aşağısında birine yardımcı olur.


0

bir kapsam tanımıyla çalışmasını sağlıyorum

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


2
Lütfen yalnızca hangi kodun çalıştığını göstermekle kalmayın, bunu neden yaptığınızı da açıklayın.
creyD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.