> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel 11 升级到 12 指南

> Laravel 11 到 12 的升级步骤与主要变更点解析。

## 前言

Laravel 12 于 2025 年 2 月发布。本指南讲解从 Laravel 11.x 升级到 12.x 的步骤。

<Info>
  预计升级时间**约 5 分钟**。当然,破坏性变更对应用的影响会因规模和所用功能而异。
</Info>

### 用 Laravel Shift 自动升级

也可以用 [Laravel Shift](https://laravelshift.com/) 自动化升级。Shift 会自动更新应用的依赖和配置文件。

***

## 按影响面分级的变更

### 影响度:高

* 依赖更新
* Laravel installer 更新

### 影响度:中

* Eloquent `HasUuids` trait 与 UUIDv7

### 影响度:低

* Carbon 3
* Concurrency 结果索引映射
* 容器的类依赖解析
* 图片校验的 SVG 排除
* 本地文件系统 disk 的默认根路径
* 多 schema 的数据库检查
* 嵌套数组请求的合并

***

## 升级步骤

### 更新依赖

**影响度:高**

请更新 `composer.json` 中的以下依赖。

```json theme={null}
{
  "require": {
    "laravel/framework": "^12.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "pestphp/pest": "^3.0"
  }
}
```

之后执行:

```shell theme={null}
composer update
```

***

### 更新 Laravel installer

**影响度:高**

如果你用 Laravel installer CLI 创建新项目,请把它升级到兼容 Laravel 12.x 和[新启动套件](https://laravel.com/starter-kits)的版本。

用 `composer global require` 安装的情况:

```shell theme={null}
composer global update laravel/installer
```

用 `php.new` 安装的情况,按操作系统运行重装命令。

<Tabs>
  <Tab title="macOS">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/mac/8.4)"
    ```
  </Tab>

  <Tab title="Windows PowerShell">
    ```shell theme={null}
    # 以管理员身份运行
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://php.new/install/windows/8.4'))
    ```
  </Tab>

  <Tab title="Linux">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/linux/8.4)"
    ```
  </Tab>
</Tabs>

如果使用 [Laravel Herd](https://herd.laravel.com) 的捆绑版本,请把 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

```shell theme={null}
laravel new my-app
```

执行命令后会提示你选择启动套件。选完之后安装依赖、启动开发服务器即可。

```shell theme={null}
cd my-app
npm install && npm run build
composer run dev
```

<Info>
  升级现有应用时不必重新引入启动套件,这个变更只针对新项目。
</Info>

***

## 破坏性变更(Breaking Changes)

### Eloquent

#### `HasUuids` trait 与 UUIDv7

**影响度:中**

`HasUuids` trait 现在会返回 UUID v7(有序 UUID)。想保留原先的“顺序 UUID v4”行为时,请换成 `HasVersion4Uuids` trait。

```php theme={null}
use Illuminate\Database\Eloquent\Concerns\HasUuids; // [tl! remove]
use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids; // [tl! add]
```

如果你之前已经在使用 `HasVersion7Uuids` trait,请改回 `HasUuids`(现在两者行为一致)。

***

### 校验

#### 图片校验的 SVG 排除

**影响度:低**

`image` 校验规则默认不再允许 SVG。想允许 SVG 时请显式指定。

```php theme={null}
use Illuminate\Validation\Rules\File;

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

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

***

### 存储

#### 本地文件系统 disk 的默认根路径

**影响度:低**

`filesystems` 配置里没有显式定义 `local` disk 时,默认根路径从 `storage/app` 改为 `storage/app/private`。

想保留旧行为,请在配置文件里显式定义 `local` disk。

```php theme={null}
// config/filesystems.php
'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],
```

***

### 数据库

#### 多 schema 的数据库检查

**影响度:低**

`Schema::getTables()`、`Schema::getViews()`、`Schema::getTypes()` 默认返回所有 schema 的结果。只想拿某个 schema 时,传入 `schema` 参数。

```php theme={null}
// 所有 schema 的表
$tables = Schema::getTables();

// 只要 'main' schema 的表
$tables = Schema::getTables(schema: 'main');
```

`Schema::getTableListing()` 默认返回带 schema 前缀的表名。

```php theme={null}
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

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

#### 数据库构造函数签名变更

**影响度:非常低**

`Illuminate\Database\Schema\Blueprint` 与 `Illuminate\Database\Grammar` 的构造函数现在要求以 `Connection` 实例作为第一个参数。

```php theme={null}
// 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()`                       | 移除 |

表前缀请直接从连接获取。

```php theme={null}
$prefix = $connection->getTablePrefix();
```

***

### Concurrency

#### 结果索引映射

**影响度:低**

给 `Concurrency::run()` 传关联数组时,结果会按各自的键返回。

```php theme={null}
$result = Concurrency::run([
    'task-1' => fn () => 1 + 1,
    'task-2' => fn () => 2 + 2,
]);

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

***

### 容器

#### 类依赖解析的默认值

**影响度:低**

DI 容器在解析类实例时会尊重类属性的默认值。

```php theme={null}
class Example
{
    public function __construct(public ?Carbon $date = null) {}
}

$example = resolve(Example::class);

// Laravel <= 11.x: 返回一个 Carbon 实例
// Laravel >= 12.x: 返回 null
```

***

### 请求

#### 嵌套数组请求的合并

**影响度:低**

`$request->mergeIfMissing()` 现在支持用点号语法合并嵌套数组数据。以前点号语法的键会被原样当作顶层键。

```php theme={null}
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);
```

***

### 路由

#### 路由优先级

**影响度:低**

多个同名路由时的行为在“缓存”和“未缓存”两种模式下统一了。未缓存模式下也不再是最后注册的优先,而是最先注册的优先。

***

### 认证

#### `DatabaseTokenRepository` 构造函数变更

**影响度:非常低**

`Illuminate\Auth\Passwords\DatabaseTokenRepository` 的构造函数中 `$expires` 参数从“分钟”改为“秒”。

***

### Carbon 3

**影响度:低**

移除了对 Carbon 2.x 的支持。Laravel 12 的应用必须使用 [Carbon 3.x](https://carbon.nesbot.com/guide/getting-started/migration.html)。

***

## 总结

Laravel 12 是一次相对平滑的升级。主要要点如下:

| 变更点                  | 影响度 | 应对                           |
| -------------------- | --- | ---------------------------- |
| `composer.json` 依赖更新 | 高   | 改为 `laravel/framework ^12.0` |
| 更新 Laravel installer | 高   | `composer global update`     |
| `HasUuids` → UUIDv7  | 中   | 需要时切换到 `HasVersion4Uuids`    |
| `image` 校验排除 SVG     | 低   | 需要 SVG 时加上 `allow_svg`       |
| 本地 disk 默认根变化        | 低   | 在配置里显式指定                     |
| 必须 Carbon 3          | 低   | 检查 API 兼容性                   |

***

## 参考资料

* [官方升级指南(英文)](https://laravel.com/docs/12.x/upgrade)
* [laravel/laravel 仓库的差异(11.x → 12.x)](https://github.com/laravel/laravel/compare/11.x...12.x)
* [新的启动套件](https://laravel.com/starter-kits)
* [Laravel Shift](https://laravelshift.com) —— 自动化升级的社区服务
* [Carbon 3 迁移指南](https://carbon.nesbot.com/guide/getting-started/migration.html)


## Related topics

- [Laravel 12 升级到 13 指南](/zh/blog/upgrade-12-to-13.md)
- [Laravel 10 升级到 11](/zh/blog/upgrade-10-to-11.md)
- [Laravel 8 升级到 9](/zh/blog/upgrade-8-to-9.md)
- [Laravel 9 升级到 10](/zh/blog/upgrade-9-to-10.md)
