🔥

CodeIgniter4のEntityを使う場合

2021/12/15に公開

CodeIgniter Advent Calendar 2021

CodeIgniter\Model

CodeIgniter4のチュートリアルのモデルでは、以下のようにEntityは使っていませんでした。

これをEntityを使うように変更してみましょう。

<?php

namespace App\Models;

use CodeIgniter\Model;

class NewsModel extends Model
{
    protected $table = 'news';

    protected $allowedFields = ['title', 'slug', 'body'];

    public function getNews($slug = false)
    {
        if ($slug === false) {
            return $this->findAll();
        }

        return $this->where(['slug' => $slug])->first();
    }
}

News Entityの作成

CodeIgniter\Entity\Entity を継承したEntityクラスを作成します。

app/Entitles/News.php

<?php

namespace App\Entities;

use CodeIgniter\Entity\Entity;

class News extends Entity
{
}

NewsModelの変更

$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のインスタンスに変わります。

Newsコントローラの変更

検索結果が配列からEntityのインスタンスになったので、配列のキーをプロパティ名に変更します。

--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -2,6 +2,7 @@
 
 namespace App\Controllers;
 
+use App\Entities\News as NewsEntity;
 use App\Models\NewsModel;
 use CodeIgniter\Controller;
 
@@ -31,7 +32,7 @@ class News extends Controller
             throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug);
         }
 
-        $data['title'] = $data['news']['title'];
+        $data['title'] = $data['news']->title;
 
         echo view('templates/header', $data);
         echo view('news/view', $data);

新規Entityの保存は、Entityのインスタンスを作成し、それを save() します。

@@ -46,11 +47,12 @@ class News extends Controller
             'title' => 'required|min_length[3]|max_length[255]',
             'body'  => 'required',
         ])) {
-            $model->save([
+            $news = new NewsEntity([
                 'title' => $this->request->getPost('title'),
                 'slug'  => url_title($this->request->getPost('title'), '-', true),
                 'body'  => $this->request->getPost('body'),
             ]);
+            $model->save($news);
 
             echo view('news/success');
         } else {

Viewの変更

ビューも配列のキーをオブジェクトのプロパティに変更します。

--- a/app/Views/news/overview.php
+++ b/app/Views/news/overview.php
@@ -4,12 +4,12 @@
 
     <?php foreach ($news as $news_item): ?>
 
-        <h3><?= esc($news_item['title']) ?></h3>
+        <h3><?= esc($news_item->title) ?></h3>
 
         <div class="main">
-            <?= esc($news_item['body']) ?>
+            <?= esc($news_item->body) ?>
         </div>
-        <p><a href="/news/<?= esc($news_item['slug'], 'url') ?>">View article</a></p>
+        <p><a href="/news/<?= esc($news_item->slug, 'url') ?>">View article</a></p>
 
     <?php endforeach ?>
 
--- a/app/Views/news/view.php
+++ b/app/Views/news/view.php
@@ -1,2 +1,2 @@
-<h2><?= esc($news['title']) ?></h2>
-<p><?= esc($news['body']) ?></p>
+<h2><?= esc($news->title) ?></h2>
+<p><?= esc($news->body) ?></p>

これで、変更完了です。

参考

Discussion