🔥
CodeIgniter\Modelを使わない場合
CodeIgniter Advent Calendar 2021
CodeIgniter\Model
CodeIgniter4のチュートリアルのモデルは、以下のように CodeIgniter\Model を使っています。
<?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();
    }
}
CodeIgniter\Model は便利ですが、いろいろな機能が混ざっており、ちょっとわかりづらいです。
もともと、CodeIgniter3でのチュートリアルのモデルは、以下のようでした。
<?php
class News_model extends CI_Model
{
    public function __construct()
    {
        parent::__construct();
        $this->load->database();
    }
    public function get_news($slug = false)
    {
        if ($slug === false) {
            $query = $this->db->get('news');
            return $query->result_array();
        }
        $query = $this->db->get_where('news', ['slug' => $slug]);
        return $query->row_array();
    }
    public function set_news()
    {
        $this->load->helper('url');
        $slug = url_title($this->input->post('title'), 'dash', true);
        $data = [
            'title' => $this->input->post('title'),
            'slug'  => $slug,
            'text'  => $this->input->post('text')
        ];
        return $this->db->insert('news', $data);
    }
}
CodeIgniter3のように、クエリビルダーが使えればいいだけという場合には、CodeIgniter\Model を使わないという選択肢もあります。
CodeIgniter\Modelを使わない場合
いきなりですが、CodeIgniter\Model を使わないで NewsModel を書くと以下のようになります。
app/Models/NewsModel.php
<?php
namespace App\Models;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\ConnectionInterface;
class NewsModel
{
    /**
     * @var string
     */
    private $table = 'news';
    /**
     * @var ConnectionInterface
     */
    private $db;
    
    /**
     * @var BaseBuilder
     */
    private $builder;
    public function __construct(?ConnectionInterface $db = null)
    {
        if ($db === null) {
            $this->db = db_connect();
        } else {
            $this->db = $db;
        }
        $this->builder = $this->db->table($this->table);
    }
    public function getNews($slug = false)
    {
        if ($slug === false) {
            $query = $this->builder->get();
            return $query->getResultArray();
        }
        $query = $this->builder->getWhere(['slug' => $slug]);
        return $query->getRowArray();
    }
    public function save($data)
    {
        return $this->builder->insert($data);
    }
}
データベース接続
db_connect() 関数は「データベース接続」オブジェクトを返します。
            $this->db = db_connect();
引数なしで呼ぶと、データベース接続にはデフォルトの設定が使われます。
クエリビルダー
「データベース接続」の table() メソッドは、新しいクエリビルダーを返します。
        $this->builder = $this->db->table($this->table);
これで、クエリビルダーを使って、クエリを構築できます。
クエリービルダーは、最初にテーブル名を指定することと、メソッド名がcamelCaseに変わっていること以外は、CodeIgniter3のクエリビルダーとほとんど同じです。
            $query = $this->builder->get();
            return $query->getResultArray();
        $query = $this->builder->getWhere(['slug' => $slug]);
        return $query->getRowArray();
        return $this->builder->insert($data);
App\Models\Model
コンストラクタをモデルごとに毎回書くのは面倒くさいという場合は、抽象クラスにまとめましょう。
app/Models/Model.php
<?php
namespace App\Models;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\ConnectionInterface;
abstract class Model
{
    /**
     * @var string
     */
    protected $table;
    /**
     * @var ConnectionInterface
     */
    protected $db;
    /**
     * @var BaseBuilder
     */
    protected $builder;
    public function __construct(?ConnectionInterface $db = null)
    {
        if ($db === null) {
            $this->db = db_connect();
        } else {
            $this->db = $db;
        }
        $this->builder = $this->db->table($this->table);
    }
}
このクラスを継承してモデルを作成すれば、クエリビルダーの生成までは行ってくれます。
app/Models/NewsModel.php
<?php
namespace App\Models;
class NewsModel extends Model
{
    /**
     * @var string
     */
    protected $table = 'news';
    public function getNews($slug = false)
    {
        if ($slug === false) {
            $query = $this->builder->get();
            return $query->getResultArray();
        }
        $query = $this->builder->getWhere(['slug' => $slug]);
        return $query->getRowArray();
    }
    public function save($data)
    {
        return $this->builder->insert($data);
    }
}



Discussion