使用表單

使用表單

本章節將介紹如何創建一個從用戶那蒐集數據的表單頁。該頁將顯示一個包含 name 輸入框和 email 輸入框的表單。當蒐集完這兩部分信息後,頁面將會顯示用戶輸入的信息。

爲了實現這個目標,除了創建一個[操作] 和兩個[視圖]外,還需要創建一個[模型]。

貫穿整個小節,你將會學到:

* 創建一個[模型](structure-models.md)代表用戶通過表單輸入的數據
* 聲明規則去驗證輸入的數據
* 在[視圖](structure-views.md)中生成一個 HTML 表單

創建模型 ​

模型類 `EntryForm` 代表從用戶那請求的數據,該類如下所示並存儲在 `models/EntryForm.php` 文件中。請參考[類自動加載] 章節獲取更多關於類命名約定的介紹。

補充:\[\[yii\\base\\Model\]\] 被用於普通模型類的父類並與數據表\*\*無關\*\*。\[\[yii\\db\\ActiveRecord\]\] 通常是普通模型類的父類但與數據表有關聯(譯者注:\[\[yii\\db\\ActiveRecord\]\] 類其實也是繼承自 \[\[yii\\base\\Model\]\],增加了數據庫處理)。 \`EntryForm\` 類包含 \`name\` 和 \`email\` 兩個公共成員,用來儲存用戶輸入的數據。它還包含一個名爲 \`rules()\` 的方法,用來返回數據驗證規則的集合。上面聲明的驗證規則表示: \* \`name\` 和 \`email\` 值都是必須的 \* \`mail\` 的值必須滿足 email 地址驗證 如果你有一個從用戶那蒐集數據的 \`EntryForm\` 對象,你可以調用它的 \[\[yii\\base\\Model::validate()|validate()\]\] 方法觸發數據驗證。如果有數據驗證失敗,將把 \[\[yii\\base\\Model::hasErrors|hasErrors\]\] 屬性設爲 ture,想要知道具體發生什麼錯誤就調用 \[\[yii\\base\\Model::getErrors|getErrors\]\]。 name = 'Qiang'; $model->email = 'bad'; if ($model->validate()) { // 驗證成功! } else { // 失敗! // 使用 $model->getErrors() 獲取錯誤詳情 } 創建操作 ​ ------ 下面你得在 \`site\` 控制器中創建一個 \`entry\` 操作用於新建的模型。操作的創建和使用已經在\[說一聲你好\](start-hello.md)小節中解釋了。 load(Yii::$app->request->post()) && $model->validate()) { // 驗證 $model 收到的數據 // 做些有意義的事 ... return $this->render('entry-confirm', \['model' => $model\]); } else { // 無論是初始化顯示還是數據驗證錯誤 return $this->render('entry', \['model' => $model\]); } } } 該操作首先創建了一個 \`EntryForm\` 對象。然後嘗試從 \`$\_POST\` 蒐集用戶提交的數據,由 Yii 的 \[\[yii\\web\\Request::post()\]\] 方法負責蒐集。如果模型被成功填充數據(也就是說用戶已經提交了 HTML 表單),操作將調用 \[\[yii\\base\\Model::validate()|validate()\]\] 去確保用戶提交的是有效數據。 \> 補充:表達式 \`Yii::$app\` 代表\[應用\] 實例,它是一個全局可訪問的單例。同時它也是一個\[服務定位器\],能提供 \`request\`,\`response\`,\`db\` 等等特定功能的組件。在上面的代碼裏就是使用 \`request\` 組件來訪問應用實例收到的 \`$\_POST\` 數據。 用戶提交表單後,操作將會渲染一個名爲 \`entry-confirm\` 的視圖去確認用戶輸入的數據。如果沒填表單就提交,或數據包含錯誤(譯者:如 email 格式不對),\`entry\` 視圖將會渲染輸出,連同表單一起輸出的還有驗證錯誤的詳細信息。 \> 注意:在這個簡單例子裏我們只是呈現了有效數據的確認頁面。實踐中你應該考慮使用 \[\[yii\\web\\Controller::refresh()|refresh()\]\] 或 \[\[yii\\web\\Controller::redirect()|redirect()\]\] 去避免\[表單重複提交問題\](http://en.wikipedia.org/wiki/Post/Redirect/Get)。 創建視圖 ​ ------ 最後創建兩個視圖文件 \`entry-confirm\` 和 \`entry\`。他們會被剛纔創建的 \`entry\` 操作渲染。 \`entry-confirm\` 視圖簡單地顯示提交的 name 和 email 數據。視圖文件保存在 \`views/site/entry-confirm.php\`。

You have entered the following information:

  • : name) ?>
  • : email) ?>

`entry` 視圖顯示一個 HTML 表單。視圖文件保存在 `views/site/entry.php`。

<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<div class="form-group">
    <?= Html::submitButton('Submit', \['class' => 'btn btn-primary'\]) ?>
</div>

視圖使用了一個功能強大的[小部件](structure-widgets.md) [[yii\widgets\ActiveForm|ActiveForm]] 去生成 HTML 表單。其中的 `begin()` 和 `end()` 分別用來渲染表單的開始和關閉標籤。在這兩個方法之間使用了 [[yii\widgets\ActiveForm::field()|field()]] 方法去創建輸入框。第一個輸入框用於 「name」,第二個輸入框用於 「email」。之後使用 [[yii\helpers\Html::submitButton()]] 方法生成提交按鈕。

嘗試下 ​

用瀏覽器訪問下面的 URL 看它能否工作:

http://hostname/index.php?r=site/entry

你會看到一個包含兩個輸入框的表單的頁面。每個輸入框的前面都有一個標籤指明應該輸入的數據類型。如果什麼都不填就點擊提交按鈕,或填入格式不正確的 email 地址,將會看到在對應的輸入框下顯示錯誤信息。
[驗證錯誤的表單]
輸入有效的 name 和 email 信息並提交後,將會看到一個顯示你所提交數據的確認頁面。
[輸入數據的確認頁]

### 效果說明 ​

你可能會好奇 HTML 表單暗地裏是如何工作的呢,看起來它可以爲每個輸入框顯示文字標籤,而當你沒輸入正確的信息時又不需要刷新頁面就能給出錯誤提示,似乎有些神奇。

是的,其實數據首先由客戶端 JavaScript 腳本驗證,然後纔會提交給服務器通過 PHP 驗證。[[yii\widgets\ActiveForm]] 足夠智能到把你在 `EntryForm` 模型中聲明的驗證規則轉化成客戶端 JavaScript 腳本去執行驗證。如果用戶瀏覽器禁用了 JavaScript, 服務器端仍然會像 `actionEntry()` 方法裏這樣驗證一遍數據。這保證了任何情況下用戶提交的數據都是有效的。

> 警告:客戶端驗證是提高用戶體驗的手段。無論它是否正常啓用,服務端驗證則都是必須的,請不要忽略它。

輸入框的文字標籤是 `field()` 方法生成的,內容就是模型中該數據的屬性名。例如模型中的 `name` 屬性生成的標籤就是 `Name`。

你可以在視圖中自定義標籤:

field($model, 'name')->label('自定義 Name') ?> field($model, 'email')->label('自定義 Email') ?>

> 補充:Yii 提供了相當多類似的小部件去幫你生成複雜且動態的視圖。在後面你還會了解到自己寫小部件是多麼簡單。你可能會把自己的很多視圖代碼轉化成小部件以提高重用,加快開發效率。

總結 

本章節指南中你接觸了 MVC 設計模式的每個部分。學到了如何創建一個模型代表用戶數據並驗證它的有效性。

你還學到了如何從用戶那獲取數據並在瀏覽器上回顯給用戶。這本來是開發應用的過程中比較耗時的任務,好在 Yii 提供了強大的小部件讓它變得如此簡單。

下一章你將學習如何使用數據庫,幾乎每個應用都需要數據庫。