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 操作,它将使用新的模型。在 说“你好” 部分解释了创建和使用操作的过程。

<?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 上编辑它 !