IT/PHP

Laravel - 컨트롤러 줄이기

Sungjun_ 2021. 4. 14. 00:21

라라벨을 공부하다 보니 게시판 하나당 컨트롤러를 하나씩 만들고 있는 제 모습을 발견했습니다.

그래서 컨트롤러 수를 줄이는 방법이 없을까 생각을 해보다가, phpinfo()를 활용한 방법이 생각났습니다.

 

예를 들어, Mbti 게시판이 있고 그 안에는 16가지의 Mbti 종류 별로 게시판이 있다고 가정을 해봅시다.

게시판 하나당 컨트롤러 하나를 만들면 16개의 컨트롤러를 더 만들어야 합니다.

 

view

mbti 안에 enfp와 infp 두 개를 만들고 진행하겠습니다.

 

MbtiController를 만들고 index 메서드를 다음과 같이 해줍니다.

public function index()
{
    phpinfo();
}

 

그러면 phpinfo 화면을 볼 수 있는데, 거기서 PHP Variables 쪽을 보시면 여러 변수들이 있는 것을 확인할 수 있습니다.

 

그중에서 $_SERVER['REQUEST_URI'] 변수를 확인해보면 아래와 같이 나옵니다.

URI

이제 저걸 이용해서 하나의 컨트롤러로 각 게시판들을 CRUD 할 수 있습니다.

 

일반적으로 enfp만을 위한 컨트롤러라면

index view를 위한 index 메소드는

public function index()
{
    return view('mbti.enfp.index');
}

 

위처럼 뷰를 리턴해주는 것이 맞습니다.

$_SERVER['REQUEST_URI'] 변수 안에 있는 enfp를 가지고 와서 다른 변수로 저장해 view() 안에 넣어주겠습니다.

 

dd($_SERVER['REQUEST_URI']); 

이용해서 값을 확인해보면 "/mbti/enfp"가 제대로 넘어는 것을 알 수 있습니다.

이제 저기서 enfp만을 가지고 와야 하기 때문에 explode()를 사용하겠습니다.

public function index()
{
      $temp = explode('/', $_SERVER['REQUEST_URI']);
      dd($temp);
      return view('mbti.enfp.index');
}

$temp

explode한 값을 temp 저장하고 확인해보면 $temp[2]에 enfp가 저장되는 것을 확인할 수 있습니다.

 

public function index()
{
     $temp = explode('/', $_SERVER['REQUEST_URI']);
     $mbtiName = $temp[2];
     return view('mbti.'.$mbtiName.'.index');
}

 

$mbtiName에 $temp[2]를 저장시키고 사용하면 제대로 작동하는 것을 확인할 수 있습니다.

infp 게시판을 불러올 때 사용해보시면 정상 작동하는 것을 확인할 수 있습니다.

 

라우트 설정은 아래처럼 했습니다.

Route::get('/', function () {
    return view('home');
})->name('home');


Route::prefix('mbti')->group(function() {
    Route::prefix('enfp')->group(function () {
        Route::get('/', [MbtiController::class, 'index'])->name('mbti.enfp.index');
        Route::get('/create', [MbtiController::class, 'create'])->name('mbti.enfp.create');
    });
    Route::prefix('infp')->group(function () {
        Route::get('/', [MbtiController::class, 'index'])->name('mbti.infp.index');
        Route::get('/create', [MbtiController::class, 'create'])->name('mbti.infp.create');
    });
});

 

 

하지만 저렇게 했을 때 발생하는 문제가 있었습니다.

 

public function mbtiName(): string
{
     $temp = explode('/', $_SERVER['REQUEST_URI']);
     return $temp[2];
}

public function index()
{
     $mbtiName = $this->mbtiName();
     $mbtis = Mbti::where('mbtiName', $mbtiName)->orderBy('id', 'desc')->paginate(5);
     return view('mbti.'.$mbtiName.'.index', compact('mbtis'));
}

 

일단 mbti 이름을 가지고 오는 부분을 따로 메서드로 만들어서 빼두었습니다.

 

발생한 문제는 페이지네이션을 사용했을 때입니다.

 

infp 게시판

 

현재 infp 게시판은 위와 같이 구성되어있습니다. 코드는 따로 적지 않겠습니다.

발생하는 문제는 페이지를 이동했을 때입니다.

 

에러

이렇게 에러가 발생합니다.

문제가 발생한 이유는 explode를 사용할 때 '/'를 구분자로 사용해서

$temp[2]에 infp?page=2 이런 식으로 저장이 되어 제대로 화면을 불러오지 못하게 됐기 때문입니다.

그래서 사용한 게 정규표현식입니다.

 

public function mbtiName(): string
{
      $temp = explode('/', $_SERVER['REQUEST_URI']);
      $name = preg_replace('/\?[a-z=&A-Z0-9]*/', '', $temp[2]);
      return $name;
}

 

preg_replace() 메서드를 사용해서 mbti 이름 뒤로는 다 삭제시켜주었습니다.

 

regexr.com/

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

저는 정규표현식이 아직 익숙하지 않아서 위에서 먼저 테스트를 하고 사용했습니다.

 

mbtiName() 메서드를 위처럼 바꾸고 다시 실행해보면

페이지를 이동해도 에러 없이 사용 가능한 것을 확인할 수 있습니다.

 

page=2

 

 

 

 

 

더 좋은 방법이 있겠지만 지금 제가 생각할 수 있는 방법으로는 이게 최고네요 ㅠㅠ

좋은 방법이 있다면 댓글로 알려주세요.