Laravel Request :: all ()은 정적으로 호출하면 안됩니다.


93

Laravel 에서 컨트롤러 $input = Request::all();store()메서드 를 호출하려고 하는데 다음과 같은 오류가 발생합니다.

비 정적 메서드 Illuminate\Http\Request::all()$this호환되지 않는 컨텍스트에서 가정 하여 정적으로 호출해서는 안됩니다.

이 문제를 해결하는 가장 좋은 방법을 찾는 데 도움이 있습니까? (나는 Laracast를 따르고 있습니다)


@patricus, 죄송합니다. 5라고 말 했어야했습니다.
Moose

외관을 사용하지 않는 것 같습니다. 당신은 가지고 있습니까 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

답변:


226

오류 메시지는 Request외관을 통과하지 않는 호출 때문 입니다.

변화

use Illuminate\Http\Request;

use Request;

작동을 시작해야합니다.

config / app.php 파일에서 클래스 별칭 목록을 찾을 수 있습니다. 여기에서 기본 클래스 Request가 클래스 에 별칭이 지정되었음을 알 수 Illuminate\Support\Facades\Request있습니다. 이 때문에 Request네임 스페이스 파일에서 파사드를 사용하려면 기본 클래스를 사용하도록 지정해야합니다 use Request;..

편집하다

이 질문에 약간의 트래픽이 발생하는 것 같아 라 라벨 5가 공식적으로 출시 된 이후로 답변을 조금 업데이트하고 싶었습니다.

위의 내용은 여전히 ​​기술적으로 정확하고 작동하지만,이 use Illuminate\Http\Request;문은 새로운 컨트롤러 템플릿에 포함되어있어 개발자가 Facade에 의존하는 대신 종속성 주입을 사용하는 방향으로 밀어 붙일 수 있습니다.

Request 객체를 생성자 (또는 Laravel 5에서 사용 가능한 메소드)에 Illuminate\Http\Request주입 할 때 주입해야하는 것은 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');
    }
}

3
대답은 정확하지만 선호도에서 Illuminate \ Support \ Facades \ Request를 사용합니다. 개인적으로 모든 것을 루트 네임 스페이스로 별칭을 지정하는 라 라벨의 습관은 애초에 네임 스페이스를 갖는 점에 위배됩니다. 또한 apigen / phpdoc가 "Request"클래스를 찾을 수 없기 때문에 API 문서 생성이 더 어려워집니다.
delatbabel

4
사실, 장인의 make : controller의 보일러 플레이트를 변경할 필요가 없습니다. 요청을 메서드에 주입하지 않고 사용하려면 $ input = \ Request :: all () 사용하십시오 (\). 주입을 사용하려면 public myFunction (Request $ 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;
Thabung

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

}

6

request()대신 도우미를 사용하십시오 . use진술 에 대해 걱정할 필요가 없으므로 이러한 종류의 문제가 다시 발생하지 않습니다.

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

단순한


4

파사드는 또 다른 요청 클래스이며 전체 경로로 액세스합니다.

$input = \Request::all();

laravel 5에서는 다음 request()함수를 통해 액세스 할 수도 있습니다 .

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

3

나는 미래의 방문객이 여기서 무슨 일이 일어나고 있는지에 대한 약간의 설명을 제공하는 것이 유용 할 것이라고 생각했습니다.

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.NET 인스턴스에서 비 정적으로 호출 Illuminate\Http\Request됩니다.

이것이 @patricus가 위의 대답에서 지적했듯이 use/ import 문을 파사드를 참조하도록 변경함으로써 PHP에 관한 한 .NET 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,

라 라벨은 설정을 기반으로 이러한 별칭 클래스를 생성하며,이를 통해 aliases마치 파사드 자체를 사용하는 것처럼 루트 네임 스페이스 ( 설정 의 문자열 키로 참조 됨)에서 사용 가능한 클래스를 활용할 수 있습니다.

use Request:

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

        // ...
    }
}

의존성 주입에 대한 참고 사항

파사드와 앨리어싱은 여전히 ​​라 라벨에서 제공되지만, 가능하며 일반적으로 의존성 주입 경로를 따르는 것이 좋습니다. 예를 들어 생성자 주입을 사용하여 동일한 결과를 얻습니다.

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;

이것은 나를 위해 일했지만 프로젝트를 생성하고 vscode를 사용하는 방식 때문에 IDE 이유가 나에게 적용되지 않는 이유를 여전히 알 수 없습니다.
Aldo Okware

0

use Illuminate\Http\Request;컨트롤러 상단에 줄 이 있어도이 문제에 직면했습니다 . 내가 $request::ip()대신 하고 있다는 것을 깨달을 때까지 머리를 계속 잡아 당겼다 $request->ip(). 밤새 잠을 자지 않고 새벽 6시에 반쯤 열린 눈으로 코드를보고 있다면 일어날 수 있습니다.

이것이 길 아래의 누군가를 돕기를 바랍니다.


0

나는 범위 정의와 함께 작동합니다.

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


2
어떤 코드가 작동하는지 보여줄뿐만 아니라 왜 그랬는지 설명 해주세요.
creyD
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.