CakePHPを使うと何ができるの?〜シンプルな掲示板システムをPHPとCakePHPでそれぞれ作って比較する〜

Advent Calendar 2022

この記事は最終更新日から1年以上が経過しています。

この記事はレコチョクAdventCalendar2022の15日目の記事となります。

はじめに

こんにちは、株式会社レコチョク新卒エンジニアの祖父江です。
駆け出しサーバーサイドエンジニアとしてmurketというサービスに携わっています。

好きなアーティストはOasis、毛皮のマリーズ、GLIM SPANKYです!よろしくおねがいします!

私のプログラミングに関する略歴は以下になります。

  • 文系学部出身で、入社前までほぼプログラミング未経験
  • 入社後、レコチョクのエンジニア研修でPHPを学ぶ
  • 今年10月に現在の部署に配属後、PHPのフレームワークであるCakePHPを勉強し始めたところ

本記事では、簡単な掲示板システムをPHPで作成した後、CakePHPでの作成方法を書き方の違いに触れながら紹介したいと思います。

「現在PHPを使っていてCakePHPにも興味があり、雰囲気を知りたい」方や「フレームワークを触ってみたい」といった方に向けて、少しでも参考になれば幸いです。

注意
本記事では素のPHPとCakePHPの違いに触れることが目的のため、最小限で実装しています。
一部丁寧さに欠ける処理があります。ご注意ください。

そもそもCakePHPとは?

CakePHPはPHPのためのオープンソースフレームワークです。

フレームワークとは、アプリケーション開発においてよく利用される機能をあらかじめ備えた枠組みのことです。

フレームワークは共通する処理部分のプログラムを自動的に作成してくれるため、作りたいシステムに必要な固有処理を追記するだけでアプリケーションを構築することができます。

PHPのフレームワークにはLaravel, Symfonyなど様々存在しますが、レコチョクではCakePHPを採用しています。

余談ですが、CakePHPという名前は、「ケーキを焼くように簡単に開発できる」という意味で名付けられたそうです。

https://cakephp.org/

今回作りたいもの

DBを用いたシンプルな掲示板システムを作ります。

要件

  • 名前とコメントを入力し、発言できる
  • 全ての利用者の過去発言を一覧で見ることができ、「名前、コメント、投稿日時」がそれぞれ表示されている
  • バリデーション
    • 名前は20文字以内、コメントは100文字以内
    • 空白・半角スペースのみの入力は許容しない
    • 入力文字の間に空白があれば、そのまま出力する
    • 入力文字に特殊文字があれば、そのまま出力する

前提

  • EC2を使用しています
    • OSイメージ:Amazon Linux 2 Kernel 5.10
  • MariaDBのバージョン:10.5.10
  • nginxのバージョン: 1.20.0
  • php-fpmのバージョン: 7.4.30
  • PHPのバージョン: 7.4.30
  • CakePHPのバージョン: 4.2

準備

データベースを作成します。

素のPHPで作った場合

まずは素のPHPで作ってみましょう!

完成した画面がこちらです。

スクリーンショット 2022-11-29 11.26.47.png

CakePHPで作ってみる

プロジェクトの作成・DB設定・ファイルの生成

今度はCakePHPを使用して作成してみましょう!

CakePHPのインストールにはComposerを使用します。

まずは現在の作業ディレクトリでComposerコマンドが打てるか確認します。

Composerのインストールがまだの場合、CakePHP公式ドキュメントを参考にインストールしてください。

出力

Composerのマークが出れば大丈夫です!

インストールを行います。

インストールが完了すると現在のディレクトリ配下にプロジェクト名のディレクトリが出来ているはずです。

ディレクトリの中身を見てみましょう!

なんだか色々なディレクトリやファイルが入っています。。。

先程素のPHPで掲示板システムを作成した際には一枚のファイルにすべてプログラムを記述しました。

CakePHPでは、ひとつのWebアプリケーションは複数のファイルから構成され、機能ごとに各ディレクトリに格納されています。

