Richiesta Laravel :: all () non dovrebbe essere chiamata staticamente


90

In Laravel, sto provando a chiamare $input = Request::all();un store()metodo nel mio controller, ma ricevo il seguente errore:

Il metodo Illuminate\Http\Request::all()non statico non dovrebbe essere chiamato staticamente, presumendo $thisda un contesto incompatibile

Qualche aiuto per capire il modo migliore per correggere questo problema? (Sto seguendo un Laracast)


@ patricus, scusa, avrei dovuto dire 5.
Moose

Sembra che tu non stia usando la facciata. Hai una use Illuminate\Http\Request;dichiarazione nel tuo controller?
patricus

@ patricus, ho l 'ʻuse Illuminate \ Http \ Request; dichiarazione nella parte superiore del mio controller.
Moose

1
@ patricus Tuttavia non ho il Illuminate\Http\Requestpacchetto in / vendor. Devo scaricarlo separatamente?
Moose

I Illuminatepacchetti sono inclusi come parte del pacchetto laravel / framework. Se vuoi guardare uno qualsiasi del codice sorgente di Laravel, lo troverai sotto/vendor/laravel/framework/src/Illuminate/...
patricus

Risposte:


222

Il messaggio di errore è dovuto al fatto che la chiamata non è passata dalla Requestfacciata.

Modificare

use Illuminate\Http\Request;

Per

use Request;

e dovrebbe iniziare a funzionare.

Nel file config / app.php, puoi trovare un elenco degli alias di classe. Lì, vedrai che la classe di base Requestè stata alias per la Illuminate\Support\Facades\Requestclasse. A causa di questo, di utilizzare la Requestfacciata in un file di namespace, è necessario specificare di utilizzare la classe di base: use Request;.

modificare

Poiché questa domanda sembra ricevere un po 'di traffico, volevo aggiornare un po' la risposta da quando Laravel 5 è stato ufficialmente rilasciato.

Sebbene quanto sopra sia tecnicamente corretto e funzionerà, la use Illuminate\Http\Request;dichiarazione è inclusa nel nuovo modello di Controller per aiutare gli sviluppatori a spingere gli sviluppatori nella direzione dell'utilizzo dell'inserimento delle dipendenze rispetto al fare affidamento sulla facciata.

Quando si inserisce l'oggetto Request nel costruttore (o nei metodi, come disponibile in Laravel 5), è l' Illuminate\Http\Requestoggetto che dovrebbe essere iniettato e non la Requestfacciata.

Quindi, invece di modificare il modello del controller per lavorare con la facciata della richiesta, è meglio lavorare con il modello del controller dato e passare all'uso dell'inserimento delle dipendenze (tramite costruttore o metodi).

Esempio tramite metodo

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

Esempio tramite costruttore

<?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
La risposta è corretta, tuttavia per preferenza userei Illuminate \ Support \ Facades \ Request; perché personalmente penso che l'abitudine di Laravel di creare alias tutto nello spazio dei nomi di root sia contro il punto di avere spazi dei nomi in primo luogo. Inoltre rende la documentazione API più difficile da generare perché apigen / phpdoc non sarà in grado di trovare la classe "Request".
delatbabel

4
Non è infatti necessario cambiare il Boilerplate della marca artigiana: controller. Se vuoi usare la richiesta senza iniettarla nel metodo usa solo $ input = \ Request :: all () (nota \). Se si desidera utilizzare l'iniezione piuttosto che utilizzare la funzione pubblica myFunction (Request $ request () {$ input = $ request-> all ()} o iniettarla nel costruttore e assegnarla a una variabile di classe
shock_gone_wild

2
Perché non posso usare Request::all();mentre lo uso use Illuminate\Http\Request; ?
SA__

@SA__ Request :: all () è un modo di facciata. quindi devi use Illuminate\Support\Facades\Request; invece diuse Illuminate\Http\Request;
Thabung

@redA c'è un modo per convertire Request :: all () in modo diretto (e non attraverso la classe di facciata)?
cid

6

Iniettare l'oggetto richiesta nel controller utilizzando l'iniezione magica di Laravel e quindi accedere alla funzione in modo non statico. Laravel inietterà automaticamente dipendenze concrete nelle classi caricate automaticamente

class MyController() 
{

   protected $request;

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

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

}

5

usa request()invece l' helper. Non devi preoccuparti delle usedichiarazioni e quindi questo tipo di problema non si ripresenterà.

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

semplice


4

La facciata è un'altra classe Request, accedete con il percorso completo:

$input = \Request::all();

Da laravel 5 puoi accedervi anche tramite la request()funzione:

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

3

Ho pensato che sarebbe stato utile per i futuri visitatori fornire un po 'di spiegazione su ciò che sta accadendo qui.

La Illuminate\Http\Requestclasse

