侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用Laravel Lift扩展包提升您的Eloquent模型

Laravel  /  管理员 发布于 1年前   410

Lift是一个用于在Laravel中增强Eloquent模型的软件包。它能让你在 Eloquent 模型中创建与表模式相匹配的公共属性。这使得你的模型在任何 IDE 中都更容易读取和使用。

通过使用 PHP 8 的属性,它提供了一种设置模型的简单方法,重点在于简单易用。

该软件包的运行依赖于 Eloquent Events。这意味着该软件包可以轻松融入您的项目,无需做任何重大改动(除非您关闭了事件触发功能)。


在这篇文章中,让我们深入了解 Lift,了解它提供的所有功能。

lift官网:

https://wendell-adriel.gitbook.io/laravel-lift/


安装 Laravel Lift

你可以通过 composer 安装软件包:

composer require wendelladriel/laravel-lift

要开始使用 Lift,您需要在 Eloquent 模型中添加 Lift 特性,然后就可以开始使用了。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
}


特性

在 Eloquent 模型中添加 Lift 特性后,您就可以在模型上创建公共属性,从而使模型更易于理解,并可在任何集成开发环境中使用。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    public $id;
 
    public $name;
 
    public $price;
}

当你开始使用软件包提供的属性时,神奇的事情就发生了。


类属性

数据库属性

Lift 提供了 DB 属性,您可以用它来定义模型的连接、表和时间戳。

不使用 Lift
use Illuminate\Database\Eloquent\Model;
 
final class Product extends Model
{
    public $timestamps = false;
 
    protected $connection = 'mysql';
 
    protected $table = 'custom_products_table';
 
    // ...
}

使用 Lift
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\DB;
use WendellAdriel\Lift\Lift;
 
#[DB(connection: 'mysql', table: 'custom_products_table', timestamps: false)]
final class Product extends Model
{
    use Lift;
    // ...
}


关系属性

Lift 提供了定义模型间关系的属性,因此您可以将它们定义为属性,而不是使用方法来定义它们。所有关系属性都接受与方法相同的参数。

不使用 Lift
// Post.php
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
 
final class Post extends Model
{
    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }
    // ...
}
 
// Comment.php
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
final class Comment extends Model
{
    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }
    // ...
}

使用 Lift
// Post.php
 
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Relations\HasMany;
use WendellAdriel\Lift\Lift;
 
#[HasMany(Comment::class)]
final class Post extends Model
{
    use Lift;
    // ...
}
 
// Comment.php
 
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Relations\BelongsTo;
use WendellAdriel\Lift\Lift;
 
#[BelongsTo(Post::class)]
final class Comment extends Model
{
    use Lift;
    // ...
}

您可以在文档中查看所有可用的关系属性。

https://wendell-adriel.gitbook.io/laravel-lift/usage/attributes/relationships

这些关系的工作方式与使用方法定义的关系相同。


属性

铸造属性

Lift 提供了一个 Cast 属性,您可以用它来定义模型属性的铸型。

除了铸入值外,它还允许您键入属性。

不使用 Lift
use Illuminate\Database\Eloquent\Model;
 
final class Product extends Model
{
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
        'active' => 'boolean',
        'expires_at' => 'immutable_datetime',
    ];
}

使用 Lift
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Cast('string')]
    public string $name;
 
    #[Cast('float')]
    public float $price;
 
    #[Cast('boolean')]
    public bool $active;
 
    #[Cast('immutable_datetime')]
    public CarbonImmutable $expires_at;
}


列属性

Lift 提供了一个 Column 属性,可用于自定义模型属性的列名并为其定义默认值。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Cast('string')]
    #[Column('product_name')]
    public string $name;
 
    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
}

在上面的示例中,name 属性将映射到 product_name 列,price 属性将映射到 product_price 列,默认值为 0.0。

您甚至可以为默认值传递一个函数名,当属性保存到数据库时,将调用该函数名。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Cast('string')]
    #[Column('product_name')]
    public string $name;
 
    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
 
    #[Cast('float')]
    #[Column(default: 'generatePromotionalPrice')]
    public float $promotional_price;
 
    public function generatePromotionalPrice(): float
    {
        return $this->price * 0.8;
    }
}


可填充属性

使用 Lift 特性时,模型的所有属性都会设置为受保护。您可以使用 Fillable 属性来定义哪些属性可以批量分配。

不使用 Lift
use Illuminate\Database\Eloquent\Model;
 
final class Product extends Model
{
    protected $fillable = [
        'name',
        'price',
    ];
 
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
    ];
}

使用 Lift
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    public float $price;
}


隐藏属性

Lift 提供了一个隐藏属性,当模型转换为数组或 JSON 时,可以用它来隐藏属性。

不使用 Lift
use Illuminate\Database\Eloquent\Model;
 
final class Product extends Model
{
    protected $fillable = [
        'name',
        'price',
        'active',
    ];
 
    protected $casts = [
        'id' => 'int',
        'name' => 'string',
        'price' => 'float',
        'active' => 'boolean',
    ];
 
    protected $hidden = [
        'active',
    ];
}

使用 Lift
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Hidden;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    public float $price;
 
    #[Hidden]
    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}


不可变属性

Lift 提供了一个 Immutable 属性,可以用来使属性不可变。这意味着一旦创建了模型,就不能更改属性。如果你试图更改它,将会抛出一个WendellAdriel\Lift\Exceptions\ImmutablePropertyException 异常。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Immutable;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Immutable]
    #[Fillable]
    #[Cast('string')]
    public string $name;
}
 