プロジェクトを作成した時点で各ディレクトリが作られ、ディレクトリ構造はMVCモデルに沿ったものになっています。

https://www.geekly.co.jp/column/cat-technology/1911_040/

各ディレクトリにどんなファイルが置かれるのか、主要なディレクトリについて簡単にまとめました。

CakePHPのディレクトリ構造

プロジェクト作成後はディレクトリ構成に沿ってプログラムを配置していくことになります。

様々なディレクトリがありますが、今回はconfig, src/Contorller, src/Model, templatesにそれぞれプログラムを記述します!

プロジェクトが作成できたので、ドキュメントルートを設定し、サーバーにアクセスした際にCakePHPのデフォルトページが表示できるか確認してみましょう。

/etc/nginx/nginx.confのルートを プロジェクトの絶対パス/webrootに変更にします。

rootを変更する

nginxを再起動し、ブラウザから http://IPアドレスにアクセスします。

スクリーンショット 2022-11-30 11.49.45.png

CakePHPのデフォルトページが表示されればOKです!

DB設定

PHPで書いた際にはPDOを用い、DB操作の度に毎回DB接続をしていました。

CakePHPの場合はconfig/app_local.phpにDB情報を記述することで、DBに接続することができます。

config/app_local.phpを開き、 Datasorcesの中の host, username, password, databaseをそれぞれ自分のものに書き換えます。

またデフォルトだとデバックモードがONになっているので切っておきます。

ファイルの生成

DB設定が作成・確認が終わったら次はファイルを作成します。

先程素のPHPで掲示板システムを作成した際には手動でファイル(必要であればディレクトリも)を作成しました。

CakePHPにはファイルの生成のためにbakeという便利機能があります!

bakeとはCakePHPが持つ機能のひとつであり、bakeコマンドを使えばディレクトリ内にプログラムの雛形となるファイルを自動生成することができます。

bakeはMVCモデルに基づき、データベースのテーブルに合わせてファイルを自動生成し、そのテーブルへのCRUD機能を持つWebアプリケーションを作成します。

CRUD機能とはCreate(生成), Read(読み取り), Update(更新), Delete(削除)機能のことです。

bakeを行う際にはテーブル名を指定して使用します。

今回はModel, Controller, Templatesのファイルを作りたいので以下のコマンドを実行します。

生成されるファイル

  • src/Model/Table/LogsTable.php
  • src/Model/Entity/Log.php

生成されるファイル

  • src/Controller/LogsController.php

生成されるファイル

  • templates/Logs/index.php
  • templates/Logs/view.php
  • templates/Logs/add.php
  • templates/Logs/edit.php

ブラウザで http://IPアドレス/logsにアクセスするとテーブルのレコード一覧が表示されています。

スクリーンショット 2022-11-30 12.32.50.png

またlogsテーブルに対し、データの詳細表示・追加・編集・削除も行うこともできます。

たった3行コマンドを打ち込むだけで、DB操作ができるWebアプリケーションが作成できました!

bakeすごい。。。

ファイルの生成方法はbakeを使う以外にも手動で対応するディレクトリ内に作成することもできます。

その場合はCakePHPの規約に沿って命名を行う必要があります。

https://book.cakephp.org/4/ja/intro/conventions.html#file-and-classname-conventions

投稿一覧の表示

bakeを使ってWebアプリケーションの雛形が作れたので、次は生成されたファイルをそれぞれ編集し、今回の要件を満たすよう機能を実装していきます。

まずはどのリクエストに対してどのメソッドが呼び出されるのか設定していきます。

今回は一画面上で投稿の一覧表示&新規投稿ができるようにしたいので、GETで/logsにアクセスされたときにはLogsController.phpのindex()メソッドが、POSTでアクセスされたときにはadd()メソッドが実行されるように config/routes.phpに設定します。

次に投稿の一覧表示していきます。

Controller

Controllerを編集します。

素のPHPの場合、SQL文を記述→実行→結果セットを配列に変換し取得というプロセスが必要でしたが、CakePHPの場合はSQL文を直接記入することなくDBの操作を行うことができます。

