morrislaptop / laravel-popo-caster
使用 Symfony's Serializer 在 Laravel 中自动将 JSON 列转换为丰富的 PHP 对象
Requires
- php: ^8.0
- illuminate/contracts: ^8.67|^9.0|^10.0|^11.0
- morrislaptop/symfony-custom-normalizers: ^0.4|^0.5
- symfony/property-access: ^5.2|^6.0|^7.0
- symfony/property-info: ^5.2|^6.0|^7.0
- symfony/serializer: ^5.2|^6.0|^7.0
Requires (Dev)
- brick/money: ^0.5.1|^0.8
- friendsofphp/php-cs-fixer: ^3.8
- mockery/mockery: ^1.4
- orchestra/testbench: ^7.9|^8.0|^9.0
- phpunit/phpunit: ^9.3
- vimeo/psalm: ^4.4|^5.6
README
Laravel 很棒。Spatie 的 数据传输对象 包对于 PHP 来说很棒。但是它们不会将对象如日期转换为 DateTime,集合有点痛苦。普通旧 PHP 对象(POPOs)在这方面稍好一些。
你是否曾经想要将你的 JSON 列转换为值对象?
此包为你提供了 2 个 caster 类
Serializer
,它将你的值对象序列化并存储在单个 JSON 字段中Normalizer
,它将你的值对象规范化并将属性存储在模型的字段上
底层实现了 Laravel 的 Castable
接口 和 Laravel 的 自定义 cast,用于在 object
(或兼容数组)和你的 JSON 数据库列之间进行序列化。它使用 Symfony 的 Serializer 来实现这一点。
此包受到 Laravel Castable Data Transfer Object 的启发!
安装
您可以通过 composer 安装此包
composer require morrislaptop/laravel-popo-caster
Serializer 使用方法
1. 创建你的 POPO
namespace App\Values; class Address { public function __construct( public string $street, public string $suburb, public string $state, public Carbon $moved_at, ) { } }
2. 配置你的 Eloquent 属性以转换为它
请注意,这应该在您的数据库模式中的 jsonb
或 json
列上。对象和数组都受支持。
namespace App\Models; use App\Values\Address; use Illuminate\Database\Eloquent\Model; use Morrislaptop\LaravelPopoCaster\Serializer; /** * @property Address $address */ class User extends Model { protected $casts = [ 'address' => Serializer::class . ':' . Address::class, 'prev_addresses' => Serializer::class . ':' . Address::class . '[]', ]; }
就这样!你现在可以传递你的 Address
类的实例,或者甚至只是一个具有兼容结构的数组。它将自动在您的类和 JSON 之间进行转换以进行存储,数据在输入和输出时将进行验证。
$user = User::create([ // ... 'address' => [ 'street' => '1640 Riverside Drive', 'suburb' => 'Hill Valley', 'state' => 'California', 'moved_at' => now(), ], 'addresses' => [ [ 'street' => '42 Wallaby Way', 'suburb' => 'Sydney', 'state' => 'NSW', 'moved_at' => '2020-01-14T00:00:00Z', ], ] ]) $residents = User::where('address->suburb', 'Hill Valley')->get();
但最好的部分是,你可以通过添加领域特定的方法来装饰你的类,将其转换为强大的值对象。
$user->address->toMapUrl(); $user->address->getCoordinates(); $user->address->getPostageCost($sender); $user->address->calculateDistance($otherUser->address); $user->address->moved_at->diffForHumans(); echo (string) $user->address;
Normalizer 使用方法
1. 创建你的 POPO
namespace App\Values; class Money { public function __construct( public int $amount, public string $currency, ) { } }
2. 配置你的 Eloquent 属性以转换为它
请注意,您的值对象的属性应该是您数据库模式中的列。
namespace App\Models; use App\Values\Money; use Illuminate\Database\Eloquent\Model; use Morrislaptop\LaravelPopoCaster\Normalizer; /** * @property Money $money */ class User extends Model { protected $casts = [ 'money' => Normalizer::class . ':' . Money::class, ]; }
就这样!你现在可以传递你的 Money
类的实例,或者在模型上设置单个属性。它将自动在您的类和属性之间进行转换以进行存储,数据在输入和输出时将进行验证。
$user = User::create([ // ... 'amount' => 1000, 'curency' => 'AUD', ]); $user = User::create([ // ... 'money' => new Money(1000, 'AUD'), ])
但最好的部分是,你可以通过添加领域特定的方法来装饰你的类,将其转换为强大的值对象。
$user->money->convertTo('USD');
插件
想要一个轻松模拟或为您的 POPO 创建工厂的方法?查看 morrislaptop/popo-factory
测试
composer test
更新日志
请参阅 CHANGELOG 以获取有关最近更改的更多信息。
贡献
请参阅 CONTRIBUTING 以获取详细信息。
安全漏洞
请查看我们关于如何报告安全漏洞的 安全策略。
鸣谢
许可证
MIT许可证(MIT)。更多信息请参阅许可证文件。