업그레이드 가이드
업데이트됨번역일: 2026년 8월 12일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 8월 12일
- 번역 갱신
- 2026년 8월 12일
업그레이드 가이드
영향도 높음
영향도 중간
영향도 낮음
- 캐시 접두사 및 세션 쿠키 이름
- 컬렉션 모델 직렬화 시 즉시 로드 관계 복원
Container::call과 nullable 클래스 기본값- 도메인 라우트 등록 우선순위
JobAttempted이벤트 예외 페이로드- Manager
extend콜백 바인딩 - MySQL
DELETE쿼리와JOIN,ORDER BY,LIMIT - 페이지네이션 Bootstrap 뷰 이름
- 다형성 피벗 테이블 이름 생성
QueueBusy이벤트 속성 이름 변경- 세션
serialization설정 - 테스트 간
Str팩토리 초기화
12.x에서 13.0으로 업그레이드
예상 소요 시간: 약 10분
NOTE
호환성을 깨는 변경 사항을 최대한 문서화하고 있으나, 일부 변경은 프레임워크의 특수한 영역에만 해당되므로 실제로 영향을 받는 항목은 일부에 그칠 수 있습니다. 업그레이드 자동화 도구인 Shift를 활용하면 시간을 절약할 수 있습니다.
AI를 활용한 업그레이드
Laravel Boost를 사용하면 업그레이드를 자동화할 수 있습니다. Boost는 Laravel 공식 MCP 서버로, AI 어시스턴트에게 업그레이드에 필요한 안내 프롬프트를 제공합니다. Laravel 12 애플리케이션에 설치한 뒤, Claude Code, Cursor, OpenCode, Gemini, VS Code 등에서 /upgrade-laravel-v13 슬래시 명령을 실행하면 Laravel 13 업그레이드가 시작됩니다. 이 명령을 사용하려면 Laravel Boost ^2.0이 필요합니다.
의존성 업데이트
영향도: 높음
composer.json 파일에서 아래 패키지 버전을 업데이트하세요.
laravel/framework를^13.0으로laravel/boost를^2.0으로laravel/tinker를^3.0으로phpunit/phpunit를^12.0으로pestphp/pest를^4.0으로
Laravel 인스톨러 업데이트
Laravel CLI 인스톨러를 사용해 새 프로젝트를 생성하는 경우, Laravel 13.x와의 호환성을 위해 인스톨러를 업데이트해야 합니다.
composer global require로 설치한 경우 다음 명령으로 업데이트할 수 있습니다.
composer global update laravel/installerLaravel Herd에 내장된 인스톨러를 사용하고 있다면, Herd 자체를 최신 버전으로 업데이트하면 됩니다.
캐시
캐시 접두사 및 세션 쿠키 이름
영향도: 낮음
Laravel의 기본 캐시 및 Redis 키 접두사가 이제 언더스코어(_) 대신 하이픈(-)을 구분자로 사용합니다.
대부분의 애플리케이션은 config/cache.php 등의 설정 파일에서 이 값을 직접 정의하므로 영향을 받지 않습니다. 다만, 애플리케이션 레벨 설정 없이 프레임워크 기본값에 의존하는 경우 업그레이드 후 캐시 키와 세션 쿠키 이름이 변경될 수 있습니다.
// Laravel <= 12.x
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_cache_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_database_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_session';
// Laravel >= 13.x
Str::slug((string) env('APP_NAME', 'laravel')).'-cache-';
Str::slug((string) env('APP_NAME', 'laravel')).'-database-';
Str::slug((string) env('APP_NAME', 'laravel')).'-session';이전 동작을 유지하려면 .env 파일에서 CACHE_PREFIX, REDIS_PREFIX, SESSION_COOKIE를 명시적으로 설정하세요.
`Store` 및 `Repository` 컨트랙트: `touch`
영향도: 매우 낮음
캐시 컨트랙트에 항목의 TTL을 연장하는 touch 메서드가 추가되었습니다. 커스텀 캐시 스토어 구현체를 관리하고 있다면 이 메서드를 추가해야 합니다.
// Illuminate\Contracts\Cache\Store
public function touch($key, $seconds);캐시 `serializable_classes` 설정
영향도: 중간
기본 cache 설정에 serializable_classes 옵션이 추가되었으며 기본값은 false입니다. 이는 APP_KEY가 유출된 경우 PHP 역직렬화 가젯 체인 공격을 방지하기 위한 보안 강화 조치입니다.
캐시에 PHP 객체를 저장해야 한다면, 역직렬화를 허용할 클래스를 명시적으로 나열해야 합니다.
'serializable_classes' => [
App\Data\CachedDashboardStats::class,
App\Support\CachedPricingSnapshot::class,
],기존에 임의의 PHP 객체를 캐시에 저장하고 있었다면, 해당 코드를 명시적 허용 목록 방식으로 전환하거나 배열 등 객체가 아닌 형태의 페이로드를 사용하도록 마이그레이션해야 합니다.
컨테이너
`Container::call`과 nullable 클래스 기본값
영향도: 낮음
Container::call이 이제 바인딩이 없는 경우 nullable 클래스 파라미터 기본값을 존중하도록 변경되었습니다. 이는 Laravel 12에서 생성자 주입에 도입된 동작과 일치하는 것입니다.
$container->call(function (?Carbon $date = null) {
return $date;
});
// Laravel <= 12.x: Carbon 인스턴스 반환
// Laravel >= 13.x: null 반환메서드 호출 주입 로직이 이전 동작에 의존하고 있었다면 코드를 수정해야 합니다.
컨트랙트
`Dispatcher` 컨트랙트: `dispatchAfterResponse`
영향도: 매우 낮음
Illuminate\Contracts\Bus\Dispatcher 컨트랙트에 dispatchAfterResponse($command, $handler = null) 메서드가 추가되었습니다. 커스텀 디스패처 구현체를 관리하고 있다면 이 메서드를 추가하세요.
`ResponseFactory` 컨트랙트: `eventStream`
영향도: 매우 낮음
Illuminate\Contracts\Routing\ResponseFactory 컨트랙트에 eventStream 메서드 시그니처가 추가되었습니다. 이 컨트랙트를 커스텀으로 구현하고 있다면 해당 메서드를 추가하세요.
`MustVerifyEmail` 컨트랙트: `markEmailAsUnverified`
영향도: 매우 낮음
Illuminate\Contracts\Auth\MustVerifyEmail 컨트랙트에 markEmailAsUnverified() 메서드가 추가되었습니다. 이 컨트랙트의 커스텀 구현체를 사용하는 경우 해당 메서드를 추가하세요.
데이터베이스
MySQL/MariaDB에서 데이터베이스 `upsert`
영향도: 중간
이제 upsert 호출 시 uniqueBy에 비어 있지 않은 값이 반드시 전달되어야 합니다. 빈 값을 전달하면 유효하지 않은 SQL을 생성하는 대신 InvalidArgumentException이 발생합니다.
MariaDB와 MySQL 드라이버는 uniqueBy 값을 실제로 사용하지 않고 테이블의 기본 키 및 유니크 인덱스를 기준으로 중복을 감지하지만, 유효성 검사는 동일하게 적용됩니다. uniqueBy가 비어 있으면 예외가 발생합니다.
MySQL `DELETE` 쿼리와 `JOIN`, `ORDER BY`, `LIMIT`
영향도: 낮음
MySQL 문법에서 DELETE ... JOIN 쿼리를 컴파일할 때 ORDER BY 및 LIMIT 절이 이제 포함됩니다.
이전 버전에서는 조인이 포함된 삭제 쿼리에서 ORDER BY/LIMIT 절이 조용히 무시될 수 있었습니다. Laravel 13부터는 이 절이 생성된 SQL에 포함되므로, 해당 구문을 지원하지 않는 데이터베이스 환경에서는 무제한 삭제가 실행되는 대신 QueryException이 발생할 수 있습니다.
Eloquent
모델 부팅 중 중첩 인스턴스 생성
영향도: 매우 낮음
모델이 부팅 중인 상태에서 동일 모델의 새 인스턴스를 생성하는 것이 이제 금지되며, LogicException이 발생합니다.
이는 모델의 boot 메서드나 트레이트의 boot* 메서드 내부에서 모델을 인스턴스화하는 코드에 영향을 줍니다.
protected static function boot()
{
parent::boot();
// 부팅 중에는 더 이상 허용되지 않음
(new static())->getTable();
}이런 로직은 부팅 사이클 외부로 이동하세요.
다형성 피벗 테이블 이름 생성
영향도: 낮음
커스텀 피벗 모델 클래스를 사용하는 다형성 피벗 모델의 테이블 이름을 자동 추론할 때, 이제 복수형 이름이 생성됩니다.
이전의 단수형 추론 이름에 의존하고 있었다면, 피벗 모델에 테이블 이름을 명시적으로 정의하세요.
컬렉션 모델 직렬화 시 즉시 로드 관계 복원
영향도: 낮음
Eloquent 모델 컬렉션을 직렬화하고 복원할 때(예: 큐 Job), 이제 즉시 로드된 관계도 함께 복원됩니다.
역직렬화 후 관계가 없는 상태를 가정하는 코드가 있다면 해당 로직을 점검하세요.
HTTP 클라이언트
HTTP 클라이언트 `Response::throw` 및 `throwIf` 시그니처
영향도: 매우 낮음
HTTP 클라이언트 응답 메서드의 콜백 파라미터가 이제 메서드 시그니처에 명시적으로 선언됩니다.
public function throw($callback = null);
public function throwIf($condition, $callback = null);이 메서드들을 커스텀 응답 클래스에서 오버라이드하고 있다면, 시그니처 호환성을 확인하세요.
알림 (Notification)
기본 비밀번호 재설정 메일 제목
영향도: 매우 낮음
Laravel의 기본 비밀번호 재설정 메일 제목이 변경되었습니다.
// Laravel <= 12.x
Reset Password Notification
// Laravel >= 13.x
Reset your password테스트, 어설션, 또는 번역 오버라이드에서 이전 기본 문자열을 참조하고 있다면 해당 내용을 업데이트하세요.
큐 알림과 누락된 모델
영향도: 매우 낮음
큐에 등록된 알림이 이제 알림 클래스에 정의된 #[DeleteWhenMissingModels] 어트리뷰트 및 $deleteWhenMissingModels 속성을 올바르게 존중합니다.
이전 버전에서는 모델이 누락된 경우에도 큐 알림 Job이 삭제되지 않고 실패하는 경우가 있었습니다.
큐
`JobAttempted` 이벤트 예외 페이로드
영향도: 낮음
Illuminate\Queue\Events\JobAttempted 이벤트에서 이전의 $exceptionOccurred 불리언 속성이 실제 예외 객체(또는 null)를 담는 $exception 속성으로 교체되었습니다.
// Laravel <= 12.x
$event->exceptionOccurred;
// Laravel >= 13.x
$event->exception;이 이벤트를 구독하는 리스너가 있다면 해당 코드를 업데이트하세요.
`QueueBusy` 이벤트 속성 이름 변경
영향도: 낮음
Illuminate\Queue\Events\QueueBusy 이벤트의 $connection 속성이 다른 큐 이벤트와의 일관성을 위해 $connectionName으로 변경되었습니다.
리스너에서 $connection을 참조하고 있다면 $connectionName으로 변경하세요.
`Queue` 컨트랙트 메서드 추가
영향도: 매우 낮음
Illuminate\Contracts\Queue\Queue 컨트랙트에 이전에는 docblock으로만 선언되어 있던 큐 크기 조회 메서드들이 공식 인터페이스로 추가되었습니다.
커스텀 큐 드라이버 구현체를 관리하고 있다면 다음 메서드들을 구현해야 합니다.
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
라우팅
도메인 라우트 등록 우선순위
영향도: 낮음
라우트 매칭 시 명시적인 도메인이 지정된 라우트가 이제 도메인 없는 라우트보다 우선 처리됩니다.
이를 통해 와일드카드 서브도메인 라우트가 비도메인 라우트보다 먼저 등록된 경우에도 일관되게 동작합니다. 도메인 라우트와 비도메인 라우트 간의 이전 등록 순서에 의존하고 있었다면 라우트 매칭 동작을 재검토하세요.
세션
세션 `serialization` 설정
영향도: 낮음
PHP 역직렬화 가젯 체인 공격을 방지하기 위해, Laravel 13 기본 스켈레톤의 config/session.php에서 serialization 옵션의 기본값이 json으로 변경되었습니다.
기존 애플리케이션을 업그레이드하면서 설정 파일을 Laravel 13 스켈레톤과 동기화한다면, 이 값을 php에서 json으로 변경하면 현재 활성화된 모든 사용자 세션이 무효화됩니다.
업그레이드 중 기존 세션을 유지하려면 이 값을 php로 유지하세요. 단, 세션에 PHP 객체를 저장하지 않고 사용자 재인증이 문제가 없는 환경이라면, 보안 강화를 위해 json으로 변경하는 것을 권장합니다.
스케줄링
`withScheduling` 등록 타이밍
영향도: 매우 낮음
ApplicationBuilder::withScheduling()으로 등록된 스케줄이 이제 Schedule이 실제로 resolve될 때까지 지연됩니다.
부트스트랩 과정 중 즉시 스케줄이 등록되는 타이밍에 의존하는 코드가 있다면 해당 로직을 수정해야 합니다.
보안
요청 위조 방지 (CSRF)
영향도: 높음
Laravel의 CSRF 미들웨어가 VerifyCsrfToken에서 PreventRequestForgery로 이름이 변경되었습니다. 또한 Sec-Fetch-Site 헤더를 활용한 요청 출처 검증이 추가되었습니다.
VerifyCsrfToken과 ValidateCsrfToken은 deprecated 별칭으로 남아 있지만, 테스트나 라우트 정의에서 미들웨어를 직접 참조하는 경우 PreventRequestForgery로 업데이트해야 합니다.
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
// Laravel <= 12.x
->withoutMiddleware([VerifyCsrfToken::class]);
// Laravel >= 13.x
->withoutMiddleware([PreventRequestForgery::class]);미들웨어 설정 API도 이제 preventRequestForgery(...)를 제공합니다.
Support
Manager `extend` 콜백 바인딩
영향도: 낮음
Manager의 extend 메서드로 등록된 커스텀 드라이버 클로저가 이제 Manager 인스턴스에 바인딩됩니다.
이전에는 클로저 내부의 $this가 서비스 프로바이더 인스턴스 등 다른 객체를 가리킬 수 있었습니다. 해당 값들은 클로저의 use (...) 캡처를 통해 명시적으로 전달하는 방식으로 변경해야 합니다.
테스트 간 `Str` 팩토리 초기화
영향도: 낮음
Laravel이 이제 테스트 종료 시 커스텀 Str 팩토리를 초기화합니다.
커스텀 UUID / ULID / 랜덤 문자열 팩토리가 테스트 메서드 간에 유지되는 것에 의존하고 있었다면, 각 테스트 또는 setUp 훅에서 팩토리를 설정하도록 변경하세요.
`Js::from`의 기본 유니코드 처리
영향도: 매우 낮음
Illuminate\Support\Js::from이 이제 기본적으로 JSON_UNESCAPED_UNICODE를 사용합니다.
테스트나 프론트엔드 출력 비교에서 이스케이프된 유니코드 시퀀스(예: \u00e8)를 기대하고 있었다면 해당 기대값을 업데이트하세요.
유틸리티
Symfony PHP 8.5 폴리필 및 전역 함수 충돌
영향도: 낮음
Laravel 13은 symfony/polyfill-php85 의존성을 새로 도입합니다. PHP 8.5 미만 환경에서는 이 폴리필이 array_first(), array_last() 등의 전역 함수를 정의합니다(부트스트랩 시점에 이미 정의되어 있지 않은 경우).
이 함수들은 laravel/helpers와 같은 레거시 헬퍼 패키지 또는 동일한 이름의 커스텀 전역 헬퍼와 충돌할 수 있습니다. 예를 들어, 기존의 array_first() 헬퍼는 콜백을 받아 조건에 맞는 첫 번째 요소를 반환했지만, 폴리필 버전은 배열의 첫 번째 요소를 단순 반환합니다.
충돌을 방지하고 PHP 버전에 관계없이 일관된 동작을 보장하려면 Illuminate\Support\Arr 메서드를 사용하세요.
use Illuminate\Support\Arr;
Arr::first($array, function ($value) {
return /* 조건 */;
});뷰
페이지네이션 Bootstrap 뷰 이름
영향도: 낮음
Bootstrap 3 기본 페이지네이션의 내부 뷰 이름이 명시적으로 변경되었습니다.
// Laravel <= 12.x
pagination::default
pagination::simple-default
// Laravel >= 13.x
pagination::bootstrap-3
pagination::simple-bootstrap-3이전 페이지네이션 뷰 이름을 직접 참조하는 코드가 있다면 업데이트하세요.
기타
laravel/laravel GitHub 저장소에서 스켈레톤 변경 사항도 함께 확인해 보세요. 변경 사항 중 일부는 필수는 아니지만, 애플리케이션 파일을 최신 상태로 유지하는 데 도움이 됩니다. 이 업그레이드 가이드에서 다루지 않는 설정 파일이나 주석 변경 등은 GitHub 비교 도구를 통해 확인하고 필요한 항목을 직접 선택해 반영할 수 있습니다.