:::
5-5 將程式函式化以便彈性呼叫
- 現在點擊標題,便會連到
http://網址/index.php?op=show&id=n的頁面,也就是要列出id編號為n的完整文章 - 換言之,
index.php現在除了要顯示所有文章外,還要顯示單一文章,也就是一個檔案可能要執行兩種以上的動作。 - 如何讓檔案可以依據不同流程來執行不同功能呢?我們可以善用
switch()或PHP8新的match()功能 - 但不管用什麼,我們都先將功能打包成函數,如此能更方便的規劃流程,也不用一直在寫重複的程式碼。
- 關於PHP的函數可參考:https://campus-xoops.tn.edu.tw/modules/tad_book3/page.php?tbsn=52&tbdsn=1820
- 我們將原本在
index.php中所做的事,打包成函式:index($perPage = 10) : array// 列出所有文章 function index($perPage = 10) { global $pdo; // 計算總資料數 try { $stmt = $pdo->prepare('SELECT count(*) FROM `news`'); $stmt->execute(); list($totalCount) = $stmt->fetch(PDO::FETCH_NUM); // 產生分頁物件 $pagination = new Pagination(['totalCount' => $totalCount, 'perPage' => $perPage]); // 產生分頁工具列 ob_start(); Paginator::widget(['pagination' => $pagination]); $paginator = ob_get_clean(); } catch (PDOException $e) { die("計算總資料數失敗:" . $e->getMessage()); } try { // 準備SQL語句 $sql = "SELECT * FROM `news` ORDER BY `date` DESC LIMIT ?, ?"; // 預備語句 $stmt = $pdo->prepare($sql); // 綁定參數並執行語句 $stmt->execute([$pagination->offset, $pagination->limit]); $all_news = []; $news = $stmt->fetchAll(); foreach ($news as $row) { $media = $row['media']; unset($row['media']); $row = array_map('htmlspecialchars', $row); $row['files'] = json_decode($media, true); $all_news[] = $row; } } catch (PDOException $e) { echo "資料庫連接錯誤:" . $e->getMessage(); } return [$all_news, $paginator]; }- 將
$perPage當作參數引入函式中,並給個預設值,表示該參數不用填可以(就10篇換一頁) - 其中
$pdo是在外部產生的,所以,用global $pdo;讓函式中也使用外部變數或物件。 - 函式中也可以直接將資料
assign到樣板,但是為了讓函式可以比較有彈性的應用(或者說維護上較容易),在此都建議用retuen傳回值方式來傳出資料,這樣未來比較好再運用,邏輯上也比較清晰(日後會更好維護)。 - 由於需要傳回所有文章
$all_news以及工具列$paginator,所以用陣列方式傳回即可傳回多個變數。
- 將
- 最後,
index.php的流程就會變得非常清楚(函式都放到最下方即可)<?php use yidas\data\Pagination; require_once 'header.php'; list($all_news, $paginator) = index($perPage); $smarty->assign('all_news', $all_news); $smarty->assign('paginator', $paginator); $smarty->display('index.tpl'); // 列出所有文章 function index($perPage = 10) { ...略... } // 顯示變數內容 function dd($array = []) { ...略... }
5-4 建立管理樣板 admin.tpl 並套用之