rossbearman / eloquent-calamari
使用 Sqids 对 Laravel 和 Eloquent 的递增 IDs 进行加密。
Requires
- php: ^8.2
- ext-mbstring: *
- illuminate/config: ^10.0 | ^11.0
- illuminate/contracts: ^10.0 | ^11.0
- illuminate/database: ^10.0 | ^11.0
- illuminate/support: ^10.0 | ^11.0
- sqids/sqids: ^0.4.0
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.13
- orchestra/testbench: ^8.21 | ^v9.0
- phpunit/phpunit: ^10.5
README
Eloquent Calamari 将 Sqids1 算法集成到 Laravel 和 Eloquent 中,使您能够无缝使用加密的唯一 ID 替代内部的自动递增 ID。
- 使用简短、唯一的标识符加密自动递增的 ID
- 模型间的 Sqids 唯一,ID 1 在每个模型上表示不同
- 可选的基于 Sqid 的路由绑定
SqidBasedRouting - 透明处理非规范 ID
example.com/link/2fC37YMkO === Link::find(1)
example.com/video/TaRfL1RAK === Video::find(1)
入门指南
使用 Composer 安装此包。
composer require rossbearman/eloquent-calamari
将 HasSqid 和 SqidBasedRouting 特性添加到您的模型中。
use RossBearman\Sqids\HasSqid; use RossBearman\Sqids\SqidBasedRouting; class Customer extends Model { use HasSqid, SqidBasedRouting; }
为您的模型创建一个路由。
Route::get('/customer/{customer}', fn (Customer $customer) => $customer);
$customer = Customer::create(['name' => 'Squidward']); $customer->id; // 1 $customer->sqid; // 3irWXI2rFV
example.com/customer/3irWXI2rFV 现在返回客户详情。
查询
常见的查询方法也可用。
Customer::findBySqid($sqid); Customer::findBySqidOrFail($sqid); Customer::whereSqid($sqid)->get(); Customer::whereSqidIn($sqids)->get(); Customer::whereSqidNotIn($sqids)->get();
表示
默认情况下,Sqid 不包含在模型的 toArray() 或 toJson() 输出中,并且 ID 也不会从这些中隐藏。您可以使用 Eloquent 的 appends 和 hidden 属性来实现这一点。
class Customer extends Model { use HasSqid, SqidBasedRouting; protected $appends = ['sqid']; protected $hidden = ['id']; }
自定义路由
您可以通过重写模型的 getRouteKeyName() 方法,在利用 SqidBasedRouting 的同时,仍拥有不同的默认绑定。
class Customer extends Model { use HasSqid, SqidBasedRouting; public function getRouteKeyName(): string { return 'id'; } }
// Routes by ID by default Route::get('/admin/customer/{customer}', fn (Customer $customer) => $customer); // Routes by Sqid when specified Route::get('/customer/{customer:sqid}', fn (Customer $customer) => $customer);
配置
默认情况下,Eloquent Calamari 为每个模型生成一个随机 字母表,通过将默认字母表与 Xoshiro256StarStar 算法进行打乱,并通过配置中设置的模型名称和键的组合进行播种。
这确保了具有相同 ID 的不同模型实体将具有唯一的 Sqid,但它对模型名称或应用密钥的变化非常敏感。如果更改了其中任何一个,Sqids 将无法解析回相同的 ID。
重要
强烈建议您使用 sqids.alphabets 配置键显式地为每个模型设置预打乱的字母表,这将禁用该模型的打乱行为。
设置字母表
首先将 sqids.php 配置文件发布到您的 config 目录。
php artisan vendor:publish --provider="RossBearman\Sqids\SqidsServiceProvider"
然后为您模型生成一个新的字母表。
php artisan sqids:alphabet "App\Models\Customer"
您也可以一次为多个模型生成字母表。
php artisan sqids:alphabet "App\Models\Customer" "App\Models\Order" "App\Models\Invoice"
按照命令提示添加新键到您的 config/sqids.php 和 .env 文件。
确认正在使用字母表
为了确保 Eloquent Calamari 使用预期的字母表为特定模型,请使用以下命令。
php artisan sqids:check
这将列出在配置中成功注册的所有模型以及类字符串是否可以在您的应用程序中解析为类。
设置最小 Sqid 长度
默认情况下,所有 Sqid 至少为 10 个字符。您可以通过分配不同的值(至少为 3)来为每个模型调整此值到 sqids.min_lengths 配置数组。
'min_lengths' => [ App\Model\Customer::class => 20, App\Model\Order::class => 8, App\Model\Invoice::class => 30, ],
Sqid的最大长度取决于输入ID和所使用的字母表。字母表更加丰富(大写和小写字母、数字和符号)将导致Sqid更短。
规范Sqid
按照设计,多个Sqid可以解析到同一个数字,但是Eloquent Calamari总是会为给定的数字返回相同的Sqid。此外,这是唯一可以用来访问实体的Sqid,任何其他可以正常解析到相同数字的Sqid都将被拒绝。
可以通过向sqids.canonical_checks配置数组添加条目来禁用每个模型上的此检查。
'canonical_checks' => [ App\Model\Customer::class => false, ],
开发
PHPUnit测试
composer test
PHPStan分析
composer analyse
Pint代码检查
composer lint
安全
如果您在此软件包中发现漏洞,请发送电子邮件至ross@rossbearman.co.uk。
许可证
MIT许可证(MIT)。有关更多信息,请参阅LICENSE.md。