Skip to content

发行说明

版本控制方案

Laravel 及其其他第一方包遵循语义版本控制。主要框架版本每年发布一次(~第一季度),而次要版本和补丁版本可能每周发布一次。次要版本和补丁版本不应包含重大更改。

当从应用程序或包中引用 Laravel 框架或其组件时,您应该始终使用版本约束,例如^11.0 ,因为 Laravel 的主要版本确实包含重大更改。但是,我们始终努力确保您可以在一天或更短的时间内更新到新的主要版本。

命名参数

Laravel 的向后兼容性指南不涵盖命名参数。必要时我们可以选择重命名函数参数,以改进 Laravel 代码库。因此,在调用 Laravel 方法时使用命名参数应谨慎进行,并了解参数名称将来可能会发生变化。

支持政策

对于所有 Laravel 版本,提供 18 个月的错误修复和 2 年的安全修复。对于包括 Lumen 在内的所有其他库,只有最新的主要版本才会收到错误修复。另外,请查看Laravel 支持的数据库版本

VersionPHP (*)发布错误修复直至安全修复直至
98.0 - 8.22022 年 2 月 8 日August 8th, 2023February 6th, 2024
108.1 - 8.32023 年 2 月 14 日August 6th, 2024February 4th, 2025
118.2 - 8.32024 年 3 月 12 日September 3rd, 2025March 12th, 2026
128.2 - 8.32025 年第一季度2026 年第三季度2027 年第一季度
html
<div class="version-colors">
    <div class="end-of-life">
        <div class="color-box"></div>
        <div>生命终结</div>
    </div>
    <div class="security-fixes">
        <div class="color-box"></div>
        <div>Security fixes only</div>
    </div>
</div>

(*) 支持的 PHP 版本

Laravel 11

Laravel 11 延续了 Laravel 10.x 中的改进,引入了简化的应用程序结构、每秒速率限制、健康路由、优雅的加密密钥轮换、队列测试改进、重新发送邮件传输、提示验证器集成、新的 Artisan 命令等。此外,还引入了第一方可扩展 WebSocket 服务器 Laravel Reverb,为您的应用程序提供强大的实时功能。

PHP 8.2

Laravel 11.x 要求 PHP 版本最低为 8.2。

简化的应用程序结构

Laravel 的精简应用程序结构由Taylor OtwellNuno Maduro开发

Laravel 11 为新的Laravel 应用程序引入了简化的应用程序结构,无需对现有应用程序进行任何更改。新的应用程序结构旨在提供更精简、更现代的体验,同时保留 Laravel 开发人员已经熟悉的许多概念。下面我们将讨论 Laravel 新应用程序结构的亮点。

应用程序引导文件

bootstrap/app.php文件已重新焕发活力,成为代码优先的应用程序配置文件。现在,您可以从此文件中自定义应用程序的路由、中间件、服务提供程序、异常处理等。该文件统一了以前分散在应用程序文件结构中的各种高级应用程序行为设置:

php
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

服务提供商

Laravel 11 只包含一个AppServiceProvider ,而不是包含五个服务提供者的默认 Laravel 应用程序结构。以前的服务提供者的功能已合并到bootstrap/app.php中,由框架自动处理,或者可以放置在应用程序的AppServiceProvider中。

例如,现在默认启用事件发现,很大程度上消除了手动注册事件及其侦听器的需要。但是,如果您确实需要手动注册事件,则只需在AppServiceProvider中进行即可。同样,您之前在AuthServiceProvider中注册的路由模型绑定或授权门也可能在AppServiceProvider中注册。

选择加入 API 和广播路由

默认情况下, api.phpchannels.php路由文件不再存在,因为许多应用程序不需要这些文件。相反,它们可以使用简单的 Artisan 命令创建:

shell
php artisan install:api

php artisan install:broadcasting

中间件

此前,新的 Laravel 应用程序包含九个中间件。这些中间件执行各种任务,例如验证请求、修剪输入字符串和验证 CSRF 令牌。

在 Laravel 11 中,这些中间件已移至框架本身中,因此它们不会增加应用程序结构的体积。用于自定义这些中间件行为的新方法已添加到框架中,并且可以从应用程序的bootstrap/app.php文件中调用:

php
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(
        except: ['stripe/*']
    );

    $middleware->web(append: [
        EnsureUserIsSubscribed::class,
    ])
})

由于所有中间件都可以通过应用程序的bootstrap/app.php轻松自定义,因此不再需要单独的 HTTP“内核”类。

