php 保存前Yi2

z6psavjg  于 2023-02-28  发布在  PHP
关注(0)|答案(3)|浏览(117)

我有一个Controller和一个用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 in Model来重命名文件:

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

    parent::beforeSave($insert);
}

看起来模型被保存了,但是保存后表单仍然呈现,这不可能。我确信这是因为beforeSave,因为如果我注解掉它,一切都正常工作。使用beforeSave怎么会导致这种不合理的行为?我错过了什么?非常感谢!

blpfk2vs

blpfk2vs1#

如果你回顾beforeSave的源代码,你会发现如果你的beforeSave没有返回true,那么insertionupdating进程将被取消。“看起来模型被保存了”,实际上不是。
因此,将代码调整为:

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

    return parent::beforeSave($insert);
}
o3imoua4

o3imoua42#

Yii和其他MVC框架都有这些功能。
虽然您可以在控制器中编写"before save"代码,但在save()函数之前,更推荐使用beforeSave()函数。
原因1:MVC中的M
beforeSave与模型相关,因此在模型文件中使用处理模型属性(字段)的代码比在控制器中使用该代码更符合逻辑。
原因2:保存是为了插入和更新
当你插入一个新记录或者更新一个已有记录时,你可以使用save()。如果不使用beforeSave内置函数,你必须在保存代码之前有两个"manual"的示例。(代码行的"浪费")
原因3:从另一个控制器保存模型
如果你被要求扩展你的应用程序,现在你不得不面对一个需要保存相同模型的新控制器(出于某种原因-只是一个可能的场景)-你必须复制你的"before save"代码到那个控制器。而如果你使用内置的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();
    }
iqxoj9l9

iqxoj9l93#

从BaseActiveRecord的github存储库中:

......
/**
 * This method is called at the beginning of inserting or updating a record.
 *
 * The default implementation will trigger an [[EVENT_BEFORE_INSERT]] event when `$insert` is `true`,
 * or an [[EVENT_BEFORE_UPDATE]] event if `$insert` is `false`.
 * When overriding this method, make sure you call the parent implementation like the following:
 *
 * ```php
 * public function beforeSave($insert)
 * {
 *     if (!parent::beforeSave($insert)) {
 *         return false;
 *     }
 *
 *     // ...custom code here...
 *     return true;
 * }
....

*自定义之前调用的父函数

相关问题