질문을 삭제하지 말아주세요.!
 
1
0
-1

안녕하세요. 좋은 책으로 열심히 공부하고 있습니다.

공부하다 네임스페이스 관련 궁금한 점이 생겨서 질문 드립니다.

네임스페이스를 사용할 때, 앞에 \를 붙이면 루트부터 시작한다고 알고 있습니다.

그리고 컴포저의 오토로드 기능으로 루트 네임스페이스의 디렉터리를 주입하는 방식으로 관리하는 걸로 알고 있습니다.

이렇게 알고 있는 제 지식이 맞는다고 가정하면, 챕터14에서 Event클래스에 접근할 때, 121p에 있는 코드 14-3에서 보면 Event클래스를 \Event 로 접근하는데 이러면, \Event 루트를 찾아야 하는거 아닌가요?

하지만 컴포저 오토로드 설정 파일들을 찾아보니 제가 못찾는지는 모르겠지만 Event라는 루트는 존재하지 않고 따라서 오류가 발생해야 할 것 같은데 잘 작동하네요.

그래서 \를 지워보니까 그래도 잘 작동합니다. \를 지우면 use Illuminate\Support\Facades\Event; 때문에 작동하는것 같아서, 이 use를 지우고 \Event 로 접근하니 잘 작동합니다.

그래서 이번엔 \를 지우고 Event로 접근하니 예상대로 오류를 내뿜네요.

궁금한점이, 도대체 \Event가 무엇이길래 잘 작동하는건가요?

왜 굳이 \Event::listen으로 코드를 작성하셨는지 그 이유가 궁금합니다.

    CommentAdd your comment...

    1 answer

    1.  
      2
      1
      0

      자기 전에 한 대 땡기러 갔다가 이 글을 보고 말았네요 ㅜㅎㅜㅎ.


      좋은 질문입니다. 사실 저는 뭔지도 모르고 그냥 썼습니다.

      급하게 한 번 정리해 볼게요.


      우선 Event와 같은 녀석들을 파사드(Facade)라고 합니다. 여기서 찾을 수 있습니다.


      https://github.com/laravel/laravel/blob/master/config/app.php#L207


      파사드의 개념을 이해하려면 다시 "서비스 프로바이더"와 "서비스 컨테이너"의 개념을 이해해야 하는데요. 라라벨은 부팅할 때 "서비스 프로바이더"를 통해 "서비스 컨테이너"를 만듭니다(==채우고 준비합니다). 대략 아래와 같은 코드 형태일겁니다.

      /* 라라벨 부팅 */
      
      class Container {
      	$services = [];
      
      	public function set($key, $value)
      	{
      		$this->services[$key] = $value;
      	}
      
      	public function get($key)
      	{
      		if (array_key_exists($this->services, $key)) {
      			return $this->services[$key];
      		}
      
      		throw new Exception('그런 서비스는 없습니다.');
      	}
      }
      
      $app = new Container;
      
      // 서비스 프로바이더 #1
      $app->set('foo', 'bar');
      
      // 서비스 프로바이더 #2
      $baz = new stdClass;
      $baz->prop = 'value';
      $app->set('baz', $baz);
      
      // 서비스 프로바이더 #3
      $qux = new QuxClass('apple', 'banana');
      $app->set('QuxClass', $qux);
      
      return $app;
      /* 이제 부팅된 프레임워크를 사용하는 애플리케이션 레이어 코드에서 */
      
      $app->get('QuxClass')->methodsInQuxClass();

      Pseudo이긴 하지만, 대략 이런 느낌입니다.


      "서비스 컨테이너"는 애플리케이션을 개발하기 위해 필요한 여러 가지 클래스 인스턴스, 환경 변수, 기타 등등을 담고 있는 큰 그릇이고, "서비스 프로바이더"는 이 큰 그릇에 내용을 채우는 역할을 합니다.


      질문하신 Illuminate\Support\Facades\Event 파사드를 열어보면, 'events'라는 문자열만 반환할 겁니다. config/app.php 파일의 'providers' 배열을 Illuminate\Foundation\Application 클래스가 가져와서 하나씩 "서비스 컨테이너"에 등록합니다. 이때 Event라는 별칭도 "서비스 컨테이너"에 등록되는 겁니다.


      https://github.com/laravel/framework/blob/5.3/src/Illuminate/Foundation/Application.php#L535-L541


      "서비스 컨테이너"에 등록된 Event라는 녀석은 이미 보셨으니, 컨테이너에 등록된 내용을 확인해 보시려면, routes/web.php 가장 윗줄에 다음 문장을 쓰고, 아무거나 실행해 보세요(콘솔에서 php artisan 하시면 될 듯해요).

      dd($this->app['Event']); // Illuminate\Support\Facades\Event {#206}
      
      
      // 또는
      
      
      dd($this->app); // 서비스 컨테이너 전체를 출력합니다.

      결론적으로 "서비스 컨테이너"는 큰 배열에 뭔가 잔뜩 담아 놓은 것이고, Event라는 녀석도 미리 만들어서 거기에 담아 놓았다고 생각하면 됩니다. 파사드는 위에서 본 대로 $this→app['Event'] 처럼 호출하지 않고, PHP의 정적 멤버 접근 문법을 빌려서 Event:: 처럼 쉽게 접근할 수 있도록 도와주는 문법적 편법이라 생각하시면 됩니다.

      1. 김태훈

        파사드는 그럼 컨테이너에서 전역 네임스페이스 공간에 정의되는 녀석이라 네임스페이스 안에서는 글로벌 스페이스로 접근해야 하기 때문에 use가 없으면 \를 써야만 되는거였군요. 답변 감사합니다.

      2. 이현석

        댓글로 깔끔히 정리해주셨네요 ㅎㅎ (smile)

      CommentAdd your comment...