调度

使用新的Schedule外观,计划任务现在可以直接在应用程序的routes/console.php文件中定义,从而无需单独的控制台“内核”类

php
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')->daily();

异常处理

与路由和中间件一样,现在可以从应用程序的bootstrap/app.php文件而不是单独的异常处理程序类来自定义异常处理,从而减少新 Laravel 应用程序中包含的文件总数:

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->dontReport(MissedFlightException::class);

    $exceptions->report(function (InvalidOrderException $e) {
        // ...
    });
})

基本Controller

新 Laravel 应用程序中包含的基本控制器已得到简化。它不再扩展 Laravel 的内部Controller类,并且AuthorizesRequestsValidatesRequests特征已被删除,因为如果需要,它们可能包含在应用程序的单独控制器中:

php
    <?php
    
    namespace App\Http\Controllers;
    
    abstract class Controller
    {
        //
    }

应用程序默认值

默认情况下,新的 Laravel 应用程序使用 SQLite 进行数据库存储,以及 Laravel 会话、缓存和队列的database驱动程序。这允许您在创建新的 Laravel 应用程序后立即开始构建应用程序,而无需安装额外的软件或创建额外的数据库迁移。

此外,随着时间的推移,这些 Laravel 服务的database驱动程序已经变得足够强大,可以在许多应用程序环境中进行生产使用;因此,它们为本地和生产应用程序提供了明智、统一的选择。

Laravel Reverb

Laravel Reverb 由Joe Dixon开发

Laravel Reverb直接为您的 Laravel 应用程序带来超快且可扩展的实时 WebSocket 通信,并提供与 Laravel 现有事件广播工具套件(例如 Laravel Echo)的无缝集成。

shell
php artisan reverb:start

此外,Reverb 通过 Redis 的发布/订阅功能支持水平扩展,允许您在多个后端 Reverb 服务器之间分配 WebSocket 流量,所有服务器都支持单个高需求应用程序。

有关 Laravel Reverb 的更多信息,请参阅完整的Reverb 文档

速率限制

每秒速率限制由Tim MacDonald贡献

Laravel 现在支持所有速率限制器的“每秒”速率限制,包括 HTTP 请求和排队作业的速率限制。以前,Laravel 的速率限制器仅限于“每分钟”粒度:

php
RateLimiter::for('invoices', function (Request $request) {
    return Limit::perSecond(1);
});

有关 Laravel 速率限制的更多信息,请查看速率限制文档

健康路由

健康路由由Taylor Otwell贡献

新的 Laravel 11 应用程序包含一个health路由指令,该指令指示 Laravel 定义一个简单的健康检查端点,该端点可以由第三方应用程序健康监控服务或 Kubernetes 等编排系统调用。默认情况下,该路由在/up提供:

php
->withRouting(
    web: __DIR__.'/../routes/web.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
)

当向此路由发出 HTTP 请求时,Laravel 还将调度DiagnosingHealth事件,允许您执行与应用程序相关的其他运行状况检查。

优雅的加密密钥轮换

优雅的加密密钥轮换是由Taylor Otwell贡献的

由于 Laravel 会加密所有 cookie,包括应用程序的会话 cookie,因此基本上对 Laravel 应用程序的每个请求都依赖于加密。但是,正因为如此,轮换应用程序的加密密钥将使所有用户退出您的应用程序。此外,解密由先前加密密钥加密的数据变得不可能。

Laravel 11 允许您通过APP_PREVIOUS_KEYS环境变量将应用程序以前的加密密钥定义为逗号分隔的列表。

加密值时,Laravel 将始终使用“当前”加密密钥,该密钥位于APP_KEY环境变量中。解密值时,Laravel 将首先尝试当前密钥。如果使用当前密钥解密失败,Laravel 将尝试所有先前的密钥,直到其中一个密钥能够解密该值。

即使您的加密密钥发生轮换,这种优雅解密的方法也允许用户不间断地继续使用您的应用程序。

有关 Laravel 中加密的更多信息,请查看加密文档

自动密码重新哈希

自动密码重新哈希由Stephen Rees-Carter贡献

Laravel 的默认密码哈希算法是 bcrypt。 bcrypt 哈希的“工作因子”可以通过config/hashing.php配置文件或BCRYPT_ROUNDS环境变量进行调整。