CakePHPはオブジェクト指向を用いるため、オブジェクト演算子(アロー演算子)を使って、LogsControllerインスタンスからLogsTableを呼び出し、find()メソッドを実行することで、SQLのSELECT文と同じ動作をすることができます。

変数logsに代入されたデータはset()メソッドを使ってViewに渡されます。

templates

MVCのViewにあたるtemplates/Logs/index.htmlを編集します。

Controllerからset()メソッドを使って渡された変数logsの値を表示します。

ブラウザから http://IPアドレス/logsにアクセスし、確認します。

スクリーンショット 2022-11-30 14.44.35.png

投稿の一覧が新しい投稿順にソートされ、テーブル形式で並んでいます!

新規投稿

名前とコメントを入力し、新たに投稿を追加できるようにします。

templates

先程編集したtemplates/Logs/index.phpにフォームを追加します。

フォームを作成したいときは、CakePHPのビューの機能であるFormHelperを使用します。

Model

フォームに入力された値に対してバリデーションチェックを行います。

Modelにバリデーションを記述することに対して、違和感を覚える方もいるのではないでしょうか?(私はめちゃめちゃ感じました)

CakePHPのModelはTableとEntityという2つのオブジェクトで構成されています。

Tableはテーブルへのアクセスを行い、Entityはテーブルの中の1レコードに対して操作することができます。

validationDefault()メソッドを使い、バリデーションの検証ルールを定義することができます。

定義された検証ルールの実行タイミングはEntityが保存される前に自動で実行される仕様になっています。(参考)

明示的に記述しなくてもCakePHPが自動で実行してくれるメソッドがあることも、素のPHPで書く時との違いのひとつです。

また、今回はCakePHPのチュートリアルに沿い、Model/Tableにバリデーションルールを記述しましたが、実際の業務では別ファイルにValidatorクラスを作成し、Controller内で呼び出す方法を使うことが多いです。(参考)

Controller

最後にControllerのadd()メソッドを編集しましょう!

最初にnewEmptyEntity()メソッドを使用して空のレコードを作成し、getData()メソッドで取得した値(入力された名前とコメント)を格納し、レコードを更新しています。

また、投稿に失敗したときor成功したときに、ユーザーに通知を行うために、Flashコンポーネントを使用しブラウザにメッセージ通知を表示しています。

ブラウザで確認します!
フォームが生成されていることが確認できました。
記事の投稿も問題なくできています。

スクリーンショット 2022-11-30 15.39.05.png

バリデーションも動いています。

スクリーンショット 2022-11-30 15.38.34.png

これで完成です!

素のPHPとCakePHPの違い

シンプルな掲示板システムを作成しただけでも、以下のような違いがあることがわかりました!

オブジェクト指向 ファイル作成 DBへの接続 テーブル操作 バリデーション
素のPHP 必須ではない 手動 PDOもしくは手続き型で毎回接続する SQL文を実行する if文を使って明示的に検証する
CakePHP 必須 bake + 手動 app_local.phpに設定するだけ クラスのメソッドを使う Tableに検証ルールを記述すると自動で実行される

まとめ

素のPHPとCakePHPでは書き方がだいぶ違うことが伝わったでしょうか。

約2ヶ月CakePHPを使ってみた所感としては、記述量が少なくてすむ点など便利さを感じる一方で、オブジェクト指向への理解不足や、CakePHPがよしなにやってくれているが故にエラーが発生した際に詰まってしまうことなど、知識不足に悩まされることもあります。

CakePHPは公式ドキュメントが充実しているので(分かりやすいとは言っていない)、今後もドキュメントやソースコードなどを読みつつ、知識を深めていきたいと思います。

コードやCakePHPについて気になる点があれば、ぜひ教えて下さい。

この記事がCakePHPに興味がある方の参考になれば幸いです。

明日のレコチョク Advent Calendarは16日目 VSCode上でCakePHPコーディング規約チェックの自動化 です。お楽しみに!

参考