Laravel Request :: all () ne doit pas être appelé statiquement

90

Dans Laravel, j'essaie d'appeler $input = Request::all();une store()méthode dans mon contrôleur, mais j'obtiens l'erreur suivante:

La méthode non statique Illuminate\Http\Request::all()ne doit pas être appelée statiquement, en partant $thisd'un contexte incompatible

Avez-vous de l'aide pour trouver la meilleure façon de corriger cela? (Je suis un Laracast)

élan
la source
@patricus, désolé, j'aurais dû dire 5.
Moose
Il semble que vous n'utilisez pas la façade. Avez-vous une use Illuminate\Http\Request;déclaration dans votre contrôleur?
patricus
@patricus, j'ai l'option `use Illuminate \ Http \ Request; déclaration en haut de mon contrôleur.
Moose
1
@patricus Je n'ai pas le Illuminate\Http\Requestpaquet dans / vendor cependant. Dois-je le télécharger séparément?
Moose
Les Illuminatepackages sont inclus dans le package laravel / framework. Si vous voulez consulter l'un des codes sources de Laravel, vous le trouverez sous/vendor/laravel/framework/src/Illuminate/...
patricus

Réponses:

223

Le message d'erreur est dû au fait que l'appel ne passe pas par la Requestfaçade.

Changement

use Illuminate\Http\Request;

À

use Request;

et cela devrait commencer à fonctionner.

Dans le fichier config / app.php, vous pouvez trouver une liste des alias de classe. Là, vous verrez que la classe de base Requesta été aliasée sur la Illuminate\Support\Facades\Requestclasse. À cause de cela, d'utiliser la Requestfaçade dans un fichier espaces de noms, vous devez spécifier d'utiliser la classe de base: use Request;.

Éditer

Comme cette question semble générer du trafic, je voulais mettre à jour un peu la réponse depuis la sortie officielle de Laravel 5.

Bien que ce qui précède soit toujours techniquement correct et fonctionnera, l' use Illuminate\Http\Request;instruction est incluse dans le nouveau modèle de contrôleur pour aider les développeurs à utiliser l'injection de dépendances plutôt que de s'appuyer sur la façade.

Lors de l'injection de l'objet Request dans le constructeur (ou les méthodes, comme disponible dans Laravel 5), c'est l' Illuminate\Http\Requestobjet qui doit être injecté, et non la Requestfaçade.

Ainsi, au lieu de changer le modèle Controller pour qu'il fonctionne avec la façade Request, il est préférable de travailler avec le modèle Controller donné et de passer à l'utilisation de l'injection de dépendances (via le constructeur ou les méthodes).

Exemple via la méthode

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

Exemple via constructeur

<?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');
    }
}
patricus
la source
3
La réponse est correcte, mais par préférence, j'utiliserais Illuminate \ Support \ Facades \ Request; car personnellement, je pense que l'habitude de Laravel de tout aliaser dans l'espace de noms racine est contre le point d'avoir des espaces de noms en premier lieu. Cela rend également la documentation de l'API plus difficile à générer car apigen / phpdoc ne pourra pas trouver la classe "Request".
delatbabel
4
En fait, vous n'avez pas besoin de changer la plaque chauffante de la marque artisanale: contrôleur. Si vous souhaitez utiliser la requête sans l'injecter dans la méthode, utilisez simplement $ input = \ Request :: all () (Notez le \). Si vous voulez utiliser l'injection plutôt que d'utiliser public myFunction (Request $ request () {$ input = $ request-> all ()} Ou injectez-le dans le constructeur et attribuez-le à une variable de classe
shock_gone_wild
2
Pourquoi je ne peux pas utiliser Request::all();pendant que j'utilise use Illuminate\Http\Request; ?
SA__
@SA__ Request :: all () est un moyen de façade. donc vous devez au use Illuminate\Support\Facades\Request; lieu deuse Illuminate\Http\Request;
Thabung
@redA existe-t-il un moyen de convertir Request :: all () pour utiliser la méthode directe (et non via la classe de façade)?
cid
6

Injectez l'objet de requête dans le contrôleur en utilisant l'injection magique de Laravel, puis accédez à la fonction de manière non statique. Laravel injectera automatiquement des dépendances concrètes dans les classes chargées automatiquement

class MyController() 
{

   protected $request;

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

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

}
Jonathan Crowe
la source
5

utilisez request()plutôt l' assistant. Vous n'avez pas à vous soucier des usedéclarations et donc ce genre de problème ne se reproduira plus.

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

Facile

lucidlogique
la source
4

La façade est une autre classe Request, accédez-y avec le chemin complet:

$input = \Request::all();

Depuis laravel 5, vous pouvez également y accéder via la request()fonction:

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

J'ai pensé qu'il serait utile que les futurs visiteurs fournissent une petite explication sur ce qui se passe ici.

La Illuminate\Http\Requestclasse

La Illuminate\Http\Requestclasse de Laravel a une méthode nommée all(en fait la allméthode est définie dans un trait que la Requestclasse utilise, appelé Illuminate\Http\Concerns\InteractsWithInput). La signature de la allméthode au moment de la rédaction ressemble à ceci:

public function all($keys = null)

Cette méthode n'est pas définie comme staticet donc lorsque vous essayez d'appeler la méthode dans un contexte statique, c'est- Illuminate\Http\Request::all()à- dire que vous obtiendrez l'erreur affichée dans la question de OP. La allméthode est une méthode d'instance et traite les informations présentes dans une instance de la Requestclasse, donc l'appeler de cette manière n'a aucun sens.

Façades

Une façade dans Laravel fournit aux développeurs un moyen pratique d'accéder aux objets du conteneur IoC et d'appeler des méthodes sur ces objets. Un développeur peut appeler une méthode "statiquement" sur une façade comme Request::all(), mais l'appel de méthode réel sur l' objet réel Illuminate\Http\Request n'est pas statique.

Une façade fonctionne comme un proxy - elle fait référence à un objet dans le conteneur IoC et transmet l'appel de méthode statique à cet objet (de manière non statique). Par exemple, prenez la Illuminate\Support\Facades\Requestfaçade, voici à quoi elle ressemble:

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

Sous le capot, la Illuminate\Support\Facades\Facadeclasse de base utilise un peu de magie PHP, à savoir la __callStaticméthode pour:

  • Écoutez un appel de méthode statique, dans ce cas allsans paramètres
  • Récupérez l'objet sous-jacent du conteneur IoC à l'aide de la clé renvoyée par getFacadeAccessor, dans ce cas, un Illuminate\Http\Requestobjet
  • Appelez dynamiquement la méthode qu'il a reçue de manière statique sur l'objet qu'il a récupéré, dans ce cas allest appelé de manière non statique sur une instance de Illuminate\Http\Request.

C'est pourquoi, comme @patricus l'a souligné dans sa réponse ci-dessus, en changeant l' useinstruction / import pour faire référence à la façade, l'erreur n'est plus là, car en ce qui concerne PHP, alla été correctement appelée sur une instance de Illuminate\Http\Request.

Aliasing

L'aliasing est une autre fonctionnalité fournie par Laravel pour plus de commodité. Il fonctionne en créant efficacement des classes d'alias qui pointent vers des façades dans l'espace de noms racine. Si vous jetez un œil à votre config/app.phpfichier, sous la aliasesclé, vous trouverez une longue liste de mappages de chaînes aux classes de façade. Par exemple:

'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 crée ces classes d'alias pour vous, en fonction de votre configuration et cela vous permet d'utiliser les classes disponibles dans l'espace de noms racine (comme indiqué par les clés de chaîne de la aliasesconfiguration) comme si vous utilisiez la façade elle-même:

use Request:

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

        // ...
    }
}

Une note sur l'injection de dépendances

Bien que les façades et l'aliasing soient toujours fournis à Laravel, il est possible et généralement encouragé de suivre la voie d'injection de dépendance. Par exemple, en utilisant l'injection de constructeur pour obtenir le même résultat:

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

        // ...
    }
}

Il y a un certain nombre d'avantages à cette approche, mais à mon avis personnel, le plus grand avantage de l'injection de dépendances est qu'elle rend votre code plus facile à tester. En déclarant les dépendances de vos classes comme arguments de constructeur ou de méthode, il devient très facile de se moquer de ces dépendances et de tester individuellement votre classe.

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

est la même chose dans le contexte en disant

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

cela se produit également lorsque vous importez la bibliothèque suivante dans le fichier api.php. cela se produit par la suggestion de certains IDE de l'importer pour ne pas trouver la classe d' itinéraire .

il suffit de le supprimer et tout fonctionnera correctement.

use Illuminate\Routing\Route;

mise à jour:

semble que si vous ajoutez cette bibliothèque, cela ne conduira pas à une erreur

use Illuminate\Support\Facades\Route;
étourdi
la source
cela a fonctionné pour moi, mais je ne comprends toujours pas pourquoi la raison IDE ne s'appliquerait pas à moi, parce que la façon dont j'ai généré le projet et j'utilise vscode.
Aldo Okware
0

J'étais confronté à ce problème même avec la use Illuminate\Http\Request;ligne en haut de mon contrôleur. J'ai continué à me tirer les cheveux jusqu'à ce que je réalise que je faisais à la $request::ip()place $request->ip(). Cela peut vous arriver si vous n'avez pas dormi de la nuit et que vous regardez le code à 6 heures du matin avec les yeux entrouverts.

J'espère que cela aidera quelqu'un sur la route.

point net
la source
0

je le fais fonctionner avec une définition de portée

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

Julian Lanfranco
la source
2
Veuillez non seulement montrer quel code fonctionne, mais également expliquer pourquoi vous l'avez fait.
creyD