← Назад к вопросам

Тригерится ли метод save() в Yii2?

1.0 Junior🔥 71 комментариев
#Фреймворки

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Триггеры ли метод save() в Yii2?

Да, метод save() в Yii2 триггерит события и является ключевой частью жизненного цикла модели ActiveRecord. Его вызов приводит к каскаду событий и операций, которые можно разделить на несколько этапов.

Основные стадии работы save()

  1. Проверка валидации (если включен параметр $validate = true):

    // Пример вызова с валидацией (по умолчанию)
    $model->save(); // Триггерит валидацию через events
    
    // Пример без валидации
    $model->save(false); // Пропускает валидацию
    
  2. События жизненного цикла модели:

    // Последовательность событий при INSERT (новая запись)
    beforeValidate() -> afterValidate() -> beforeSave() -> (обращение к БД) -> afterSave()
    
    // Последовательность при UPDATE (существующая запись)
    beforeValidate() -> afterValidate() -> beforeSave() -> (обращение к БД) -> afterSave()
    

Ключевые события, которые триггерятся

События валидации:

  • beforeValidate() - вызывается до начала валидации
  • afterValidate() - вызывается после успешной валидации

События сохранения:

  • beforeSave() - вызывается перед записью в БД
  • afterSave() - вызывается после успешной записи

Пример поведения в коде

class Product extends \yii\db\ActiveRecord
{
    public function behaviors()
    {
        return [
            [
                'class' => TimestampBehavior::class,
                'value' => new Expression('NOW()'),
            ],
        ];
    }
    
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($insert) {
                // Логика только для новой записи
                $this->created_at = time();
            }
            $this->updated_at = time();
            return true;
        }
        return false;
    }
}

// При вызове save() произойдет:
$product = new Product();
$product->name = 'Телефон';
$product->save(); // Триггерит цепочку событий:

// 1. beforeValidate() - если есть behaviors или переопределения
// 2. Валидация всех правил из rules()
// 3. afterValidate()
// 4. beforeSave() - здесь сработает TimestampBehavior и наш метод
// 5. Выполнение SQL запроса (INSERT/UPDATE)
// 6. afterSave()

Важные нюансы работы save()

Параметры метода:

save($runValidation = true, $attributeNames = null)

Что происходит внутри:

  1. Определение, является ли запись новой ($this->getIsNewRecord())
  2. Вызов beforeValidate() и afterValidate() (если $runValidation = true)
  3. Вызов beforeSave() - если возвращает false, сохранение прерывается
  4. Выполнение insert() или update() через DAO
  5. Вызов afterSave()

Откат транзакции:

$transaction = Yii::$app->db->beginTransaction();
try {
    $model->save();
    // Другие операции
    $transaction->commit();
} catch (\Exception $e) {
    $transaction->rollBack();
    throw $e;
}

Отличия между insert()/update() и save()

  • insert() и update() не триггерят события валидации, только beforeSave()/afterSave()
  • save() автоматически выбирает нужный метод на основе флага isNewRecord
  • save() выполняет больше проверок и предоставляет более высокоуровневый API

Поведения (Behaviors), влияющие на save()

Поведения, прикрепленные к модели, также могут реагировать на события save():

  • TimestampBehavior - автоматическое обновление полей времени
  • BlameableBehavior - автоматическое заполнение полей пользователем
  • SluggableBehavior - генерация URL1-friendly строк

Таким образом, метод save() в Yii2 является центральным триггером для большинства событий жизненного цикла модели. Он обеспечивает согласованное выполнение валидации, событий и бизнес-логики, что делает его предпочтительным способом сохранения данных по сравнению с прямыми вызовами insert() или update(). При разработке приложений на Yii2 понимание этого механизма критически важно для написания надежного и поддерживаемого кода.

Тригерится ли метод save() в Yii2? | PrepBro