iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

一套真實運作中的 Laravel 系統,拆解它的原生機制系列 第 1

Day 01:系列介紹——一套真實運作中的 Laravel 系統,拆解它的原生機制

  • 分享至 

  • xImage
  •  

前言:官方文件教的用法,跟真實系統裡的用法是同一回事嗎?

「Laravel 的用法官方文件不是寫得很清楚嗎?Eloquent、Policy、Job 這些,跟著文件範例做就好,為什麼還需要一個系列講『用法』?」

這是我開始寫這個系列前,設想讀者會問的第一個問題。官方文件的範例確實清楚,但它有一個天生的侷限:範例是為了講清楚「這個功能怎麼用」而設計的,資料表通常只有兩三個欄位,關聯通常只有一層,Job 通常只印一行 log。真實系統不是這樣——一個 Model 身兼多個職責、一份設定要同時應付好幾種執行環境、一個 Job 要處理外部系統回傳的髒資料,這些「文件範例不會告訴你」的複雜度,恰恰是官方文件用法跟真實系統用法之間的落差。

這個系列想做的事很直接:找一套真實運作中、還在持續維護的 Laravel 系統,把它裡面用得上原生框架機制的地方一個一個拆開來看——不是「這個功能怎麼用」的教學文,是「這個真實系統為什麼這樣用、踩過什麼坑、後來怎麼改」的案例記錄。

今日目標

  • 認識這次系列的素材:一個真實運作中的大學官網入口網站
  • 理解這個系列的範圍界線——刻意排除 Filament,只講底層 Laravel 機制
  • 知道接下來 30 天分成哪四個部分、各自的重點是什麼
  • 建立這個系列貫穿全程的主題句,作為後面 29 篇的判斷基準

本文主體

這個系統長什麼樣

素材是一個大學官網的入口網站,用 Laravel 12 開發,負責對外呈現新聞公告、單頁內容、輪播、快速連結、視訊頻道這幾類內容,後台則是一套已經運作一段時間、持續有真實使用者在維護內容的系統。它不是為了寫這個系列而生的 demo 專案,程式碼裡累積了將近 600 筆 commit,每一筆背後幾乎都對應到一個真實發生過的需求或 bug。

核心資料模型大致分四類:

  • News(新聞公告):全站邏輯最複雜的 Model,牽涉到分類、負責人指派、審計紀錄、附件媒體、標籤
  • Page(單頁內容):用階層樹狀結構管理整個網站的頁面架構,一個頁面底下可以掛子頁面
  • Banner/QuickLink:首頁輪播圖跟快速連結區塊,看起來單純但牽涉到排序邏輯跟分類
  • Webcast(視訊頻道):串接外部影音平台的連結管理

這幾類內容背後,都要處理同一組共通的問題:內容怎麼發佈、誰有權限改什麼、怎麼跟外部系統同步資料。這正是這個系列想拆解的三條主線。

為什麼刻意排除 Filament

這個系統的後台管理介面是用 Filament 開發的,Filament 本身是很好的套件,但這個系列不會展開講 Filament 的用法。原因很單純:Filament 是一層建立在 Laravel 之上的後台框架,它的資源(Resource)、表單、表格背後,終究還是呼叫 Model、Policy、Eloquent 關聯這些 Laravel 原生機制。這個系列想聚焦的正是這一層——不靠套件、靠框架本身能做到什麼——所以碰到「這個類別背後對應到一個 Filament 後台頁面」的情況,會刻意只講底層的 Model/Job/Policy 怎麼寫,Filament 表單怎麼組不會展開。

這個限制帶來一個附加價值:拆掉 Filament 這一層之後,剩下的內容幾乎都是任何 Laravel 專案(不管後台用什麼套件、甚至沒有後台)都用得上的東西。

這 30 天要看的四個部分

  • 第一部(Day 1-7):Model 與資料層。從 Eloquent 模型設計的真實重構故事,到 Model::shouldBeStrict() 抓出的真實 N+1 bug,到一個身兼多職的 Model(疊了樹狀結構、又用動態型別分派行為)
  • 第二部(Day 8-16):授權與背景工作。Policy 怎麼決定誰能看見什麼、排程怎麼設計、Queue Job 怎麼安全處理外部資料、Observer 跟 Event/Listener 怎麼掛進資料生命週期
  • 第三部(Day 17-24):外部系統整合與安全。跟一個不受自己控制的外部系統對接(SOAP 協議)、逾時防護、一次真實攻擊事件後補上的檔案上傳防護、Docker 環境下的網路坑
  • 第四部(Day 25-30):套件整合與總結。第三方套件怎麼包裝進系統自己的抽象層、一套用 middleware 動態切換整站畫面的設計,最後回頭整理這些「原生機制」教我的事

貫穿全系列的主題句

這個系列接下來 29 篇,都會回到同一句話:

一個功能「能動」跟「這樣寫是對的」中間,隔著這個系統自己的真實負擔——真正教你怎麼用 Laravel 的,往往不是官方文件的範例,是一個真實系統上一次真實發生過的 bug、一次真實補上的防護、一次事後才想清楚的設計取捨。

官方文件教的是「這個 API 怎麼呼叫」,真實系統教的是「這個 API 該在什麼情境下用、用錯會踩到什麼」。這兩者不衝突,但只讀文件學不到後者——後者只能從真實踩過的案例裡看到。

今日思考題

回想你手上維護的專案,有沒有一段程式碼是「當初照著文件範例寫,後來因為真實情境的複雜度,改了好幾次才變成現在的樣子」?那個改動的過程,你有沒有記錄下來?如果沒有,這個系列接下來的寫法,或許可以當一個參考範本。

今日重點回顧

  • 這個系列的素材是一套真實運作中的大學官網入口網站,用 Laravel 12 開發,累積近 600 筆 commit
  • 核心內容分四類:News、Page、Banner/QuickLink、Webcast,背後共通處理發佈、授權、外部系統同步三件事
  • 這個系列刻意排除 Filament,只講底層 Laravel 原生機制,讓內容適用於任何 Laravel 專案
  • 貫穿全系列的主題句:真正教你怎麼用 Laravel 的,是真實系統踩過的坑,不是文件範例

明日預告

明天要具體看 Eloquent 模型設計的一個真實重構故事——一段原本寫在 View 裡的字串處理邏輯,後來為什麼、又是怎麼搬進 Model 的 accessor 裡。


延伸閱讀:本次鐵人賽同時並行的其他系列,會從不同角度處理相關的經驗,有興趣可以一起追:


系列文
一套真實運作中的 Laravel 系統,拆解它的原生機制1
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言