Skip to content

发布说明

版本方案

Laravel及其其他一方包遵循语义化版本控制。主要框架版本每六个月发布一次(大约在二月和八月),而次要和补丁版本可能每周发布一次。次要和补丁版本绝不应包含破坏性更改。

在从您的应用程序或包中引用Laravel框架或其组件时,您应始终使用诸如^7.0之类的版本约束,因为Laravel的主要版本确实包含破坏性更改。然而,我们努力确保您可以在一天或更短的时间内更新到新的主要版本。

支持政策

对于LTS版本,例如Laravel 6,提供2年的错误修复和3年的安全修复。这些版本提供最长的支持和维护窗口。对于一般版本,提供6个月的错误修复和1年的安全修复。对于所有其他库,包括Lumen,只有最新版本会收到错误修复。此外,请查看Laravel支持的数据库版本数据库介绍

版本发布错误修复截止日期安全修复截止日期
6 (LTS)2019年9月3日2021年9月3日2022年9月3日
72020年3月3日2020年9月10日2021年3月3日
82020年9月8日2021年3月8日2021年9月8日

Laravel 7

Laravel 7在Laravel 6.x的改进基础上继续前进,引入了Laravel Sanctum、路由速度改进、自定义Eloquent转换、Blade组件标签、流畅的字符串操作、面向开发者的HTTP客户端、第一方CORS支持、改进的路由模型绑定范围、存根自定义、数据库队列改进、多邮件驱动、查询时转换、新的artisan test命令以及各种其他错误修复和可用性改进。

Laravel Sanctum

Laravel Sanctum由Taylor Otwell构建

Laravel Sanctum为SPA(单页应用程序)、移动应用程序和简单的基于令牌的API提供了一种轻量级的身份验证系统。Sanctum允许您的应用程序的每个用户为其帐户生成多个API令牌。这些令牌可以被授予能力/范围,以指定令牌被允许执行的操作。

有关Laravel Sanctum的更多信息,请查阅Sanctum文档

自定义Eloquent转换

自定义Eloquent转换由Taylor Otwell贡献

Laravel有多种内置的、实用的转换类型;然而,您可能偶尔需要定义自己的转换类型。您现在可以通过定义一个实现CastsAttributes接口的类来实现这一点。

实现此接口的类必须定义getset方法。get方法负责将数据库中的原始值转换为转换值,而set方法应将转换值转换为可以存储在数据库中的原始值。作为示例,我们将重新实现内置的json转换类型作为自定义转换类型:

php
<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Json implements CastsAttributes
{
    /**
     * 转换给定的值。
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return array
     */
    public function get($model, $key, $value, $attributes)
    {
        return json_decode($value, true);
    }

    /**
     * 准备存储的给定值。
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return json_encode($value);
    }
}

定义自定义转换类型后,您可以使用其类名将其附加到模型属性:

php
<?php

namespace App;

use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 应转换为本机类型的属性。
     *
     * @var array
     */
    protected $casts = [
        'options' => Json::class,
    ];
}

要了解如何编写自定义Eloquent转换,包括转换为值对象的自定义转换,请查阅Eloquent文档

Blade组件标签和改进

Blade组件标签由SpatieMarcel PociotCaleb PorzioDries VintsTaylor Otwell贡献

lightbulb

Blade组件已被彻底改造,以允许基于标签的渲染、属性管理、组件类、内联视图组件等。由于Blade组件的改造非常广泛,请查阅完整的Blade组件文档以了解此功能。

总之,组件现在可以有一个关联的类来指定它接受的数据。组件类上定义的所有公共属性和方法将自动提供给组件视图。组件上指定的任何其他HTML属性可以使用自动包含的$attributes变量进行管理,该变量是一个属性包实例。

在此示例中,我们将假设已定义一个App\View\Components\Alert组件,如下所示:

