# 說聲 Hello
本章描述了如何在你的應用中創建一個新的 “Hello” 頁面。為了實現這一目標,將會創建一個[操作](http://www.yiichina.com/doc/guide/2.0/structure-controllers#creating-actions)和一個[視圖](http://www.yiichina.com/doc/guide/2.0/structure-views.md):
* 應用將會分派頁面請求給操作
* 操作將會依次渲染視圖呈現 “Hello” 給最終用戶
貫穿整個章節,你將會掌握三件事:
1. 如何創建一個[操作](http://www.yiichina.com/doc/guide/2.0/structure-controllers)去響應請求,
2. 如何創建一個[視圖](http://www.yiichina.com/doc/guide/2.0/structure-views)去構造響應內容,
3. 以及一個應用如何分派請求給[操作](http://www.yiichina.com/doc/guide/2.0/structure-controllers#creating-actions)。
## 創建操作
為了 “Hello”,需要創建一個?`say`?[操作](http://www.yiichina.com/doc/guide/2.0/structure-controllers#creating-actions),從請求中接收?`message`?參數并顯示給最終用戶。如果請求沒有提供?`message`?參數,操作將顯示默認參數 “Hello”。
> 補充:[操作](http://www.yiichina.com/doc/guide/2.0/structure-controllers#creating-actions)是最終用戶可以直接訪問并執行的對象。操作被組織在[控制器](http://www.yiichina.com/doc/guide/2.0/structure-controllers.md)中。一個操作的執行結果就是最終用戶收到的響應內容。
操作必須聲明在[控制器](http://www.yiichina.com/doc/guide/2.0/structure-controllers)中。為了簡單起見,你可以直接在?`SiteController`?控制器里聲明?`say`?操作。這個控制器是由文件`controllers/SiteController.php`?定義的。以下是一個操作的聲明:
~~~
<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
// ...其它代碼...
public function actionSay($message = 'Hello')
{
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() 被用來渲染一個名為?`say`?的[視圖](http://www.yiichina.com/doc/guide/2.0/structure-views)文件。?`message`?參數也被傳入視圖,這樣就可以在里面使用。操作方法會返回渲染結果。結果會被應用接收并顯示給最終用戶的瀏覽器(作為整頁 HTML 的一部分)。
## 創建視圖
[視圖](http://www.yiichina.com/doc/guide/2.0/structure-views)是你用來生成響應內容的腳本。為了說 “Hello”,你需要創建一個?`say`?視圖,以便顯示從操作方法中傳來的?`message`?參數。
~~~
<?php
use yii\helpers\Html;
?>
<?= Html::encode($message) ?>
~~~
`say`?視圖應該存為?`views/site/say.php`?文件。當一個操作中調用了 yii\web\Controller::render() 方法時,它將會按?`views/控制器 ID/視圖名.php`?路徑加載 PHP 文件。
注意以上代碼,`message`?參數在輸出之前被 yii\helpers\Html::encode() 方法處理過。這很有必要,當參數來自于最終用戶時,參數中可能隱含的惡意 JavaScript 代碼會導致[跨站腳本(XSS)攻擊](http://en.wikipedia.org/wiki/Cross-site_scripting)。
當然了,你大概會在?`say`?視圖里放入更多內容。內容可以由 HTML 標簽,純文本,甚至 PHP 語句組成。實際上?`say`?視圖就是一個由 yii\web\Controller::render() 執行的 PHP 腳本。視圖腳本輸出的內容將會作為響應結果返回給應用。應用將依次輸出結果給最終用戶。
## 試運行
創建完操作和視圖后,你就可以通過下面的 URL 訪問新頁面了:
~~~
http://hostname/index.php?r=site/say&message=Hello+World
~~~

這個 URL 將會輸出包含 “Hello World” 的頁面,頁面和應用里的其它頁面使用同樣的頭部和尾部。
如果你省略 URL 中的?`message`?參數,將會看到頁面只顯示 “Hello”。這是因為?`message`?被作為一個參數傳給?`actionSay()`?方法,當省略它時,參數將使用默認的?`“Hello”`?代替。
> 補充:新頁面和其它頁面使用同樣的頭部和尾部是因為 yii\web\Controller::render() 方法會自動把?`say`?視圖執行的結果嵌入稱為[布局](http://www.yiichina.com/doc/guide/2.0/structure-views#layouts)的文件中,本例中是?`views/layouts/main.php`。
上面 URL 中的參數?`r`?需要更多解釋。它代表[路由](http://www.yiichina.com/doc/guide/2.0/runtime-routing),是整個應用級的,指向特定操作的獨立 ID。路由格式是?`控制器 ID/操作 ID`。應用接受請求的時候會檢查參數,使用控制器 ID 去確定哪個控制器應該被用來處理請求。然后相應控制器將使用操作 ID 去確定哪個操作方法將被用來做具體工作。上述例子中,路由?`site/say`?將被解析至?`SiteController`?控制器和其中的?`say`?操作。因此`SiteController::actionSay()`?方法將被調用處理請求。
> 補充:與操作一樣,一個應用中控制器同樣有唯一的 ID。控制器 ID 和操作 ID 使用同樣的命名規則。控制器的類名源自于控制器 ID,移除了連字符,每個單詞首字母大寫,并加上?`Controller`?后綴。例子:控制器 ID?`post-comment`?相當于控制器類名`PostCommentController`。
## 總結
通過本章節你接觸了 MVC 設計模式中的控制器和視圖部分。創建了一個操作作為控制器的一部分去處理特定請求。然后又創建了一個視圖去構造響應內容。在這個小例子中,沒有模型調用,唯一涉及到數據的地方是?`message`?參數。
你同樣學習了 Yii 路由的相關內容,它是用戶請求與控制器操作之間的橋梁。
下一章,你將學習如何創建一個模型,以及添加一個包含 HTML 表單的頁面。
- 介紹(Introduction)
- 關于 Yii(About Yii)
- 從 Yii 1.1 升級(Upgrading from Version 1.1)
- 入門(Getting Started)
- 安裝 Yii(Installing Yii)
- 運行應用(Running Applications)
- 第一次問候(Saying Hello)
- 使用 Forms(Working with Forms)
- 玩轉 Databases(Working with Databases)
- 用 Gii 生成代碼(Generating Code with Gii)
- 更上一層樓(Looking Ahead)
- 應用結構(Application Structure)
- 結構概述(Overview)
- 入口腳本(Entry Scripts)
- 應用(Applications)
- 應用組件(Application Components)
- 控制器(Controllers)
- 模型(Models)
- 視圖(Views)
- 模塊(Modules)
- 過濾器(Filters)
- 小部件(Widgets)
- 前端資源(Assets)
- 擴展(Extensions)
- 請求處理(Handling Requests)
- 運行概述(Overview)
- 引導(Bootstrapping)
- 路由引導與創建 URL(Routing and URL Creation)
- 請求(Requests)
- 響應(Responses)
- Sessions and Cookies
- 錯誤處理(Handling Errors)
- 日志(Logging)
- 關鍵概念(Key Concepts)
- 組件(Components)
- 屬性(Properties)
- 事件(Events)
- 行為(Behaviors)
- 配置(Configurations)
- 別名(Aliases)
- 類自動加載(Class Autoloading)
- 服務定位器(Service Locator)
- 依賴注入容器(Dependency Injection Container)
- 配合數據庫工作(Working with Databases)
- 數據庫訪問(Data Access Objects): 數據庫連接、基本查詢、事務和模式操作
- 查詢生成器(Query Builder): 使用簡單抽象層查詢數據庫
- 活動記錄(Active Record): 活動記錄對象關系映射(ORM),檢索和操作記錄、定義關聯關系
- 數據庫遷移(Migrations): 在團體開發中對你的數據庫使用版本控制
- Sphinx
- Redis
- MongoDB
- ElasticSearch
- 接收用戶數據(Getting Data from Users)
- 創建表單(Creating Forms)
- 輸入驗證(Validating Input)
- 文件上傳(Uploading Files)
- 收集列表輸入(Collecting Tabular Input)
- 多模型同時輸入(Getting Data for Multiple Models)
- 顯示數據(Displaying Data)
- 格式化輸出數據(Data Formatting)
- 分頁(Pagination)
- 排序(Sorting)
- 數據提供器(Data Providers)
- 數據小部件(Data Widgets)
- 操作客戶端腳本(Working with Client Scripts)
- 主題(Theming)
- 安全(Security)
- 認證(Authentication)
- 授權(Authorization)
- 處理密碼(Working with Passwords)
- 客戶端認證(Auth Clients)
- 安全領域的最佳實踐(Best Practices)
- 緩存(Caching)
- 概述(Overview)
- 數據緩存(Data Caching)
- 片段緩存(Fragment Caching)
- 分頁緩存(Page Caching)
- HTTP 緩存(HTTP Caching)
- RESTful Web 服務
- 快速入門(Quick Start)
- 資源(Resources)
- 控制器(Controllers)
- 路由(Routing)
- 格式化響應(Response Formatting)
- 授權驗證(Authentication)
- 速率限制(Rate Limiting)
- 版本化(Versioning)
- 錯誤處理(Error Handling)
- 開發工具(Development Tools)
- 調試工具欄和調試器(Debug Toolbar and Debugger)
- 使用 Gii 生成代碼(Generating Code using Gii)
- TBD 生成 API 文檔(Generating API Documentation)
- 測試(Testing)
- 概述(Overview)
- 搭建測試環境(Testing environment setup)
- 單元測試(Unit Tests)
- 功能測試(Functional Tests)
- 驗收測試(Acceptance Tests)
- 測試夾具(Fixtures)
- 高級專題(Special Topics)
- 高級應用模版(Advanced Project Template)
- 從頭構建自定義模版(Building Application from Scratch)
- 控制臺命令(Console Commands)
- 核心驗證器(Core Validators)
- 國際化(Internationalization)
- 收發郵件(Mailing)
- 性能優化(Performance Tuning)
- 共享主機環境(Shared Hosting Environment)
- 模板引擎(Template Engines)
- 集成第三方代碼(Working with Third-Party Code)
- 小部件(Widgets)
- Bootstrap 小部件(Bootstrap Widgets)
- jQuery UI 小部件(jQuery UI Widgets)
- 助手類(Helpers)
- 助手一覽(Overview)
- Array 助手(ArrayHelper)
- Html 助手(Html)
- Url 助手(Url)