よしかわーるど

プログラミングで世界を変える

2018-06-29

CakePHP 入門 5日目

前回の記事

CakePHP 入門 4 日目

データベースの利用の基本

モデルについて

MVC の M である「モデル」についてまとめます。

CakePHP のモデルは、2 つのクラスから構成されています。「Entity(エンティティ)」と「Table(テーブル)」です。

  • テーブルクラス
    • データベースのテーブルに対応するクラスです。これにより、データベースのテーブルにアクセスする手段を手に入れることができます。
  • エンティティクラス
    • 取り出したデータに対応するクラスです。データの具体的な値などを管理します。

テーブルの基本設計

オープンソースの MariaDB を使います。

テーブルに用意する項目

  • ID
    • 各レコードを識別するためのプライマリーキーとなる整数
  • NAME
    • 投稿者の名前を示すテキスト
  • TITLE
    • タイトルとなるテキスト
  • CONTENT
    • 投稿内容のテキスト

これらの項目を持ったテーブルを用意します。

  • モデル
    • Board
  • データベーステーブル
    • boards
  • テーブルクラス
    • BoardsTable クラス(BoardsTable.php)
  • エンティティクラス
    • Board クラス(Board.php)
  • コントローラクラス
    • BoardsController クラス(BoardsController.php)
  • ビュー(テンプレート)

    • 「Template」内の「Boards」フォルダに、index.ctp などのテンプレートを配置

モデルの基本クラスであるテーブルとエンティティは、「モデル名 Table」「モデル名」という形で名付けられています。

MVC の命名規則を整理する

MVC の命名規則について説明します。

  1. モデル関係(モデルの名前、エンティティクラス名)は単数形、それ以外(テーブル関係など)でデータベースのデータを扱う名前は複数形にする。
  2. クラスとして定義されるものはキャメル記法、クラスとは直接関係ないものはアンダースコア記法にする。

モデルの命名規則

  • データベースのテーブルは、「複数形」で命名する。
  • モデル(MVC の「Model」の部分)の名前は「単数形」の「キャメル記法」で命名する。
  • テーブルクラスは、「複数形」+「Table」という形の「キャメル記法」で命名する。
  • エンティティクラスは、「単数形」の「キャメル記法」で命名する。
  • スクリプトファイル名はクラス名をそのまま(単数形のキャメル記法で)命名する。

コントローラの命名規則

  • コントローラクラス名は、コントローラ名(通常、モデル名と同じ)の「複数形」+「Controller」という形の「キャメル記法」で命名する。
  • スクリプトファイルは、コントローラクラス名を「複数形」+「Controller」という形の「キャメル記法」で命名する。
  • アクションメソッド名は、一般的なメソッド

ビューの命名規則

  • ビューを保管するフォルダ名は、コントローラ名を「複数形」のキャメル記法で命名する。
  • 各ビューテンプレートファイル名は、アクションメソッド名を「アンダースコア記法」にしたもので命名する。

データベースの利用

今回、MariaDBを使用します。MySQL でも大丈夫です。書き方が異なるので、気をつけましょう。

テーブルを作成する

id, name, title, content を用意します

データベースの作成

CREATE DATABASE cake_chat;

テーブルの作成

CREATE TABLE boards (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name TEXT NOT NULL,
  title TEXT,
  content TEXT
);

CREATE TABLE posts ( id INT AUTO_INCREMENT PRIMARY KEY, imgname TEXT NOT NULL, imgData created, created modified TEXT );

INSERT INTO boards VALUES(1,'ueda','test','this is test!');
INSERT INTO boards VALUES(2,'yoshikawa','hello','welcome to cakephp!');

config 設定を変更する。(config/app.php) username と password と database を自分で変更します。

    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            /**
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',
            'username' => 'root',
            'password' => 'root',
            'database' => 'cake_chat',
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,

確認してみよう

Terminal でコマンドを叩きます。 bin/cake server -p 8765 Web アプリケーションのホームページにアクセスすると、データベースアクセスしているか確認します。 localhost:8765

モデルの作成

Entity/Chat.php

<?php
namespace App\Model\Entity;

use Cake\ORM\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
   */
class Chat extends Entity
{
  protected $_accessible = [
    '*' => ture,
    'id' => false
  ];
}
 ?>

$_accessible について

$_accessible という変数について、エンティティに用意される値への「一括代入」と呼ばれる昨日を設定するためのものです。エンティティのインスタンスを作成する際に、保管する値を一括して指定する機能です。

’$id’に対して false が指定されています。これで、id については一括代入で値が設定できなくなります。’*‘はワイルドカードで「すべての項目」を示します。これにより。id 以外の項目は一括代入できるようになります。

Table/ChatsTable.php

<?php
namespace App\Model\Table;

use Cake\ORM\Table;

/**
 * テーブルクラスは、App\Model\Table名前空間に配置
 * Tableというクラスを継承して作成
 * ただデータベースに繋げるのみなので、空のクラス
 */
class ChatsTable extends Table {
}
 ?>

Controller/ChatsController.php

<?php
namespace App\Controller;

/**
 * モデル名のメンバ変数が用意されています
 * $this->Chats はChatsTableクラスのインスタンス
 * 引数に'all'を渡すことで、テーブルにあるレコード全てを得ることが出来る
 */
class ChatsController extends AppController
{
  public function index()
  {
    $data = $this->Chats->find('all');
    $this->set('data', $data);
  }
}
 ?>