it-swarm.com.ru

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

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

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

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

69
Moose

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

+ Правка

use Illuminate\Http\Request;

К

use Request;

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

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

Правка

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

Хотя вышеприведенное все еще технически правильно и будет работать, оператор use Illuminate\Http\Request; включен в новый шаблон Controller, чтобы помочь разработчикам подталкивать в направлении использования внедрения зависимостей вместо использования Фасада.

При внедрении объекта Request в конструктор (или методы, доступные в Laravel 5), должен вводиться объект Illuminate\Http\Request, а не фасад Request.

Таким образом, вместо изменения шаблона Controller для работы с фасадом запроса, лучше поработать с данным шаблоном Controller и перейти к использованию внедрения зависимостей (через конструктор или методы).

Пример с помощью метода

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

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

class MyController() 
{

   protected $request;

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

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

}
6
Jonathan Crowe

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

$input = \Request::all();
2
Luca C.

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

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

просто

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

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

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

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

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

0
dotNET

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

Класс 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(), но фактический вызов метода для объекта realIlluminate\Http\Request является not static.

Фасад работает как прокси - он ссылается на объект в контейнере 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();

        // ...
    }
}

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

0
Jonathon

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

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

0
Julian Lanfranco