9 追蹤者

表單操作

本節介紹如何建立一個新頁面,其中包含一個表單,用於從使用者那裡取得資料。該頁面將顯示一個表單,其中包含姓名輸入欄位和電子郵件輸入欄位。從使用者那裡取得這兩項資訊後,頁面將回顯輸入的值以進行確認。

為了實現這個目標,除了建立一個動作和兩個視圖之外,您還將建立一個模型

透過本教學,您將學習如何

  • 建立一個模型來表示使用者透過表單輸入的資料,
  • 宣告規則以驗證輸入的資料,
  • 視圖中建立 HTML 表單。

建立模型

要從使用者請求的資料將由 EntryForm 模型類別表示,如下所示,並保存在檔案 models/EntryForm.php 中。有關類別檔案命名約定的更多詳細資訊,請參閱類別自動載入章節。

<?php

namespace app\models;

use Yii;
use yii\base\Model;

class EntryForm extends Model
{
    public $name;
    public $email;

    public function rules()
    {
        return [
            [['name', 'email'], 'required'],
            ['email', 'email'],
        ];
    }
}

該類別繼承自 yii\base\Model,這是 Yii 提供的一個基底類別,通常用於表示表單資料。

資訊: yii\base\Model 用作與資料庫表關聯的模型類別的父類別。yii\db\ActiveRecord 通常是與資料庫表對應的模型類別的父類別。

EntryForm 類別包含兩個公有成員 nameemail,它們用於儲存使用者輸入的資料。它還包含一個名為 rules() 的方法,該方法返回一組用於驗證資料的規則。上面宣告的驗證規則說明:

  • nameemail 值都是必填項
  • email 資料必須是語法上有效的電子郵件地址

如果您有一個使用使用者輸入的資料填充的 EntryForm 物件,您可以呼叫其 validate() 方法來觸發資料驗證例程。資料驗證失敗會將 hasErrors 屬性設定為 true,您可以透過 errors 了解發生了哪些驗證錯誤。

<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
    // Good!
} else {
    // Failure!
    // Use $model->getErrors()
}

建立動作

接下來,您需要在 site 控制器中建立一個 entry 動作,該動作將使用新的模型。在 Hello 範例 章節中解釋了建立和使用動作的過程。

<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\EntryForm;

class SiteController extends Controller
{
    // ...existing code...

    public function actionEntry()
    {
        $model = new EntryForm();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            // valid data received in $model

            // do something meaningful here about $model ...

            return $this->render('entry-confirm', ['model' => $model]);
        } else {
            // either the page is initially displayed or there is some validation error
            return $this->render('entry', ['model' => $model]);
        }
    }
}

該動作首先建立一個 EntryForm 物件。然後,它嘗試使用來自 $_POST 的資料填充模型,這些資料由 Yii 中的 yii\web\Request::post() 提供。如果模型已成功填充(即,如果使用者已提交 HTML 表單),則該動作將呼叫 validate() 以確保輸入的值有效。

資訊: 表達式 Yii::$app 表示應用程式實例,它是一個全域可存取的單例。它也是一個服務定位器,提供 requestresponsedb 等組件以支援特定功能。在上面的程式碼中,應用程式實例的 request 組件用於存取 $_POST 資料。

如果一切正常,該動作將呈現名為 entry-confirm 的視圖,以確認資料已成功提交給使用者。如果未提交任何資料或資料包含錯誤,則將呈現 entry 視圖,其中將顯示 HTML 表單以及任何驗證錯誤訊息。

注意: 在這個非常簡單的範例中,我們僅在有效資料提交後呈現確認頁面。在實務中,您應該考慮使用 refresh()redirect() 以避免 表單重新提交問題

建立視圖

最後,建立兩個名為 entry-confirmentry 的視圖檔案。這些檔案將由剛剛描述的 entry 動作呈現。

entry-confirm 視圖僅顯示姓名和電子郵件資料。它應儲存在檔案 views/site/entry-confirm.php 中。

<?php
use yii\helpers\Html;
?>
<p>You have entered the following information:</p>

<ul>
    <li><label>Name</label>: <?= Html::encode($model->name) ?></li>
    <li><label>Email</label>: <?= Html::encode($model->email) ?></li>
</ul>

entry 視圖顯示 HTML 表單。它應儲存在檔案 views/site/entry.php 中。

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'name') ?>

    <?= $form->field($model, 'email') ?>

    <div class="form-group">
        <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>

該視圖使用一個功能強大的小工具,稱為 ActiveForm 來建立 HTML 表單。小工具的 begin()end() 方法分別呈現開始和結束表單標籤。在兩個方法呼叫之間,輸入欄位由 field() 方法建立。第一個輸入欄位用於「姓名」資料,第二個用於「電子郵件」資料。在輸入欄位之後,呼叫 yii\helpers\Html::submitButton() 方法以生成提交按鈕。

嘗試看看

若要查看其運作方式,請使用瀏覽器存取以下 URL

https://hostname/index.php?r=site%2Fentry

您將看到一個頁面,其中顯示一個表單,其中包含兩個輸入欄位。在每個輸入欄位前面,都有一個標籤指示要輸入的資料。如果您在未輸入任何內容的情況下點擊提交按鈕,或者如果您未提供有效的電子郵件地址,您將在每個有問題的輸入欄位旁邊看到錯誤訊息。

Form with Validation Errors

輸入有效的姓名和電子郵件地址並點擊提交按鈕後,您將看到一個新頁面,其中顯示您剛才輸入的資料。

Confirmation of Data Entry

原理說明

您可能想知道 HTML 表單如何在幕後運作,因為它看起來幾乎像魔法一樣,它可以為每個輸入欄位顯示標籤,並且如果您未正確輸入資料,則顯示錯誤訊息,而無需重新載入頁面。

是的,資料驗證最初是在用戶端使用 JavaScript 完成的,然後在伺服器端透過 PHP 執行。yii\widgets\ActiveForm 足夠聰明,可以提取您在 EntryForm 中宣告的驗證規則,將它們轉換為可執行的 JavaScript 程式碼,並使用 JavaScript 執行資料驗證。如果您在瀏覽器上停用了 JavaScript,則驗證仍將在伺服器端執行,如 actionEntry() 方法中所示。這確保了在所有情況下資料的有效性。

警告: 用戶端驗證是一種便利措施,可提供更好的使用者體驗。無論用戶端驗證是否到位,始終需要伺服器端驗證。

輸入欄位的標籤由 field() 方法使用模型中的屬性名稱生成。例如,將為 name 屬性生成標籤 Name

您可以使用以下程式碼在視圖中自訂標籤

<?= $form->field($model, 'name')->label('Your Name') ?>
<?= $form->field($model, 'email')->label('Your Email') ?>

資訊: Yii 提供了許多這樣的小工具,以幫助您快速建立複雜且動態的視圖。正如您稍後將了解的那樣,編寫新的小工具也非常容易。您可能希望將大部分視圖程式碼轉換為可重複使用的小工具,以簡化未來視圖的開發。

總結

在本指南的這一節中,您接觸了 MVC 架構模式的每個部分。您學習了如何建立模型類別來表示使用者資料並驗證所述資料。

您還學習了如何從使用者那裡取得資料以及如何在瀏覽器中顯示回資料。這是在開發應用程式時可能需要花費大量時間的任務,但 Yii 提供了功能強大的小工具來使此任務變得非常容易。

在下一節中,您將學習如何使用資料庫,這在幾乎每個應用程式中都是需要的。

發現錯字或您認為此頁面需要改進?
在 github 上編輯 !