Laravel 라이프 사이클

라이프 사이클

라라벨의 요청(Request) 라이프사이클은 다음과 같은 순서로 진행됩니다

// 첫번째 이미지 기준으로 설명

  1. 인덱스 파일 로드: 클라이언트로부터의 요청이 들어오면 웹 서버는 라라벨의 public폴더에 있는 index.php
    파일을 로드합니다.

    // 매번 request가 올때마다 실행됨

    // index.php
    
    require __DIR__.'/../vendor/autoload.php'; // 1.composer의 패키지를 autoload해서 require할 필요가 없게함
    $app = require_once __DIR__.'/../bootstrap/app.php'; // 2.bootstrap/app.php에서 서비스 컨테이너 ($app)을 받아옴 
    $kernel = $app->make(Kernel::class); // 3.서비스 컨테이너에서 바인딩된 Kernel::class를 리졸브한다 (바인딩=>객체넣음,리졸브=>객체사용)
    $response = $kernel->handle(   // 4.HTTP의 커널 파일에서 Request를 처리한후 Response를 보낸다
        $request = Request::capture()
    )->send();
  2. 애플리케이션 인스턴스 생성 :

    // bootstrap/app.php
    
    // 1.서비스 컨테이너 객체 생성 (라라벨의 핵심이 되는 객체 $app생성)  
    $app = new Illuminate\Foundation\Application(
        $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
    );
    
    // 2.HTTP의 커널클래스를 싱글톤으로 바인딩
    // 3.여기서 config/app.php의 서비스 프로바이더가 등록됨
    // 4.등록되는 서비스 프로바이더중에 RouteServiceProvider도 포함됨
    $app->singleton(
        Illuminate\Contracts\Http\Kernel::class,
        App\Http\Kernel::class
    );
    
    // HTTP의 콘솔클래스를 싱글톤으로 바인딩
    $app->singleton(
        Illuminate\Contracts\Console\Kernel::class,
        App\Console\Kernel::class
    );
    
    return $app;


    서비스 컨테이너란?

    라라벨에서 생성되는 객체(인스턴스)들을 생성하고 한곳에 모아서 관리가능하게함

    // 서비스 컨테이너 취득 방법
    $app = app(); 
    $app = \Illuminate\Foundation\Application::getInstance();
    $app = \App::getInstance(); // 퍼사드로부터 얻음

    바인드

    서비스 컨테이너에 인스턴스 생성방법을 등록하는것

    // 1.형식
    // 2.bind형식
    $app->bind(인터페이스/클래스/문자열 , 클로저(무명함수)/문자열);
    
    // 2. 싱글턴형식
    // 첫번째 생성된 인스턴스가 캐시(저장)되고 그 후에 캐시된 인스턴스가 반환됨
    app()->singleton(
        Illuminate\Contracts\Http\Kernel::class, // 인터페이스명
        App\Http\Kernel::class
    );
    
    // 3.instance형식
    // 인스턴스를 직접 바인드함
    $numcls = new Number(1000);
    app()->instance( 'ShareNumber' , $numcls); 
    app('ShareNumber'); //1000
    //app('리졸브클래스명') => app헬퍼함수 사용해서 리졸브
    
    // 4.문자열을 이용한 방법 (중요*)
    app()->singleton(
        Illuminate\Contracts\Http\Kernel::class, // 인터페이스명을 문자열로 받음, ::class는 매직상수로 클래스명을 문자열로 반환함
        App\Http\Kernel::class // 구현하는 클래스명을 문자열로 입력
    );
    // app헬퍼함수를 사용해서, app('리졸브할인터페이스명')으로 리졸브하며, 인터페이스명을 문자열을 인수로 사용해서 인스턴스를 취득한다
    $kernelInstance = app('Illuminate\Contracts\Http\Kernel::class'); 

    리졸브

    서비스 컨테이너에 저장된 인스턴스를 사용할수있게 전달하는것

    app()->make(bind에서 첫번째 인수인 인터페이스/클래스/문자열) // make()함수사용시
    app(bind에서 첫번째 인수인 인터페이스/클래스/문자열) // app헬퍼함수사용시

    DI (Dependency Injection)

    외부에서 의존성(인스턴스/객체)을 주입하는것

    말이 어렵지만 해당 객체 외부에서 인스턴스를 매개변수로 전달하는것이라고보면된다

    아래 예제를 보면 함수와 생성자 어디에든 의존성주입을 할수있다

    인터페이스를 의존성주입하므로써 결합성을 낮춰서 유연하게 사용가능하다 (사실 인터페이스가 아니라 클래스도 의존성주입가능함)

    예를 들어서 의존성을 주입할 객체를 DependencyInterface를 상속받은 여러 클래스를 의존성주입할수있다 (갈아 끼우며 사용가능)

    class ExampleClass {
        private $dependency;
    
        public function __construct(DependencyInterface $dependency) {
            $this->dependency = $dependency;
        }
        public function someMethod(DependencyInterface $dependency) {
            // ...
        }
    }

    CI(Constructor Injection)

    사실 위의 예제에서 생성자에 의존성을 주입하는걸 CI라고하며 DI라는 큰 범주의 하나이다

    그래서 MI(Method Injection)는 메서드에 의존성을 주입하는것을 뜻하기도 한다

    DI와 바인드/리졸브의 관계와 예제

    바인딩과 리졸브를 사용하여 클래스의 생성자와 함수의 인자로 해당 인터페이스명을 사용하였을때 리졸브된 객체를 얻을수있다 (*중요)

    class ExampleClass {
        private $dependency;
        // 1.클래스의 생성자의 인수에 인터페이스를 선언할 경우 자동으로 리졸브해준다
        // 2.리졸브한 결과 new DependencyClass()를 반환한다
        public function __construct(DependencyInterface $dependency) {
            $this->dependency = $dependency;
        }
    }
    
    app()->bind(DependencyInterface::class, function () {
        return new DependencyClass();
    });

    퍼사드란?

    스태틱함수를 호출하는것처럼 보이겠지만 사실 라라벨의 퍼사드라는 기능을 사용하며 config/app.php의 aliases의 정의를 사용한다

    해당 클래스를 누르면 상세히 사용가능한 메서드 리스트가 보인다

    (서비스 컨테이너에 등록된 객체를 간단하게 사용가능하게함)

    config/app.php의 aliases중..
    
    'App' => App::class,
                'Auth' => Auth::class, // 해당 클래스를 클릭하면 사용가능한 메서드 리스트가 보인다
                'Blade' => Blade::class,
                'Config' => Config::class,
                'Cookie' => Cookie::class,
                'Date' => Date::class,
                'DB' => DB::class,
                'Eloquent' => Model::class,
                'File' => File::class,
                'Http' => Http::class,
                'Request' => Request::class,
                'Response' => Response::class,
                'Route' => Route::class,
                'Session' => Session::class,
                'Storage' => Storage::class,

    서비스 프로바이더란

    주요기능은?

    서비스 컨테이너로의 바인드

    미들웨어, 라우팅등록

    외부 컴포넌트통합

    config/app.php의 providers의 속성에 정의되어있다

    register메서드와 boot메서드가 있다

    모든 프로바이더의 register메서드가 실행된 이후에 boot메서드가 실행된다

    (DatabaseServiceProvider.php을 참조)

    register메소드란?

    서비스 컨테이너에 바인딩하는 부분이 모여있다

    boot메소드란?

    모든 바인드 처리가 완료된 상태이므로 서비스 컨테이너에서 다른 기능을 리졸브가능함

    DeferrableProvider

    register메소드의 실행타이밍이 리졸브될때 실행되기때문에 성능적으로 이점이있다

    CacheServiceProvider.php등에서 사용된다


  1. index.php파일에서는 애플리케이션 인스턴스를 생성합니다. 이는 bootstrap/app.php
    파일의 코드를 실행하여 Illuminate\Foundation\Application 클래스의 인스턴스를 생성합니다.

  2. 애플리케이션 부트스트래핑: 생성된 애플리케이션 인스턴스는 bootstrap/app.php
    파일을 통해 부트스트랩됩니다. 이 단계에서는 설정 파일을 로드하고 필요한 서비스 프로바이더를 등록합니다.

  3. 서비스 프로바이더 등록: 부트스트래핑 과정에서 config/app.php
    파일을 로드하고, 해당 파일의 providers배열에 등록된 서비스 프로바이더(라우팅관련 서비스 프로바이더 포함)들이 애플리케이션에 등록됩니다.

  4. 라우팅: 애플리케이션은 들어온 요청의 URL을 기반으로 라우팅(Route)을 수행합니다. 이 단계에서는 등록된 라우트 파일들을 확인하고, 요청과 매칭되는 라우트를 찾습니다.

  5. 미들웨어 처리: 매칭된 라우트에 정의된 미들웨어들이 실행됩니다. 미들웨어는 요청과 응답 사이에서 동작하는 중간 처리기로, 요청 전처리, 인증, 권한 부여 등 다양한 작업을 수행할 수 있습니다.

  6. 요청 처리: 매칭된 라우트에 대한 처리를 담당하는 컨트롤러(Controller)가 호출됩니다. 컨트롤러는 요청을 처리하고, 데이터를 가져와 비즈니스 로직을 실행합니다.

  7. 응답 생성: 컨트롤러에서 처리한 결과를 기반으로 응답(Response)을 생성합니다. 이 단계에서는 HTML, JSON, 파일 다운로드 등 다양한 응답 형식을 처리할 수 있습니다.

  8. 응답 전송: 생성된 응답은 클라이언트로 전송되어 최종 사용자에게 반환됩니다.

평소 내가 사용하는 __contruct에 의존성 주입이 어떻게 되는가 설명

https://laravel.kr/docs/9.x/container#%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%97%90%20%EA%B5%AC%ED%98%84%EA%B0%9D%EC%B2%B4%20%EB%B0%94%EC%9D%B8%EB%94%A9%ED%95%98%EA%B8%B0

0708추가

서비스컨테이너 -> 서비스프로바이더 boot/register -> 객체생성및주입 bind/resolve


참조:

https://stackhoarder.com/2019/08/04/laravel-%ea%b8%b0%ec%b4%88-3-request-lifecycle/

https://laravel.kr/docs/9.x/lifecycle

https://phppot.com/php/php-laravel-project-example/

https://medium.com/@ankitatejani84/laravel-request-lifecycle-7c2145aa1257

Jun 4, 2023 Views 206