Поведения и фильтры
Поведение — готовый кусок логики, который подключают к классу, не меняя его код. Модели оно добавляет, например, автоматическое заполнение дат. Фильтр — поведение контроллера, которое выполняется до действия и может его запретить. Оба подключают одинаково — в методе behaviors().
TimestampBehavior в модели
До сих пор столбцы created_at и updated_at приходилось заполнять вручную. Добавьте в models/Post.php:
// models/Post.php
use yii\behaviors\TimestampBehavior;
public function behaviors(): array
{
return [
TimestampBehavior::class,
];
}Теперь при создании статьи в оба столбца записывается текущее время, а при изменении обновляется updated_at. Строки $post->created_at = time() из контроллера можно убрать. По умолчанию поведение ждёт именно эти имена столбцов и хранит время числом секунд.
Настройка поведения
Если столбцы называются иначе или имеют тип DATETIME, поведение настраивают массивом:
use yii\db\Expression;
public function behaviors(): array
{
return [
[
'class' => TimestampBehavior::class,
'createdAtAttribute' => 'created',
'updatedAtAttribute' => 'modified',
'value' => new Expression('NOW()'),
],
];
}Expression передаёт в запрос выражение SQL как есть — время возьмёт сам сервер базы данных.
Другие поведения моделей
| Класс | Что делает |
|---|---|
yii\behaviors\TimestampBehavior | Заполняет даты создания и изменения |
yii\behaviors\BlameableBehavior | Записывает номер текущего пользователя в created_by и updated_by |
yii\behaviors\SluggableBehavior | Строит slug — часть адреса — из заголовка |
VerbFilter в контроллере
Удалять запись обычной ссылкой опасно: её может открыть поисковый робот. VerbFilter разрешает действию только указанные методы запроса. Добавьте в controllers/PostController.php:
// controllers/PostController.php
use yii\filters\VerbFilter;
public function behaviors(): array
{
return [
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionDelete(int $id)
{
Post::findOne($id)?->delete();
return $this->redirect(['post/index']);
}Если открыть /post/delete?id=1 в адресной строке, Yii ответит ошибкой 405 «Method Not Allowed», и статья останется на месте.
Ссылка, отправляющая POST
Чтобы кнопка удаления работала, ссылке добавляют атрибут data-method:
<?php
// views/post/view.php
use yii\helpers\Html;
?>
<?= Html::a('Удалить', ['post/delete', 'id' => $post->id], [
'data' => ['method' => 'post', 'confirm' => 'Удалить статью?'],
]) ?>Скрипт Yii перехватит щелчок, спросит подтверждение и отправит запрос POST вместе с ключом защиты _csrf.
Другие фильтры
| Класс | Что делает |
|---|---|
yii\filters\VerbFilter | Ограничивает методы запроса |
yii\filters\AccessControl | Пускает только вошедших пользователей или роли |
yii\filters\PageCache | Кеширует страницу целиком |
AccessControl разобран в уроке об авторизации.
Частая ошибка
Метод behaviors() в контроллере, созданном Gii, уже есть. Если дописать ниже второй метод с тем же именем, PHP остановится с ошибкой «Cannot redeclare». Добавляйте новые фильтры в массив существующего метода, каждый под своим ключом.