在CakePHP中,如何确定编辑操作中的字段是否已更改?

时间:2008-09-22 15:47:03

标签: php cakephp

我正在使用cacheCounter中的CakePHP,这会增加相关字段的计数器。

示例,我有一个Person表和一个Source表。 Person.source_id映射到Source表中的一行。每个人都有一个Source,每个Source都没有或很多Person行。

当我更改某人的来源值时,

cacheCounter工作得很好。它递增Source.Person_Count。凉。

但是当它递增时,它会将其添加到某人的目标源,但不会将其从旧值中删除。我在updateCacheControl()中尝试了afterSave,但没有做任何事情。

然后我在afterSave的模型中编写了一些代码,它会减去源source_id,但即使我甚至没有更改source_id,它也总是这样做。 (所以计数变为负数)。

我的问题:有没有办法判断CakePHP模型中的字段是否已更改?

7 个答案:

答案 0 :(得分:17)

要监控字段中的更改,您可以在模型中使用此逻辑,而不需要在其他位置进行更改:

function beforeSave() {
    $this->recursive = -1;
    $this->old = $this->find(array($this->primaryKey => $this->id));
    if ($this->old){
        $changed_fields = array();
        foreach ($this->data[$this->alias] as $key =>$value) {
            if ($this->old[$this->alias][$key] != $value) {
                $changed_fields[] = $key;
            }
        }
    }
    // $changed_fields is an array of fields that changed
    return true;
}

答案 1 :(得分:7)

参考 Alexander Morland 答案。

如何在过滤之前循环使用它。

$result = array_diff_assoc($this->old[$this->alias],$this->data[$this->alias]);

你也会获得关键和价值。

答案 2 :(得分:1)

在编辑视图中,为要监视的字段包含另一个隐藏字段,但在字段名称后加上“_prev”,并将值设置为要监视的字段的当前值。然后在控制器的编辑操作中,如果两个字段不相等,则执行某些操作。 e.g。

echo $form->input('field_to_monitor');
echo $form->hidden('field_to_monitor_prev', array('value'=>$form->value('field_to_monitor')));

答案 3 :(得分:0)

编辑很少发生,因此在进行更新之前进行另一次选择并不重要,因此,在保存之前获取记录,保存,将编辑表单中提交的数据与您从数据库中提取的数据进行比较保存它,如果它不同,做点什么。

答案 4 :(得分:0)

您可以在实体中使用-> isDirty()来查看字段是否已被修改。

// Prior to 3.5 use dirty()
$article->isDirty('title');

检查文档:https://book.cakephp.org/3/en/orm/entities.html#checking-if-an-entity-has-been-modified

答案 5 :(得分:-1)

查看“save”是否使用某种返回“受影响的行”的DBAL调用,通常这是判断上次查询是否更改数据的方式,或者是否更改数据。因为如果没有,UPDATE语句后受影响的行为0。

答案 6 :(得分:-1)

您可以在任何模型类上调用getAffectedRows()。

来自班级模特:

/**
 * Returns the number of rows affected by the last query
 *
 * @return int Number of rows
 * @access public
 */
    function getAffectedRows() {
        $db =& ConnectionManager::getDataSource($this->useDbConfig);
        return $db->lastAffected();
    }