Solicitação Laravel :: all () não deve ser chamada estaticamente

95

No Laravel, estou tentando chamar $input = Request::all();um store()método em meu controlador, mas estou recebendo o seguinte erro:

O método Illuminate\Http\Request::all()não estático não deve ser chamado estaticamente, assumindo a $thispartir de um contexto incompatível

Alguma ajuda para descobrir a melhor maneira de corrigir isso? (Estou seguindo um Laracast)

alce
fonte
@patricus, desculpe, eu deveria ter dito 5.
Moose
Parece que você não está usando a fachada. Você tem uma use Illuminate\Http\Request;declaração em seu controlador?
patricus
@patricus, eu tenho o `use Illuminate \ Http \ Request; declaração na parte superior do meu controlador.
Moose
1
@patricus No entanto, não tenho o Illuminate\Http\Requestpacote em / vendor. Tenho que fazer o download separadamente?
Moose
Os Illuminatepacotes são incluídos como parte do pacote laravel / framework. Se você quiser dar uma olhada no código-fonte do Laravel, você o encontrará em/vendor/laravel/framework/src/Illuminate/...
patricus

Respostas:

232

A mensagem de erro é devido à chamada não passar pela Requestfachada.

mudança

use Illuminate\Http\Request;

Para

use Request;

e deve começar a funcionar.

No arquivo config / app.php, você pode encontrar uma lista de aliases de classe. Lá, você verá que a classe base Requestfoi substituída pela Illuminate\Support\Facades\Requestclasse. Devido a isso, para usar a Requestfachada em um arquivo com namespace, é preciso especificar o uso da classe base: use Request;.

Editar

Como esta questão parece estar recebendo algum tráfego, eu queria atualizar um pouco a resposta já que o Laravel 5 foi oficialmente lançado.

Embora o acima ainda esteja tecnicamente correto e funcione, a use Illuminate\Http\Request;instrução está incluída no novo modelo de controlador para ajudar a empurrar os desenvolvedores na direção de usar injeção de dependência em vez de confiar na fachada.

Ao injetar o objeto Request no construtor (ou métodos, como disponíveis no Laravel 5), é o Illuminate\Http\Requestobjeto que deve ser injetado, e não a Requestfachada.

Portanto, em vez de alterar o template do Controller para trabalhar com a fachada Request, é melhor trabalhar com o template do Controller fornecido e passar a usar injeção de dependência (via construtor ou métodos).

Exemplo via método

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

Exemplo via construtor

<?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');
    }
}
patrício
fonte
3
A resposta está correta, mas por preferência eu usaria Illuminate \ Support \ Facades \ Request; porque pessoalmente acho que o hábito do Laravel de aliasar tudo para o namespace raiz é contra o ponto de ter namespaces em primeiro lugar. Isso também torna a documentação da API mais difícil de gerar porque apigen / phpdoc não será capaz de encontrar a classe "Request".
delatbabel
4
Na verdade, você não precisa alterar o Boilerplate do artesão make: controller. Se você quiser usar o Request sem injetá-lo no método, basta usar $ input = \ Request :: all () (Observe o \). Se você quiser usar injeção, então use public myFunction (Request $ request () {$ input = $ request-> all ()} Ou injete-o no construtor e atribua-o a uma variável de classe
shock_gone_wild
2
Por que não posso usar Request::all();enquanto uso use Illuminate\Http\Request; ?
SA__
@SA__ Request :: all () é uma forma de fachada. então você tem que, em use Illuminate\Support\Facades\Request; vez deuse Illuminate\Http\Request;
Thabung
@redA existe uma maneira de converter Request :: all () para usar a maneira direta (e não por meio da classe de fachada)?
cid
7

em request()vez disso, use o auxiliar. Você não precisa se preocupar com usedeclarações e, portanto, esse tipo de problema não acontecerá novamente.

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

simples

lucidlógica
fonte
6

Injete o objeto de solicitação no controlador usando a injeção mágica do Laravel e então acesse a função não estaticamente. O Laravel irá injetar dependências concretas automaticamente nas classes carregadas automaticamente

class MyController() 
{

   protected $request;

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

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

}
Jonathan Crowe
fonte
4

A fachada é outra classe Request, acesse-a com o caminho completo:

$input = \Request::all();

Do laravel 5 você também pode acessá-lo através da request()função:

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

Achei que seria útil para os futuros visitantes darem uma pequena explicação sobre o que está acontecendo aqui.

A Illuminate\Http\Requestclasse

A Illuminate\Http\Requestclasse do Laravel tem um método chamado all(na verdade o allmétodo é definido em uma característica que a Requestclasse usa, chamada Illuminate\Http\Concerns\InteractsWithInput). A assinatura do allmétodo no momento da escrita se parece com isto:

public function all($keys = null)

Este método não é definido como statice assim quando você tenta chamar o método em um contexto estático, ou seja, Illuminate\Http\Request::all()você obterá o erro exibido na pergunta do OP. O allmétodo é um método de instância e lida com informações que estão presentes em uma instância da Requestclasse, portanto, chamá-lo dessa forma não faz sentido.

Fachadas

Uma fachada no Laravel fornece aos desenvolvedores uma maneira conveniente de acessar objetos no container IoC e chamar métodos nesses objetos. Um desenvolvedor pode chamar um método "estaticamente" em uma fachada Request::all(), mas o método real chama no real Illuminate\Http\Request objeto não é estática.

Uma fachada funciona como um proxy - ela se refere a um objeto no contêiner IoC e passa a chamada do método estático para esse objeto (não estaticamente). Por exemplo, pegue oIlluminate\Support\Facades\Request fachada, é assim que se parece:

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

Sob o capô, a Illuminate\Support\Facades\Facadeclasse base usa alguma mágica do PHP, a saber, o__callStatic método para:

  • Ouça uma chamada de método estático, neste caso allsem parâmetros
  • Pegue o objeto subjacente do contêiner IoC usando a chave retornada por getFacadeAccessor , neste caso um Illuminate\Http\Requestobjeto
  • Chame dinamicamente o método que recebeu estaticamente no objeto que recuperou; neste caso, allé chamado de forma não estática em uma instância de Illuminate\Http\Request.

É por isso que, como @patricus apontou em sua resposta acima, ao alterar a useinstrução / import para se referir à fachada, o erro não está mais lá, porque no que diz respeito ao PHP,all foi corretamente chamado em uma instância de Illuminate\Http\Request.

Aliasing

Aliasing é outro recurso que o Laravel oferece para sua conveniência. Ele funciona criando classes de alias que apontam para fachadas no namespace raiz. Se você der uma olhada em seu config/app.phparquivo, sob a aliaseschave, você encontrará uma longa lista de mapeamentos de strings para classes de fachada. Por exemplo:

'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,

O Laravel cria essas classes de alias para você, com base na sua configuração e isso permite que você utilize as classes disponíveis no namespace raiz (como referido pelas chaves de string da aliasesconfiguração) como se você estivesse usando a própria fachada:

use Request:

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

        // ...
    }
}

Uma nota sobre injeção de dependência

Embora fachadas e aliasing ainda sejam fornecidos no Laravel, é possível e geralmente encorajado a seguir a rota de injeção de dependência. Por exemplo, usando injeção de construtor para obter o mesmo resultado:

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

        // ...
    }
}

Há uma série de benefícios nessa abordagem, mas na minha opinião pessoal, o maior benefício para injeção de dependência é que ela torna o seu código mais fácil de testar. Ao declarar as dependências de suas classes como argumentos de construtor ou método, torna-se muito fácil simular essas dependências e testar a unidade de sua classe isoladamente.

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

é o mesmo no contexto dizendo

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

também acontece quando você importa a seguinte biblioteca para o arquivo api.php. isso acontece por sugestão de algum IDE de importá-lo por não encontrar a Rota classe de .

basta removê-lo e tudo vai funcionar bem.

use Illuminate\Routing\Route;

atualizar:

parece que se você adicionar esta biblioteca não levará a erro

use Illuminate\Support\Facades\Route;
tonto
fonte
isso funcionou para mim, mas ainda não entendo por que o motivo do IDE não se aplica a mim, porque a forma como gerei o projeto e uso o vscode.
Aldo Okware
0

Eu estava enfrentando esse problema mesmo com a use Illuminate\Http\Request;linha na parte superior do meu controlador. Continuei puxando meu cabelo até perceber que estava fazendo em $request::ip()vez de$request->ip() . Pode acontecer com você se você não dormiu a noite toda e está olhando para o código às 6h com os olhos semicerrados.

Espero que isso ajude alguém no caminho.

ponto Net
fonte
0

eu faço funcionar com uma definição de escopo

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

Julian Lanfranco
fonte
2
Não apenas mostre qual código está funcionando, mas também explique por que você fez isso.
creyD