Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Формы

Форма — способ получить данные от посетителя: новую статью, комментарий, пароль. Ей нужны два маршрута: один показывает страницу с формой, другой принимает отправленные данные. Функции для тегов формы, вывода ошибок и прежних значений собраны в помощнике form.

Маршруты и подключение помощника

// app/Config/Routes.php
$routes->get('posts/new', 'Posts::new');
$routes->post('posts', 'Posts::create');

Маршрут posts/new должен стоять выше, чем posts/(:num). Помощник form добавьте в BaseController: protected $helpers = ['form'];.

Шаблон формы

Создайте файл app/Views/posts/new.php:

<!-- app/Views/posts/new.php -->
<?= form_open('posts') ?>
    <label for="title">Заголовок</label>
    <input type="text" id="title" name="title">
 
    <label for="body">Текст</label>
    <textarea id="body" name="body"></textarea>
 
    <button type="submit">Сохранить</button>
<?= form_close() ?>

form_open('posts') выводит открывающий тег формы с методом POST и полным адресом /posts, form_close() — закрывающий. Поля можно писать обычным HTML.

Контроллер

// app/Controllers/Posts.php
public function new(): string
{
    return view('posts/new');
}

Откройте /posts/new — появится форма. Её данные принимает метод create() из прошлого урока: он проверяет поля и либо сохраняет статью, либо возвращает посетителя назад.

Защита от CSRF

CSRF — атака, при которой чужой сайт отправляет форму от имени вошедшего посетителя. Защищает от неё секретный токен в скрытом поле. Проверку включают в app/Config/Filters.php:

// app/Config/Filters.php
public array $globals = [
    'before' => [
        'csrf',
    ],
];

После этого form_open() сам добавляет в форму скрытое поле с токеном, а запрос POST без него будет отклонён. В форму, написанную обычным тегом form, поле вставляют вызовом <?= csrf_field() ?>.

Вывод ошибок

После неудачной проверки контроллер возвращает посетителя вызовом redirect()->back()->withInput(). Сообщение для поля выводит validation_show_error():

<label for="title">Заголовок</label>
<input type="text" id="title" name="title">
<p class="error"><?= validation_show_error('title') ?></p>

Отправьте пустую форму — под полем появится текст ошибки. Все сообщения одним списком выводит <?= validation_list_errors() ?>.

Прежние значения

Чтобы посетителю не пришлось набирать текст заново, поля заполняют функцией old():

<input type="text" id="title" name="title" value="<?= old('title') ?>">
 
<textarea id="body" name="body"><?= old('body') ?></textarea>

old('title') возвращает значение, введённое в прошлый раз, уже экранированным. При первом открытии формы она возвращает пустоту.

Функции помощника form

ФункцияЧто делает
form_open('posts')Открывающий тег формы и токен CSRF
form_close()Закрывающий тег
csrf_field()Скрытое поле с токеном
old('title')Прежнее значение поля
validation_show_error('title')Ошибка одного поля
validation_list_errors()Список всех ошибок

Частая ошибка

Если вернуть посетителя через redirect()->back() без withInput(), ни old(), ни validation_show_error() ничего не выведут: значения и ошибки не были сохранены для следующего запроса. Форма просто откроется пустой, и посетитель не поймёт, что произошло.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.