Laravel自动转换长整型雪花ID为字符串的示例

  介绍

这篇文章给大家分享的是有关Laravel自动转换长整型雪花ID为字符串的示例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

在设计API时,出于安全性等因素考虑,有时需要放弃使用自增ID,使ID非连续且不可猜测。通常可以使用散列ID、UUID、雪花ID等来实现。

在最近的一个项目中,我尝试使用雪花ID。一通折腾下来发现,逼格挺高,实现也挺简单,然而当我继续撸起袖子与前端部分对接时,却出现了JS精度丢失问题,因为存储的ID是一个无符号长整型数字型的值。(至于为什么会有精度丢失现象,这里就不具体解释了,不清楚的可以自行搜索),本文主要介绍解决办法。

想要解决这问题,基本原理也很简单,就是把ID转成字符串再返回给前端。

错误尝试

一开始我想到的是使用Laravel雄辩的模型的模型访问器。只要给需要转换的模型加一个getIdAttribute,将ID转成字符串不就行了嘛?

如:应用\ \用户模型模型里这样写:

/* *      ,* @return 字符串      ,*/public  function  getIdAttribute () {      ,,,return  strval ($ this→属性(& # 39;ID # 39;]);}

但事实并非如此,属性访问器确实能让API返回给前端变的ID为字符串。但同时也会影响关联模型插入,修改时的结果,例如,用户关联的了后模型,使用$ user→帖子()→saveMany (…);这种方式保存的新职位的记录,对应的user_id会为空。

这也不难理解,因为模型访问器是要参与模型相关处理的,访问器将ID由数字转为了字符串,自然会导致数据错乱。

正确姿势

冷静下来决定先认真思考再动的手,查阅了官方文档,才发现资源正是我想要的.Resource只会影响返回给前端的数据,我们可以通过自定义资源来实现API返回结果的结构,类型转换等功能。转换个ID自然也不在话下。

为了省的事,我直接修改程序\ Http \资源这个基类,只需要重载它的toArray()方法,在其中使用递归,对可能超出JS安全数值范围的值进行转换就可以了。大家也可以根据自己的实际情况,新建资源类,如UserResource来处理。

& lt; php ?      namespace  App \ Http \资源;      use 阐明\ Http \ \ Json \ JsonResource资源;      class  Resource  extends  JsonResource   {   ,,,/* *   ,,,,*,Transform 从而resource  into  an 数组。   ,,,,   ,,,,*,@param  \照亮\ Http \ Request 美元请求   ,,,,   ,,,,*,@return 数组   ,,,*/,,,public  function  toArray(请求)   ,,,{   ,,,,,,,parentReturn 美元;=,父:toArray($请求);      ,,,,,,,foreach (中的(parentReturn美元),as 美元键),{   ,,,,,,,,,,,//,为方便演示这里把所有整型字段都转成字符串   ,,,,,,,,,,,if  (is_int ($ parentReturn [$ key])), {   ,,,,,,,,,,,,,,,parentReturn美元(美元关键),=,strval ($ parentReturn [$ key]);   ,,,,,,,,,,,}      ,,,,,,,,,,,//,关联的字段,如,用户→美元,相当于递归处理   ,,,,,,,,,,,if  (is_array ($ parentReturn [$ key])), {   ,,,,,,,,,,,,,,,parentReturn美元(美元关键),=,new 资源($ parentReturn [$ key]);   ,,,,,,,,,,,}   ,,,,,,,}      ,,,,,,,return  parentReturn美元;   ,,,}   }

然后,在接口控制器中返回资源返回数据,整型字段值就会自动变为字符串了。

& lt; php ?      namespace 应用\ Http \控制器;      use  \ App \ Http \资源资源;      use 应用\ \用户模型;      use 照亮\ Http \请求;      class  TestController  extends 控制器   {   ,,,/* *   ,,,,*,@return  \ \ App \ Http \资源资源   ,,,*/,,,public  function  __invoke (Request  $请求)   ,,,{   ,,,,,,,user 美元;=,用户:第();   ,,,,,,,return  new 资源(用户);   ,,,}   }

结果如下图:
 Laravel自动转换长整型雪花ID为字符串的示例

注意事项

<李>

因为这种办法使用了遍历,而且有递归处理,当数据结构复杂,数据量较大时可能会对性能造成一定影响。我这里算是比较偷懒取巧的写法,如果对性能有追求,自定义资源类,然后根据特定的已知的字段名来进行转换会比较好

Laravel自动转换长整型雪花ID为字符串的示例