发布说明
版本控制方案
Laravel及其其他一方包遵循语义化版本控制。主要框架版本每年发布(大约在二月),而次要和补丁版本可能每周发布。次要和补丁版本绝不应包含破坏性更改。
当从您的应用程序或包中引用Laravel框架或其组件时,您应始终使用诸如^8.0
之类的版本约束,因为Laravel的主要版本确实包含破坏性更改。然而,我们努力确保您可以在一天或更短的时间内更新到新的主要版本。
例外情况
命名参数
目前,PHP的命名参数功能不在Laravel的向后兼容性指南的覆盖范围内。我们可能会在必要时重命名函数参数,以改善Laravel代码库。因此,在调用Laravel方法时使用命名参数应谨慎进行,并理解参数名称可能会在将来更改。
支持政策
对于所有Laravel版本,错误修复提供18个月,安全修复提供2年。对于所有附加库,包括Lumen,只有最新的主要版本会收到错误修复。此外,请查看Laravel支持的数据库版本数据库介绍。
版本 | PHP (*) | 发布 | 错误修复截止日期 | 安全修复截止日期 |
---|---|---|---|---|
6 (LTS) | 7.2 - 8.0 | 2019年9月3日 | 2022年1月25日 | 2022年9月6日 |
7 | 7.2 - 8.0 | 2020年3月3日 | 2020年10月6日 | 2021年3月3日 |
8 | 7.3 - 8.1 | 2020年9月8日 | 2022年7月26日 | 2023年1月24日 |
9 | 8.0 - 8.1 | 2022年2月8日 | 2023年8月8日 | 2024年2月6日 |
10 | 8.1 - 8.3 | 2023年2月14日 | 2024年8月6日 | 2025年2月4日 |
(*) 支持的PHP版本
Laravel 8
Laravel 8通过引入Laravel Jetstream、模型工厂类、迁移压缩、作业批处理、改进的速率限制、队列改进、动态Blade组件、Tailwind分页视图、时间测试助手、artisan serve
改进、事件监听器改进以及各种其他错误修复和可用性改进,继续了Laravel 7.x的改进。
Laravel Jetstream
Laravel Jetstream由Taylor Otwell编写。
Laravel Jetstream是一个为Laravel设计的美观的应用程序脚手架。Jetstream为您的下一个项目提供了完美的起点,并包括登录、注册、电子邮件验证、双因素认证、会话管理、通过Laravel Sanctum的API支持以及可选的团队管理。Laravel Jetstream替代并改进了以前版本的Laravel可用的传统认证UI脚手架。
Jetstream使用Tailwind CSS设计,并提供Livewire或Inertia脚手架的选择。
模型目录
由于社区的强烈要求,默认的Laravel应用程序骨架现在包含一个app/Models
目录。我们希望您喜欢这个新的Eloquent模型之家!所有相关的生成器命令已更新为假设模型存在于app/Models
目录中(如果存在)。如果目录不存在,框架将假定您的模型应放置在app
目录中。
模型工厂类
模型工厂类由Taylor Otwell贡献。
Eloquent 模型工厂已完全重写为基于类的工厂,并改进为具有一流的关系支持。例如,Laravel附带的UserFactory
是这样编写的:
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* 工厂对应模型的名称。
*
* @var string
*/
protected $model = User::class;
/**
* 定义模型的默认状态。
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // 密码
'remember_token' => Str::random(10),
];
}
}
感谢生成模型上可用的HasFactory
特性,模型工厂可以像这样使用:
use App\Models\User;
User::factory()->count(50)->create();
由于模型工厂现在是简单的PHP类,状态转换可以写为类方法。此外,您可以根据需要将任何其他助手类添加到您的Eloquent模型工厂中。
例如,您的User
模型可能有一个suspended
状态,该状态修改其默认属性值之一。您可以使用基础工厂的state
方法定义状态转换。您可以将状态方法命名为任何您喜欢的名称。毕竟,这只是一个典型的PHP方法:
/**
* 表示用户被暂停。
*
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function suspended()
{
return $this->state([
'account_status' => 'suspended',
]);
}
定义状态转换方法后,我们可以像这样使用它:
use App\Models\User;
User::factory()->count(5)->suspended()->create();
如前所述,Laravel 8的模型工厂包含对关系的一流支持。因此,假设我们的User
模型有一个posts
关系方法,我们可以简单地运行以下代码来生成一个有三个帖子(posts)的用户:
$users = User::factory()
->hasPosts(3, [
'published' => false,
])
->create();
为了简化升级过程,发布了laravel/legacy-factories包,以在Laravel 8.x中提供对模型工厂先前迭代的支持。
Laravel重写的工厂包含许多我们认为您会喜欢的功能。要了解有关模型工厂的更多信息,请查阅数据库测试文档。
迁移压缩
迁移压缩由Taylor Otwell贡献。
随着您构建应用程序,您可能会随着时间的推移积累越来越多的迁移。这可能导致您的迁移目录变得臃肿,可能有数百个迁移。如果您使用MySQL或PostgreSQL,您现在可以将迁移“压缩”到一个SQL文件中。要开始,请执行schema:dump
命令:
php artisan schema:dump
// 转储当前数据库架构并修剪所有现有迁移...
php artisan schema:dump --prune
执行此命令时,Laravel会将“架构”文件写入您的database/schema
目录。现在,当您尝试迁移数据库且没有其他迁移已执行时,Laravel将首先执行架构文件的SQL。在执行架构文件的命令后,Laravel将执行任何不属于架构转储的剩余迁移。
作业批处理
作业批处理由Taylor Otwell和Mohamed Said贡献。
Laravel的作业批处理功能允许您轻松执行一批作业,然后在作业批处理完成执行时执行某些操作。
Bus
facade的新batch
方法可用于调度一批作业。当然,批处理主要在与完成回调结合使用时有用。因此,您可以使用then
、catch
和finally
方法为批处理定义完成回调。每个回调在调用时都会接收一个Illuminate\Bus\Batch
实例:
use App\Jobs\ProcessPodcast;
use App\Models\Podcast;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
use Throwable;
$batch = Bus::batch([
new ProcessPodcast(Podcast::find(1)),
new ProcessPodcast(Podcast::find(2)),
new ProcessPodcast(Podcast::find(3)),
new ProcessPodcast(Podcast::find(4)),
new ProcessPodcast(Podcast::find(5)),
])->then(function (Batch $batch) {
// 所有作业成功完成...
})->catch(function (Batch $batch, Throwable $e) {
// 检测到第一个批处理作业失败...
})->finally(function (Batch $batch) {
// 批处理已完成执行...
})->dispatch();
return $batch->id;
要了解有关作业批处理的更多信息,请查阅队列文档。
改进的速率限制
速率限制改进由Taylor Otwell贡献。
Laravel的请求速率限制器功能已增强,具有更大的灵活性和功能,同时仍然保持与以前版本的throttle
中间件API的向后兼容性。
速率限制器使用RateLimiter
facade的for
方法定义。for
方法接受速率限制器名称和一个返回应应用于分配此速率限制器的路由的限制配置的闭包:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000);
});
由于速率限制器回调接收传入的HTTP请求实例,您可以根据传入请求或已认证用户动态构建适当的速率限制:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});
有时您可能希望按某个任意值分段速率限制。例如,您可能希望允许用户每分钟每个IP地址访问给定路由100次。为此,您可以在构建速率限制时使用by
方法:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});
速率限制器可以使用throttle
中间件附加到路由或路由组。节流中间件接受您希望分配给路由的速率限制器的名称:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
//
});
Route::post('/video', function () {
//
});
});
要了解有关速率限制的更多信息,请查阅路由文档。
改进的维护模式
维护模式改进由Taylor Otwell贡献,灵感来自Spatie。
在以前的Laravel版本中,可以使用允许访问应用程序的IP地址“允许列表”绕过php artisan down
维护模式功能。此功能已被删除,取而代之的是更简单的“秘密”/令牌解决方案。
在维护模式下,您可以使用secret
选项指定维护模式绕过令牌:
php artisan down --secret="1630542a-246b-4b66-afa1-dd72a4c43515"
将应用程序置于维护模式后,您可以导航到与此令牌匹配的应用程序URL,Laravel将向您的浏览器发出维护模式绕过cookie:
https://example.com/1630542a-246b-4b66-afa1-dd72a4c43515
访问此隐藏路由时,您将被重定向到应用程序的/
路由。一旦cookie已发出到您的浏览器,您将能够正常浏览应用程序,就像它不在维护模式下一样。
预渲染维护模式视图
如果您在部署期间使用php artisan down
命令,您的用户可能仍会偶尔遇到错误,如果他们在您的Composer依赖项或其他基础设施组件更新时访问应用程序。这是因为必须启动Laravel框架的很大一部分,以确定您的应用程序处于维护模式并使用模板引擎渲染维护模式视图。
因此,Laravel现在允许您预渲染将在请求周期的最开始返回的维护模式视图。此视图在加载应用程序的任何依赖项之前渲染。您可以使用down
命令的render
选项预渲染您选择的模板:
php artisan down --render="errors::503"
闭包调度/链式catch
catch
改进由Mohamed Said贡献。
使用新的catch
方法,您现在可以提供一个闭包,如果排队的闭包在耗尽队列的所有配置重试尝试后未能成功完成,则应执行该闭包:
use Throwable;
dispatch(function () use ($podcast) {
$podcast->publish();
})->catch(function (Throwable $e) {
// 此作业已失败...
});
动态Blade组件
动态Blade组件由Taylor Otwell贡献。
有时您可能需要渲染一个组件,但在运行时不知道应该渲染哪个组件。在这种情况下,您现在可以使用Laravel内置的dynamic-component
组件根据运行时值或变量渲染组件:
<x-dynamic-component :component="$componentName" class="mt-4" />
要了解有关Blade组件的更多信息,请查阅Blade文档。
事件监听器改进
事件监听器改进由Taylor Otwell贡献。
基于闭包的事件监听器现在可以通过仅将闭包传递给Event::listen
方法来注册。Laravel将检查闭包以确定监听器处理的事件类型:
use App\Events\PodcastProcessed;
use Illuminate\Support\Facades\Event;
Event::listen(function (PodcastProcessed $event) {
//
});
此外,基于闭包的事件监听器现在可以使用Illuminate\Events\queueable
函数标记为可排队:
use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;
Event::listen(queueable(function (PodcastProcessed $event) {
//
}));
像排队的作业一样,您可以使用onConnection
、onQueue
和delay
方法自定义排队监听器的执行:
Event::listen(queueable(function (PodcastProcessed $event) {
//
})->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10)));
如果您希望处理匿名排队监听器失败,您可以在定义queueable
监听器时为catch
方法提供一个闭包:
use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;
use Throwable;
Event::listen(queueable(function (PodcastProcessed $event) {
//
})->catch(function (PodcastProcessed $event, Throwable $e) {
// 排队监听器失败...
}));
时间测试助手
时间测试助手由Taylor Otwell贡献,灵感来自Ruby on Rails。
在测试时,您可能偶尔需要修改now
或Illuminate\Support\Carbon::now()
等助手返回的时间。Laravel的基本功能测试类现在包括允许您操控当前时间的助手:
public function testTimeCanBeManipulated()
{
// 旅行到未来...
$this->travel(5)->milliseconds();
$this->travel(5)->seconds();
$this->travel(5)->minutes();
$this->travel(5)->hours();
$this->travel(5)->days();
$this->travel(5)->weeks();
$this->travel(5)->years();
// 旅行到过去...
$this->travel(-5)->hours();
// 旅行到明确的时间...
$this->travelTo(now()->subHours(6));
// 返回到现在的时间...
$this->travelBack();
}
Artisan serve
改进
Artisan serve
改进由Taylor Otwell贡献。
Artisan serve
命令已改进,当检测到本地.env
文件中的环境变量更改时自动重新加载。以前,必须手动停止和重新启动命令。
Tailwind分页视图
Laravel分页器已更新为默认使用Tailwind CSS框架。Tailwind CSS是一个高度可定制的低级CSS框架,提供了构建定制设计所需的所有构建块,而无需与任何烦人的意见化样式作斗争。当然,Bootstrap 3和4视图仍然可用。
路由命名空间更新
在以前的Laravel版本中,RouteServiceProvider
包含一个$namespace
属性。此属性的值会自动前缀到控制器路由定义和对action
助手/URL::action
方法的调用。在Laravel 8.x中,此属性默认值为null
。这意味着Laravel不会自动进行命名空间前缀。因此,在新的Laravel 8.x应用程序中,控制器路由定义应使用标准PHP可调用语法定义:
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
对action
相关方法的调用应使用相同的可调用语法:
action([UserController::class, 'index']);
return Redirect::action([UserController::class, 'index']);
如果您更喜欢Laravel 7.x风格的控制器路由前缀,您可以简单地将$namespace
属性添加到应用程序的RouteServiceProvider
中。
此更改仅影响新的Laravel 8.x应用程序。从Laravel 7.x升级的应用程序仍将具有其RouteServiceProvider
中的$namespace
属性。