iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
自我挑戰組

PHP 沿途的風景系列 第 29

[Day 29] Laravel 怎麼觸發設定在 class ProductResource 的 toArray()?

  • 分享至 

  • xImage
  •  

ProductResource::make() 怎麼觸發設定在 class ProductResource 的 toArray()?

先前幾篇文章都在探討 ProductResource::make() 的 make() 的作用,這篇文章講解 『class ProductResource 的 toArray()』 怎麼被觸發的過程,過程猶如行徑 Laravel Request Lifecycle 請求的生命週期。
request 怎麼變成 Response 的過程,推薦 Laravel Request Lifecycle 請求的生命週期
一文,裡面的內容和圖片解說,很讚!
經作者同意,我引用文章中的 『Laravel Request Lifecycle 請求的生命週期』,如圖:

追程式的過程

  • 第一站. 到 class Kernel 找 handle()
  • 第二站. class Kernel 找不到 handle(),往 class Kernel 的父層 (class HttpKernel)
      • 在 class HttpKernel 找到 handle(),發現 $response 透過 sendRequestThroughRouter($request) 產生
      • https://ithelp.ithome.com.tw/upload/images/20231014/20152511ybr0fN2REt.jpg
      • 來看看 method sendRequestThroughRouter($request) 做什麼事? 經過 middleware 然後 dispatchToRouter()
      • https://ithelp.ithome.com.tw/upload/images/20231014/201525111D0AmiQ6Hf.jpg
      • 繼續往dispatchToRouter()
      • https://ithelp.ithome.com.tw/upload/images/20231014/201525113BQc9zyKot.jpg
      • 要飛到 $this->router 的 dispatch(),這個 $this->router 在 class HttpKernel __contruct() type hint 顯示是 class Router
      • 要飛的目的地是 class Router 的 dispatch()
      • https://ithelp.ithome.com.tw/upload/images/20231014/20152511ibl2LlpdaN.jpg
  • 第三站. 歡迎到達 class Router 的 dispatch(),要前往下一個 method dispatchToRoute($request)
  • https://ithelp.ithome.com.tw/upload/images/20231014/20152511URqVOFwv1B.jpg
    • 派發 request 到 route 和 return response,我要找的是 response 相關,所以重點在 runRoute() ,略過 findRoute()runRoute() 如:
    • https://ithelp.ithome.com.tw/upload/images/20231014/20152511REFXHAm3fH.jpg
    • 有 response 的字眼了,預先處理 response 出發, 前往prepareResponse()
    • https://ithelp.ithome.com.tw/upload/images/20231014/201525113OdSJ6ir73.jpg
    • toResponse(): request 轉換為 response 的過程,種種的判斷式都在 toResponse() 內。
    • https://ithelp.ithome.com.tw/upload/images/20231014/20152511i3fJaoMwcf.jpg
    • 這個 Responseable 很眼熟啊! Responseable 經常在 JsonResource 出現,咱們來去 JsonResource 看看
  • 第四站. Responseable 作為 JsonResource 的介面(implements),表示 class JsonResource 必須實作 Responseable 的每個方法
    • 從第四站 開始,我會把前面幾篇文章提到的 class ProductResource 帶入討論 (ps. class ProductResourceclass JsonResource 的 子類別)

    • https://ithelp.ithome.com.tw/upload/images/20231014/20152511lWQ5yRVfZ0.jpg

    • 因此,從 class JsonResourcetoResponse() 開始著手

    • https://ithelp.ithome.com.tw/upload/images/20231014/20152511K38bXxk5og.jpg

      • new ResourceResponse($this),$this 指的是 class JsonResource,然而,在 route 或 Controller 經過 return ProductResource()::make() 後,$this 視作 class ProductResource 的 instance ( make() 作用,詳細參考 [Day 19] Laravel 的 XXXResource::make() 的 make() 作用 - new static())
      • new ResourceResponse($this),表示我要再前往 class ResourceResponse 底下,看看 toResponse() 的作用
      • https://ithelp.ithome.com.tw/upload/images/20231014/20152511CKqfCC2KXK.jpg
    • json() 的格式如:

      • $this->wrap(): 表示的是 json 的 data
      • $this->resource 表示的是 用 class JsonResource 建立一個 response
      • https://ithelp.ithome.com.tw/upload/images/20231014/20152511VjtrAg2XNL.jpg
  • 註. json() 格式:
<?php
// $this->wrap(): 內容,表示的是 json 的 $data
public function json(
    $data = [],
    $status = 200,
    array $headers = [],
    $options = 0
) 
  • 第五站. 返回 class JsonResource 的 resolve()
    • 經過 第四站 new ResourceResponse($this)解釋,此時的 $this 視作 class ProductResource
      https://ithelp.ithome.com.tw/upload/images/20231014/20152511vsOnJSq3qb.jpg
    • $this->toArray() 就會去 call class ProductResource 的 public function toArray($request)

追 Laravel Request Lifecycle 過程如下

response 產生經過 (第一站 ~ 第三站):

public/index.php ->
Kernel handle() 處理 request ->
處理 request 到對應的 route ->
派發 request 到配對的 route ->
預處理 response ->
request 轉為 response, 判斷 response 類別(Responseable, Stringable, Arrayable..等), 以及將 response 轉換成 JSON 格式 輸出

產出 ProductResource 的 Response 格式 (第四站 ~ 第五站):

Responseable 與 JsonResource 關係 ->
『new ResourceResponse($this)->toResponse($request)』 ->
class ResourceResponse method toResponse() ->
返回 class JsonResource 的 resolve() ->
第四站 new ResourceResponse($this)解釋,此時的 $this 視作 class ProductResource ->
此時 $this->toArray(),就會去 call class ProductResource 的 public function toArray($request)

結語

Laravel 底層把每個 method 都包得太好了,追程式的過程我忘記自己追到哪裡時,幸虧有 Laravel Request Lifecycle 做為指引,因此,迷失在程式大洋中時,我都會重新再看一次指引的地圖,在此感謝 Mia 提供的 Laravel Request Lifecycle 地圖 和 SoJ 作為嚮導。


參考文章

1 Laravel Request Lifecycle 請求的生命週期

2 [Day 19] Laravel 的 XXXResource::make() 的 make() 作用 - new static()


上一篇
[Day 28] Call API use JWT in Laravel: Quick start
下一篇
[Day 30] Laravel's Blade Templates 引入 JavaScript
系列文
PHP 沿途的風景30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言