Блог экспериментатора инженера-разработчика: Infanty.
Я пишу how-to статьи на редкие темы или статьи обзоры - для себя и тех кто со мной работает.
Блог существует при поддержке: "Оккупационных сил Марса".

Добавим простую форму к модулю demo - который содержит реализацию простой страницы с "hello world". Для этого в корневой директории сайта перейдём в папку: modules и в ней перейдём в папку ранее созданного модуля demo. После чего в папке модуля создадим подпапку: src, а в ней папку: Form в котором разместим файл: DemoForm.php с описанием класса формы.

 <?php

/**
 * @file
 * Contains \Drupal\demo\Form\DemoForm.
 */

 // Объявляем пространство имён формы. Drupal\НАЗВАНИЕ_МОДУЛЯ\Form.
namespace Drupal\demo\Form;

// Указываем что нам потребуется FormBase, от которого мы будем наследоваться.
use Drupal\Core\Form\FormBase;

/**
 * Объявляем нашу форму, наследуясь от FormBase.
 * Название класса строго должно соответствовать названию файла.
 */
class DemoForm extends FormBase {
  
  /**
   * {@inheritdoc}.
   *
   * В данном случае указано, что документацию
   * к данному методу надо взять из комментария к самому классу.
   *
   * Мы возвращаем название нашей формы в виде строки.
   * Эта строка используется для альтера формы.
   *
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'demo_form';
  }
  
  /**
   * {@inheritdoc}.
   *
   * Создание нашей формы.
   */
  public function buildForm(array $form, array &$form_state) {
    
    $form['email'] = array(
      '#type' => 'email',
      '#title' => $this->t('Your .com email address.')
    );
    $form['show'] = array(
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    );
    
    return $form;
  }
  
  /**
   * {@inheritdoc}
   *
   * Валидация отправленных данных в форме.
   */
  public function validateForm(array &$form, array &$form_state) {    
    if (strpos($form_state['values']['email'], '.com') === FALSE ) {
      $this->setFormError('email', $form_state, $this->t('This is not a .com email address.'));
    } 
  }
  
  /**
   * {@inheritdoc}
   *
   * Отправка формы.
   */
  public function submitForm(array &$form, array &$form_state) {    
    drupal_set_message($this->t('Your email address is @email', array('@email' => $form_state['values']['email'])));
  }
  
}

?> 

Осталось добавить роут для нашего классы формы для того, что бы её можно было начать использовать. Для этого в папке модуля создадим файл demo.routing.yml с настройкой пути к форме, её заголовка и доступов к ней:

 demo.form:
  path: '/demo/form'
  defaults:
    _form: '\Drupal\demo\Form\DemoForm'
    _title: 'Demo Form'
  requirements:
    _permission: 'access content' 

Очищаем кэш и проверяем доступность форы по заданному URL.

Аналог drupal_get_form() из Drupal 7 в Drupal 8 будет выглядеть как:

 $form = \Drupal::formBuilder()->getForm('Drupal\demo\Form\DemoForm'); 

Функция: hook_form_FORM_ID_alter() так же присутствует в Drupal 8 и её работа аналогична функции из Drupal 7.