- Published on
cakePHPとDjango比較しながら、セットアップ備忘録
- Authors
- Name
目的
下記クイックスタートを完了し、設計思想を一通り学習する。
- cakePHPチュートリアルを完了する(windows)
- クイックスタート後は、ページ下部の復習コンテンツ
要約
- DRFはフロント、バックが明確に分かれる設計。APIから取得したデータを表示し、ユーザーの操作を処理。フロントエンドの変更がバックエンドに影響を与えない。
- CakePHPは、バックエンドとフロントエンドを同じシステムで管理が基本。一応、APIルーティングの設定はできて、DRFと同じ運用はできる。
- フルスタックフレームワークを使ったことなかったため、慣れが必要。フロントとバックを同時に開発できるのは、開発スピードの観点で優位か。
- CakePHPでは、アプリケーションロジックをできるだけモデル層に配置し、コントローラーのアクションを簡潔に保つという設計方針がある。ファインダーメソッドをテーブル(モデル)に書く。
- コントローラーは本来、リクエストを受け取り、適切なモデルを呼び出し、ビューに渡すという責務に限定するべき
- CakePHPの設計原則では、モデル(テーブルやエンティティ)にビジネスロジックを集中させ、コントローラーをシンプルに保つことが推奨
- 「Fat Models, Skinny Controllers」:モデル(テーブル)がビジネスロジックやデータ操作の責任を持つ。コントローラーはそのロジックを呼び出し、結果をビューに渡すだけにする。
要約2(DRFとの比較抽出)
CakePHPの設計思想
- Fat Models, Skinny Controllers(太いモデル、薄いコントローラー)
- ビジネスロジックやデータ処理をモデル(テーブル)に集中させる。
- コントローラーは、リクエストを受け取り、モデルを呼び出し、ビューに渡すだけの責務。
Django REST Frameworkの設計思想
- Thin Models, Fat Views(薄いモデル、太いビュー)
- Djangoではモデルはデータ定義に留める。
- ビジネスロジックやデータ処理は、ビューやシリアライザで記述。
- DRFでは、ビューセットやシリアライザがCakePHPのモデルのような役割を一部引き継ぐ。
CakePHPのファイル構成と責務
ファイル/ディレクトリ | 役割 | 具体例 |
---|---|---|
src/Model/Table | ビジネスロジックとデータ処理を記述。テーブルごとの関連付けやファインダーメソッドを定義。 | ArticlesTable.php で findTagged を定義し、タグで記事を検索するロジックを記述。 |
src/Controller | リクエストを受け取り、適切なモデルやビューを呼び出す。ロジックはモデル(テーブル)に委譲。 | ArticlesController.php で tags() アクションを定義し、findTagged を呼び出して結果をビューに渡す。 |
templates | ビューのテンプレートを配置。データの表示に集中。 | templates/Articles/tags.php で、$articles をループして記事一覧を表示。 |
config/routes.php | URLとコントローラー・アクションのマッピング。 | /articles/tagged/* を ArticlesController::tags() にマッピング。 |
Django REST Frameworkのファイル構成と責務
ファイル/ディレクトリ | 役割 | 具体例 |
---|---|---|
models.py | データ構造を定義。データ処理はほとんど記述しない。 | Article モデルに ManyToManyField(Tag) を定義し、記事とタグを多対多で関連付け。 |
serializers.py | データの整形(JSON化)や入力検証を担当。 | ArticleSerializer にタグを含む記事のデータをシリアライズ。 |
views.py | ビジネスロジックとデータ処理を記述。リクエストを処理し、シリアライザやクエリセットを利用。 | ArticleByTagsView を定義し、タグで記事を検索して結果を返す。 |
urls.py | URLとビューのマッピング。 | /articles/tagged/<tags> を ArticleByTagsView にマッピング。 |
CakePHPとDRFの比較表
項目 | CakePHP | Django REST Framework (DRF) |
---|---|---|
データ定義 | モデル(ArticlesTable.php )に関連付けやカスタムクエリを記述。 | モデル(models.py )はデータ構造の定義のみ。 |
データ処理 | モデル(テーブル)内のファインダーメソッドでデータ処理を実装。 | ビュー(views.py )でクエリロジックを実装。 |
JSONレスポンス生成 | ビューではなくテンプレートを使用しHTML出力がメイン。JSONは明示的に設定が必要。 | シリアライザでJSONレスポンスを生成。REST API向けに最適化。 |
ルートの定義 | routes.php でURLとコントローラーアクションをマッピング。 | urls.py でURLとビューをマッピング。 |
利便性 | 自動化(Bake )でファイル構成を迅速に生成可能。 | 手動で構成を記述するが柔軟性が高い。 |
設計思想 | Fat Models, Skinny Controllers。モデルが中心。 | Thin Models, Fat Views。ビューが中心。 |
CakePHP:
- モデル中心でロジックを再利用可能。
Bake
による迅速なスケルトン生成が可能。- テンプレートエンジンを使用しHTMLレンダリングに適している。
Django REST Framework:
- ビュー中心でREST API開発に最適。
- シリアライザによる柔軟なJSONデータ処理。
- APIエコシステム全体を簡単に構築可能。
チュートリアル開始
composerインストール
- URL
- README
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
cakePHPプロジェクト作成
django startprojectと同じ。
php composer.phar create-project --prefer-dist cakephp/app:"4.*" my_app_name
compposer install
pip install requirements.pyや、npm installのようなもの
composer install
20,30分低スペックPCだと時間がかかる
開発用サーバー
アプリケーションに対し、GUIで操作できるようなGUIツールらしい。XAMPPがあるならApacheサーバーでいい。
cakeの簡易サーバーで進める場合、下記。
bin/cake server
Apacheの場合。
- Apache をXAMPPで起動でもいい。
http://localhost:8080/phpmyadmin/
にアクセス。
DB作成
- phpMyAdminの「SQL」から、下記URLのSQL実行しサンプル用テーブル作成
- 参考
- モデルの作成
- Table オブジェクトは、指定されたテーブルの中に保存されたエンティティーの集合へのアクセスを提供
- bakeコマンドで生成するもの
- bakeはDjango REST Framework (DRF) におけるモデル定義とシリアライザの自動生成にあたる。
- その前に、各種設定必要
- app_local.php
'Security' => [
// 'salt' => env('SECURITY_SALT', '__SALT__'),
'salt' => env('SECURITY_SALT', 'default_salt_key'),
],
- そのあと
- .env
export SECURITY_SALT=
- そのあと
- config/bootstrap.phpで書きコメントイン
if (!env('APP_NAME') && file_exists(CONFIG . '.env')) {
- XAMPPの場合Datasourcesの設定で進める。app_local.phpを修正
'Datasources' => [
'default' => [
'className' => Cake\Database\Connection::class, // 正しいクラス名
'driver' => Mysql::class,
'persistent' => false,
'host' => 'localhost',
'username' => 'root',
'password' => '', // XAMPPデフォルトの場合
'database' => 'cake_cms',
'encoding' => 'utf8mb4',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
]
- bake コマンドで、下記出力続く
bin/cake bake model all
bin/cake bake model all
One moment while associations are detected.
Baking table class for Articles...
Creating file C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Table\ArticlesTable.php
Wrote `C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Table\ArticlesTable.php`
Deleted `C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Table\.gitkeep`
Baking entity class for Article...
Creating file C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Entity\Article.php
Wrote `C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Entity\Article.php`
Deleted `C:\Users\user\source\learning\php_practice\my_app_name\src\Model\Entity\.gitkeep`
Baking test fixture for Articles...
Creating file C:\Users\user\source\learning\php_practice\my_app_name\tests\Fixture\ArticlesFixture.php
Wrote `C:\Users\user\source\learning\php_practice\my_app_name\tests\Fixture\ArticlesFixture.php`
Deleted `C:\Users\user\source\learning\php_practice\my_app_name\tests\Fixture\.gitkeep`
Bake is detecting possible fixtures...
Baking test case for App\Model\Table\ArticlesTable ...
Creating file C:\Users\user\source\learning\php_practice\my_app_name\tests\TestCase\Model\Table\ArticlesTableTest.php
Wrote `C:\Users\user\source\learning\php_practice\my_app_name\tests\TestCase\Model\Table\ArticlesTableTest.php`
Done
One moment while associations are detected.
Bake cannot generate associations for composite primary keys at this time.
Baking table class for ArticlesTags...
3. 規約と構成の違い
項目 | CakePHP | Django(DRF) |
---|---|---|
モデル定義 | Table クラスを使用 | Model クラスを使用 |
タイムスタンプ管理 | ビヘイビアで管理(Timestamp ) | フィールド設定(auto_now_add など) |
フィールド定義 | SQLスキーマに従いテーブル操作 | モデル内で直接定義 |
規約と設定 | 規約優先(クラス名とテーブル名をマッピング) | 設定重視(明示的にモデルを定義) |
CakePHPのbin/cake bake model all
は、Django REST Framework (DRF) におけるモデル定義とシリアライザの自動生成に相当します。ただし、CakePHPのbake
コマンドは、さらに広範囲な機能をカバーします。
項目 | CakePHP (bake) | Django REST Framework |
---|---|---|
モデル生成 | bin/cake bake model all コマンドで自動生成 | models.py に手動記述。またはinspectdb |
シリアライザ生成 | Entity クラスが自動生成される | シリアライザは手動で記述 (serializers.py ) |
リレーション定義 | Table クラスで定義 | モデル内でForeignKey やManyToManyField |
対応する自動化範囲 | データベーススキーマからモデルと関連クラスの生成 | inspectdb + 手動でシリアライザ作成 |
CakePHPはbake
コマンドで多数のファイルを一気に生成できるのが強みで、開発の初期段階で非常に効率的。一方で、DRFは自由度が高く、個別に調整しやすい設計が特徴
コントローラーの作成
1. コントローラーの役割
CakePHP:
- コントローラーはリクエストを処理し、データベース操作を行うモデルと、HTMLを生成するビューをつなぐ役割を果たす。
- リクエストごとにアクション(メソッド)を定義。
- 例えばコントローラーでは、リクエストもとにデータベースから記事を取得して、テンプレートにデータを変数で渡す。その後、CakePHPではテンプレート(HTML含むPHP)を探し、そこに格納されるというわけ。そのHTMLがサーバーからブラウザに送信されユーザに表示。
- DRFだったら、viewからjsonでレスポンスは返し、フロントエンドがjsonで受け取り、いかようにするといった流れ。
DRF:
- DRFでは、コントローラーに相当するのはビュークラスやビューセット。
- モデルやシリアライザと連携して、APIリクエストを処理し、データを返す責任がある。
2. CakePHPとDRFの基本的な対応関係
CakePHP | Django REST Framework | 説明 |
---|---|---|
コントローラー | ビュー(クラスまたは関数) | リクエストを処理し、レスポンスを生成する部分。 |
アクション(メソッド) | 関数ベースビュー/メソッド | HTTPリクエスト(GET, POST, PUTなど)ごとに処理を記述。 |
テンプレート | HTMLレスポンス/テンプレート | HTMLを生成する部分。ただし、DRFではAPIのためHTMLを扱うことは少ない。 |
ヘルパー | Djangoテンプレートタグや関数 | フォームやリンクの生成、HTMLタグの簡素化など。 |
3. HTML返却とAPI返却の違い
項目 | HTML返却 (MVC従来構成) | API返却 (JSON構成) |
---|---|---|
リクエスト例 | http://example.com/articles/index | http://example.com/api/articles |
ルーティング | ArticlesController@index | ArticlesController@index |
レスポンス内容 | HTML(テンプレートで生成) | JSONデータ(直接生成) |
ビュー (View) | templates/Articles/index.php でHTML生成 | 不要(_serialize でデータを直返し) |
フロントエンド処理 | サーバーからHTMLを受け取り、直接表示 | フロントエンド(例: React)がJSONを処理してUI更新 |
例外処理 | CakePHPがテンプレートを探せない場合にエラーページを表示 | APIレスポンスにHTTPステータスコードでエラーを返す |
4.処理の流れを図示
HTML返却(従来MVC)
リクエスト: GET /articles/index
↓
ルーティング: routes.php → ArticlesController@index
↓
コントローラー: ArticlesControllerがモデルからデータ取得
↓
ビュー: templates/Articles/index.phpでHTML生成
↓
レスポンス: HTMLを返却
API返却
リクエスト: GET /api/articles
↓
ルーティング: routes.php → ArticlesController@index
↓
コントローラー: ArticlesControllerがモデルからデータ取得
↓
JSON生成: _serializeオプションでJSONレスポンス生成
↓
レスポンス: JSONを返却
コントローラーtutorial
- 注意点、特定のURLを取得できるように、コントローラとアクションの命名はせず、CakePHPの規約に従うこと
- クラス名: 複数形 + パスカルケース + Controller
- ファイル名とクラス名、データベース、モデル、ビュー、プラグインそれぞれ
データベース: articles テーブル
Controller: ArticlesController(src/Controller/ArticlesController.php)
Table クラス: ArticlesTable(src/Model/Table/ArticlesTable.php)
Entity クラス: Article(src/Model/Entity/Article.php)
ビュー: templates/Articles/index.php
URL例: http://example.com/articles → ArticlesController::index() にマップ。
作成
- CakePHP は、 コントローラーのアクションが完了した後、自動的にテンプレートを描画
テンプレート
- CakePHP のテンプレートファイルは、 templates の中で 対応するコントローラーの名前をつけたフォルダーの中に保存。 今回の場合、 'Articles' という名前のフォルダーを作成する必要があり
- $this->Html->link CAKEPHPのヘルパー関数でリンク生成
xamppの設定変更
- httpd.confを修正する
- アプリの場所をApacheに教える
- DocumentRoot(ウェブサイトの入口)を、CakePHPのwebrootフォルダに変更
- Apacheに「このフォルダの中身をウェブで公開してOK」と設定
- CakePHPでは、URLを自由にデザインできる「ルーティング」という仕組み.Apacheの「mod_rewrite」という機能が必要.
- 「どの窓口でウェブサイトを提供するか」を決めるので、Apcheサーバーのポートを確認
- ブラウザで以下のURLにアクセスすれば、CakePHPのアプリが表示
http://localhost:8080
- CakePHPアプリは「家」,Apacheはその家に手紙を届ける「郵便配達員」
# 元の設定
DocumentRoot "C:/xampp/htdocs"
<Directory "C:/xampp/htdocs">
# 修正後の設定
DocumentRoot "C:/Users/user/source/learning/php_practice/my_app_name/webroot"
<Directory "C:/Users/user/source/learning/php_practice/my_app_name/webroot">
# 修正箇所を確認して有効化
LoadModule rewrite_module modules/mod_rewrite.so
view テンプレート作成
- templates/Articles/view.php
- レスポンスで返すHTML
- $this->Articles->find() を使うことで、記事の検索条件やソート順を柔軟に設定可能
POSTリクエスト処理(addメソッドをコントローラに追加)
- CakePHP のリクエストは、 $this->request を使用してアクセス可能なリクエストオブジェクト
- POST データは、 $this->request->getData() で利用可能
- データを保存するために、まず POST データを Article エンティティーに 「変換 (marshal)」
- 新しい記事を保存した後、セッションにメッセージをセットするために FlashComponent の success() メソッドを使用
- レイアウトの中に、フラッシュメッセージを表示し、対応するセッション変数をクリア
- パラメーター ['action' => 'index'] は、例えば ArticlesController の index アクションの場合、 URL /articles に変換
POSTのテンプレート
add.php
を追加edit.php
を追加
バリデーション
- Table.phpに追加すること
複数の作成者が、CMSで作業できるように。
- Bake はCakePHPのコード生成ツールで、モデル、コントローラー、テンプレートを迅速に生成するためのもの。
- Django/DRF では、モデルやビューセットを手動で記述するが、
makemigrations
やDefaultRouter
によって効率化できる。
bakeコマンド
cd /path/to/our/app
bin/cake bake model users
bin/cake bake controller users
bin/cake bake template users
これらの3つのコマンドは次を生成。
- テーブル、エンティティー、フィクスチャーファイル
- コントローラー
- CRUD テンプレート
- 生成された各クラスのテストケース
BakeとDjango/DRFの違い
機能 | CakePHP Bake | Django/DRF |
---|---|---|
モデル生成 | bin/cake bake model users | モデルを手動で定義 + makemigrations + migrate |
コントローラー生成 | bin/cake bake controller users | ViewSet を手動で定義 |
ビュー生成 | bin/cake bake template users | DRFでは自動的にJSON形式のレスポンスを提供 |
ルーティング | 自動で生成される | DefaultRouter を使用して簡単に設定 |
CLIツール | 自動生成に特化(Bake) | CLIでマイグレーションや管理が可能(manage.py ) |
タグ追加
タグによる検索
- ルートに追加
config/routes.php
- タグを使って記事を検索できる機能を実装
- 特定のタグが付けられた記事を検索するための ルート(URLとアクションのマッピング)、コントローラーのアクション、および検索用の ファインダーメソッド を作成
計算フィールドの追加
- 記事に関連付けられているタグをまとめた文字列(tag_string) を生成する計算フィールド
- タグ一覧をカンマ区切りの文字列として取得できるようにする
- _getTagString メソッドは、tag_string プロパティが呼び出されたときに自動的に実行(CakePHP の命名規則に基づく)
- フロントエンドに使いやすい形に整形する。価格であれば税込み価格に変換する。データの文字列化。人間が読みやすい形にする。
データベース
↓
Table (Model) -----------------+ (全体の操作を管理)
↓ |
Entity (1レコード) | (仮想プロパティを生成)
↓ |
仮想プロパティ (例: tag_string) | (動的に生成された値を提供)
↓ |
テンプレート (View) | (仮想プロパティを使って表示)
データベース
↓
ArticlesTable (Model/Table)
↓
Article (Model/Entity) ── 仮想プロパティを生成
↓
ArticlesController (Controller)
↓
テンプレート (View) ── HTML レスポンスを作成
DRFだと
クライアント (ブラウザ/アプリ)
↓ HTTP リクエスト
ビュー (APIView)
↓ モデルからデータ取得
モデル (Article)
↓ データをシリアライザに渡す
シリアライザ (ArticleSerializer)
- 仮想プロパティ (tag_string) を生成
↓
レスポンス (加工済みJSON)
↓ HTTP レスポンス
クライアントが表示
{
"id": 1,
"title": "First Post",
"body": "Hello World",
"created": "2024-11-30T12:00:00Z",
"tag_string": "Funny, Cat"
}
処理のステップ | CakePHP | DRF |
---|---|---|
モデル定義 | 役割: 記事テーブル全体の構造と操作を定義する。 該当ファイル: src/Model/Table/ArticlesTable.php | 役割: 記事モデルを定義し、データベース構造を記述する。 該当ファイル: articles/models.py |
具体例 | 記事一覧を取得するクエリメソッドを定義する。 例: 公開済みの記事を取得するメソッドを作成する。 | 記事のタイトルや本文を含むフィールドを定義する。 例: 公開状態を示すフィールドを持つモデルを作成する。 |
個別データ操作 | 役割: 記事ごとにデータを操作するためのエンティティを定義。 該当ファイル: src/Model/Entity/Article.php | 役割: モデルインスタンスを取得してデータを操作。 該当ファイル: articles/models.py |
具体例 | 記事のタイトルを取得、または加工したデータを返すメソッドを定義する。 | 特定の記事のタイトルを取得して、クライアントで表示するデータを準備する。 |
仮想プロパティの定義 | 役割: 動的なプロパティをエンティティに定義。 例: 記事のタグをカンマ区切りで取得する仮想プロパティ。 該当ファイル: src/Model/Entity/Article.php | 役割: シリアライザで動的プロパティを定義し、レスポンスデータを整形。 該当ファイル: articles/serializers.py |
データの加工 | 役割: テーブルやエンティティでデータを加工。 例: タグ付きの記事一覧を取得するクエリを作成する。 該当ファイル: src/Model/Table/ArticlesTable.php | 役割: シリアライザで加工処理を記述し、クライアントに適したデータ形式に整形。 該当ファイル: articles/serializers.py |
レスポンス生成 | 役割: コントローラーでデータを取得し、テンプレートに渡す。 例: タグ付きの記事一覧を取得して HTML を生成する。 該当ファイル: src/Controller/ArticlesController.php | 役割: APIView でデータを取得し、シリアライザを通して加工したデータを返す。 該当ファイル: articles/views.py |
クライアントへの出力 | 役割: テンプレートで加工済みデータを HTML として生成。 該当ファイル: templates/Articles/tags.php | 役割: JSON フォーマットで加工済みデータをクライアントに返す。 該当ファイル: テンプレートは不要。 |
タグの永続化(テーブルへの保存)
- CakePHP の ORM
記事保存リクエストを受け取る:
ユーザーがフォームで記事を投稿または編集してリクエストを送信します。
エンティティにデータがセットされる:
フォームから送信されたデータが記事エンティティ($entity)に格納されます。
beforeSave() がフックされる:
ORM がデータを保存する直前に beforeSave() メソッドが自動的に呼び出されます。
_buildTags() の実行:
beforeSave() 内でタグ文字列(tag_string)が渡され、_buildTags() が呼び出されます。
タグ文字列を分解し、既存のタグとの照合、新しいタグの作成を行います。
タグエンティティの設定:
_buildTags() の結果であるタグエンティティのリストが $entity->tags に設定されます。
タグと記事の関連を保存:
ORM が自動的に中間テーブル(articles_tags)への保存を処理。
認証
CMSチュートリアル認証
- パスワードハッシュ化。平文だったらセキュリティとしてだめ。
- チュートリアル通り authentication:2.0では依存関係の衝突あったので、2.11
composer require "cakephp/authentication"