This document is for CakePHP's development version, which can be significantly different
from previous releases.
You may want to read
current stable release documentation instead.
このチュートリアルは簡単なブックマークのためのアプリケーション (bookmarker) を作ります。 はじめに CakePHP のインストールを行い、データベースの作成、 そしてアプリケーションを素早く仕上げるための CakePHP が提供するツールを使います。
必要なもの:
データベースサーバー。このチュートリアルでは MySQL サーバーを使います。
データベースを作成するための SQL の知識が必要です。CakePHP は、それを前提としています。
MySQL を使用するとき、 PHP で pdo_mysql
が有効になっていることを確認してください。
基礎的な PHP の知識。
始める前に、最新の PHP バージョンであることを確認してください。
php -v
最低でも PHP 8.1 (CLI) 以上をインストールしてください。 あなたのウェブサーバーの PHP バージョンもまた、8.1 以上でなければなりません。そして、 コマンドラインインターフェイス (CLI) の PHP バージョンと同じバージョンがベストです。 完全なアプリケーションを確認したい場合、 cakephp/bookmarker をチェックアウトしてください。 さあ、はじめましょう!
最も簡単な CakePHP のインストール方法は Composer を使う方法です。Composer は、 ターミナルやコマンドラインプロンプトから CakePHP をインストールするためのシンプルな方法です。 まだ準備ができていない場合、最初に Composer をダウンロードとインストールが必要です。 cURL がインストールされていたら、以下のように実行するのが簡単です。
curl -s https://getcomposer.org/installer | php
もしくは Composer のウェブサイト
から composer.phar
をダウンロードすることができます。
そして、CakePHP アプリケーションのスケルトンを bookmarker ディレクトリーにインストールするために、 インストールディレクトリーからターミナルに以下の行をシンプルにタイプしてください。
php composer.phar create-project --prefer-dist cakephp/app:4.* bookmarker
Composer Windows Installer をダウンロードして実行した場合、インストールディレクトリー (例えば、 C:\wamp\www\dev\cakephp3) からターミナルに以下の行をタイプしてください。
composer self-update && composer create-project --prefer-dist cakephp/app:4.* bookmarker
Composer を使うメリットは、 正しいファイルパーミッションの設定や、 config/app.php ファイルの作成などのように、自動的に完全なセットアップをしてくれることです。
CakePHP をインストールする他の方法があります。 Composer を使いたくない場合、 インストール セクションをご覧ください.
CakePHP のダウンロードやインストール方法にかかわらず、いったんセットアップが完了すると、 ディレクトリー構成は以下のようになります。
/bookmarker
/bin
/config
/logs
/plugins
/src
/tests
/tmp
/vendor
/webroot
.editorconfig
.gitignore
.htaccess
.travis.yml
composer.json
index.php
phpunit.xml.dist
README.md
CakePHP のディレクトリー構造がどのように働くかを学ぶのにいい機会かもしれません。 CakePHP のフォルダー構成 セクションをご覧ください。
デフォルトホームページを確認することで、インストールが正しいことをざっと確かめることができます。 その前に、開発用サーバーを起動する必要があります。
bin/cake server
注釈
Windows では、このコマンドは bin\cake server
(バックスラッシュ) です。
これで、 8765 ポートで PHP のビルトインウェブサーバーが起動します。ウェルカムページを見るために http://localhost:8765 をウェブブラウザーで開いてください。CakePHP がデータベース接続が 可能かどうか以外は、すべての確認事項がチェック済みになるべきです。そうでなければ、PHP 拡張の 追加のインストールやディレクトリーのパーミッション設定が必要かもしれません。
次に、ブックマークアプリケーションのデータベースをセットアップしましょう。
まだセットアップしていない場合、例えば cake_bookmarks
のように、あなたの好きな名前で、
このチュートリアルで使用する空のデータベースを作成してください。必要なテーブルを作成するために、
以下の SQL を実行することができます。
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE bookmarks (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(50),
description TEXT,
url TEXT,
created DATETIME,
modified DATETIME,
FOREIGN KEY user_key (user_id) REFERENCES users(id)
);
CREATE TABLE tags (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
created DATETIME,
modified DATETIME,
UNIQUE KEY (title)
);
CREATE TABLE bookmarks_tags (
bookmark_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (bookmark_id, tag_id),
FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
FOREIGN KEY bookmark_key(bookmark_id) REFERENCES bookmarks(id)
);
複合主キーを持つ bookmarks_tags
テーブルにお気づきでしょうか。CakePHP は、
ほぼどこでも複合主キーをサポートします。それは、マルチテナントなアプリケーションの構築が
しやすくなります。
私たちが使用するテーブルやカラムの名前は恣意的ではありませんでした。CakePHP の 命名規則 を使用することによって、CakePHP がより効果的になり、 フレームワークの設定を避けられます。CakePHP はレガシーなデータベーススキーマに対応できるくらい 十分に柔軟ですが、規約に従うことで、時間を節約できます。
次に、どこにデータベースあるか、そしてどうやってテータベースに接続するかを CakePHP に伝えましょう。おそらく、これが何らかの設定が必要となる最初で最後です。
この設定はとても単純です。あなたのセットアップを適用するために config/app.php
ファイルの中の Datasources.default
配列の値を置き換えてください。
完全な設定配列の例は、以下のようになります。
return [
// More configuration above.
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'cakephp',
'password' => 'AngelF00dC4k3~',
'database' => 'cake_bookmarks',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
],
// More configuration below.
];
1度 config/app.php ファイルを保存して、 'CakePHP is able to connect to the database' がチェック済みであることを確認してください。
注釈
CakePHP のデフォルト設定ファイルは config/app.default.php にあります。
データベースが CakePHP の命名規則に従っているので、 基本的なアプリケーションを 素早く生成するために bake コンソール アプリケーションが使用できます。 コマンドライン上で、以下のコマンドを実行してください。
// Windows 上では、代わりに bin\cake を使用する必要があります。
bin/cake bake all users
bin/cake bake all bookmarks
bin/cake bake all tags
これは、 users、 bookmarks、 tags リソースのためのコントローラー、モデル、ビュー、 それらに対応するテストケース、フィクスチャーを生成します。あなたのサーバーが停止している場合、 再起動して http://localhost:8765/bookmarks に行ってください。
アプリケーションのデータベーステーブルへのデータアクセスを提供する基本的だが機能的な アプリケーションを見てください。1度、ブックマーク一覧を表示して、いくつかの ユーザー、ブックマーク、タグを追加してください。
(http://localhost:8765/users にアクセスして) ユーザーを作成した時、パスワードが平文で保存されることにおそらく気づくでしょう。 これはセキュリティの観点から、とても良くありませんので修正しましょう。
これはまた、CakePHP のモデル層について説明する良い機会です。CakePHP では、
オブジェクトの集合と、異なるクラスの単一オブジェクトを操作する方法を分けてます。
エンティティーの集合は、 Table
クラス内に格納され、1つのレコードに属する機能は、
Entity
クラス内に格納されます。
例えば、パスワードのハッシュ化は、個々のレコードで行われ、エンティティーオブジェクトに この振る舞いを実装します。パスワードがセットされるたびにハッシュ化したいので、 ミューテーターメソッドやセッターメソッドを使います。CakePHP は規約に基づいて、 エンティティーの一つにプロパティーをセットするセッターメソッドを呼びます。 では、パスワードのためのセッターを追加してみましょう。 src/Model/Entity/User.php に 以下を追加してください。
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher; // この行を追加してください
use Cake\ORM\Entity;
class User extends Entity
{
// bake で生成されたコード
protected function _setPassword($value)
{
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
}
}
今から既存のユーザーのパスワードを更新してくだい。パスワードを変更した際、一覧もしくは詳細ページで、 入力した値の代わりにハッシュ化されたパスワードがあることを確認してください。CakePHP は、 デフォルトで bcrypt を使ってパスワードをハッシュ化します。既存のデータベースが動作している場合、 sha1 や md5 も 使用できます。
注釈
パスワードがハッシュ化されない場合、セッター関数の命名について、 クラスのパスワードメンバーと大文字小文字が同じかを確認してください。
これで、パスワードを安全に保存できますので、アプリケーションにもっと面白い機能を構築できます。 一度ブックマークのコレクションを蓄えて、タグでの検索ができるようになると便利です。 次は、タグでのブックマークを検索するため、ルート、コントローラーのアクション、finder メソッドを実装します。
理想的には、 http://localhost:8765/bookmarks/tagged/funny/cat/gifs のような URL にしたいと思います。この URL は、 'funny', 'cat', もしくは 'gifs' タグが付いたブックマークすべてを検索することを意図しています。これを実装する前に、 新しいルートを追加します。 config/routes.php を以下のようにしてください。
<?php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\Router;
Router::defaultRouteClass(DashedRoute::class);
// 新しいルートを tagged アクションのために追加します。
// 末尾の `*` は、渡された引数を持っていることを
// CakePHP に伝えます。
Router::scope(
'/bookmarks',
['controller' => 'Bookmarks'],
function ($routes) {
$routes->connect('/tagged/*', ['action' => 'tags']);
}
);
Router::scope('/', function ($routes) {
// デフォルトのホームと /pages/* ルートへの接続
$routes->connect('/', [
'controller' => 'Pages',
'action' => 'display', 'home'
]);
$routes->connect('/pages/*', [
'controller' => 'Pages',
'action' => 'display'
]);
// デフォルトのルートへ接続
$routes->fallbacks();
});
上記は、 /bookmarks/tagged/ パスを BookmarksController::tags()
に接続する
新しい「ルート」を定義します。ルートを定義することによて、 URL の見た目と、
それらどのように実装されたかを分離することができます。
http://localhost:8765/bookmarks/tagged にアクセスした場合、CakePHP から
コントローラーのアクションがないことを伝える役に立つエラーページが表示されます。
今から存在しないメソッドを実装してみましょう。 src/Controller/BookmarksController.php
に以下を追加してください。
public function tags()
{
// CakePHP によって提供された 'pass' キーは全ての
// リクエストにある渡された URL のパスセグメントです。
$tags = $this->request->getParam('pass');
// タグ付きのブックマークを探すために BookmarksTable を使用
$bookmarks = $this->Bookmarks->find('tagged', [
'tags' => $tags
]);
// ビューテンプレートに変数を渡します
$this->set([
'bookmarks' => $bookmarks,
'tags' => $tags
]);
}
リクエストデータの他の部分にアクセスするためには リクエスト セクションを 参考にしてください。
CakePHP では、コントローラーのアクションをスリムに保ち、アプリケーションの多くのロジックを
モデルに置くことをお勧めします。 /bookmarks/tagged の URL にアクセスした場合、
findTagged()
メソッドがまだ実装されていないエラーが表示されます。
src/Model/Table/BookmarksTable.php に以下を追加してください。
// $query 引数は、クエリービルダーのインスタンスです。
// $options 配列には、コントローラーのアクション中で find('tagged') に渡した
// 'tag' オプションが含まれます。
public function findTagged(Query $query, array $options)
{
$bookmarks = $this->find()
->select(['id', 'url', 'title', 'description']);
if (empty($options['tags'])) {
$bookmarks
->leftJoinWith('Tags')
->where(['Tags.title IS' => null]);
} else {
$bookmarks
->innerJoinWith('Tags')
->where(['Tags.title IN ' => $options['tags']]);
}
return $bookmarks->group(['Bookmarks.id']);
}
カスタム Finder メソッド を実装しました。
これは、再利用可能なクエリーをまとめることを実現する CakePHP の非常に強力な概念です。
Finder メソッドは、常に クエリービルダー オブジェクトとオプション配列を
パラメーターとして取得します。Finder メソッドは、クエリーを操作し、任意の必須条件や抽出条件を
追加することができます。完了時、Finder メソッドは更新されたクエリーオブジェクトを
返さなければなりません。finder の中で、一致するタグを持つ特定のブックマークを検索するために、
innerJoinWith()
、 where()
そして group
メソッドを使います。
タグの指定がない場合、タグなしでブックマークを検索するために leftJoinWith()
を使用して、
'where' 条件を変更します。
/bookmarks/tagged の URL にアクセスすると、 CakePHP は、ビューファイルがないことを
知らせるエラーを表示します。次に、ビューファイルを tags()
アクションのために作りましょう。
templates/Bookmarks/tags.php に以下の内容を追加します。
<h1>
Bookmarks tagged with
<?= $this->Text->toList(h($tags)) ?>
</h1>
<section>
<?php foreach ($bookmarks as $bookmark): ?>
<article>
<!-- リンクを作成するために HtmlHelper を使用 -->
<h4><?= $this->Html->link($bookmark->title, $bookmark->url) ?></h4>
<small><?= h($bookmark->url) ?></small>
<!-- テキストを整形するために TextHelper を使用 -->
<?= $this->Text->autoParagraph(h($bookmark->description)) ?>
</article>
<?php endforeach; ?>
</section>
上記のコードは Html と Text を
ビューの出力生成を補助するために使いました。また、 HTML エンコード出力するために
h
ショートカット関数を使いました。HTML インジェクション問題を防ぐために
ユーザーデータ出力時には、必ず h()
を使用することを覚えておいて下さい。
ビューテンプレートファイルのための CakePHP の規約に従って tags.php ファイルを作りました。 この規約は、小文字を使い、コントローラーのアクション名をアンダースコアー化したテンプレート名にすることです。
ビューで $tags
や $bookmarks
変数を使えることにお気づきでしょう。
コントローラーで set()
メソッドを使って、指定した変数をビューに送るためにセットします。
ビューは、渡されたすべての変数をテンプレート内でローカル変数として利用可能にします。
/bookmarks/tagged/funny の URL にアクセスできるようにして、 全ての 'funny' でタグ付けされたブックマークを確認しましょう。
ここまで、ブックマーク、タグ、ユーザーを管理する基本的なアプリケーションを作成してきました。 しかしながら、全員のタグが全員に見えてしまいます。次の章では、認証を実装し、現在のユーザーに 属するブックマークのみを表示するよう制限します。
あなたのアプリケーションの構築を続けるために ブックマークチュートリアル パート2 を読み続けるか、 CakePHP で出来ることをより詳しく学ぶために ドキュメントの中に飛び込んで ください。