Yii2 通过传递新旧记录并比较数据来创建审计记录
Posted
技术标签:
【中文标题】Yii2 通过传递新旧记录并比较数据来创建审计记录【英文标题】:Yii2 create audit record by passing old and newly updated record and comparing the data 【发布时间】:2016-10-21 08:43:45 【问题描述】:我正在尝试创建一个可以与其他模型一起使用的create audit
方法。我使用的逻辑是在 submit
从表单和 save()
出现之前传递旧记录。并在“save()”之后传递新更新的数据。我在“发布”请求之前检查了contentBefore
数据,我得到了旧记录。但是在 'save()' contentBefore 数据使用新更新的数据进行更新之后,这显然不是我想要的。
有人可以提出更好的方法或在我的代码中找到错误吗?
谢谢!
这是模型更新动作的代码
public function actionUpdate($id)
$model = $this->findModel($id);
// get the old data before update
$contentBefore = $model;
// If I var_dump('contentBefore') here I get the old data
if ($model->load(Yii::$app->request->post()) && $model->save())
// get the newly updated data and pass it to 'createaudit'
$contentAfter = $model;
$tableName = $model->formName();
$operation = Yii::$app->controller->action->id;
// Here var_dump($contentBefore) I get the newly updated data
AuditTrialController::Createaudit($contentBefore, $contentAfter, $tableName, $operation);
return $this->redirect(['view', 'id' => $model->id]);
else
return $this->render('update', [
'model' => $model,
]);
我在 AuditTrialController 中创建审核代码
public static function Createaudit($contentBefore, $contentAfter, $tableName, $operation)
$model = new AuditTrial();
$model->old = '';
$model->new = '';
foreach($contentBefore as $name => $value)
$tempOne = $name .': '. $value.', ';
$before[] = $tempOne;
foreach($contentAfter as $name => $value)
$tempTwo = $name .': '. $value.', ';
$after[] = $tempTwo;
$length = count($after);
for($x = 0; $x < $length; $x++)
if ( $before[$x] != $after[$x] )
$model->old = $model->old.' '.$before[$x];
$model->new = $model->new.' '.$after[$x];
$model->modified_by = Yii::$app->user->identity->username;
$model->operation = $operation;
$model->date = date('Y-m-d h:i:s a');
$model->table_name = $tableName;
$model->save();
【问题讨论】:
【参考方案1】:你应该先阅读这篇关于 php Objects and references 的文章:
从 PHP5 开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问者找到实际对象。
这只是意味着$contentBefore
和$contentAfter
是相同的...
一个简单的解决方法是使用$attributes,例如:
$model = $this->findModel($id);
$oldAttributes = $model->attributes;
if ($model->load(Yii::$app->request->post()) && $model->save())
$newAttributes = $model->attributes;
$tableName = $model->formName();
$operation = Yii::$app->controller->action->id;
AuditTrialController::Createaudit($oldAttributes, $newAttributes, $tableName, $operation);
return $this->redirect(['view', 'id' => $model->id]);
另一种解决方案是使用Dirty Attributes(但新旧值的比较将使用===
)。
【讨论】:
【参考方案2】:我已经解决了我的问题。感谢 Soju 指出我的错误。我通过活动记录获得$contentBefore
和$contentAfter
值。这对我有用。如果我需要改进我的代码,请告诉我。
public function actionUpdate($id)
$model = $this->findModel($id);
// get the old data before update
$modelname = get_class($model); // updated part
$contentBefore = $modelname::findOne($id); // updated part
if ($model->load(Yii::$app->request->post()) && $model->save())
// get the newly updated data and pass it to 'createaudit'
$contentAfter = $modelname::findOne($id); // updated part
$tableName = $model->formName();
$operation = Yii::$app->controller->action->id;
AuditTrialController::Createaudit($contentBefore, $contentAfter, $tableName, $operation);
return $this->redirect(['view', 'id' => $model->id]);
else
return $this->render('update', [
'model' => $model,
]);
【讨论】:
是的,您确实需要更好的代码...您尝试过我的吗? 你是说使用dirty attributes吗?以上是关于Yii2 通过传递新旧记录并比较数据来创建审计记录的主要内容,如果未能解决你的问题,请参考以下文章