🔥
CodeIgniter4のCodeIgniter\Model (2)Entityクラスの利用
CodeIgniter Advent Calendar 2021
CodeIgniter4の CodeIgniter\Model
でEntityクラスを使ってみましょう。
目次
- CodeIgniter4のCodeIgniter\Model (1)CRUDメソッド
- CodeIgniter4のCodeIgniter\Model (2)Entityクラスの利用
- CodeIgniter4のCodeIgniter\Model (3)モデル内でのバリデーション
Entityクラスとは?
Entityクラスは、1つのテーブルのレコードを表すクラスです。POPOではありません。
テーブルのカラムを表す(マジック)プロパティを持ち、様々なデータをキャストするハンドラーを内蔵しています。
Entityクラスには、そのオブジェクトのビジネスロジックを実装するためのメソッドを追加します。
Entityクラスは自分自身を永続化する方法については何も知りません。永続化はモデルクラスが行います。
Entityの作成
CodeIgniter\Entity\Entity
を継承したEntityクラスを作成します。
app/Entitles/News.php
<?php
namespace App\Entities;
use CodeIgniter\Entity\Entity;
class News extends Entity
{
}
これだけで動作します。
Entityの利用
データの検索
モデルクラスの $returnType
にEntityクラス名の指定します。
--- a/app/Models/NewsModel.php
+++ b/app/Models/NewsModel.php
@@ -2,6 +2,7 @@
namespace App\Models;
+use App\Entities\News;
use CodeIgniter\Model;
class NewsModel extends Model
@@ -10,6 +11,8 @@ class NewsModel extends Model
protected $allowedFields = ['title', 'slug', 'body'];
+ protected $returnType = News::class;
+
public function getNews($slug = false)
{
if ($slug === false) {
これで、検索結果が配列から、Entityクラスのインスタンスに変わります。
$newsItem = $newsModel->find(1);
object(App\Entities\News)#78 (8) {
["datamap":protected]=>
array(0) {
}
["dates":protected]=>
array(3) {
[0]=>
string(10) "created_at"
[1]=>
string(10) "updated_at"
[2]=>
string(10) "deleted_at"
}
["casts":protected]=>
array(0) {
}
["castHandlers":protected]=>
array(0) {
}
["defaultCastHandlers":"CodeIgniter\Entity\Entity":private]=>
array(14) {
["array"]=>
string(33) "CodeIgniter\Entity\Cast\ArrayCast"
["bool"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["boolean"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["csv"]=>
string(31) "CodeIgniter\Entity\Cast\CSVCast"
["datetime"]=>
string(36) "CodeIgniter\Entity\Cast\DatetimeCast"
["double"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["float"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["int"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["integer"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["json"]=>
string(32) "CodeIgniter\Entity\Cast\JsonCast"
["object"]=>
string(34) "CodeIgniter\Entity\Cast\ObjectCast"
["string"]=>
string(34) "CodeIgniter\Entity\Cast\StringCast"
["timestamp"]=>
string(37) "CodeIgniter\Entity\Cast\TimestampCast"
["uri"]=>
string(31) "CodeIgniter\Entity\Cast\URICast"
}
["attributes":protected]=>
array(4) {
["id"]=>
string(1) "1"
["title"]=>
string(13) "Elvis sighted"
["slug"]=>
string(13) "elvis-sighted"
["body"]=>
string(95) "Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app."
}
["original":protected]=>
array(4) {
["id"]=>
string(1) "1"
["title"]=>
string(13) "Elvis sighted"
["slug"]=>
string(13) "elvis-sighted"
["body"]=>
string(95) "Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app."
}
["_cast":"CodeIgniter\Entity\Entity":private]=>
bool(true)
}
$newsItem->title
で title
カラムの値を取得できます。
複数レコードの場合は、オブジェクトの配列が返ります。
$newsItems = $newsModel->find([1, 2]);
array(2) {
[0]=>
object(App\Entities\News)#79 (8) {
["datamap":protected]=>
array(0) {
}
["dates":protected]=>
array(3) {
[0]=>
string(10) "created_at"
[1]=>
string(10) "updated_at"
[2]=>
string(10) "deleted_at"
}
["casts":protected]=>
array(0) {
}
["castHandlers":protected]=>
array(0) {
}
["defaultCastHandlers":"CodeIgniter\Entity\Entity":private]=>
array(14) {
["array"]=>
string(33) "CodeIgniter\Entity\Cast\ArrayCast"
["bool"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["boolean"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["csv"]=>
string(31) "CodeIgniter\Entity\Cast\CSVCast"
["datetime"]=>
string(36) "CodeIgniter\Entity\Cast\DatetimeCast"
["double"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["float"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["int"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["integer"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["json"]=>
string(32) "CodeIgniter\Entity\Cast\JsonCast"
["object"]=>
string(34) "CodeIgniter\Entity\Cast\ObjectCast"
["string"]=>
string(34) "CodeIgniter\Entity\Cast\StringCast"
["timestamp"]=>
string(37) "CodeIgniter\Entity\Cast\TimestampCast"
["uri"]=>
string(31) "CodeIgniter\Entity\Cast\URICast"
}
["attributes":protected]=>
array(4) {
["id"]=>
string(1) "1"
["title"]=>
string(13) "Elvis sighted"
["slug"]=>
string(13) "elvis-sighted"
["body"]=>
string(95) "Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app."
}
["original":protected]=>
array(4) {
["id"]=>
string(1) "1"
["title"]=>
string(13) "Elvis sighted"
["slug"]=>
string(13) "elvis-sighted"
["body"]=>
string(95) "Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app."
}
["_cast":"CodeIgniter\Entity\Entity":private]=>
bool(true)
}
[1]=>
object(App\Entities\News)#80 (8) {
["datamap":protected]=>
array(0) {
}
["dates":protected]=>
array(3) {
[0]=>
string(10) "created_at"
[1]=>
string(10) "updated_at"
[2]=>
string(10) "deleted_at"
}
["casts":protected]=>
array(0) {
}
["castHandlers":protected]=>
array(0) {
}
["defaultCastHandlers":"CodeIgniter\Entity\Entity":private]=>
array(14) {
["array"]=>
string(33) "CodeIgniter\Entity\Cast\ArrayCast"
["bool"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["boolean"]=>
string(35) "CodeIgniter\Entity\Cast\BooleanCast"
["csv"]=>
string(31) "CodeIgniter\Entity\Cast\CSVCast"
["datetime"]=>
string(36) "CodeIgniter\Entity\Cast\DatetimeCast"
["double"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["float"]=>
string(33) "CodeIgniter\Entity\Cast\FloatCast"
["int"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["integer"]=>
string(35) "CodeIgniter\Entity\Cast\IntegerCast"
["json"]=>
string(32) "CodeIgniter\Entity\Cast\JsonCast"
["object"]=>
string(34) "CodeIgniter\Entity\Cast\ObjectCast"
["string"]=>
string(34) "CodeIgniter\Entity\Cast\StringCast"
["timestamp"]=>
string(37) "CodeIgniter\Entity\Cast\TimestampCast"
["uri"]=>
string(31) "CodeIgniter\Entity\Cast\URICast"
}
["attributes":protected]=>
array(4) {
["id"]=>
string(1) "2"
["title"]=>
string(16) "Say it isn't so!"
["slug"]=>
string(14) "say-it-isnt-so"
["body"]=>
string(64) "Scientists conclude that some programmers have a sense of humor."
}
["original":protected]=>
array(4) {
["id"]=>
string(1) "2"
["title"]=>
string(16) "Say it isn't so!"
["slug"]=>
string(14) "say-it-isnt-so"
["body"]=>
string(64) "Scientists conclude that some programmers have a sense of humor."
}
["_cast":"CodeIgniter\Entity\Entity":private]=>
bool(true)
}
}
データの保存
新規にレコードを保存したい場合は、以下のようなコードになります。
$model = model(NewsModel::class);
$news = new \App\Entities\News([
'title' => $this->request->getPost('title'),
'slug' => url_title($this->request->getPost('title'), '-', true),
'body' => $this->request->getPost('body'),
]);
$model->save($news);
CodeIgniter4のCodeIgniter\Model (3)モデル内でのバリデーション
へ続く。
Discussion