메인 콘텐츠로 건너뛰기

시작하며

Laravel 12는 2025년 2월에 릴리스되었습니다. 이 가이드에서는 Laravel 11.x에서 12.x로의 업그레이드 절차를 설명합니다.
업그레이드에 필요한 예상 시간은 약 5분입니다. 다만 파괴적 변경이 애플리케이션에 미치는 영향은 규모나 사용하고 있는 기능에 따라 다릅니다.

Laravel Shift를 사용한 자동 업그레이드

Laravel Shift를 사용하여 업그레이드를 자동화할 수도 있습니다. Shift는 애플리케이션의 의존관계나 설정 파일을 자동으로 갱신해 줍니다.

영향도별 변경점

영향도: 높음

  • 의존관계 갱신
  • Laravel 인스톨러의 갱신

영향도: 중간

  • Eloquent HasUuids 트레이트와 UUIDv7

영향도: 낮음

  • Carbon 3
  • Concurrency의 결과 인덱스 매핑
  • 컨테이너의 클래스 의존 해결
  • 이미지 유효성 검증의 SVG 제외
  • 로컬 파일 시스템 디스크의 기본 루트 경로
  • 멀티 스키마의 데이터베이스 인스펙션
  • 중첩된 배열 요청의 병합

업그레이드 절차

의존관계 갱신

영향도: 높음 composer.json의 이하 의존관계를 갱신해 주세요.
{
  "require": {
    "laravel/framework": "^12.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "pestphp/pest": "^3.0"
  }
}
갱신 후, 이하 명령으로 의존관계를 설치합니다.
composer update

Laravel 인스톨러 갱신

영향도: 높음 Laravel 인스톨러 CLI를 사용하여 새 Laravel 애플리케이션을 만들 경우에는, Laravel 12.x 및 새로운 스타터 킷에 대응한 버전으로 갱신해 주세요. composer global require로 설치한 경우:
composer global update laravel/installer
php.new로 설치한 경우에는 OS에 맞춰 재설치 명령을 실행해 주세요.
/bin/bash -c "$(curl -fsSL https://php.new/install/mac/8.4)"
Laravel Herd의 번들 버전을 사용하고 있는 경우에는 Herd 자체를 최신 릴리스로 갱신해 주세요.

새 스타터 킷

Laravel 12에서는 기존의 Breeze나 Jetstream을 대신하는 새로운 스타터 킷이 도입되었습니다. laravel new를 실행하면 프론트엔드 스택을 대화식으로 선택할 수 있습니다. 이용 가능한 스타터 킷:
  • React — Inertia 2, React 19, TypeScript, Tailwind 4, shadcn/ui
  • Vue — Inertia 2, Vue Composition API, TypeScript, Tailwind 4, shadcn-vue
  • Svelte — Inertia 2, Svelte 5, TypeScript, Tailwind 4, shadcn-svelte
  • Livewire — Livewire, Tailwind 4, Flux UI
laravel new my-app
명령을 실행하면 스타터 킷의 선택이 촉구됩니다. 선택 후에는 의존관계를 설치하고 개발 서버를 기동하는 것만으로 됩니다.
cd my-app
npm install && npm run build
composer run dev
기존 애플리케이션을 업그레이드하는 경우, 스타터 킷을 다시 도입할 필요는 없습니다. 신규 프로젝트용 변경입니다.

파괴적 변경 (Breaking Changes)

Eloquent

HasUuids 트레이트와 UUIDv7

영향도: 중간 HasUuids 트레이트가 UUID v7 (순서가 있는 UUID)를 반환하도록 되었습니다. 이전의 순서 있는 UUID v4의 동작을 유지하고 싶은 경우에는 HasVersion4Uuids 트레이트로 전환해 주세요.
use Illuminate\Database\Eloquent\Concerns\HasUuids; // [tl! remove]
use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids; // [tl! add]
이전부터 HasVersion7Uuids 트레이트를 사용하고 있었던 경우에는 HasUuids 트레이트로 변경해 주세요 (동일한 동작이 되었습니다).

유효성 검증

이미지 유효성 검증의 SVG 제외

영향도: 낮음 image 유효성 검증 룰이 기본으로 SVG를 허가하지 않게 되었습니다. SVG를 허가하는 경우는 명시적으로 지정해 주세요.
use Illuminate\Validation\Rules\File;

'photo' => 'required|image:allow_svg'

// 또는
'photo' => ['required', File::image(allowSvg: true)],

스토리지

로컬 파일 시스템 디스크의 기본 루트 경로

