2015-02-03 2 views
4

필자가 이해 한 한, 클래스 공급자의 도움을 받아 인스턴스화하는 클래스의 생성자에서 클래스 인스턴스 인수를 입력 힌트 할 수 있어야합니다. 불행히도 누락 된 인수에 대한 오류가 발생합니다.Laravel 5 IoC 타입 힌팅이 작동하지 않습니다.

Tracker.php

function __construct($query, Tracker\Shipment $shipment) { 
    $this->query = $query; 
    $this->shipment = $shipment; 
} 

TrackerServiceProvider.php

class TrackerServiceProvider extends \Illuminate\Support\ServiceProvider { 
    public function register() { 
     $this->app->bind('TrackerAPI', function($app, $shipment_number) { 
      return new Tracker\API($shipment_number); // omitting Shipment argument should resolve on its own? 
     }); 
    } 
} 

클래스 API 따라서 생성자를 사용하여, 추적기 연장된다. 왜 묵시적인 클래스 유형 힌트없이 해결되지 않습니까?

답변

6

입력 힌트 기능을 통해 Laravel의 의존성 주입과 PHP new 기능을 혼동했습니다.

TrackerAPI 바인딩에서 return new Tracker\API($shipment_number);을 지정하면 누락 된 매개 변수를 없애기 위해 PHP에 내장 된 것이 없습니다. 이렇게하려면 return $app->make('Tracker\API', [$shipment_number]);

메서드를 사용하면 Laravel이 마법을 사용하여 새 개체를 만듭니다. 먼저 명시 적으로 정의 된 바인딩을 확인합니다. 명시 적 바인딩을 찾지 못하면 제공된 매개 변수와 유형 힌트의 조합을 사용하여 누락 된 매개 변수에 대한 객체를 만드는 것으로 돌아갑니다.

App::make('Tracker\API', [$shipment_number])을 사용하십시오. Tracker\API에 대한 명시 적으로 정의 된 바인딩이 없다고 가정합니다. Tracker\API 생성자에는 두 개의 매개 변수가 필요합니다. $shipment_number이 매개 변수 배열에 전달되므로 첫 번째 매개 변수로 사용됩니다. 하나의 매개 변수 만 제공되었으므로 Laravel은 형식 힌트를 사용하여 나머지 매개 변수를 App::make()으로 지정합니다.

그러나 new 키워드를 사용하여 개체를 구체적으로 인스턴스화하면 이러한 상황이 발생하지 않습니다. 이는 평범한 PHP 객체 인스턴스 생성입니다.

+0

그래서 내 바인딩 (서비스 제공 업체)을 버리고 내 컨트롤러에서 App :: make (Tracker \ API)를 사용하면 처음 생각한대로 작동하게됩니까? – silkfire

+0

@silkfire 예, 타입 힌트 (예 :'$ shipment_number')를 통해 빌드 할 수없는 매개 변수를 전달하는 한. Laravel이 자체적으로 알아 내지 못하는 것을하려는 경우에만 바인딩을 정의하면됩니다. 예를 들어 인터페이스를 삽입하는 경우 Laravel에게 해당 인터페이스에 대해 빌드 할 인스턴스를 지정하기 위해 바인딩을 만들어야합니다. 또는 '새'인스턴스를 삽입하고 싶지는 않지만 기존 인스턴스를 삽입하려는 경우 (예 : [Sentry] (https://cartalyst.com/manual/sentry/2.1) 서비스를 삽입하는 경우). – patricus

+0

정말 고마워요! 방금 만든 메서드를 사용하여 배열의 배송 번호를 제공하고 자동으로 자동 해결되었습니다. 실제로 서비스 제공 업체가 필요하지 않습니다! 어느 편도 좋지만 이제는 내가 필요할 때 더 혼란스러워지고 있습니다. 나는 클래스의 같은 인스턴스를 사용하도록 할 필요가 없었고, 단순히 이미 작성된 변수를 코드에서 재사용했다. – silkfire

1

아니요. Laravel은 그런 부분을 해결할 수 없습니다. 당신은 명시해야한다 :

use Tracker\API; 
use Tracker\Shipment; 
use Illuminate\Support\ServiceProvider; 

class TrackerServiceProvider extends ServiceProvider { 

    public function register() 
    { 
     $this->app->bind('TrackerAPI', function($app, $shipment_number) 
     { 
      return new API($shipment_number, $app[Shipment::class]); 
     }); 
    } 
} 
+0

답변 해 주셔서 감사합니다. 그런데 왜 유형 힌팅과 자동 해결이라는 개념을 오해 한 것입니까? 또는 인터페이스가 아닌 클래스에서만 작동합니까? – silkfire

+0

쿼리 인수가 형식 힌트가 아닙니다. Laravel은 건설을 위해 무엇을 전달해야할지 모릅니다. 서비스 공급자는 객체가 인스턴스화 될 때마다 전달되어야하는 것을 명시 적으로 명시했습니다. – Everon

관련 문제