前言
突然意識到似乎很久沒有上來這邊寫寫文章了,最近都在埋頭練習 PHP 與 MySQL ,實做了一個超級陽春的 job board 與 blog ,初期弄一個簡單的 blog ,自然是沒什麼問題。但隨著需求的提升,就困難許多了,像是「把一篇文章只能有一個分類,變成一篇文章允許多個分類」,這件事情就會讓難度高上不少,而這篇就是記錄這個過程哩,順便也描述一下自己遇到什麼困難。
資料庫架構的調整
做這樣的改變,首當其衝的必然是資料表與資料表之間的關聯,如果「一篇文章只有一個分類」,我們只需要再 article
的資料表內新增一個 categoryID
的欄位,然後需要時,透過 join
查詢這樣就搞定了。
但如果是「一篇文章有多個分類」呢?
- 在
articles
的資料表內新增一個categoryID
的欄位,利用字串拼接的方式儲存? - 多建立一張資料表以下簡稱
ref
表,儲存文章與類別的關聯性
我最後想想是選擇了第二種方式,感覺比較好。
於是使用 Workbench 規劃如下:
文章的新增 C
主要是 PHP 與 MySQL 與 HTML 上的調整。
- 新增文章的網頁
由於變成可以選擇多個類別,所以這部份的選單需要變成多選式的,而我也是第一次發現可以再 name
屬性內加上 [] ,使其傳回陣列。
1 | <select multiple="multiple" name="category[]" id="category"> |
- PHP
這部份我是選擇分開處理,因為根據畫的 modal 圖, articles
這張表其實跟類別已經沒什麼關係了,所以我選擇拆成兩段:
- 先進行文章的新增,取得文章
id
- 接著於
ref
表內新增文章與類別的關聯
而資料庫部份使用 PDO 來連接,認為比較關鍵的語法就是
1 | $pdo->lastInsertId(); |
這可以讓我取得最後一筆新增的 id
,這樣我就知道新增的那篇文章 id
是多少。
文章的讀取 R
主要是 PHP 與 MySQL 的調整。需要在 admin.php (後台) 把文章資料讀出來,但這部份也是我比較苦惱的,因為對於 SQL 的語法並不是很擅長,這一段雖然我有做出來,但總覺得如果我更熟悉 SQL 語法,應該可以更好做。
- MySQL
這部份我試了好一陣,總是沒辦法單獨使用 MySQL 就把文章、類別、關聯表的資料漂亮的串好,頂多就串成下面這樣。
1 | SELECT a.*, b.name |
但這樣我也不知道該怎麼用,因為我想要得到的結果是,每篇文章只有一筆資料,然後後面會帶上類別名稱這樣。
這部份我卡了很久,後來決定用比較笨的方法,跟新增文章一樣分成兩段:
- 先取得全部的文章,存成陣列
- 對這個陣列進行
foreach
,取得每篇文章id
後,再透過 SQL 語法取得該文章對應的類別,最後插入陣列。
因為不確定這麼做好不好,感覺這樣很沒有效率。
文章的更新 U
主要是 PHP 與 MySQL 與 HTML 上的調整,這部份的 HTML 畫面也讓我卡了好一陣子,原因是當類別變成多選後,進入編輯時需要將對應的類別設定預設選取,這部份會卡關主要是邏輯卡住了,因為我用了兩層的 foreach
,腦袋轉不過來,應該會有更好的解法但我不知道。
這部份我也是不知道有沒有比較好的做法,也不確定我這麼做對不對。因為如果是更新到類別的話,勢必得到 ref 表內做一些查詢、修改,也有可能把原本的 3 個類別改成 2 個類別,那這樣子要怎麼做出相應的處理呢?
所以這部份我後來想到的做法是
- 先更新文章本身
- 到
ref
表內刪除所有跟這篇文章的關聯並重建關聯
這麼做的好處就是不用管要怎麼處理了,反正就是重建新的關聯,只是我不確定這麼做好不好就是了,只是這樣子做讓我輕鬆不少。
文章的刪除 D
主要是 PHP 與 MySQL 的調整,不過也不是說想刪除文章就可以直接刪除文章,MySQL 是關聯式資料庫,從 modal 上看來,文章關係到了 ref
表與 comment
表,所以如果直接針對文章做刪除是肯定會失敗的。
所以這部份的做法是:逐一刪除有關聯的部份
- 透過該文章
ID
刪除comment
內對應的資料 - 接著刪除
ref
表內對應的資料 - 最後才是刪除文章本體
刪除的部份是相對簡單的呢。
心得
折騰了一陣子總算是把功能都做完了,不過卻也開始懷疑這樣的做法 O 不 OK 就是了,但有做出來總是好的!
畢竟先求有再求好,對吧?