Owen Labs

[PHP | Laravel] Laravel Framework를 이용한 MVC 패턴 구현 - 2. 프로젝트 구조를 살펴보자.(Kernel, Handler) 본문

개발/PHP

[PHP | Laravel] Laravel Framework를 이용한 MVC 패턴 구현 - 2. 프로젝트 구조를 살펴보자.(Kernel, Handler)

parkjg20 2021. 8. 18. 20:43

 

이전 게시글

 

[PHP | Laravel] Laravel Framework를 이용한 MVC 패턴 구현 - 1. 개발환경 구성

이직하는 업체에서 PHP를 익혀오면 좋을 것 같다고 요청해서 간단하게라도 실습을 진행해 보려고 한다. 본인도 알아보면서 진행하고 있어서 본문은 계속 수정될 수 있다. 혹시라도 잘못된 정보

dev-err.tistory.com

이전 포스트에서는 PHP/Laravel 개발환경을 구축하고 프로젝트를 생성하는 부분까지 진행했다.

 

이번에는 생성된 프로젝트의 구조를 파악하고 라라벨 앱을 실행해보려고 한다.

 

라라벨을 처음부터 공부하는 사람이 작성하는 포스트입니다. 잘못된 내용은 댓글로 남겨주시면 수정하도록 하겠습니다.

 


1. 프로젝트 구조

먼저 터미널을 이용해 생성된 라라벨 프로젝트 디렉토리에 접근해보았다.

 

CMD에서 본 프로젝트 구조

 

위와 같은 구조로 생성되었는데 각 파일별로 무슨 역할을 하는지 조사해보았다.

이후로는 편의상 VSCODE에서 프로젝트 구조를 파악해보겠다.

 


APP 디렉토리

app 디렉토리에는 웹앱의 소스코드가 저장됨

 

디렉토리 내 구조는 위와 같고 각 파일에 대해 하나하나 파악해보려고 한다.

 

일단은 PHP에 대한 사전 지식이 없는 상태에서 파악하는 것이니 보자마자 든 내 생각이나 조금 조사해 본 결과에 대해서 작성해보겠다.


Console/Kernel.php

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

가장 먼저 보이는 파일은 Console/kernel.php이다. 알아본 바로 해당 파일의 역할은 다음과 같다.

  1. CLI에서 발생한 앱과의 상호작용 등을 처리
  2. artisan, scheduled job, queued job을 처리할 때 커널을 통과함

여기서 말하는 scheduled job은 schedule 메소드의 내부에 작성한 동작들을 의미하는 것 같다. 아직 실행 전이지만 대충 첫인상은 functional 하게 되어있는 것 같아서 깔끔하다고 느꼈다.

daily, monthly 등으로 응용할 수 있어 보이고, 직관적인 것 같아서 마음에 들었다.

 

commands 함수는 routes/console.php 파일에서 정의한 CLI 명령을 application에 등록해주는 동작인 것으로 보이는데, 이 routes/console.php는 다른 포스트에서 다뤄보겠다.

 


Http/Kernel

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}

다음은 Http/Kernel.php 파일이다.

해당 파일은 웹(HTTP)를 통해 들어오는 요청(웹 사이트 요청, AJAX 등)을 처리하는 역할을 수행한다고 한다는데 이 곳에서는 미들웨어만 지정하고 있는 것 같다.

 

여기서 미들웨어는 에러 처리, 로그 설정, 애플리케이션 동작 환경의 감지 등 실제로 요청이 처리되기 전에 수행해야 되는 작업들이라고 이해할 수 있다. Spring Boot식으로 말하면 Filter정도로 이해할 수 있을 것 같다.

 

먼저 $middleware와 $middlewareGroups, $routeMiddleware라는 Array Type 변수가 선언/초기화 되어있다. 

설명에 따르면

 

$middleware

: 전역 http middleware 스택, 매 요청마다 해당 미들웨어들이 실행된다.

ex) /home, /api/user, /var, /etc 등에 대해 모두 실행

 

$middlewareGroups

: route middleware 그룹이다. route마다 실행할 미들웨어를 지정한다.

ex) /home, /var, /etc -> 실행 안됨

    /api/user, /api/post, /api/* -> 실행

 

$routeMiddleware

: routeMiddleware다. 개별 route에 대해 실행할 미들웨어를 지정한다.

ex) /home, /var, /etc, /api/post -> 실행 안 됨

     /api/user -> 실행 됨

 

다시 한 번 풀어서 설명하자만 middleware에는 모든 요청에 대해 실행할 미들웨어를 지정하는 것이고, middlewareGroups에는 routes 그룹에 대해 실행할 미들웨어를 지정한다. 마지막으로 routeMiddleware는 지정한 하나의 route에서만 작동하는 미들웨어를 지정하는 것이다.

 

이 미들웨어들은 HTTP 세션을 읽고/쓰고, 애플리케이션이 유지 관리 모드인지 확인하고, CSRF 토큰을 확인 하는 작업들을 처리한다.

 


Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }
}

이곳은 이름에서부터 알 수 있듯이 예외 처리에 관한 설정 파일인 것 같다.

 

주석에 따르면 배열 $dontReport에는 무시할 예외들을 지정할 수 있는 것 같고, $dontFlash는 지정된 exception(주로 validation에 관한 예외)이 발생했을 때 페이지를 새로고침 하지 말라는 의미인 것 같다. 

 

register 함수에서는 각 예외마다 callback handler를 지정하는 것으로 보인다.

 

역시나 자세한 내용은 사용해보면서 추가해보겠다.