目錄
關鍵要點
安裝
創建數據庫
創建Transformer
創建控制器
分頁
包含子資源
急切加載
結論
PHP Fractal常見問題解答
什麼是PHP Fractal,為什麼它很重要?
PHP Fractal是如何工作的?
PHP Fractal中的Transformer是什麼?
PHP Fractal中的Serializer是什麼?
我如何在項目中實現PHP Fractal?
我可以將PHP Fractal與任何PHP項目一起使用嗎?
使用PHP Fractal的好處是什麼?
PHP Fractal與其他數據轉換工具相比如何?
我可以自定義PHP Fractal的輸出嗎?
我在哪裡可以了解更多關於PHP Fractal的信息?
首頁 後端開發 php教程 PHP Fractal-使您的API json變得漂亮,永遠!

PHP Fractal-使您的API json變得漂亮,永遠!

Feb 10, 2025 am 09:01 AM

PHP Fractal - Make Your API's JSON Pretty, Always!

本文經Viraj Khatavkar同行評審。感謝所有SitePoint的同行評審員,使SitePoint的內容達到最佳狀態!


如果您之前構建過API,我敢打賭您習慣於直接將數據作為響應輸出。如果操作正確,這可能不會造成危害,但有一些實際的替代方案可以幫助解決這個問題。

其中一個可用的解決方案是Fractal。它允許我們在將模型作為響應返回之前,為模型創建一個新的轉換層。它非常靈活,易於集成到任何應用程序或框架中。

PHP Fractal - Make Your API's JSON Pretty, Always!

關鍵要點

  • PHP Fractal是一種解決方案,允許開發人員在將模型作為響應返回之前為其模型創建新的轉換層,從而使JSON數據更易於管理和保持一致性。
  • Fractal靈活且易於集成到任何應用程序或框架中。它的工作原理是使用Transformer將復雜的數據結構轉換為更簡單的格式,並使用Serializer來格式化最終輸出。
  • Fractal還允許在用戶請求時包含子資源(關係)到響應中,從而為數據呈現增加了另一層靈活性和控制。
  • 使用Fractal可以通過一次性急切加載關係來優化查詢性能,從而解決了Eloquent延遲加載經常遇到的n 1問題。

安裝

我們將使用Laravel 5.3應用程序來構建示例並將Fractal包與其集成,因此請繼續使用安裝程序或通過Composer創建一個新的Laravel應用程序。

<code>laravel new demo</code>
登入後複製
登入後複製
登入後複製

<code>composer create-project laravel/laravel demo</code>
登入後複製
登入後複製
登入後複製

然後,在文件夾內,我們需要Fractal包。

<code>composer require league/fractal</code>
登入後複製
登入後複製

創建數據庫

我們的數據庫包含users和roles表。每個用戶都有一個角色,每個角色都有一個權限列表。

// app/User.php

class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'role_id',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}
登入後複製
登入後複製
// app/Role.php

class Role extends Model
{
    protected $fillable = [
        'name',
        'slug',
        'permissions'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}
登入後複製
登入後複製

創建Transformer

我們將為每個模型創建一個Transformer。我們的UserTransformer類如下所示:

// app/Transformers/UserTransformer.php

namespace App\Transformers;

use App\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email
        ];
    }
}
登入後複製
登入後複製

是的,創建Transformer就這麼簡單!它只是以開發人員可以管理的方式轉換數據,而不是留給ORM或存儲庫。

我們擴展TransformerAbstract類並定義transform方法,該方法將使用User實例調用。 RoleTransformer類也是如此。

namespace App\Transformers;

use App\Role;
use League\Fractal\TransformerAbstract;

class RoleTransformer extends TransformerAbstract
{
    public function transform(Role $role)
    {
        return [
            'name' => $role->name,
            'slug' => $role->slug,
            'permissions' => $role->permissions
        ];
    }
}
登入後複製
登入後複製

創建控制器

我們的控制器應該在將數據發送回用戶之前轉換數據。我們現在將處理UsersController類,暫時只定義index和show操作。

// app/Http/Controllers/UsersController.php

class UsersController extends Controller
{
    /**
     * @var Manager
     */
    private $fractal;

    /**
     * @var UserTransformer
     */
    private $userTransformer;

    function __construct(Manager $fractal, UserTransformer $userTransformer)
    {
        $this->fractal = $fractal;
        $this->userTransformer = $userTransformer;
    }

    public function index(Request $request)
    {
        $users = User::all(); // 从数据库获取用户
        $users = new Collection($users, $this->userTransformer); // 创建资源集合转换器
        $users = $this->fractal->createData($users); // 转换数据

        return $users->toArray(); // 获取转换后的数据数组
    }
}
登入後複製
登入後複製

