CakePHPの初期ディレクトリ構造から、各ファイルの役割を解説する【CakePHP4】③src/model

srcディレクトリとは?

srcディレクトリでは、ウェブアプリケーションの中心となる、MVCモデルのうちM(Model)とC(Controller)の設定を行います。

MVCモデルの解説については、下記外部サイト様をご参照ください。

【解説】MVCモデルとは?メリット・デメリット
MVCモデルとは「Model」「View」「Controller」の3つに分けてコードを管理するシステム開発においての設...

Webサービスのコアとなるディレクトリですので、CakePHPを運用する際には最もよく触ることになるでしょう。

初期ディレクトリ構造

初期ディレクトリ構造は下記です。

初期ファイル構造

Modelディレクトリについて

概要

Modelディレクトリには、データベースに関する設定ファイルが設置されます。

初期状態

初期状態ではModelディレクトリにファイルがありません。
※.gitkeepはgit管理用のファイルなので、cakephpの挙動とは関係ありません。

このファイルは自分で作成する必要はなく、DBとCakePHPを連携した後に、bakeコマンドを実行すれば自動で作成されます。

※bakeコマンドについて下記外部サイト様をご参照ください。

【CakePHP入門】bakeの使い方 | 侍エンジニアブログ
この記事では「 【CakePHP入門】bakeの使い方 」といった内容について、誰でも理解できるように解説します。この記...

Modelディレクトリにファイルを生成する

初期DB設定

CakePHPのデータベース初期連携設定は下記をご参照ください。

bakeして、ファイルを自動作成する

DBに下記のようなテーブル「users」があるとします。

DBのusersテーブル

このテーブルのModelファイルを生成します。

サーバにSSHアクセスして、下記のようにbakeコマンドを実行すると、Modelファイルが作成されます。

bin/cake bake model users

下記画像のように、ファイルが生成されているのがわかります。

以降は、生成されたファイルの内容について解説していきます。

Model以下の各ディレクトリについて:Table、Entity

Table、Entityそれそれの概要

Table:DBのテーブル全体の設定
Entity:テーブルの各データの設定

Table

コード全文

src/table/UsersTable.php

<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Users Model
 *
 * @method \App\Model\Entity\User newEmptyEntity()
 * @method \App\Model\Entity\User newEntity(array $data, array $options = [])
 * @method \App\Model\Entity\User[] newEntities(array $data, array $options = [])
 * @method \App\Model\Entity\User get($primaryKey, $options = [])
 * @method \App\Model\Entity\User findOrCreate($search, ?callable $callback = null, $options = [])
 * @method \App\Model\Entity\User patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
 * @method \App\Model\Entity\User[] patchEntities(iterable $entities, array $data, array $options = [])
 * @method \App\Model\Entity\User|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\User saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface|false saveMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface saveManyOrFail(iterable $entities, $options = [])
 * @method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface|false deleteMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface deleteManyOrFail(iterable $entities, $options = [])
 */
class UsersTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('users');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator): Validator
    {
        $validator
            ->scalar('name')
            ->maxLength('name', 255)
            ->requirePresence('name', 'create')
            ->notEmptyString('name');

        return $validator;
    }
}

このファイルでやっていること

公式によれば、以下のように説明されています。
テーブルオブジェクトは特定のテーブルに保存されたエンティティーのコレクションへのアクセスを提供します。』

大雑把に言えば、DBのテーブル全体の設定が行われている、と考えていいでしょう。

具体的には下記のような設定がされています。

・このファイルと連携するDB名
・プライマリーキー
・テーブルのバリデーション設定
・DBのリレーション関係

等々

実際にコードでどのように設定されているかみてみましょう

コード解説

先述のように下記画像のようなDBを参照しています。

DBのusersテーブル

以下は、先ほどのUsersTable.php全文から、一部(36~60行目)を抜粋し、コメントを追加したものです。

public function initialize(array $config): void
    {
        parent::initialize($config);

        //テーブル名の設定。どのテーブルにアクセスするか?
        $this->setTable('users');

        //「nameというカラムがあるよ」という登録
        $this->setDisplayField('name');

       //プライマリーキーの指定
        $this->setPrimaryKey('id');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator): Validator
    {
        //バリデーターの指定。
        $validator
            ->scalar('name')

            //nameのデータ型はvarchar255なので最長255文字
            ->maxLength('name', 255)
            ->requirePresence('name', 'create')

            //emptyはNGなのでその旨設定。
            ->notEmptyString('name');

        return $validator;
    }

テーブル全体の設定が行われているのがわかるかと思います。

Entity

コード全文

src/Model/Entity/user.php

<?php
declare(strict_types=1);

namespace App\Model\Entity;

use Cake\ORM\Entity;

/**
 * User Entity
 *
 * @property int $id
 * @property string $name
 */
class User extends Entity
{
    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array<string, bool>
     */
    protected $_accessible = [
        'name' => true,
    ];
}

このファイルでやっていること

公式によれば、以下のように説明されています。
エンティティーは、個々レコード意味し、 /レコードレベル振る舞いや機能定義可能にします。』

つまり、TableがDBのテーブル全体の設定だったのに対し、Entityは個別のデータに関する設定を行うわけです。

具体的には下記のような内容です。

・各データのPHP上でのData型(String?int?)
・各データは編集可否

等々

コード解説

参照しているDBは、これまでと同様に以下です。

DBのusersテーブル

以下は、先ほどのUsers.php全文から、一部(11~28行目)を抜粋し、コメントを追加したものです。

//各テーブルのデータ型を記載
 * @property int $id
 * @property string $name
 */
class User extends Entity
{
    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array<string, bool>
     */
    protected $_accessible = [
        //「nameは編集していいよ」という設定。(idはダメ。デフォルトではfalseのため)
        'name' => true,
    ];
}

18行目を見ると、id(プライマリーキー)がデフォルトで編集不可になっています。

idは通し番号のため、ユーザに勝手に編集されてしまうと困るので、このように指定するわけです。

参考

CakePHP公式:テーブルオブジェクト

CakePHP公式:エンティティー

コメント

タイトルとURLをコピーしました