首页 > 解决方案 > 当响应为 JSON 且字段包含数字时,模型访问器不起作用

问题描述

我有许多“get”突变器可以解密数据,以便它可以在视图中读取。这些变异器是数据库中字段的名称。除了 2 之外,大多数这些工作。这 2 个 mutator 的唯一区别是 mutator 函数名称包含数字。

有效的突变器示例:

public function getDateOfBirthAttribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

不起作用的突变器示例:

public function getAddressLine1Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

public function getAddressLine2Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

表中的字段名称:

关于这一切的非常奇怪的事情是,当响应不是 json 时,mutator 会按预期工作并解密该字段。(例如使用return view('view.name', compact($user))),但是当我将此数据放入 JSON 响应时(例如return response()->json([$user]);,2 个地址行突变器不起作用并返回未触及的字段。

我已经尝试添加return "test"到这 2 个 mutators 以查看它是否甚至可以达到该功能,但事实并非如此。

为什么在这种情况下 JSON 会阻止 mutator 工作?函数名称中的数字可能是问题吗?我可以重命名数据库中的字段吗?

标签: phplaravellaravel-5

解决方案


我现在无法验证这一点,但我认为这可能与 laravel 的计算方式snake_casecamel_case.

基本上,当您请求类似 的字段时$user->address_line_1,laravel 会转换 camelCase ( AddressLine1) 中的字段并检查自定义访问器,它会找到它并返回正确的修改值。

但是,当模型序列化为 Json 时,它会执行相反的操作:它会尝试通过查看访问器来检测需要修改的字段。因此,它找到getAddressLine1Attribute并将其转换为 snake_case.. yielding address_line1,一个错误的字段。

这里的基本问题是两者都address_line_1具有address_line1相同的驼峰式表示,因此不可能可靠地将转换反转为驼峰式。

您可以尝试的一种技巧是将访问器定义为getAddressLine_1Attribute,但直接访问该字段时它将不起作用($user->address_line_1

您可以将其定义为使用先前定义的访问器,因此您没有代码重复:

public function getAddressLine_1Attribute($value)
{
    return $this->getAddressLine1Attribute($value);
}

public function getAddressLine1Attribute($value)
{
    return empty($value) ? '' : decrypt($value);
}

编辑:我的理论已经通过 camel_case() 和 snake_case() 辅助函数的一些测试得到证实


推荐阅读