通常,随着 CPU/GPU 处理能力的增加,bcrypt 工作因子应该随着时间的推移而增加。如果您增加应用程序的 bcrypt 工作系数,Laravel 现在将在用户通过您的应用程序进行身份验证时优雅地自动重新哈希用户密码。

及时验证

即时验证器集成由Andrea Marco Sartori贡献

Laravel Prompts是一个 PHP 包,用于向命令行应用程序添加美观且用户友好的表单,具有类似浏览器的功能,包括占位符文本和验证。

Laravel Prompts 支持通过闭包进行输入验证:

php
$name = text(
    label: 'What is your name?',
    validate: fn (string $value) => match (true) {
        strlen($value) < 3 => 'The name must be at least 3 characters.',
        strlen($value) > 255 => 'The name must not exceed 255 characters.',
        default => null
    }
);

然而,在处理许多输入或复杂的验证场景时,这可能会变得很麻烦。因此,在 Laravel 11 中,您可以在验证提示输入时充分利用 Laravel验证器的全部功能:

php
$name = text('What is your name?', validate: [
    'name' => 'required|min:3|max:255',
]);

队列交互测试

队列交互测试由Taylor Otwell贡献

以前,尝试测试排队作业是否被释放、删除或手动失败非常麻烦,并且需要定义自定义队列伪造品和存根。但是,在 Laravel 11 中,您可以使用withFakeQueueInteractions方法轻松测试这些队列交互:

php
use App\Jobs\ProcessPodcast;

$job = (new ProcessPodcast)->withFakeQueueInteractions();

$job->handle();

$job->assertReleased(delay: 30);

有关测试排队作业的更多信息,请查看队列文档

新 Artisan 命令

类创建 Artisan 命令由Taylor Otwell贡献

添加了新的 Artisan 命令以允许快速创建类、枚举、接口和特征:

shell
php artisan make:class
php artisan make:enum
php artisan make:interface
php artisan make:trait

模型转换改进

模型铸件的改进由努诺·马杜罗 (Nuno Maduro)贡献

Laravel 11 支持使用方法而不是属性来定义模型的强制转换。这允许简化、流畅的强制转换定义,特别是在使用带有参数的强制转换时:

php
    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'options' => AsCollection::using(OptionCollection::class),
                      // AsEncryptedCollection::using(OptionCollection::class),
                      // AsEnumArrayObject::using(OptionEnum::class),
                      // AsEnumCollection::using(OptionEnum::class),
        ];
    }

有关属性转换的更多信息,请查看Eloquent 文档

once 函数

*once帮手是泰勒·奥特韦尔努诺·马杜罗*贡献的。

once辅助函数执行给定的回调,并在请求期间将结果缓存在内存中。任何具有相同回调的once函数的后续调用都将返回之前缓存的结果:

php
    function random(): int
    {
        return once(function () {
            return random_int(1, 1000);
        });
    }
    
    random(); // 123
    random(); // 123 (cached result)
    random(); // 123 (cached result)

For more information on the once helper, check out the helpers documentation.

使用内存数据库进行测试时提高了性能

Anders Jenbo贡献了改进的内存数据库测试性能https://github.com/AJenbo)

在测试期间使用:memory: SQLite 数据库时,Laravel 11 提供了显着的速度提升。为了实现这一目标,Laravel 现在维护对 PHP PDO 对象的引用并跨连接重用它,通常会将总测试运行时间减少一半。

改进了对 MariaDB 的支持

Improved support for MariaDB was contributed by Jonas Staudenmeir and Julius Kiekbusch

Laravel 11 改进了对 MariaDB 的支持。在以前的 Laravel 版本中,您可以通过 Laravel 的 MySQL 驱动程序使用 MariaDB。然而,Laravel 11 现在包含一个专用的 MariaDB 驱动程序,它为该数据库系统提供了更好的默认值。

有关 Laravel 数据库驱动程序的更多信息,请查看数据库文档

检查数据库并改进架构操作

Hafez Divandari贡献了改进的模式操作和数据库检查

Laravel 11 提供了额外的数据库模式操作和检查方法,包括本机修改、重命名和删除列。此外,还提供了高级空间类型、非默认模式名称以及用于操作表、视图、列、索引和外键的本机模式方法:

php
    use Illuminate\Support\Facades\Schema;
    
    $tables = Schema::getTables();
    $views = Schema::getViews();
    $columns = Schema::getColumns('users');
    $indexes = Schema::getIndexes('users');
    $foreignKeys = Schema::getForeignKeys('users');