시작하며
Laravel 13은 2026년 3월에 릴리스되었습니다. 이 가이드에서는 Laravel 12.x에서 13.x로의 업그레이드 절차를 설명합니다.업그레이드에 필요한 예상 시간은 약 10분입니다. 다만 파괴적 변경이 애플리케이션에 미치는 영향은 규모나 사용하고 있는 기능에 따라 다릅니다.
AI를 사용한 업그레이드
Laravel Boost를 사용하여 업그레이드를 자동화할 수도 있습니다. Boost는 퍼스트파티 MCP 서버로, AI 어시스턴트에 단계적인 업그레이드 프롬프트를 제공합니다. Laravel 12 애플리케이션에 설치한 후, Claude Code, Cursor, OpenCode, Gemini, VS Code에서/upgrade-laravel-v13 슬래시 명령을 사용하여 Laravel 13으로의 업그레이드를 시작할 수 있습니다. 이 명령에는 laravel/boost ^2.0이 필요합니다.
슬래시 명령을 사용할 수 없는 AI 도구에서도 프롬프트 파일을 직접 참조함으로써 같은 업그레이드 절차를 실행할 수 있습니다. 아래의 프롬프트를 그대로 AI에 붙여 넣어 주세요.
프롬프트
영향도별 변경점
영향도: 높음
- 의존관계 갱신
- Laravel 인스톨러 갱신
- 요청 위조 방지 (CSRF)
영향도: 중간
- 캐시
serializable_classes설정 - 세션
serialization설정
영향도: 낮음
- 캐시 프리픽스와 세션 쿠키 이름
- 컬렉션 모델 시리얼라이제이션
Container::call과 Nullable 클래스 기본값- 도메인 라우트 등록의 우선순위
JobAttempted이벤트의 예외 페이로드- Manager
extend콜백의 바인딩 - MySQL
DELETE쿼리 (JOIN / ORDER BY / LIMIT) - 페이지네이션 Bootstrap 뷰 이름
- 폴리모픽 피벗 테이블 이름의 생성
QueueBusy이벤트의 프로퍼티 이름 변경Str팩토리의 테스트 간 리셋
업그레이드 절차
의존관계 갱신
영향도: 높음composer.json의 이하 의존관계를 갱신해 주세요.
Laravel 인스톨러 갱신
영향도: 높음 Laravel 인스톨러 CLI를 사용하여 새 Laravel 애플리케이션을 만드는 경우, Laravel 13.x 대응 버전으로 갱신해 주세요.composer global require로 설치한 경우:
파괴적 변경 (Breaking Changes)
보안
요청 위조 방지
영향도: 높음 Laravel의 CSRF 미들웨어가VerifyCsrfToken에서 PreventRequestForgery로 리네임되었습니다. 또한 Sec-Fetch-Site 헤더를 이용한 요청 발신처의 검증이 추가되었습니다.
VerifyCsrfToken과 ValidateCsrfToken은 비권장 별칭으로 남아 있지만, 직접 참조하고 있는 부분은 모두 PreventRequestForgery로 갱신할 필요가 있습니다. 특히 테스트나 라우트 정의에서 미들웨어를 제외하고 있는 경우에는 주의가 필요합니다.
preventRequestForgery(...)가 사용 가능해졌습니다.
캐시
캐시 프리픽스와 세션 쿠키 이름
영향도: 낮음 Laravel의 기본 캐시 및 Redis 키 프리픽스가 하이픈 구분의 서픽스를 사용하도록 되었습니다. 또한 기본 세션 쿠키 이름이Str::snake(...)를 사용하도록 되었습니다.
많은 애플리케이션에서는 설정 파일에서 명시적으로 값을 설정하고 있으므로, 이 변경의 영향을 받지 않습니다. 프레임워크의 폴백 설정에 의존하고 있는 애플리케이션만 영향을 받습니다.
.env 파일에서 명시적으로 설정해 주세요.
캐시 serializable_classes 설정
영향도: 중간
기본 cache 설정에 serializable_classes 옵션이 추가되었으며, 기본은 false가 되었습니다. 이로 인해 APP_KEY가 유출된 경우의 PHP 디시리얼라이제이션 가젯 체인 공격을 방지합니다.
애플리케이션이 의도적으로 캐시에 PHP 오브젝트를 저장하고 있는 경우, 디시리얼라이즈를 허가할 클래스를 명시적으로 리스트업할 필요가 있습니다.
세션 serialization 설정
영향도: 중간
Laravel 13의 스켈레톤(laravel/laravel)의 config/session.php에 'serialization' => 'json'이 추가되어 있습니다. 다만, 프레임워크 내부의 기본은 php 그대로입니다.
공식 업그레이드 가이드에는 이 설정의 변경이 기재되어 있지 않습니다. 이것은 변경하지 않아도 된다는 의도로 생각됩니다. Laravel에서는 하나 이전 버전에서의 업그레이드에서는 영향이 없으므로 업그레이드 가이드에 기재되지 않는 변경이 때때로 있습니다. 몇 년 후에 업그레이드하려고 했을 때 정보가 없어 곤란해지므로 비공식적인 기록이 중요합니다.
Laravel 12까지와 같은 동작을 유지하려면, 'serialization' => 'php'를 명시적으로 설정해 주세요.
컨테이너
Container::call과 Nullable 클래스 기본값
영향도: 낮음
Container::call이, 바인딩이 존재하지 않는 경우에 nullable 클래스 파라미터의 기본값을 존중하도록 되었습니다 (Laravel 12에서 생성자 인젝션에 도입된 동작과 일치합니다).
데이터베이스
MySQL DELETE 쿼리
영향도: 낮음
Laravel이 MySQL 문법에서 ORDER BY와 LIMIT을 포함하는 완전한 DELETE ... JOIN 쿼리를 컴파일하도록 되었습니다.
이전 버전에서는 JOIN을 동반하는 DELETE에서 ORDER BY / LIMIT 절이 무시되는 경우가 있었습니다. Laravel 13에서는 이 절들이 생성되는 SQL에 포함됩니다. 그 결과, 이 구문을 지원하지 않는 일부 데이터베이스 엔진에서 QueryException이 발생할 가능성이 있습니다.
Eloquent
폴리모픽 피벗 테이블 이름의 생성
영향도: 낮음 커스텀 피벗 모델 클래스를 사용하는 폴리모픽 피벗 모델의 테이블 이름이 추측될 때, Laravel이 복수형 이름을 생성하도록 되었습니다. 이전의 단수형 추측 이름에 의존하고 있었던 경우에는 피벗 모델에서 테이블 이름을 명시적으로 정의해 주세요.컬렉션 모델 시리얼라이제이션
영향도: 낮음 Eloquent 모델 컬렉션이 시리얼라이즈 및 리스토어(큐 투입된 잡 등)될 때, Eager 로드된 릴레이션이 모델을 위해 복원되도록 되었습니다. 디시리얼라이제이션 후에 릴레이션이 존재하지 않는 것에 의존하고 있었던 코드가 있는 경우에는 수정이 필요합니다.큐
JobAttempted 이벤트의 예외 페이로드
영향도: 낮음
Illuminate\Queue\Events\JobAttempted 이벤트가 이전의 boolean인 $exceptionOccurred 프로퍼티 대신에, 예외 오브젝트(또는 null)를 $exception으로 공개하도록 되었습니다.
QueueBusy 이벤트의 프로퍼티 이름 변경
영향도: 낮음
Illuminate\Queue\Events\QueueBusy 이벤트의 프로퍼티 $connection이, 다른 큐 이벤트와의 일관성을 위해 $connectionName으로 리네임되었습니다.
라우팅
도메인 라우트 등록의 우선순위
영향도: 낮음 명시적인 도메인을 가지는 라우트가 라우트 매칭에서 비도메인 라우트보다 우선되도록 되었습니다. 이로 인해 캐치올 서브도메인 라우트가, 비도메인 라우트가 먼저 등록되어 있는 경우에도 일관되게 동작하도록 됩니다.서포트
Manager extend 콜백의 바인딩
영향도: 낮음
Manager의 extend 메서드로 등록된 커스텀 드라이버의 클로저가, 매니저 인스턴스에 바인딩되도록 되었습니다.
이전에는 이 콜백들 내에서 별도의 오브젝트(서비스 프로바이더 인스턴스 등)가 $this로서 참조되고 있었던 경우, use (...)로 값을 클로저 캡처에 이동시켜야 합니다.
Str 팩토리의 테스트 간 리셋
영향도: 낮음
Laravel이 테스트의 티어다운 시에 커스텀 Str 팩토리를 리셋하도록 되었습니다.
커스텀 UUID / ULID / 랜덤 문자열 팩토리가 테스트 메서드 간에 지속되는 것에 의존하고 있었던 경우에는, 관련된 각 테스트 또는 셋업 훅에서 설정하도록 해 주세요.
뷰
페이지네이션 Bootstrap 뷰 이름
영향도: 낮음 Bootstrap 3 기본의 내부 페이지네이션 뷰 이름이 명시적으로 되었습니다.비권장이 된 기능
| 기능 | 대체 수단 |
|---|---|
VerifyCsrfToken 미들웨어 | PreventRequestForgery |
ValidateCsrfToken 미들웨어 | PreventRequestForgery |
JobAttempted::$exceptionOccurred | JobAttempted::$exception |
QueueBusy::$connection | QueueBusy::$connectionName |
컨트랙트 추가
영향도: 매우 낮음 커스텀 구현을 가지는 경우에만 영향이 있습니다.Dispatcher 컨트랙트
Illuminate\Contracts\Bus\Dispatcher 컨트랙트에 dispatchAfterResponse($command, $handler = null) 메서드가 추가되었습니다.
ResponseFactory 컨트랙트
Illuminate\Contracts\Routing\ResponseFactory 컨트랙트에 eventStream 시그니처가 추가되었습니다.
MustVerifyEmail 컨트랙트
Illuminate\Contracts\Auth\MustVerifyEmail 컨트랙트에 markEmailAsUnverified()가 추가되었습니다.
Queue 컨트랙트
Illuminate\Contracts\Queue\Queue 컨트랙트에 이하의 큐 크기 검사 메서드가 추가되었습니다 (이전에는 docblock에서만 선언되어 있었습니다).
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
Store / Repository 컨트랙트
캐시 컨트랙트에 TTL 연장을 위한 touch 메서드가 추가되었습니다.
새 기능의 하이라이트
AI 어시스트 업그레이드 (Laravel Boost)
Laravel Boost는 공식 MCP 서버입니다. AI 에디터와 연동하여/upgrade-laravel-v13 명령으로 업그레이드를 반자동화할 수 있습니다.
Sec-Fetch-Site 헤더에 의한 요청 발신처 검증
PreventRequestForgery 미들웨어가 Sec-Fetch-Site 헤더를 이용한 추가 오리진 검증을 수행합니다. 이로 인해 CSRF 보호가 강화되어 있습니다.
캐시의 안전한 디시리얼라이제이션
serializable_classes 설정에 의해, 허가된 클래스만이 디시리얼라이즈되도록 되었습니다. PHP 디시리얼라이제이션 공격에 대한 보안이 향상되어 있습니다.
SSE (Server-Sent Events)의 eventStream
ResponseFactory 컨트랙트에 eventStream이 추가되어, Server-Sent Events 지원이 개선되었습니다.
큐 가시성의 향상
Queue 컨트랙트의 pendingSize, delayedSize, reservedSize 등의 메서드에 의해, 큐의 상태를 보다 세밀하게 모니터링할 수 있게 되었습니다.
자주 있는 마이그레이션 시의 문제와 해결책
문제: CSRF 관련 테스트가 실패한다
증상:VerifyCsrfToken을 참조하고 있는 테스트가 클래스가 발견되지 않는 오류로 실패한다.
해결책: 모든 참조를 PreventRequestForgery로 갱신해 주세요.
문제: 캐시에서 오브젝트를 복원할 수 없다
증상: 캐시에서 취득한 데이터가null이 되거나, UnserializationFailedException이 발생한다.
해결책: config/cache.php에서 serializable_classes에 사용할 클래스를 추가하거나, 캐시하는 값을 배열로 변환해 주세요.
문제: JobAttempted 리스너가 기능하지 않는다
증상: $event->exceptionOccurred가 null이나 미정의 오류가 된다.
해결책: $event->exception !== null로 변경해 주세요.
문제: 세션이 무효화된다
증상: 업그레이드 후에 사용자가 로그아웃된다. 해결책: 기본 세션 쿠키 이름이 변경되어 있습니다..env에서 SESSION_COOKIE를 명시적으로 설정하여 이전 값을 유지해 주세요.
문제: 캐시 키가 발견되지 않는다
증상: 업그레이드 후에 캐시 미스가 증가한다. 해결책: 캐시 프리픽스가 변경되어 있습니다..env에서 CACHE_PREFIX를 설정하거나, 캐시를 클리어해 주세요.
참고 자료
- 공식 업그레이드 가이드 (영어)
- laravel/laravel 리포지토리의 차분 (12.x → 13.x)
- Laravel Shift — 업그레이드를 자동화하는 커뮤니티 서비스
- Laravel Boost — AI 어시스트 업그레이드용 MCP 서버