La Illuminate\Http\Requestclasse di Laravel ha un metodo chiamato all(infatti il allmetodo è definito in un tratto che la Requestclasse usa, chiamato Illuminate\Http\Concerns\InteractsWithInput). La firma del allmetodo al momento della scrittura è simile a questa:

public function all($keys = null)

Questo metodo non è definito come statice così quando provi a chiamare il metodo in un contesto statico, cioè Illuminate\Http\Request::all()otterrai l'errore visualizzato nella domanda di OP. Il allmetodo è un metodo di istanza e si occupa delle informazioni presenti in un'istanza della Requestclasse, quindi chiamarlo in questo modo non ha senso.

Facciate

Una facciata in Laravel fornisce agli sviluppatori un modo conveniente per accedere agli oggetti nel contenitore IoC e chiamare metodi su tali oggetti. Uno sviluppatore può chiamare un metodo "staticamente" su una facciata simile Request::all(), ma la chiamata al metodo effettiva Illuminate\Http\Request sull'oggetto reale non è statica.

Una facciata funziona come un proxy: fa riferimento a un oggetto nel contenitore IoC e passa la chiamata al metodo statico su quell'oggetto (non staticamente). Ad esempio, prendi la Illuminate\Support\Facades\Requestfacciata, ecco come appare:

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

Sotto il cofano, la Illuminate\Support\Facades\Facadeclasse base utilizza un po 'di magia PHP, vale a dire il __callStaticmetodo per:

  • Ascolta una chiamata al metodo statico, in questo caso allsenza parametri
  • Prendi l'oggetto sottostante dal contenitore IoC usando la chiave restituita da getFacadeAccessor, in questo caso un Illuminate\Http\Requestoggetto
  • Chiama dinamicamente il metodo che ha ricevuto staticamente sull'oggetto che ha recuperato, in questo caso allviene chiamato non staticamente su un'istanza di Illuminate\Http\Request.

Questo è il motivo per cui, come ha sottolineato @patricus nella sua risposta sopra, cambiando l' useistruzione / import per riferirsi alla facciata, l'errore non c'è più, perché per quanto riguarda PHP, allè stato correttamente chiamato su un'istanza di Illuminate\Http\Request.

Aliasing

L'aliasing è un'altra funzionalità fornita da Laravel per comodità. Funziona creando efficacemente classi alias che puntano a facciate nello spazio dei nomi radice. Se dai un'occhiata al tuo config/app.phpfile, sotto la aliaseschiave, troverai un lungo elenco di mappature di stringhe in classi di facciata. Per esempio:

'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 crea queste classi alias per te, in base alla tua configurazione e questo ti consente di utilizzare le classi disponibili nello spazio dei nomi root (come indicato dalle chiavi stringa della aliasesconfigurazione) come se stessi usando la facciata stessa:

use Request:

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

        // ...
    }
}

Una nota sull'inserimento delle dipendenze

Sebbene facciate e alias siano ancora forniti in Laravel, è possibile e di solito incoraggiato a seguire il percorso di iniezione delle dipendenze. Ad esempio, utilizzando l'iniezione nel costruttore per ottenere lo stesso risultato:

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

        // ...
    }
}

Ci sono una serie di vantaggi in questo approccio, ma a mio parere personale il più grande vantaggio per l'inserimento delle dipendenze è che rende il tuo codice più facile da testare. Dichiarando le dipendenze delle tue classi come argomenti del costruttore o del metodo, diventa molto facile deridere quelle dipendenze e testare la tua classe in isolamento.


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

è lo stesso nel contesto che dice

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

1

succede anche quando importi la seguente libreria nel file api.php. questo accade per suggerimento di alcuni IDE di importarlo per non trovare la Route Class.

basta rimuoverlo e tutto funzionerà bene.

use Illuminate\Routing\Route;

aggiornare:

sembra che se aggiungi questa libreria non causerà errori

use Illuminate\Support\Facades\Route;

questo ha funzionato per me, ma ancora non capisco perché il motivo dell'IDE non si applicherebbe a me, perché il modo in cui ho generato il progetto e utilizzo vscode.
Aldo Okware

0

Stavo affrontando questo problema anche con la use Illuminate\Http\Request;linea nella parte superiore del mio controller. Ho continuato a tirarmi i capelli finché non ho capito che stavo facendo $request::ip()invece di $request->ip(). Può succedere a te se non hai dormito tutta la notte e guardi il codice alle 6 del mattino con gli occhi socchiusi.

Spero che questo aiuti qualcuno lungo la strada.


0

lo faccio funzionare con una definizione dell'ambito

pagar funzione pubblica (\ Illuminate \ Http \ Request $ request) {//


2
Per favore, non solo mostra quale codice funziona, ma spiega anche perché lo hai fatto.
creyD
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.