dyrynda/laravel-model-uuid

此包允许您在 Laravel 模型中轻松地处理 UUID。

8.1.1 2024-08-07 00:46 UTC

README

Build Status Scrutinizer Code Quality Code Coverage Latest Stable Version Total Downloads License Dependency Status Buy us a tree

简介

最近我发现自己正在多个项目中使用 UUID,所以将这个功能打包起来,而不是从项目复制粘贴。

注意:此包明确不会禁用 Eloquent 模型上的自动递增。在数据库索引方面,通常使用自动递增整数进行内部查询更为高效。对 uuid 列进行索引可以使对该列的查找更快,而不会影响相关模型之间的查询。

有关更多信息,请参阅关于以优化方式存储和使用 UUID 的这篇文章

如果您想轻松生成将 UUID 高效存储在数据库中的迁移,请查看laravel-efficient-uuid

如果您需要与 ramsey/uuid >= 4.1 兼容,请使用此包的版本 >= 6.2.0。

从版本 7.1.0 开始,此包仅支持 UUID 版本 1 (uuid1)、4 (uuid4)、6 (uuid6 - 有序) 和 有序 (Laravel 的有序 UUID v4) 以及 7 (uuid7)。

此包支持 Laravel 10 和 PHP 8.1 及以上版本。

代码示例

为了使用此包,您只需在 Eloquent 模型中导入并使用该特质。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Dyrynda\Database\Support\GeneratesUuid;

class Post extends Model
{
    use GeneratesUuid;
}

假设您已经在数据库中有一个名为 uuid 的字段,用于存储生成的值。如果您希望使用自定义列名,例如,如果您希望主 id 列是 UUID,您可以在模型中定义一个 uuidColumn 方法。

class Post extends Model
{
    public function uuidColumn(): string
    {
        return 'custom_column';
    }
}

您可以通过指定 uuidColumns 方法中的数组在每个表中拥有多个 UUID 列。当使用 whereUuid 范围进行查询时,将使用由 uuidColumn 指定的默认列。

class Post extends Model
{
    public function uuidColumns(): array
    {
        return ['uuid', 'custom_column'];
    }
}

默认情况下,此包将使用 uuid 作为存储生成的 UUID 值的列名。如果您希望使用不同的名称,您可以更改 model-uuid.column_name 配置变量。

您还可以在每个模型级别上覆盖 uuidColumn 方法。

默认情况下,此包将使用 UUID 版本 4 值,但是,您可以在模型中指定受保护的属性 $uuidVersion 来使用 uuid1uuid4uuid6uuid7。如果您想利用在 Laravel 5.6 中引入的 有序 UUID(版本 4)值,您应该在模型中将 $uuidVersion 指定为 ordered

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Dyrynda\Database\Support\GeneratesUuid;

class Post extends Model
{
    use GeneratesUuid;

    public function uuidVersion(): string
    {
        return 'uuid5';
    }
}

虽然不推荐,但如果您确实选择使用UUID作为主模型键(id),请确保正确配置模型。不更新这些属性会导致Laravel尝试将您的id列转换为整数,这将转换为0。当与laravel-efficient-uuid结合使用时,这种转换将导致抛出Ramsey\Uuid\Exception\InvalidUuidStringException异常。

<?php

namespace App;

use Dyrynda\Database\Support\GeneratesUuid;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use GeneratesUuid;

    public $incrementing = false;

    protected $keyType = 'string';
}

此特性还提供了一种查询范围,允许您根据其UUID轻松找到记录,并尊重您选择的任何自定义字段名称。

// Find a specific post with the default (uuid) column name
$post = Post::whereUuid($uuid)->first();

// Find multiple posts with the default (uuid) column name
$post = Post::whereUuid([$first, $second])->get();

// Find a specific post with a custom column name
$post = Post::whereUuid($uuid, 'custom_column')->first();

// Find multiple posts with a custom column name
$post = Post::whereUuid([$first, $second], 'custom_column')->get();

如果您使用推荐的laravel-efficient-uuid包,则需要将转换添加到模型中,以正确设置和检索您的UUID值。这将确保您的UUID以二进制形式写入您的(MySQL)数据库,并以字符串形式展示。

<?php

namespace App;

use Dyrynda\Database\Support\Casts\EfficientUuid;
use Dyrynda\Database\Support\GeneratesUuid;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use GeneratesUuid;

    protected $casts = [
        'uuid' => EfficientUuid::class,
    ];
}

路由模型绑定

从6.5.0版本开始,如果您想利用uuid字段的隐式路由模型绑定,可以使用BindsOnUuid特性,它将默认使用配置的uuidColumn

<?php

namespace App;

use Dyrynda\Database\Support\BindsOnUuid;
use Dyrynda\Database\Support\GeneratesUuid;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use BindsOnUuid, GeneratesUuid;
}

如果您需要额外的绑定控制,或使用此包的版本小于6.5.0,您可以直接覆盖getRouteKeyName方法。

public function getRouteKeyName(): string
{
    return 'uuid';
}

如果您使用laravel-efficient-uuid包,隐式路由模型绑定将不会直接工作。

在针对存储在数据库中的二进制数据进行查询时,Laravel将使用uuid字段的字符串表示形式执行查询。在这种情况下,您需要使用在您的RouteServiceProvider中包含的查询范围显式绑定参数。

// app/Providers/RouteServiceProvider.php

public function boot()
{
    Route::bind('post', function ($post) {
        return \App\Post::whereUuid($post)->first();
    });
}

安装

此包通过Composer安装。要安装,请运行以下命令。

composer require dyrynda/laravel-model-uuid

如果您想覆盖默认配置,可以将配置文件发布到您的应用程序。

php artisan vendor:publish --tag=model-uuid-config

支持

如果您对此包有任何一般性问题,请随时通过Twitter联系我。

如果您认为您发现了一个问题,请使用GitHub问题跟踪器报告它,或者更好的做法是,克隆仓库并提交一个pull request。

如果您在使用此包,我很乐意听到您的想法。谢谢!

实体书

您可以使用此包,但如果它进入您的生产环境,您需要为世界买一棵树。

现在众所周知,应对气候危机并防止气温上升超过1.5C的最佳工具之一是植树。如果您支持此包并为Treeware森林做出贡献,您将为当地家庭创造就业机会并恢复野生动物栖息地。

您可以在这里购买树木。

有关Treeware的更多信息,请参阅treeware.earth