$product = Product::query()->create([
    'name' => 'Product 1',
]);
 
$product->name = 'Product 2';
$product->save(); // Throws an WendellAdriel\Lift\Exceptions\ImmutablePropertyException


主键属性

Lift 提供了一个 PrimaryKey 属性,您可以用它来自定义模型的主键。

不使用 Lift
use Illuminate\Database\Eloquent\Model;
 
final class Product extends Model
{
    public $incrementing = false;
 
    protected $primaryKey = 'uuid';
 
    protected $keyType = 'string';
    // ...
}
使用 Lift
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\PrimaryKey;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[PrimaryKey(type: 'string', incrementing: false)]
    #[Cast('string')]
    public string $uuid;
    // ...
}


规则属性

Lift 提供了一个 Rules 属性,你可以用它来定义模型属性的验证规则。

>验证规则的设置方法与 Laravel 表单请求中的方法相同,甚至还可以为每条规则设置自定义信息。

只有在保存模型(创建或更新)时才会验证规则。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;
 
    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}


观察属性

默认情况下,Eloquent 会在模型创建、更新、删除等操作时触发事件。但这只是一个通用事件,有时你需要在属性发生变化时触发一个特定事件。这就是 Watch 属性的用武之地。

你可以定义一个自定义事件,在属性发生变化时触发。该事件将接收更新的模型实例作为参数。

// Product.php
 
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Watch;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    #[Watch(PriceChangedEvent::class)]
    public float $price;
 
    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}
 
// PriceChangedEvent.php
 
final class PriceChangedEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
 
    public function __construct(
        public Product $product,
    ) {
    }
}


方法

除了该软件包提供的所有属性外,它还提供了一些方法,您可以使用这些方法获取有关模型的更多信息。


自定义列

它将返回一个数组,其中包含您在模型中定义的所有自定义列。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Cast('string')]
    #[Column('product_name')]
    public string $name;
 
    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
}
 
Product::customColumns();
 
// WILL RETURN
[
    'name' => 'product_name',
    'price' => 'product_price',
]


defaultValues()

将返回一个数组,其中包含已定义默认值的所有属性。如果默认值是一个函数,那么返回的将是函数名而不是函数结果,因为这是一个静态调用。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Cast('string')]
    #[Column('product_name')]
    public string $name;
 
    #[Cast('float')]
    #[Column(name: 'product_price', default: 0.0]
    public float $price;
 
    #[Cast('float')]
    #[Column(default: 'generatePromotionalPrice')]
    public float $promotional_price;
 
    public function generatePromotionalPrice(): float
    {
        return $this->price * 0.8;
    }
}
 
Product::defaultValues();
 
// WILL RETURN
[
    'price' => 0.0,
    'promotional_price' => 'generatePromotionalPrice',
]

immutableProperties()

将返回一个数组,其中包含所有不可变的属性。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Immutable;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Immutable]
    #[Fillable]
    #[Cast('string')]
    public string $name;
}
 
Product::immutableProperties();
 
// WILL RETURN
[
    'name',
]

validationMessages()

将返回一个数组,其中包含您在模型中定义的所有验证信息。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;
 
    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}
 
Product::validationMessages();
 
// WILL RETURN
[
    'name' => [],
    'price' => [],
    'active' => [
        'required' => 'You must set the active status for the product',
    ],
]

validationRules()

将返回一个数组,其中包含您在模型中定义的所有验证规则。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Rules;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    #[Rules(['required', 'string', 'max:255'])]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    #[Rules(['required', 'numeric', 'min:0.0'])]
    public float $price;
 
    #[Fillable]
    #[Cast('boolean')]
    #[Rules(rules: ['required', 'boolean'], messages: ['required' => 'You must set the active status for the product'])]
    public bool $active;
}
 
Product::validationRules();
 
// WILL RETURN
[
    'name' => ['required', 'string', 'max:255'],
    'price' => ['required', 'numeric', 'min:0.0'],
    'active' => ['required', 'boolean'],
]

watchedProperties()

将返回一个数组,其中包含定义了自定义事件的所有属性。

use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Fillable;
use WendellAdriel\Lift\Attributes\Watch;
use WendellAdriel\Lift\Lift;
 
final class Product extends Model
{
    use Lift;
 
    #[Cast('int')]
    public int $id;
 
    #[Fillable]
    #[Cast('string')]
    public string $name;
 
    #[Fillable]
    #[Cast('float')]
    #[Watch(PriceChangedEvent::class)]
    public float $price;
 
    #[Fillable]
    #[Cast('boolean')]
    public bool $active;
}
 
Product::watchedProperties();
 
// WILL RETURN
[
    'price' => PriceChangedEvent::class,
]


结论

Lift是一个将 Doctrine、Spring 和 Entity Framework 等工具的某些功能引入 Eloquent 的软件包。

通过利用 PHP 8 的属性,它能让你的模型更易于阅读和理解,外观也更简洁。



  • 上一条:
    Laravel 10.21版本发布
    下一条:
    在go语言中实现使用异步方式读取MySQL数据流程步骤及代码示例
  • 昵称:

    邮箱:

    1条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • Laravel 11.14版本发布 - 新的字符串助手和ServeCommand改进(0个评论)
    • Laravel 11.12版本发布 - Artisan的`make`命令自动剪切`.php `扩展(0个评论)
    • Laravel的轻量型购物车扩展包:binafy/laravel-cart(0个评论)
    • Laravel 11.11版本发布 - 查看模型中的第三方关系:show(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-01
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客