index操作將從數據庫查詢所有用戶,使用用戶列表和轉換器創建一個資源集合,然後執行實際的轉換過程。

{
  "data": [
    {
      "name": "Nyasia Keeling",
      "email": "crooks.maurice@example.net"
    },
    {
      "name": "Laron Olson",
      "email": "helen55@example.com"
    },
    {
      "name": "Prof. Fanny Dach III",
      "email": "edgardo13@example.net"
    },
    {
      "name": "Athena Olson Sr.",
      "email": "halvorson.jules@example.com"
    }
    // ...
  ]
}
登入後複製
登入後複製

當然,一次返回所有用戶是沒有意義的,我們應該為此實現分頁器。

分頁

Laravel傾向於簡化事情。我們可以像這樣實現分頁:

<code>laravel new demo</code>
登入後複製
登入後複製
登入後複製

但是為了使這與Fractal一起工作,我們可能需要添加一些代碼來轉換數據,然後再調用分頁器。

<code>composer create-project laravel/laravel demo</code>
登入後複製
登入後複製
登入後複製

第一步是從模型分頁數據。接下來,我們像以前一樣創建一個資源集合,然後在集合上設置分頁器。

Fractal為Laravel提供了一個分頁器適配器來轉換LengthAwarePaginator類,它還為Symfony和Zend提供了一個適配器。

<code>composer require league/fractal</code>
登入後複製
登入後複製

請注意,它為分頁詳細信息添加了額外的字段。您可以在文檔中閱讀更多關於分頁的信息。

包含子資源

現在我們已經熟悉了Fractal,是時候學習如何在用戶請求時包含子資源(關係)到響應中了。

我們可以請求包含額外資源到響應中,例如http://demo.vaprobash.dev/users?include=role。我們的轉換器可以自動檢測正在請求的內容並解析include參數。

// app/User.php

class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'role_id',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}
登入後複製
登入後複製

$availableIncludes屬性告訴轉換器我們可能需要包含一些額外的數據到響應中。如果include查詢參數請求用戶角色,它將調用includeRole方法。

// app/Role.php

class Role extends Model
{
    protected $fillable = [
        'name',
        'slug',
        'permissions'
    ];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}
登入後複製
登入後複製

$this->fractal->parseIncludes行負責解析include查詢參數。如果我們請求用戶列表,我們應該看到類似這樣的內容:

// app/Transformers/UserTransformer.php

namespace App\Transformers;

use App\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email
        ];
    }
}
登入後複製
登入後複製

如果每個用戶都有一個角色列表,我們可以將轉換器更改為如下所示:

namespace App\Transformers;

use App\Role;
use League\Fractal\TransformerAbstract;

class RoleTransformer extends TransformerAbstract
{
    public function transform(Role $role)
    {
        return [
            'name' => $role->name,
            'slug' => $role->slug,
            'permissions' => $role->permissions
        ];
    }
}
登入後複製
登入後複製

包含子資源時,我們可以使用點表示法嵌套關係。假設每個角色都有一個存儲在單獨表中的權限列表,並且我們想列出具有其角色和權限的用戶。我們可以這樣做include=role.permissions。

有時,我們需要默認包含一些必要的關聯,例如地址關聯。我們可以通過在轉換器中使用$defaultIncludes屬性來實現。

// app/Http/Controllers/UsersController.php

class UsersController extends Controller
{
    /**
     * @var Manager
     */
    private $fractal;

    /**
     * @var UserTransformer
     */
    private $userTransformer;

    function __construct(Manager $fractal, UserTransformer $userTransformer)
    {
        $this->fractal = $fractal;
        $this->userTransformer = $userTransformer;
    }

    public function index(Request $request)
    {
        $users = User::all(); // 从数据库获取用户
        $users = new Collection($users, $this->userTransformer); // 创建资源集合转换器
        $users = $this->fractal->createData($users); // 转换数据

        return $users->toArray(); // 获取转换后的数据数组
    }
}
登入後複製
登入後複製

我最喜歡Fractal包的一件事是能夠將參數傳遞給include參數。文檔中的一個很好的例子是按順序排列。我們可以將其應用到我們的示例中,如下所示:

{
  "data": [
    {
      "name": "Nyasia Keeling",
      "email": "crooks.maurice@example.net"
    },
    {
      "name": "Laron Olson",
      "email": "helen55@example.com"
    },
    {
      "name": "Prof. Fanny Dach III",
      "email": "edgardo13@example.net"
    },
    {
      "name": "Athena Olson Sr.",
      "email": "halvorson.jules@example.com"
    }
    // ...
  ]
}
登入後複製
登入後複製

這裡重要的部分是list($orderCol, $orderBy) = $paramBag->get('order') ?: ['created_at', 'desc'];,這將嘗試從用戶include獲取order參數,並將其應用於查詢構建器。

