피드로 돌아가기
Episode 2: I Was a Junior Developer and I Must Be Stopped
Dev.toDev.to
Backend

N+1 쿼리 6회, 랜덤 방 번호,幽灵 롤백 코드 포함된 PHP 청구서 생성기가 시니어 리뷰로 개선됨

Episode 2: I Was a Junior Developer and I Must Be Stopped

Adam - The Developer2026년 4월 2일18beginner

Context

Laravel 기반 호텔 청구서 생성 PHP 클래스에서 Excel 파일을 임포트하고 각 게스트별 청구서를 생성하여 zip으로 패키징하는 기능이 구현됨. 단일 PR에서 N+1 쿼리 문제, 필요 없는 코드, 그리고 실제 데이터 활용 실패가 동시에 발생함.

Technical Solution

  • N+1 Query 해결: $config->where('id', 1)->pluck(...) 패턴이 루프 내부에서 반복 호출됨. 루프 외부에서 단일 쿼리로 설정 값을 미리 가져와야 함
  • 사용하지 않는 변수 제거: $this->export() 호출 전 이미 Excel::import()로 데이터가 저장되었으므로 $filedata 파라미터 의존성이 불분명함
  • 하드코딩 값 대체: rand(1, 19)로 생성된 방 번호 대신 실제 게스트 데이터의 방 번호를 사용해야 함
  • Phantom Rollback 제거: try 블록 내에 DB::rollBack()이 존재하지만 실제 transaction이 시작된 적이 없음
  • 파일 존재 여부 로직 개선: file_exists() 조건이 있어도 항상 기본 파일 경로로 덮어씌워지는 구조적 결함이 존재함

다중 레코드 처리 로직에서 쿼리가 루프 내부에 위치할 때 루프 외부로 이동하여 Eloquent Collection 메서드를 활용할 것. PHPLeague PHPSpreadsheet 사용 시 설정 값은 별도 쿼리로 한 번만 가져온 뒤 배열 또는 객체로 관리하는 것이 성능과 가독성 모두에 유리함.

원문 읽기