データの保存
データの新規作成
データの新規作成は以下の流れで行われる。
- newEntity()でエンティティをビルド
- エンティティのプロパティに値をセット
- save()でエンティティを保存
<?php use Cake\ORM\TableRegistry; $articlesTable = TableRegistry::getTableLocator()->get('Articles'); $article = $articlesTable->newEntity(); $article->title = '新しい記事'; $article->body = 'これは記事の本文です'; $articlesTable->save($article); ?>
データの更新
データの更新も新規作成と同様にsave()で行われる。
<?php $article = $articlesTable->get(12); // id 12 の記事を返します $article->title = 'CakePHP は最高のフレームワークです!'; $articlesTable->save($article) ?>
アソシエーションの保存
デフォルトではsaveでアソシエーションの一階層目を保存できる。
<?php $author = $articlesTable->Authors->findByUserName('mark')->first(); // 関連のあるテーブルからレコードを取得 $article = $articlesTable->newEntity(); // エンティティを生成 $article->title = 'mark の記事'; $article->author = $author; // 関連付け $articlesTable->save($article); // 保存 ?>
save()でアソシエーションのレコードを保存することもできる。
<?php $Comment = $articlesTable->Comments->newEntity(); // アソシエーションのエンティティを生成 $Comment->body = 'CakePHP の機能は傑出しています'; $article = $articlesTable->get(12); $article->comments = [$Comment]; // 関連付け $articlesTable->save($article); // 保存 ?>
関連付けにlink()を用いても可。
<?php $articlesTable->Tags->link($article, [$tag1, $tag2]); // 関連付け $articlesTable->save($article); $articlesTable->Tags->unlink($article, $tags); // 関連付け解除 ?>
リクエストデータをもとにエンティティを保存
getData()で取得したリクエストデータをnewEntity()に渡し、エンティティに変換。saveで保存する。
<?php $entity = $articles->newEntity($this->request->getData()); $articlesTable->save($entity); ?>
エンティティ構築前のリクエストデータ変更
beforeMarshalイベントの中でエンティティ構築前のリクエストデータ変更処理を行う。
<?php // ファイルの先頭に use ステートメントを入れること。 use Cake\Event\Event; use ArrayObject; // テーブルまたはビヘイビアークラスの中で public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) { if (isset($data['username'])) { $data['username'] = mb_strtolower($data['username']); } } ?>
マスアサインメント攻撃の回避
マスアサインメント攻撃を回避するには、エンティティの一括代入機能を使う。編集可能なプロパティの配列を$_accessibleとして定義する。
<?php namespace App\Model\Entity; use Cake\ORM\Entity; class Article extends Entity { protected $_accessible = [ 'title' => true, 'body' => true, ]; } ?>
または、newEntity()あるいはpatchEntity()でfieldListオプションを使用する。
<?php $data = $this->request->getData(); // タイトルのみ変更することを許します $entity = $this->patchEntity($entity, $data, [ 'fieldList' => ['title'] ]); $this->save($entity); ?>
厳密な保存
saveOrFail()を使うと、次の条件でCake\ORM\Exception\PersistenceFailedExceptionを投げる。
- アプリケーションルールのチェックに失敗した場合
- エンティティーにエラーが含まれている場合
- 保存がコールバックによって中断された場合
<?php try { $table->saveOrFail($entity); } catch (\Cake\ORM\Exception\PersistenceFailedException $e) { echo $e->getEntity(); // エラーの内容を表示 } ?>