The following tutorial column will introduce you to the method of Laravel automatically converting long integer snowflake IDs into strings. I hope it will be helpful to friends in need! When designing an API, for reasons such as security, it is sometimes necessary to abandon the use of auto-incrementing IDs to make the IDs non-continuous and unguessable. This can usually be achieved using Hash id, UUID, Snowflake ID, etc. In a recent project, I tried using Snowflake ID. After a lot of fiddling around, I found that the performance is quite high and the implementation is quite simple. However, when I continued to roll up my sleeves and connect with the front-end part, the problem of JS precision loss occurred because the stored ID was an unsigned bigint value. (As for why there is a loss of accuracy, I will not explain it in detail here. If you are not sure, you can search it by yourself). This article mainly introduces solutions.
To solve this problem, the basic principle is very simple, that is, convert the ID into a string and then return it to the front end.
Bad Attempt
/** * @return string */public function getIdAttribute(){ return strval($this->attributes['id']);}
But this is not the case. The attribute accessor can indeed make the ID returned by the API to the front end become a string. But it will also affect the results of inserting and modifying the associated model. For example, if user is associated with the post model, use $user->posts()->saveMany(…); to save new posts records in this way. The corresponding user_id will be empty.
This is not difficult to understand, because the model accessor needs to participate in model-related processing. The accessor converts the ID from a number to a string, which will naturally lead to data confusion.
Correct posture
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class Resource extends JsonResource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request $request * * @return array */ public function toArray($request) { $parentReturn = parent::toArray($request); foreach (array_keys($parentReturn) as $key) { // 为方便演示这里把所有整型字段都转成字符串 if (is_int($parentReturn[$key])) { $parentReturn[$key] = strval($parentReturn[$key]); } // 关联的字段,如 $user->post,相当于递归处理 if (is_array($parentReturn[$key])) { $parentReturn[$key] = new Resource($parentReturn[$key]); } } return $parentReturn; } }
Then, return Resource in the interface controller to return data, and the integer field value will automatically become a string.
<?php namespace App\Http\Controllers; use App\Http\Resources\Resource; use App\Models\User; use Illuminate\Http\Request; class TestController extends Controller { /** * @return \App\Http\Resources\Resource */ public function __invoke(Request $request) { $user = User::first(); return new Resource($user); } }
The result is as shown below:
Notes
Because it is returned to The front-end ID is converted to a string, and the front-end needs to pay special attention when making comparison judgments, especially === judgments
The above is the detailed content of Teach you how Laravel automatically converts long integer snowflake ID to string. For more information, please follow other related articles on the PHP Chinese website!