Laravel模型如何对JSON列的嵌套元素执行类型转换?
Laravel 中 JSON 字段嵌套元素的加密处理方案
Laravel 的 $casts 不支持直接对 JSON 嵌套字段做类型转换,你可以通过以下两种方案实现 credentials 数组中 pass 元素的加密:
方法一:使用访问器与修改器
通过自定义字段的读写逻辑,手动处理加密和解密:
保留数组类型转换
在 User 模型中维持原有配置:protected $casts = [ 'credentials' => 'array', ];添加修改器(存储时加密)
定义setCredentialsAttribute方法,在存储数据时自动加密pass:public function setCredentialsAttribute($value) { if (isset($value['pass'])) { $value['pass'] = encrypt($value['pass']); } $this->attributes['credentials'] = json_encode($value); }添加访问器(读取时解密)
定义getCredentialsAttribute方法,读取数据时自动解密pass:public function getCredentialsAttribute($value) { $credentials = json_decode($value, true); if (isset($credentials['pass'])) { $credentials['pass'] = decrypt($credentials['pass']); } return $credentials; }
方法二:自定义类型转换类
如果需要在多个模型复用该逻辑,可以创建自定义转换类:
创建转换类
在app/Casts目录下新建EncryptedCredentials.php:namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Support\Facades\Crypt; class EncryptedCredentials implements CastsAttributes { public function get($model, $key, $value, $attributes) { $credentials = json_decode($value, true); if (isset($credentials['pass'])) { $credentials['pass'] = Crypt::decrypt($credentials['pass']); } return $credentials; } public function set($model, $key, $value, $attributes) { if (isset($value['pass'])) { $value['pass'] = Crypt::encrypt($value['pass']); } return json_encode($value); } }在模型中应用转换类
修改 User 模型的$casts配置:protected $casts = [ 'credentials' => \App\Casts\EncryptedCredentials::class, ];
注意事项
- 确保
.env文件中已配置有效的APP_KEY,否则加密/解密会失败。 - 若数据库中已有未加密的
pass数据,需先批量加密后再启用上述代码,避免读取时报错。
内容的提问来源于stack exchange,提问作者qwaz
相关产品推荐
相关产品推荐