php
<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    /**
     * 警报类型。
     *
     * @var string
     */
    public $type;

    /**
     * 创建组件实例。
     *
     * @param  string  $type
     * @return void
     */
    public function __construct($type)
    {
        $this->type = $type;
    }

    /**
     * 获取给定警报类型的类。
     *
     * @return string
     */
    public function classForType()
    {
        return $this->type == 'danger' ? 'alert-danger' : 'alert-warning';
    }

    /**
     * 获取表示组件的视图/内容。
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

假设组件的Blade模板已定义如下:

php
<!-- /resources/views/components/alert.blade.php -->

<div class="alert {{ $classForType }}" {{ $attributes }}>
    {{ $heading }}

    {{ $slot }}
</div>

可以使用组件的标签在另一个Blade视图中渲染组件:

php
<x-alert type="error" class="mb-4">
    <x-slot name="heading">
        警报内容...
    </x-slot>

    默认插槽内容...
</x-alert>

如前所述,这只是Laravel 7中Blade组件改造功能的一个非常小的示例,并未展示匿名组件、内联视图组件和其他各种功能。请查阅完整的Blade组件文档以了解此功能。

exclamation

以前的Blade组件@component语法没有也不会被移除。

HTTP客户端

HTTP客户端是Guzzle的包装器,由Adam WathanJason McCrearyTaylor Otwell贡献

Laravel现在提供了一个围绕Guzzle HTTP客户端的简洁、最小的API,使您可以快速发出外部HTTP请求以与其他Web应用程序通信。Laravel围绕Guzzle的包装器专注于其最常见的用例和出色的开发者体验。例如,客户端使POST和与JSON数据的接口变得轻而易举:

php
use Illuminate\Support\Facades\Http;

$response = Http::withHeaders([
    'X-First' => 'foo',
    'X-Second' => 'bar'
])->post('http://test.com/users', [
    'name' => 'Taylor',
]);

return $response['id'];

此外,HTTP客户端提供了出色的、符合人体工程学的测试功能:

php
Http::fake([
    // 为GitHub端点存根JSON响应...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // 为Google端点存根字符串响应...
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),

    // 为Facebook端点存根一系列响应...
    'facebook.com/*' => Http::sequence()
                            ->push('Hello World', 200)
                            ->push(['foo' => 'bar'], 200)
                            ->pushStatus(404),
]);

要了解HTTP客户端的所有功能,请查阅HTTP客户端文档

流畅的字符串操作

流畅的字符串操作由Taylor Otwell贡献

您可能已经熟悉Laravel现有的Illuminate\Support\Str类,该类提供了多种有用的字符串操作功能。Laravel 7现在提供了一个更面向对象的、流畅的字符串操作库,构建在这些功能之上。您可以使用Str::of方法创建一个流畅的Illuminate\Support\Stringable对象。然后可以将各种方法链接到对象上以操作字符串:

php
return (string) Str::of('  Laravel Framework 6.x ')
                    ->trim()
                    ->replace('6.x', '7.x')
                    ->slug();

有关流畅字符串操作可用方法的更多信息,请查阅其完整文档

路由模型绑定改进

路由模型绑定改进由Taylor Otwell贡献

键自定义

有时您可能希望使用id以外的列来解析Eloquent模型。为此,Laravel 7允许您在路由参数定义中指定列:

php
Route::get('api/posts/{post:slug}', function (App\Post $post) {
    return $post;
});

自动范围

有时,在单个路由定义中隐式绑定多个Eloquent模型时,您可能希望将第二个Eloquent模型的范围限定为必须是第一个Eloquent模型的子级。例如,考虑这种情况,它为特定用户按slug检索博客文章:

php
use App\Post;
use App\User;

Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

当使用自定义键的隐式绑定作为嵌套路由参数时,Laravel 7将自动将查询范围限定为通过其父级检索嵌套模型,使用约定来猜测父级上的关系名称。在这种情况下,将假定User模型有一个名为posts的关系(路由参数名称的复数形式),可以用来检索Post模型。

有关路由模型绑定的更多信息,请查阅路由文档

多邮件驱动

多邮件驱动支持由Taylor Otwell贡献

Laravel 7允许为单个应用程序配置多个“邮件程序”。在mail配置文件中配置的每个邮件程序都可以有自己的选项,甚至可以有自己独特的“传输”,允许您的应用程序使用不同的电子邮件服务发送某些电子邮件。例如,您的应用程序可能使用Postmark发送事务邮件,而使用Amazon SES发送批量邮件。

默认情况下,Laravel将使用在mail配置文件中配置为default的邮件程序。然而,您可以使用mailer方法使用特定的邮件程序配置发送消息:

php
Mail::mailer('postmark')
        ->to($request->user())
        ->send(new OrderShipped($order));

路由缓存速度改进

路由缓存速度改进由上游Symfony贡献者和Dries Vints贡献

Laravel 7包括一种新的方法来匹配已使用route:cache Artisan命令缓存的编译路由。在大型应用程序中(例如,具有800个或更多路由的应用程序),这些改进可以在每秒请求数上实现2倍速度提升,在简单的“Hello World”基准测试中。无需对您的应用程序进行更改。

CORS支持

CORS支持由Barry vd. Heuvel贡献

Laravel 7通过集成Barry vd. Heuvel编写的流行Laravel CORS包,包含了配置跨域资源共享(CORS)OPTIONS请求响应的第一方支持。在默认Laravel应用程序骨架中包含了新的cors配置。

有关Laravel 7.x中CORS支持的更多信息,请查阅CORS文档

查询时转换

查询时转换由Matt Barlow贡献

有时您可能需要在执行查询时应用转换,例如在从表中选择原始值时。例如,考虑以下查询:

php
use App\Post;
use App\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->get();

此查询结果中的last_posted_at属性将是一个原始字符串。如果我们可以在执行查询时对该属性应用date转换,那将很方便。为此,我们可以使用Laravel 7提供的withCasts方法:

php
$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->withCasts([
    'last_posted_at' => 'date'
])->get();

MySQL 8+数据库队列改进

MySQL数据库队列改进由Mohamed Said贡献

在以前的Laravel版本中,由于死锁,database队列不被认为足够稳健以用于生产。然而,Laravel 7为使用MySQL 8+作为其数据库支持队列的应用程序提供了改进。通过使用FOR UPDATE SKIP LOCKED子句和其他SQL增强功能,database驱动现在可以安全地用于更高容量的生产应用程序。

Artisan test命令

test命令由Nuno Maduro贡献

除了phpunit命令,您现在可以使用test Artisan命令运行您的测试。Artisan测试运行器提供了美观的控制台用户体验和有关当前正在运行的测试的更多信息。此外,运行器将在第一个测试失败时自动停止:

php
php artisan test

可以传递给phpunit命令的任何参数也可以传递给Artisan test命令:

php
php artisan test --group=feature

Markdown邮件模板改进

Markdown邮件模板改进由Taylor Otwell贡献

默认的Markdown邮件模板基于Tailwind CSS调色板获得了一个新的、更现代的设计。当然,可以根据您的应用程序需求发布和自定义此模板:

有关Markdown邮件的更多信息,请查阅邮件文档

存根自定义

存根自定义由Taylor Otwell贡献

Artisan控制台的make命令用于创建各种类,例如控制器、作业、迁移和测试。这些类是使用“存根”文件生成的,这些文件根据您的输入填充值。然而,您有时可能希望对Artisan生成的文件进行小的更改。为此,Laravel 7提供了stub:publish命令来发布最常见的存根以供自定义:

php
php artisan stub:publish

发布的存根将位于应用程序根目录中的stubs目录中。您对这些存根所做的任何更改将在使用Artisan make命令生成其对应类时反映出来。

队列maxExceptions配置

maxExceptions属性由Mohamed Said贡献

有时您可能希望指定一个作业可以尝试多次,但如果重试是由给定数量的异常触发的,则应失败。在Laravel 7中,您可以在作业类上定义一个maxExceptions属性:

php
<?php

namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * 作业可以尝试的次数。
     *
     * @var int
     */
    public $tries = 25;

    /**
     * 在失败之前允许的最大异常数。
     *
     * @var int
     */
    public $maxExceptions = 3;

    /**
     * 执行作业。
     *
     * @return void
     */
    public function handle()
    {
        Redis::throttle('key')->allow(10)->every(60)->then(function () {
            // 获得锁,处理播客...
        }, function () {
            // 无法获得锁...
            return $this->release(10);
        });
    }
}

在此示例中,如果应用程序无法获得Redis锁,则作业将释放十秒钟,并将继续重试最多25次。然而,如果作业抛出三个未处理的异常,则作业将失败。