第一個程式HelloWord


 

說聲 Hello


本章節描述了如何在你的應用中建立一個新的 “Hello” 頁面。為了做到這點,將會建立一個[操作]和一個[檢視]:

* 應用將會分派頁面請求給操作
* 操作將會依次渲染檢視呈現 “Hello” 給終端使用者

貫穿整個章節,你將會掌握三件事:

1. 如何建立一個[操作]去響應請求,
2. 如何建立一個[檢視]去構造響應內容,
3. 以及一個應用如何分派請求給[操作]。

建立操作 

為了說 “Hello”,需要建立一個 `say` [操作],從請求中接收 `message` 引數並顯示給終端使用者。如果請求沒有提供 `message` 引數,操作將顯示預設引數 “Hello”。

> 補充:[操作]是終端使用者可以直接存取並執行的物件。操作被組織在[控制器]中。一個操作的執行結果就是終端使用者收到的響應內容。

操作必須宣告在[控制器]中。為了簡單起見,你可以直接在 `SiteController` 控制器裡宣告 `say` 操作。這個控制器是由檔案 `controllers/SiteController.php` 定義的。以下是一個操作的宣告:
<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
    // ...其它程式碼...
    public function actionSay($message = '你好')
    {
        return $this->render('say', ['message' => $message]);
    }
}
在上述 `SiteController` 程式碼中,`say` 操作被定義為 `actionSay` 方法。Yii 使用 `action` 字首區分普通方法和操作。`action` 字首後面的名稱被對映為操作的 ID。

涉及到給操作命名時,你應該理解 Yii 如何處理操作 ID。操作 ID 總是被以小寫處理,如果一個操作 ID 由多個單詞組成,單詞之間將由連字元連線(如 `create-comment`)。操作 ID 對映為方法名時移除了連字元,將每個單詞首字母大寫,並加上 `action` 字首。 例子:操作 ID `create-comment` 相當於方法名 `actionCreateComment`。

上述程式碼中的操作方法接受一個引數 `$message`,它的預設值是 `“Hello”`(就像你設定 PHP 中其它函式或方法的預設值一樣)。當應用接收到請求並確定由 `say` 操作來響應請求時,應用將從請求的引數中尋找對應值傳入進來。換句話說,如果請求包含一個 `message` 引數,它的值是 `“Goodybye”`, 操作方法中的 `$message` 變數也將被填充為 `“Goodbye”`。

在操作方法中,[[yii\web\Controller::render()|render()]] 被用來渲染一個名為 `say` 的[檢視](structure-views.md)檔案。 `message` 引數也被傳入檢視,這樣就可以在裡面使用。操作方法會返回渲染結果。結果會被應用接收並顯示給終端使用者的瀏覽器(作為整頁 HTML 的一部分)。

建立檢視 

[檢視]是你用來生成響應內容的指令碼。為了說 “Hello”,你需要建立一個 `say` 檢視,以便顯示從操作方法中傳來的 `message` 引數。
<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>

`say` 檢視應該存為 `views/site/say.php` 檔案。當一個操作中呼叫了 [[yii\web\Controller::render()|render()]] 方法時,它將會按 `views/控制器 ID/檢視名.php` 路徑載入 PHP 檔案。

注意以上程式碼,`message` 引數在輸出之前被 [[yii\helpers\Html::encode()|HTML-encoded]] 方法處理過。這很有必要,當引數來自於終端使用者時,引數中可能隱含的惡意 JavaScript 程式碼會導致[跨站指令碼(XSS)攻擊](http://en.wikipedia.org/wiki/Cross-site_scripting)。

當然了,你大概會在 `say` 檢視裡放入更多內容。內容可以由 HTML 標籤,純文字,甚至 PHP 語句組成。實際上 `say` 檢視就是一個由 [[yii\web\Controller::render()|render()]] 執行的 PHP 指令碼。檢視指令碼輸出的內容將會作為響應結果返回給應用。應用將依次輸出結果給終端使用者。

嘗試下 ?

建立完操作和檢視後,你就可以通過下面的 URL 存取新頁面了:
http://hostname/index.php?r=site/say&message=Hello+World
[Hello World]

這個 URL 將會輸出包含 “Hello World” 的頁面,頁面和應用裡的其它頁面使用同樣的頭部和尾部。

如果你省略 URL 中的 `message` 引數,將會看到頁面只顯示 “Hello”。這是因為 `message` 被作為一個引數傳給 `actionSay()` 方法,當省略它時,引數將使用預設的 `“Hello”` 代替。

> 補充:新頁面和其它頁面使用同樣的頭部和尾部是因為 [[yii\web\Controller::render()|render()]] 方法會自動把 `say` 檢視執行的結果嵌入稱為[布局]的檔案中,本例中是 `views/layouts/main.php`。

上面 URL 中的引數 `r` 需要更多解釋。它代表[路由],是整個應用級的,指向特定操作的獨立 ID。路由格式是 `控制器 ID/操作 ID`。應用接受請求的時候會檢查引數,使用控制器 ID 去確定哪個控制器應該被用來處理請求。然後相應控制器將使用操作 ID 去確定哪個操作方法將被用來做具體工作。上述例子中,路由 `site/say` 將被解析至 `SiteController` 控制器和其中的 `say` 操作。因此 `SiteController::actionSay()` 方法將被呼叫處理請求。

> 補充:與操作一樣,一個應用中控制器同樣有唯一的 ID。控制器 ID 和操作 ID 使用同樣的命名規則。控制器的類名源自於控制器 ID,移除了連字元,每個單詞首字母大寫,並加上 `Controller` 字尾。例子:控制器 ID `post-comment` 相當於控制器類名 `PostCommentController`。

總結 ?

通過本章節你接觸了 MVC 設計模式中的控制器和檢視部分。建立了一個操作作為控制器的一部分去處理特定請求。然後又建立了一個檢視去構造響應內容。在這個小例子中,沒有模型呼叫,唯一涉及到資料的地方是 `message` 引數。

你同樣學習了 Yii 路由的相關內容,它是使用者請求與控制器操作之間的橋樑。

下一章,你將學習如何建立一個模型,以及新增一個包含 HTML 表單的頁面。