영향도: 낮음 filesystems 설정에서 local 디스크를 명시적으로 정의하지 않은 경우, 기본 루트 경로가 storage/app에서 storage/app/private로 변경되었습니다. 이전의 동작을 유지하려면, 설정 파일에서 local 디스크를 명시적으로 정의해 주세요.
// config/filesystems.php
'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],

데이터베이스

멀티 스키마의 데이터베이스 인스펙션

영향도: 낮음 Schema::getTables(), Schema::getViews(), Schema::getTypes()가 기본으로 모든 스키마의 결과를 반환하도록 되었습니다. 특정 스키마만을 대상으로 하려면 schema 인자를 전달해 주세요.
// 모든 스키마의 테이블
$tables = Schema::getTables();

// 'main' 스키마의 테이블만
$tables = Schema::getTables(schema: 'main');
Schema::getTableListing()이 기본으로 스키마 수식된 테이블 이름을 반환하도록 되었습니다.
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

$tables = Schema::getTableListing(schema: 'main', schemaQualified: false);
// ['migrations', 'users']

데이터베이스 생성자 시그니처 변경

영향도: 매우 낮음 Illuminate\Database\Schema\BlueprintIlluminate\Database\Grammar의 생성자가 Connection 인스턴스를 첫 번째 인자로 요구하도록 되었습니다.
// Laravel <= 11.x
$grammar = new MySqlGrammar;
$grammar->setConnection($connection);

// Laravel >= 12.x
$grammar = new MySqlGrammar($connection);
또한 이하의 API가 삭제 또는 비권장이 되었습니다.
API상태
Blueprint::getPrefix()비권장
Connection::withTablePrefix()삭제
Grammar::getTablePrefix() / setTablePrefix()비권장
Grammar::setConnection()삭제
테이블 프리픽스는 커넥션에서 직접 취득해 주세요.
$prefix = $connection->getTablePrefix();

Concurrency

결과 인덱스 매핑

영향도: 낮음 Concurrency::run()에 연관 배열을 전달한 경우, 결과가 각각의 키와 대응하여 반환되도록 되었습니다.
$result = Concurrency::run([
    'task-1' => fn () => 1 + 1,
    'task-2' => fn () => 2 + 2,
]);

// ['task-1' => 2, 'task-2' => 4]

컨테이너

클래스 의존 해결의 기본값

영향도: 낮음 DI 컨테이너가 클래스 인스턴스를 해결할 때 클래스 프로퍼티의 기본값을 존중하도록 되었습니다.
class Example
{
    public function __construct(public ?Carbon $date = null) {}
}

$example = resolve(Example::class);

// Laravel <= 11.x: Carbon 인스턴스 반환
// Laravel >= 12.x: null 반환

요청

중첩된 배열 요청의 병합

영향도: 낮음 $request->mergeIfMissing()에서 점 표기법을 사용한 중첩된 배열 데이터를 병합할 수 있게 되었습니다. 이전에는 점 표기법의 키가 그대로 최상위 키로서 작성되고 있었습니다.
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);

라우팅

라우트의 우선순위

영향도: 낮음 같은 이름을 가진 여러 라우트가 있는 경우의 동작이, 캐시 유/무에서 통일되었습니다. 캐시 없는 라우팅에서도, 마지막이 아니라 최초로 등록된 라우트가 우선되도록 되었습니다.

인증

DatabaseTokenRepository 생성자의 변경

영향도: 매우 낮음 Illuminate\Auth\Passwords\DatabaseTokenRepository의 생성자가 $expires 파라미터를 분 단위가 아니라 초 단위로 받도록 되었습니다.

Carbon 3

영향도: 낮음 Carbon 2.x의 지원이 삭제되었습니다. Laravel 12의 애플리케이션은 모두 Carbon 3.x가 필요합니다.

정리

Laravel 12는 비교적 부드럽게 업그레이드할 수 있는 버전입니다. 주요 주의점을 정리합니다.
변경점영향도대응
composer.json의 의존관계 갱신높음laravel/framework ^12.0으로 변경
Laravel 인스톨러의 갱신높음composer global update
HasUuids → UUIDv7중간필요하면 HasVersion4Uuids로 전환
image 유효성 검증의 SVG 제외낮음SVG를 허가하는 경우는 allow_svg 추가
로컬 디스크의 기본 루트 변경낮음설정 파일에서 명시적으로 지정
Carbon 3 필수낮음API 호환성 확인

참고 자료

마지막 수정일 2026년 7월 13일