我們現在可以通過傳遞參數來按順序排列包含的用戶列表(/roles?include=users:order(name|asc))。您可以在文檔中閱讀更多關於包含資源的信息。

但是,如果用戶沒有任何關聯的角色會怎樣?它將停止並出現錯誤,因為它期望的是有效數據而不是null。讓我們從響應中刪除該關係,而不是顯示其null值。

<code>laravel new demo</code>
登入後複製
登入後複製
登入後複製

急切加載

因為Eloquent在訪問模型時會延遲加載模型,所以我們可能會遇到n 1問題。這可以通過一次性急切加載關係來解決,以優化查詢。

<code>composer create-project laravel/laravel demo</code>
登入後複製
登入後複製
登入後複製

這樣,在訪問模型關係時,我們將不會有任何額外的查詢。

結論

我在閱讀Phil Sturgeon撰寫的《構建你不會討厭的API》時偶然發現了Fractal,這是一本很棒且內容豐富的讀物,我強烈推薦。

您在構建API時是否使用過轉換器?您是否有任何首選的執行相同工作的包,或者您只是使用json_encode?請在下面的評論部分告訴我們!

PHP Fractal常見問題解答

什麼是PHP Fractal,為什麼它很重要?

PHP Fractal是一個強大的工具,有助於為API呈現和轉換數據。它很重要,因為它提供了一種標準化的方法來輸出複雜、嵌套的數據結構,確保API的數據輸出一致、結構良好且易於理解。這使得開發人員更容易使用您的API,並減少了出錯的可能性。

PHP Fractal是如何工作的?

PHP Fractal的工作原理是獲取複雜的數據結構並將其轉換為更易於使用的格式。它通過兩個主要組件來實現:Transformer和Serializer。 Transformer負責將復雜的數據轉換為更簡單的格式,而Serializer則格式化最終輸出。

PHP Fractal中的Transformer是什麼?

PHP Fractal中的Transformer是定義應用程序數據應如何在API響應中輸出的類。它們獲取複雜的數據結構並將它們轉換為更簡單、更易於使用的格式。這允許您精確控制API響應中包含哪些數據以及數據的結構。

PHP Fractal中的Serializer是什麼?

PHP Fractal中的Serializer負責格式化API的最終輸出。它們獲取已由Transformer轉換的數據,並將其格式化為特定的結構。這允許您確保API的輸出一致且易於理解。

我如何在項目中實現PHP Fractal?

在項目中實現PHP Fractal包括通過Composer安裝Fractal庫,為數據創建Transformer,然後使用Fractal類使用Transformer轉換數據。然後,您可以使用Fractal的Serializer之一輸出轉換後的數據。

我可以將PHP Fractal與任何PHP項目一起使用嗎?

是的,PHP Fractal是一個獨立的庫,可以與任何PHP項目一起使用。它不依賴於任何特定的框架或平台,這使得它成為任何PHP開發人員的通用工具。

使用PHP Fractal的好處是什麼?

使用PHP Fractal提供了許多好處。它確保API的輸出一致且結構良好,使開發人員更容易使用。它還提供了一種標準化的方法來轉換複雜的數據結構,減少了出錯的可能性,並使代碼更容易維護。

PHP Fractal與其他數據轉換工具相比如何?

PHP Fractal以其簡單性和靈活性而脫穎而出。它提供了一種直接的方法來轉換複雜的數據結構,並且它使用Transformer和Serializer允許高度定制。這使得它成為任何使用API的開發人員的強大工具。

我可以自定義PHP Fractal的輸出嗎?

是的,PHP Fractal是高度可定制的。您可以創建自定義Transformer來精確控制數據的轉換方式,並且您可以使用不同的Serializer以不同的方式格式化輸出。這允許您根據您的特定需求調整API的輸出。

我在哪裡可以了解更多關於PHP Fractal的信息?

有很多資源可以幫助您了解更多關於PHP Fractal的信息。官方PHP League網站提供了全面的文檔,並且網上有許多教程和博文。此外,PHP Fractal GitHub存儲庫是一個探索代碼並查看其使用方法示例的好地方。

以上是PHP Fractal-使您的API json變得漂亮,永遠!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1274
29
C# 教程
1256
24
說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

您如何防止PHP中的SQL注入? (準備的陳述,PDO) 您如何防止PHP中的SQL注入? (準備的陳述,PDO) Apr 15, 2025 am 12:15 AM

在PHP中使用預處理語句和PDO可以有效防範SQL注入攻擊。 1)使用PDO連接數據庫並設置錯誤模式。 2)通過prepare方法創建預處理語句,使用佔位符和execute方法傳遞數據。 3)處理查詢結果並確保代碼的安全性和性能。

See all articles