靜態頁面¶
備註
這個教學預設你已經下載了 CodeIgniter 並且在開發環境中 佈署了框架 。
你要做的第一件事就是設置一個 控制器 來處理靜態頁面。控制器是一個有助於指派工作的類別。它可以說是 Web 應用程式間的黏著劑。
舉個例子,當呼叫:
http://example.com/news/latest/10
我們可以想像有個控制器名為「新聞( news )」,新聞呼叫的是 「最新的(latest)」這個方法( method )。這個方法可能會獲取 10 條新聞,並且將其呈現在畫面上。在 MVC 中,你經常會看到這子的 URL 映射模式:
http://example.com/[controller-class]/[controller-method]/[arguments]
隨著 URL 的需求變得越來越複雜,這種方案可能會有所變化。但是現在,我們只需要先了解這些就好了。
讓我們製作第一個控制器¶
在 app/Controllers/Pages.php 中創建一個有以下程式碼的檔案。
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class Pages extends Controller
{
public function index()
{
return view('welcome_message');
}
public function view($page = 'home')
{
// ...
}
}
你創建了一個名為 Pages
的類別,這個類別具有 view
方法,這個方法將會被傳入 $page
引數。 還有一個 index()
方法,這與 app/Controllers/Home.php 這個控制器相同,將會預設顯示 CodeIgniter 歡迎頁面。
備註
本教學中提到了兩個 view()
函數。一種是 public function view($page = 'home')
另一種則是 echo view('welcome_message')
。前者為類別中的方法,後者用於顯示視圖。在技術上兩者都可以稱之為函數(function)。但是,當你在類別中撰寫一個函數時,我們會稱它為方法(method)。
Pages
繼承 CodeIgniter\Controller
類別。這代表, Pages 類別將可以呼叫 CodeIgniter\Controller
類別( system/Controller.php )中定義的方法與變數。
控制器是每個 Web 應用程式的 請求中心 。與任何 PHP 類別一樣,在控制器中必須使用 $this
呼叫。
現在,你已經創建了第一個方法,是時候製作一些用於 footer 與 header 的頁面樣板了。我們將建立兩個視圖(頁面樣板),作為網頁的頁首與頁尾。
在 app/Views/templates/header.php 路徑上創建含有下列程式碼的 header 檔案:
<!doctype html>
<html>
<head>
<title>CodeIgniter Tutorial</title>
</head>
<body>
<h1><?= esc($title) ?></h1>
header 包含載入主要視圖之前輸出的基本 HTML 程式碼與標題。它還會輸出 $title
變數,等等我們將會在控制器對這個變數進行定義。接著,在 app/Views/templates/footer.php 路徑上創建含有下列程式碼的 footer 檔案:
<em>© 2021</em>
</body>
</html>
備註
如果你仔細觀察過 header.php
樣板,你會發現我們使用了一個 esc()
函數。這是 CodeIgniter 提供的全域函數,可以幫助你防止 XSS 攻擊。你可以在 這裡 閱讀更多關於它的資訊。
在控制器中新增邏輯¶
剛才,你設定了一個包含 view()
方法的控制器。這個方法將傳入一個引數,
這個引數是被載入的頁面的名稱。靜態頁面的主體將被儲存在 app/Views/pages/ 目錄中。
在這個目錄中,創建名為 home.php 與 about.php 兩個檔案。在這些檔案中,輸入一些你喜歡的文字,並且保存它們。如果你不喜歡獨樹一格,你可以鍵入「 Hello World! 」。
為了載入這些頁面,你必須檢查請求的頁面是否實際存在,這些判斷邏輯是在創建 Pages
控制器後,於 view()
方法中的主體。
public function view($page = 'home')
{
if ( ! is_file(APPPATH.'/Views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
throw new \CodeIgniter\Exceptions\PageNotFoundException($page);
}
$data['title'] = ucfirst($page); // Capitalize the first letter
echo view('templates/header', $data);
echo view('pages/'.$page, $data);
echo view('templates/footer', $data);
}
現在,當請求的頁面實際存在時,將載入該頁面(包含 header 與 footer ),並顯示給使用者。如果請求的頁面不存在,將顯示「 404 Page not found 」錯誤。
這個方法中的第一行將檢查頁面是否實際存在。 PHP 的原生 is_file()
函數用於檢查檔案是否位於預期的位置。拋出 PageNotFoundException
異常將會導致 CodeIgniter 顯示預設的錯誤頁面。
在 header 樣板中, $title
變數用於自訂頁面的標題。標題的值將在這個方法中進行定義。它不是將值直接宣告在變數之中,而是宣告成 $data
陣列中鍵值為 title 的元素。
最後我們得按照順序依序載入視圖,對於這個操作,我們使用 CodeIgniter 內建的 view()
方法。view()
方法中的第二個引數用於將一些值傳遞給視圖。 $data
陣列中的每個值在傳遞給視圖後,將會被宣告為以鍵值命名的變數。所以控制器中的 $data['title']
將等價於視圖中的 $title
。
備註
傳入 view() 函數的任何檔案名稱與目錄名稱都必須真實存在且完全一致,否則你的程式可能會在一些區分大小寫的系統平台上出現錯誤。你可以在 這裡 閱讀到更多的訊息。
執行應用程式¶
準備好進行測試了嗎?你不能將這個 app 執行在 PHP 內建的伺服器之中,因為它無法正確處理 public
資料夾下 .htaccess
檔案所提供的路徑規則。這個檔案中的規則主要是讓你在 URL 中省略 「 index.php/ 」。而 CodeIgniter 有自己的命令,你可以使用這個命令。
在命令列中移動到專案的根目錄,執行:
php spark serve
這行指令將會把 Web 伺服器啟動在 8080 埠上,如果在瀏覽器中前往 localhost:8080
,你應該可以看到 CodeIgniter 的歡迎畫面。
現在,你可以在瀏覽器中嘗試多種 URL ,以查看上面製作的 Pages
究竟產生了甚麼……
URL | Will show |
---|---|
localhost:8080/pages | 將顯示控制器中 index 方法的結果,也就是顯示 CodeIgniter 「 welcome 」 頁面,因為 index 是控制器的預設方法。 |
localhost:8080/pages/index | 也會顯示 CodeIgniter 「 welcome 」 頁面,因為我們明確的要求使用 index 方法。 |
localhost:8080/pages/view | 將顯示剛才製作的「 home 」頁面,因為它是 view() 方法所預設的 page 引數。 |
localhost:8080/pages/view/home | 將顯示 「 home 」頁面 ,因為我們明確的要求了 page 的值。 |
localhost:8080/pages/view/about | 因為我們明確的要求了 about ,將顯示你剛才製作的 about 頁面。 |
localhost:8080/pages/view/shop | 將顯示「 404 - File Not Found 」錯誤畫面,因為 app/Views/pages/shop.php 並不存在。 |
路由¶
控制器執行正常!
使用自訂的路由規則,你可以將任何 URL 映射到任何控制器和方法,並且跳出這個預設的路由約定:
http://example.com/[controller-class]/[controller-method]/[arguments]
讓我們試試看吧!打開 app/Config/Routes.php 這個路由設定檔,並查找其中「定義路由( Route Definitions )」的部分。
唯一沒有被註解的程式應該是這一行:
$routes->get('/', 'Home::index');
這個指令指出,未指定任何內容的請求都應該由 Home
控制器的 index
方法進行處理。
我們緊接著在這一行程式下方新增下列程式:
$routes->get('(:any)', 'Pages::view/$1');
CodeIgniter 將從上至下依序讀取路由規則,並將請求導向至第一個匹配的規則。每一個規則都是左側的正規表示法,以及右側的控制器和方法名稱所組成(以斜線分隔)。當請求進入時, CodeIgniter 會找到第一個匹配項,並且呼叫適當的控制器與方法(可能會有引數),
有關路由的詳細資訊,請參閱 URL 路由條目。
在這裡, $routes
陣列中的第二個規則是, 任何 請求都會與萬用字元字串 (:any)
相匹配後,再引數傳遞給 Pages
類別的 view()
方法。
現在造訪 home
。它是不是正確將路由導向至控制器中的 view()
方法呢?做得好!
你應該可以看到類似於以下內容的畫面:
備註
當手動指定路由時,建議在 Routes.php 檔案中設定 $routes->setAutoRoute(false);
禁用自動路由。這樣可以確保只有你定義的路由可以被造訪。