Запит Laravel :: all () Не слід називати статично


90

У Laravel, я намагаюся подзвонити $input = Request::all();по store()методі в моєму контролері, але я отримую наступне повідомлення про помилку:

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

Будь-яка допомога у з’ясуванні найкращого способу виправити це? (Я стежу за Laracast)


@patricus, вибачте, я повинен був сказати 5.
Лось

Схоже, ви не використовуєте фасад. У вас є use Illuminate\Http\Request;заява у вашому контролері?
patricus

@patricus, у мене є `use Illuminate \ Http \ Request; у верхній частині мого контролера.
Moose

1
@patricus У мене немає Illuminate\Http\Requestпакунку в / vendor. Чи потрібно це завантажувати окремо?
Moose

У Illuminateпакети включені як частина Laravel / рамковий пакет. Якщо ви хочете подивитися будь-який вихідний код Laravel, ви знайдете його під/vendor/laravel/framework/src/Illuminate/...
patricus

Відповіді:


222

Повідомлення про помилку пов’язано з тим, що дзвінок не проходить через 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');
    }
}

3
Відповідь правильна, однак із переваги я б використав Illuminate \ Support \ Facades \ Request; тому що особисто я думаю, що звичка Ларавела об’єднувати все в кореневий простір імен суперечить тому, що в першу чергу мають простори імен. Це також ускладнює створення документації API, оскільки apigen / phpdoc не зможе знайти клас "Запит".
delatbabel

4
Насправді, вам не потрібно міняти панель керування artisan make: controller. Якщо ви хочете використовувати Запит, не вводячи його в метод, просто використовуйте $ input = \ Request :: all () (Зверніть увагу на \). Якщо ви хочете використовувати ін'єкцію, ніж використовуйте загальнодоступну myFunction (Запит $ request () {$ input = $ request-> all ()} Або вводьте його в конструктор і призначайте змінній класу
shock_gone_wild

2
Чому я не можу використовувати Request::all();під час використання use Illuminate\Http\Request; ?
SA__

@SA__ Request :: all () - це фасад. тож вам доведеться use Illuminate\Support\Facades\Request; замістьuse Illuminate\Http\Request;
Табунг

@redA чи є спосіб перетворити Request :: all () на прямий шлях (а не через фасадний клас)?
cid

6

Введіть об'єкт запиту в контролер, використовуючи чарівну ін'єкцію Laravel, а потім отримайте доступ до функції не статично. Laravel автоматично вводить конкретні залежності в автоматично завантажені класи

class MyController() 
{

   protected $request;

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

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

}

5

скористайтеся request()замість цього помічником. Вам не потрібно турбуватися про useзаяви, і, отже, подібні проблеми не повторюватимуться знову.

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

просто


4

Фасад - це ще один клас запиту, зверніться до нього із повним шляхом:

$input = \Request::all();

З laravel 5 ви також можете отримати до нього доступ за допомогою request()функції:

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

3

Я вважав, що для майбутніх відвідувачів було б корисно трохи пояснити, що тут відбувається.

Illuminate\Http\Requestклас

Illuminate\Http\RequestКлас Laravel має метод з іменем 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.

Згладжування

Псевдонім - ще одна особливість, яку 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();

        // ...
    }
}

Цей підхід має ряд переваг, але, на мою особисту думку, найбільшим плюсом введення залежності є те, що це полегшує перевірку вашого коду. Оголошуючи залежності ваших класів як аргументи конструктора або методу, стає дуже легко висміяти ці залежності та ізольовано перевірити свій клас.


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

те саме в контексті

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

1

також це відбувається, коли ви імпортуєте наступну бібліотеку у файл api.php. це трапляється за пропозицією якої-небудь IDE імпортувати його за не знаходження маршруту класу .

просто видаліть його, і все буде працювати нормально.

use Illuminate\Routing\Route;

оновлення:

здається, якщо ви додасте цю бібліотеку, це не призведе до помилки

use Illuminate\Support\Facades\Route;

це спрацювало для мене, але я все ще не розумію, чому причина IDE не стосується мене, оскільки спосіб створення проекту та використання vscode.
Aldo Okware

0

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

Сподіваюся, це допомагає комусь у дорозі.


0

я змушую це працювати з визначенням сфери

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


2
Будь ласка, не лише покажіть, який код працює, але також поясніть, чому ви це зробили.
creyD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.