Запрос Laravel :: all() не должен вызываться статически

В Laravel, я пытаюсь вызвать $input = Request::all(); по методу store() в моем контроллере, но я получаю следующую ошибку:

Нестатический метод Illuminate\Http\Request::all() не следует вызывать статически, предполагая $this из несовместимого контекста

Любая помощь в определении лучшего способа исправить это? (Я следую за Ларакастом)

Ответ 1

Сообщение об ошибке связано с вызовом, не проходящим через фасад Request.

Изменить

use Illuminate\Http\Request;

Для

use Request;

и он должен начать работать.

В файле config/app.php вы можете найти список псевдонимов классов. Там вы увидите, что базовый класс Request был псевдонимом класса Illuminate\Support\Facades\Request. Из-за этого, чтобы использовать фасад Request в файле с расширением имен, вам нужно указать, использовать базовый класс: use Request;.

Изменить

Поскольку этот вопрос, кажется, получает некоторый трафик, я хотел немного обновить ответ с тех пор, как был официально выпущен Laravel 5.

В то время как вышеописанное по-прежнему технически корректно и будет работать, оператор use Illuminate\Http\Request; включен в новый шаблон контроллера, чтобы помочь толкнуть разработчиков в направлении использования инъекции зависимостей и полагаться на фасад.

При вводе объекта 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');
    }
}

Ответ 2

Внесите объект запроса в контроллер, используя магическую инъекцию Laravel, а затем получите доступ к функции нестатически. Laravel автоматически введет конкретные зависимости в классы с автозагрузкой

class MyController() 
{

   protected $request;

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

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

}

Ответ 3

используйте вместо этого помощник request(). Вам не нужно беспокоиться об утверждениях use, и, таким образом, такого рода проблемы больше не повторятся.

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

простой

Ответ 4

Фасад - это еще один класс Request, доступ к нему осуществляется по полному пути:

$input = \Request::all();

Из laravel 5 вы также можете получить к нему доступ через функцию request():

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

Ответ 5

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

то же самое в контексте, говоря

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

Ответ 6

Я подумал, что для будущих посетителей было бы полезно немного объяснить, что здесь происходит.

Класс Illuminate\Http\Request

В классе Laravel Illuminate\Http\Request есть метод с именем all (фактически метод all определен в признаке, используемом классом Request, который называется Illuminate\Http\Concerns\InteractsWithInput). Подпись метода all на момент написания выглядит следующим образом:

public function all($keys = null)

Этот метод не определен как static поэтому при попытке вызвать метод в статическом контексте, т.е. Illuminate\Http\Request::all() вы получите сообщение об ошибке, отображаемое в вопросе OP. Метод all является методом экземпляра и имеет дело с информацией, присутствующей в экземпляре класса Request, поэтому вызывать его таким образом не имеет смысла.

Фасады

Фасад в Laravel предоставляет разработчикам удобный способ доступа к объектам в контейнере IoC и вызова методов для этих объектов. Разработчик может вызвать метод "статически" на фасаде, как Request::all(), но фактический вызов метода для реального объекта Illuminate\Http\Request не является статическим.

Фасад работает как прокси - он ссылается на объект в контейнере IoC и передает статический вызов метода этому объекту (нестатически). Например, возьмем фасад Illuminate\Support\Facades\Request, это выглядит так:

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

Под капотом базовый класс Illuminate\Support\Facades\Facade использует некоторую магию PHP, а именно метод __callStatic для:

  • Слушайте статический вызов метода, в этом случае all без параметров
  • Захватите базовый объект из контейнера IoC, используя ключ, возвращаемый getFacadeAccessor, в данном случае объект Illuminate\Http\Request
  • Динамически вызывайте метод, который он получил статически для полученного объекта, в этом случае all вызывается нестатически для экземпляра Illuminate\Http\Request.

Вот почему, как указал @patricus в своем ответе выше, путем изменения оператора use/import для ссылки на фасад, ошибки больше нет, поскольку в отношении PHP all правильно вызывается в экземпляре. Illuminate\Http\Request.

Aliasing

Псевдоним - еще одна особенность, которую Laravel предоставляет для удобства. Он работает путем эффективного создания псевдонимов классов, которые указывают на фасады в корневом пространстве имен. Если вы посмотрите на свой файл 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), как если бы вы использовали сам фасад:

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

        // ...
    }
}

У этого подхода есть ряд преимуществ, но, по моему личному мнению, величайшим плюсом для внедрения зависимостей является то, что он облегчает тестирование вашего кода. Объявляя зависимости ваших классов как аргументы конструктора или метода, становится очень легко смоделировать эти зависимости и провести модульное тестирование вашего класса изолированно.

Ответ 7

Я сталкивался с этой проблемой даже при use Illuminate\Http\Request; линия в верхней части моего контроллера. Держал меня за волосы, пока я не понял, что я делаю $request::ip() вместо $request->ip(). Может случиться с вами, если вы не спали всю ночь и смотрите на код в 6 утра с полуоткрытыми глазами.

Надеюсь, это поможет кому-то в будущем.

Ответ 8

я заставляю это работать с определением области

публичная функция pagar (\ Illuminate\Http\Request $ request) {//