【问题标题】:Saving only changed fields in a CakePHP 2.0 Form在 CakePHP 2.0 表单中仅保存更改的字段
【发布时间】:2013-02-04 23:50:27
【问题描述】:

我正在创建一个可以让多个用户同时编辑相同信息的 CakePHP 应用程序。为了防止用户覆盖彼此的更改,我希望在用户保存表单时只保存用户更改的一两个字段。

我不能只将字段与数据库值进行比较,因为这些数据库值实际上可能是来自其他用户的较新值。

CakePHP 是否提供任何方式仅通过 POST 发送更新的字段?

【问题讨论】:

  • 你有没有想过一个 javascript 解决方案? onchange() 更新“changedFields”数组,然后提交并仅处理列出的字段?
  • 戴夫,这正是我真正希望做的。老实说,我更像是一个 Objective-C 和 C++ 的人,而不是一个 JavaScript 和 PHP 的人,所以我不确定它会如何实现。另一个优点是 CakePHP 的 save() 命令有一个参数,用于保存哪些字段(以防止黑客攻击)。那么我唯一的问题是如何在表单提交时将额外的数据附加到 $this->request->data 中?
  • 那会很好用,谢谢!我认为在文本字段中将 JS 数组作为逗号分隔的数据发送可能会很麻烦,但应该没有任何问题。

标签: forms cakephp save field


【解决方案1】:

我不相信有内置的解决方案。我想出了一些有效的代码,但您肯定希望将其放入自己的函数中,以便多个控制器操作可以使用它。此外,它并不完美。例如,它会在日期字段上失败,因为 CakePHP 的日期字段在表单中呈现为 selects。

这是一个编辑操作。原代码:

public function edit($id = null) {
    $this->User->id = $id;
    if (!$this->User->exists()) {
        throw new NotFoundException(__('Invalid user'));
    }
    if ($this->request->is('post') || $this->request->is('put')) {
        if ($this->User->save($this->request->data)) {
            $this->Session->setFlash(__('The user has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $this->request->data = $this->User->read(null, $id);
    }
}

修改代码:

public function edit($id = null) {
    $this->User->id = $id;
    if (!$this->User->exists()) {
        throw new NotFoundException(__('Invalid user'));
    }
    if ($this->request->is('post') || $this->request->is('put')) {
        $originalData = unserialize(base64_decode($this->request->data['Extra']['original_data']));
        $save = $this->request->data;
        unset($save['Extra']);

        foreach ($save as $model => $modelFields) {
            if (!array_key_exists($model, $originalData)) {
                continue;
            }

            foreach ($modelFields as $field => $value) {
                if (!array_key_exists($field, $originalData[$model])) {
                    continue;
                }

                if ($save[$model][$field] === $originalData[$model][$field]) {
                    unset($save[$model][$field]);
                }
            }
        }

        $this->User->set($save);

        if ($this->User->validates() && $this->User->save($save, false)) {
            $this->Session->setFlash(__('The user has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $this->request->data = $this->User->read(null, $id);
        $this->request->data['Extra']['original_data'] = base64_encode(serialize($this->request->data));
    }
}

另外,在edit.ctp 的表单中添加这个:

echo $this->Form->hidden('Extra.original_data');

【讨论】:

  • 谢谢!这绝对是朝着正确方向迈出的一步。另外,我讨厌 CakePHP 将日期处理为三个单独的选择的方式,所以我将日期布置为文本字段。
猜你喜欢
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多