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

srcディレクトリとは?

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

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

【解説】MVCモデルとは?メリット・デメリット
MVCモデルとは「Model」「View」「Controller」の3つに分けてコードを管理するシステム開発においての設計方針になります。このモデルにはシステムの保守性や生産性の向上を図ることができるというメリットがあります。システム開発の外注をご検討されている方に向けて、「MVCモデル」とは何かについて解説いたします...

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をコピーしました