@ CakePHP

モデル(データベースの利用)

MVC の中で、データベースとの連携を行うのが「モデル」役割です。

また、モデルにはフォームから入力されたデータが想定したルールに適合するかをチェックするバリデーショや、複数のモデルを関連させて操作するアソシエーションという機能が用意されています。

データベースの準備

cake_bbs という名前で空のデータベースを作成しておきます。このデータベースでは、「掲示板」の投稿を保存するためのテーブルをひとつ作成します。

aticles.sql

/* articlesテーブルを作成します: */
CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    title VARCHAR(50) NOT NULL,
    content TEXT,
    created DATETIME,
    modified TIMESTAMP
);

/* テスト用に記事をいくつか入れておきます: */
INSERT INTO articles (title,name,content,created)
    VALUES ('タイトル', '太郎', 'これは、記事の本文です。', NOW());
INSERT INTO articles (title,name,content,created)
    VALUES ('またタイトル', '花子', 'そこに本文が続きます。', NOW());
INSERT INTO articles (title,name,content,created)
    VALUES ('タイトルの逆襲', '健二', 'こりゃ本当にわくわくする!うそ。', NOW());

テーブル名とフィールド名は、CakePHP のデータベース命名規約と クラスの命名規約に従っておくと、たくさんの機能を自由に使うことができ、設定作業をする必要がなくなります。‘articles’ というテーブル名にしておけば、自動的に Articles モデルが呼び出され、’modified’ と ‘created’ というフィールドがあると、自動的にCakePHP が管理するようになります。

データベース設定ファイルの作成

データベースの接続設定は config/app.php ファイルの中の Datasources.default 配列の値を置き換えて行います。

設定例を以下に示します。

cake3app\config\app.php

'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',  // ホスト名
            'username' => 'root',  // データベースユーザ名
            'password' => 'root',  // データベースパスワード
            'database' => 'cake_bbs',  // データベース名
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,
            'quoteIdentifiers' => false,
            'url' => env('DATABASE_URL', null),
        ],
    ],

モデルの作成

データベース内にある「ひとこと掲示板」の投稿の情報を取得することにします。

データの入出力は「モデル」を介して行われます。articles.sql で生成されたデータベースでは、投稿の情報は「articles テーブル」に格納されているので、モデル名は「Article」とします。

CakePHP のコーディング規約で、テーブル名は「複数形のスネークケース」、モデル名は「単数形キャメルケース」とルール付けられています。

モデル関連スクリプトは src/Model フォルダの中に格納されています。この中に 「Entity」と「Table」フォルダが用意されています。それぞれに「エンティティクラス」と「テーブルクラス」を作成します。

エンティティクラスの作成

cake3app\src\Model\Entity\Article.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity
{

    protected $_accessible = [
        '*' => true,
        'id' => false
    ];
}

エンティティクラスは、Entity クラスを継承して作成します。

この Entity クラスには、「エンティティ」(データベースから取得したレコード情報をまとめたオブジェクト)操作に関する基本的な仕組みが組みこまれています。

テーブルクラスの作成

テーブルクラスは、Table クラスを継承して作成します。

テーブル操作に関する基本的な機能は Table クラスに用意されているので、データベースに接続するだけであれば、空のクラスを定義しておくだけです。

cake3app\src\Model\Table\ArticlesTable.php

<?php
namespace App\Model\Table;

use Cake\ORM\Table;

class ArticlesTable extends Table
{

}

コントローラの作成

Article モデルを利用するコントローラは、ArticlesController クラスとして定義します。

cake3app\src\Controller\ArticlesController.php

<?php
namespace App\Controller;

class ArticlesController extends AppController
{

    public function index()
    {
        $data = $this->Articles->find('all');
        $this->set('data', $data);
    }
}

ここでは、index アクションだけを用意して Article モデルのfind()メソッドを呼び出し、全てのレコードの情報を配列として受け取り、ビューに渡しています。

ビューの作成

コントローラにプログラムを書いただけでは「画面に表示する」ことはできません。「画面表示」はビューの役割です。

index.ctp をつぎのように作成します。

cake3app\src\Template\Articles\index.ctp

<h1>レコードの取得</h1>
<table>
<tr>
  <th>id</th>
  <th>name</th>
  <th>title</th>
  <th>content</th>
</tr>

<?php foreach ($data as $obj): ?>
<tr>
  <td><?= $obj->id ?></td>
  <td><?= $obj->name ?></td>
  <td><?= $obj->title ?></td>
  <td><?= $obj->content ?></td>
</tr>
<?php endforeach; ?>
</table>

アプリケーションへのアクセス

ブラウザを起動し、以下の URL でアプリケーションにアクセスできます。

< http://localhost/cake3app/articles/ >

toArray()

データベースのデータは、toArray() メソッドを使って、配列として取り出すことができます。

例えば、テンプレートへの記述は次のようになります。

cake3app\src\Template\Articles\index.ctp

<pre><?php print_r($data->toArray()) ?></pre>

HTMLヘルパーの利用

CakePHP に用意されている「HTML ヘルパー」を使えば、簡単にビューテンプレートを記述できます。

例えば、テンプレートへの記述は次のようになります。

cake3app\src\Template\Articles\index.ctp

<h1>HTMLヘルパーの利用</h1>
<table>
<tr>
  <th>id</th>
  <th>name</th>
  <th>title</th>
  <th>content</th>
  <th>created</th>
  <th>modified</th>
</tr>
<?php
$arr = $data->toArray();
for($i = 0; $i < count($arr); $i++) {
    echo $this->Html->tableCells(
        $arr[$i]->toArray(),
        ['style' => 'background-color:#eaeaea'],
        ['style' => 'background-color:#ffffff'],
        true
    );
}
?>
</table>

表示するカラムを制御する場合は、次のように記述します。

cake3app\src\Template\Articles\index.ctp

<h1>HTMLヘルパーの利用</h1>
<table>
<tr>
  <th>id</th>
  <th>name</th>
  <th>title</th>
  <th>content</th>
</tr>
<?php foreach ($data as $obj): ?>
<?=$this->Html->tableCells(
    [
        $obj['id'],
        $obj['name'],
        $obj['title'],
        $obj['content']
    ],
    ['style'=>'color:#000066; background-color: #eaeaea'],
    ['style'=>'color:#006600; background-color: #ffffff'],
    false, true) ?>
<?php endforeach; ?>
</table>