Drupal 8 模块开发:使用 Form API 添加表单完整流程

表单(Form)是 Drupal 开发以及 Web 开发中最常见的需求之一,用户与网站的数据交互几乎都需要通过表单来作为入口。作为 Drupal 开发工程师,掌握 Form API 的重要性不言而喻。

Drupal 8 表单基础

Drupal 中的表单,是通过 PHP 数组以特定结构进行定义(最终会转换成 HTML 代码),而不是直接编写 HTML 代码。采取这种方式的原因有以下几点:

  • 使所有表单的 HTML 代码结构保持一定的一致性
  • 使表单能够方便地被其它模块进行修改调整,而不必大费周章地调整表单逻辑
  • 复杂的表单元素(如文件上传)可以被封装成可复用的整体,使开发更简便

Drupal 表单的基本工作流程分为:定义表单、数据验证和提交处理三个步骤。在 Drupal 8 中,开发人员通过复写 buildForm(), validateForm()submitForm() 这三个方法即可实现相应的步骤。

Drupal 8 表单的基类定义于 \Drupal\Core\Form\FormInterface 中,开发人员需根据不同的需求来选择不同的基类:

  • ConfigFormBase - 创建系统配置表单,用于存放模块配置信息,如管理 > 配置 > 系统 > 站点信息(admin/config/system/site-information)页面表单
  • ConfirmFormBase - 提供需要确认步骤的表单,例如删除内容时的操作
  • FormBase - 最常用的普通表单

创建表单文件

以我们之前创建的 hello_world 模块为基础(详见《Drupal 8 模块开发入门教程》),创建 src/Form/HelloWorldExampleForm.php 文件,用于放置表单相关的代码

定义表单

不论打算创建哪种类型的表单,在 Drupal 8 中都需要复写 getFormId()buildForm() 方法,我们以通用表单为例,在 HelloWorldExampleForm.php 中加入以下代码:

namespace Drupal\hello_world\Form;

use \Drupal\Core\Form\FormBase;
use \Drupal\Core\Form\FormStateInterface;

class HelloWorldExampleForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'hello_world_example_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['who'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Who'),
      '#description' => $this->t('Who do you want to say hello to?'),
    );

    $form['save'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Save'),
    );

    return $form;
  }

}

检验表单数据

当用户填写完表单并点击提交按钮后,通常需要对表单中的数据进行一些检查校验,而执行此操作是通过对 validateForm() 方法进行复写而实现。往往我们会在这个阶段对提交数据的格式、长度、安全性进行充分的检查,以便确认用户提交的数据符合格式、规则,同时也不会对系统造成安全隐患。

用户提交的数据会存放在 $form_state 对象中,可以通过 $form_state->getValue('field_id') 取得指定的值,或者使用 $form_state->getValues() 取得提交的所有值。

如果经过校验发现有些数据不符合要求,可以通过 $form_state->setErrorByName() 方法返回表单错误。

在此示例中,我们要求输入的值必须大于2个字符,相应的示例代码如下:

/**
 * {@inheritdoc}
 */
publi
剩余50%内容付费后可查看

未完成付费阅读配置或配置有误

看完了?还不过瘾?点此向作者提问
打赏一下,鼓励Ta创作更多好内容!