ホームページ  >  記事  >  PHPフレームワーク  >  Laravel が長整数のスノーフレーク ID を文字列に自動的に変換する方法を説明します

Laravel が長整数のスノーフレーク ID を文字列に自動的に変換する方法を説明します

藏色散人
藏色散人転載
2020-11-03 15:06:072740ブラウズ

次のチュートリアルコラムでは、Laravel が長整数のスノーフレーク ID を文字列に自動的に変換する方法を紹介します。困っている友達を助けましょう! API を設計する場合、セキュリティなどの理由から、自動インクリメント ID の使用を放棄して、ID を非連続で推測不可能にする必要がある場合があります。これは通常、ハッシュ ID、UUID、Snowflake ID などを使用して実現できます。 最近のプロジェクトで、Snowflake ID を使用してみました。いろいろいじってみた結果、パフォーマンスは非常に高く、実装は非常に簡単であることがわかりました。しかし、続けてフロントエンド部分に接続すると、保存されている ID が符号なしの bigint 値であるため、JS の精度が失われるという問題が発生しました。 (なぜ精度が落ちるのかについては、ここでは詳しく説明しません。わからない場合はご自身で調べてください。) この記事では主に解決策を紹介します。

この問題を解決するための基本原理は非常に単純です。つまり、ID を文字列に変換してフロントエンドに返すというものです。

悪い試み

最初は、Laravel Eloquent モデルのモデル アクセサーを使用することを考えていました。変換する必要があるモデルに getIdAttribute を追加し、ID を文字列に変換するだけですよね。 例: App\Models\User モデルは次のように記述します:

/**

 * @return string

 */public function getIdAttribute(){

    return strval($this->attributes['id']);}

ただし、これは当てはまりません。属性アクセサーは、API によってフロントエンドに返される ID を実際に作成できます。弦。ただし、関連付けられたモデルの挿入と変更の結果にも影響します。たとえば、ユーザーが投稿モデルに関連付けられている場合、$user->posts()->saveMany(…); を使用して新しい投稿レコードを保存します。対応する user_id は空になります。

モデル アクセサーはモデル関連の処理に参加する必要があるため、これを理解するのは難しくありません。アクセサーは ID を数値から文字列に変換するため、当然データの混乱が生じます。

正しい姿勢

落ち着いて、よく考えてから行動しようと公式ドキュメントを確認したところ、Resourceはまさに私が求めていたものであることがわかりました。リソースはフロントエンドに返されるデータにのみ影響します。リソースをカスタマイズして、API が返す結果の構造、型変換、その他の関数を実装することができます。 IDの変更も簡単です。 トラブルを避けるために、App\Http\Resource 基本クラスを直接変更します。 toArray() メソッドをオーバーロードし、再帰を使用して JS の安全範囲を超える可能性のある値を変換するだけです。実際の状況に応じて、UserResource などの新しい Resource クラスを作成することもできます。

<?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;
    }
}

次に、インターフェイス コントローラーで Resource を返してデータを返すと、整数フィールドの値が自動的に文字列になります。

<?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);
    }
}

結果は以下のようになります。


Laravel 自动转换长整型雪花 ID 为字符串注意事項

このメソッドはトラバーサルを使用しているため、 、再帰的な処理があり、データ構造が複雑でデータ量が多い場合、パフォーマンスに一定の影響を与える可能性があります。これは怠惰な書き方だと思いますが、パフォーマンスを追求する場合は、Resource クラスをカスタマイズしてから、特定の既知のフィールド名に基づいて変換する方が良いでしょう。フロントエンド ID は文字列に変換され、フロントエンドは比較判断、特に === 判断を行う際に特別な注意を払う必要があります。

以上がLaravel が長整数のスノーフレーク ID を文字列に自動的に変換する方法を説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。