Php 保存之前的Yii2

Php 保存之前的Yii2,php,yii2,before-save,Php,Yii2,Before Save,我有一个控制器和一个用giiant生成的updateAction: public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load($_POST) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); }

我有一个控制器和一个用giiant生成的updateAction:

public function actionUpdate($id) {
    $model = $this->findModel($id);

    if ($model->load($_POST) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
        return $this->render('update', [
            'model' => $model,
        ]);
    }
}
我想通过在模型中重写beforeSave来重命名文件:

public function beforeSave($insert) {
    if ($this->isAttributeChanged('name')) {
        rename($this->getOldAttribute('name') . '.pdf', $this->name . '.pdf');
    }

    parent::beforeSave($insert);
}

看起来模型保存了,保存后的表单仍然是渲染的,什么都不可能。我确信这是因为在保存之前
,因为如果我把它注释掉,一切都正常。使用beforeSave如何导致这种不合理的行为?我错过了什么?非常感谢

Yii和其他MVC框架都有这样的功能

虽然您可以在控制器中编写“保存前”代码,但在使用save()函数之前,最好使用beforeSave()函数

原因1:MVC中的M

beforeSave与模型相关,因此在模型文件中有一个处理模型属性(字段)的代码比在控制器中有该代码更符合逻辑

原因2:保存是为了插入和更新

插入新记录和更新现有记录时,使用save()。如果不使用beforeSave内置函数,在保存代码之前,您必须有两个“手册”实例。(“浪费”代码行)

原因3:从另一个控制器保存模型

如果您被要求扩展应用程序,而现在您必须面对一个需要保存相同模型的新控制器(出于某种原因,这只是一种可能的情况),您必须将“保存前”代码复制到该控制器上。而如果您正在使用内置的beforeSave函数,则不会

总之,框架的主要目的是减少需要编写的代码,同时保持逻辑性(MVC分离)。虽然你可以做不同的事情,为什么不使用已经存在的东西呢

一个简单的例子:

我有一个带有两个日期字段的表。每次尝试执行插入或更新时,我都需要获取当前系统日期,并根据操作类型进行操作

    public function beforeSave() {

        if ($this->isNewRecord) {
            $this->insertDate = new CDbExpression('NOW()');
        } else {
            $this->updateDate = new CDbExpression('NOW()');
        }

        return parent::beforeSave();
    }
我写过一次,所以我不必每次调用该对象的save()时都写

此外,有些数据库更喜欢不同的时间格式,因此您可以在此处进行处理:

    public function beforeSave() {
        $this->date = date('Y-m-d', $this->date);
        return parent::beforeSave();
    }

如果查看的源代码,您会发现如果您的
beforeSave
未返回
true
,则
插入
更新
过程将被取消。“看起来模型被保存了”,实际上不是

因此,请将代码调整为:

public function beforeSave($insert) {
    if ($this->isAttributeChanged('name')) {
        rename($this->getOldAttribute('name') . '.pdf', $this->name . '.pdf');
    }

    return parent::beforeSave($insert);
}

@user2511599您的
在保存之前不会返回任何内容。您必须返回
true
false
以指示是否应取消保存过程。我现在明白了,它正在工作,非常感谢您的帮助!祝你今天愉快,伙计!您缺少
父项::beforeSave($insert)之前的
返回值