保存数据
CakePHP 会为保存模型数据制作快照。准备保存的数据使用如下基本格式传递给模型的 save() 方法:
1 Array
2 (
3 [ModelName] => Array
4 (
5 [fieldname1] => 'value'
6 [fieldname2] => 'value'
7 )
8 )
多数时候你无需担心这种格式: CakePHP 的 FormHelper 和模型的 find 方法都用这种格式打包所有数据。如果使用其它的助手,数据也能方便地以 $this->request->data 形式使用。
下面是使用 CakePHP 模型向数据库表存入数据的控制器动作的示例:
1 public function edit($id) {
2 // 有表单数据被 POST?
3 if ($this->request->is('post')) {
4 // 如果表单数据能够通过校验并保存...
5 if ($this->Recipe->save($this->request->data)) {
6 // 设置 session 跳转信息并跳转
7 $this->Session->setFlash('Recipe Saved!');
8 $this->redirect('/recipes');
9 }
10 }
11
12 // 如果没有表单数据,查找被编辑的 recipe 并将其赋值给视图。
13 $this->set('recipe', $this->Recipe->findById($id));
14 }
在 save 方法被调用时,在第一个参数中传递给它的数据,被 CakePHP 校验机制校验(更多信息请参见 数据校验 一节)。 如果因为某些原因,数据没有被保存,检查一下是不是没有符合某些校验规则。 可以通过输出Model::$validationErrors 来 debug 这种情况。
1 if ($this->Recipe->save($this->request->data)) {
2 // "保存" 成功后的处理逻辑
3 }
4 debug($this->Recipe->validationErrors);
其它一些与保存相关的有用的模型方法:
Model::set($one, $two = null)
Model::set() 能够用于将数据的一个或多个列放入模型的 data 数组。当使用带有由 Model 提供的 ActiveRecord 特性的模型时很有用:
1 $this->Post->read(null, 1);
2 $this->Post->set('title', 'New title for the article');
3 $this->Post->save();
此例展示了如何使用 ActiveRecord 的 set() 方法更新和保存单个列。还可以使用 set() 给多个列赋新值:
1 $this->Post->read(null, 1);
2 $this->Post->set(array(
3 'title' => 'New title',
4 'published' => false
5 ));
6 $this->Post->save();
上例将更新 thitle 和 published 列并保存到数据库中。
Model::save(array $data = null, boolean $validate =true, array $fieldList = array())
这个方法保存数组格式的数据。第二个参数允许跳过校验,第三个参数允许提供要保存的模型的列的列表。为了提高安全性,可以使用 $fieldList 限制要保存的列。
注解
如果不提供 $fieldList,恶意用户能够向表单数据中添加附加的列(在你没有使用 SecurityComponent 的情况下),并通过这种方法来改变原本不可以被改变的列。
save 方法还有一个替代语法:
1 save(array $data = null, array $params = array())
$params 数组可以用如下选项作为其键:
validate 设置为 true/false 能够 允许/禁止 校验。
fieldList 允许保存的列构成的数组。
callbacks 设置为 false 将禁止回调。使用 ‘before’ 或 ‘after’ 将仅允许指定的回调。
关于模型回调的更多信息请参见 这里
小技巧
如果你不想更新列在保存某些数据时被更新,在 $data 数组中添加 'updated' => false。
一旦保存完成,可以使用模型对象的 $id 属性获得对象的 ID - 在创建新对象时可能会非常有用。
1 $this->Ingredient->save($newData);
2 $newIngredientId = $this->Ingredient->id;
创建或更新是通过模型的 id 列来控制的。如果设置了 $Model->id,带有这个主键的记录将被更新。 其它情况下,一条新记录被创建:
1 // 创建新记录: id 没有设置或设置为 null
2 $this->Recipe->create();
3 $this->Recipe->save($this->request->data);
4
5 // 更新记录: id 被设置为一个数字值
6 $this->Recipe->id = 2;
7 $this->Recipe->save($this->request->data);
小技巧
在循环中调用 save 时,不要忘记调用 create() 。
如果想更新一个值,而不是创建一条新记录,必须确保向数据数组传递了主键列:
1 $data = array('id' => 10, 'title' => 'My new title');
2 // 将更新 id 为 10 的 Recipe 记录
3 $this->Recipe->save($data);
Model::create(array $data = array())
这个方法为保存新信息重置模型的状态。 实际上它并不在数据库中创建新记录,而是清除预先设置的 Model::$id,并在 Model::$data 中设置基于数据库列默认的默认值。
如果传递了 $data 参数(使用上面描述的数组格式),模型实例将准备保存这些数据(使用 $this->data)。
如果用 false 代替一个数组传递给此方法,模型实际将不根据之前没有设置的模型结构来初始化列,而仅仅重置已经设置的列, 并且保留未设置的列。 这么做是为了避免更新数据库中已经设置的列的值。
小技巧
如果想要用插入一个新行来代替更新已经存在的一行,必须先调用 create()。这样能够避免与回调或者其它位置中曾调用过的 save 发生冲突。
Model::saveField(string $fieldName, string$fieldValue, $validate = false)
用于保存单个列的值。在使用 saveField() 之前要先设置模型的 ID ($this->ModelName->id = $id)。在使用这个方法时,$fieldName 仅需要包含列名,不需要模型名和列。
例如,更新一条博客的标题,可以用如下方式在控制器中调用 saveField:
1 $this->Post->saveField('title', 'A New Title for a New Day');
警告
在使用这个方法更新时不能停止更新列,你需要使用 save() 方法。
saveField 方法也有一个替代语法:
1 saveField(string $fieldName, string $fieldValue, array $params = array())
$params 数组可以用如下选项作为其键:
validate 设置为 true/false 能够 允许/禁止 校验。
callbacks 设置为 false 将禁止回调。使用 ‘before’ 或 ‘after’ 将仅允许指定的回调。
Model::updateAll(array $fields, array $conditions)
一次调用更新一条或多条记录。被更新的记录通过 $conditions 数组标识,$fields 参数指定的列和值被更新。
例如,批准所有成为会员超过一年的面包师,调用如下的更新语句:
1 $this_year = date('Y-m-d h:i:s', strtotime('-1 year'));
2
3 $this->Baker->updateAll(
4 array('Baker.approved' => true),
5 array('Baker.created <=' => $this_year)
6 );
小技巧
$fields 数组接受 SQL 表达式。字面值使用 Sanitize::escape() 手动引用。
注解
即使列中存在的编辑列被更新,它也不会通过 ORM 自动更新。必须手动
补充:Web开发 , php ,