そろそろ来そうなCakePHP3をざっくり見通してみた


今回は、CakePHP3について書きたいと思います。サンプルのアプリケーションをつくって、bakeされたController、Model、View、ViewCellを見てみました。

CakePHP3について

CakePHPは、Ruby on Rails流の「設定より規約優先」なパラダイムによる高速開発PHPフレームワークです。現在の安定版は2系で、nanapinanapiワークスアンサーのサーバサイドで使っています。

次世代のCakePHPであるバージョン3は現在開発中で、約2ヶ月前に CakePHP 3.0.0 dev preview 2 がでました。CakePHP3でどんな機能が実装されていくかはロードマップhttps://github.com/cakephp/cakephp/wiki/3.0-Roadmapに書かれています。PHP5.4以降のみでの動作とし、各クラス間を疎結合に、よりシンプルでより小さいCakePHPを目指しているようです。より良いプラグインとして実装されている機能については本体から機能を削除されていくようです。Scaffolding機能は削除されています。そしてなにより、ORMの部分が一新され、モデルのfind結果が配列からオブジェクトになったのが大きい変更点かなあと思います。

CakePHP3を動かす

PHPの環境を作ってCakePHP3を動かすまでやってみます。MacにHomebrewを使って、PHPとMySQLをインストールします。PHPのビルトインサーバが使えるのでApacheやnginx等httpサーバは不要です。また、Rubyでいうところのbundler、パッケージ管理をするComposerもHomebrewでインストールします。

PHPとMySQLの準備

ホームディレクトリにBrewfileを作って brew bundle を実行します。

HomebrewでインストールしたPHPを使う設定をします。bash_profileなどにパスの情報を書いたら、 source ~/.bash_profile などして再読込します。

次に、 mysql.server start  でMySQLを起動したら、MySQLの初期設定するために mysql_secure_installation を実行します。

これで終わり。かなり楽ですね。

アプリケーションの作成

CakePHP3のプロジェクトを作成します。

composer create-project は、すでにあるComposerパッケージから新しいプロジェクトをつくるコマンドです。https://github.com/cakephp/appをgit cloneしてプラスアルファでいくつかの自動処理するイメージです。デフォルトで作成されるアプリケーションディレクトリはappです。違う名前にしたい場合は、 composer create-project -s dev cakephp/app myproject のように指定します。

設定ファイルの作成、tmpディレクトリのパーミションの設定、Security.salt値の更新 もやってくれます。最後にcakephp/appリポジトリのバージョン情報を削除するかと聞かれるので、消しておきます。

ビルトインサーバで起動

php -S localhost:8000 -t app/webroot/ でビルトインサーバを起動したら、http://localhost:8000 にアクセスするといつものCakePHPの画面が現れます。ビルトインサーバを止めるときは、Ctrl-cです。

サンプルアプリケーション

アプリケーションを作ってみます。ユーザが複数の記事を持つ、Users hasMany Articlesの構造です。

SQL

上のSQLを実行してデータを投入したら、次にMySQLへの接続情報を設定ファイル(app/App/Config/app.php)に書きます。CakePHP2の頃と違い、database.phpではなくなっています。

timezoneはDB接続ごとのタイムゾーンの設定です。

bake

データを投入したら、Model、Controller、Viewの各ファイルを生成してみます。コンソールからbakeコマンドを実行します。

http://localhost:8000/users にアクセスすると、アプリケーションが動きます。

CakePHP3のソース

bakeして焼かれたソースを見てみます。

Model

モデルはCakePHP2とは大きく違っています。EntityクラスとTableクラスに分かれるようになりました。設定はTableクラスに、ロジックはEntityクラスに、といった分担でしょうか。テーブル名やプライマリキー、デフォルトで有効にするビヘイビアなどの設定はTableクラスのinitialize()メソッド内に書かれています。バリデーションはvalidationDefault()メソッド内に書かれています。そして各設定はメンバ変数ではなくメソッドを使っての指定となりました。

 View

ビュー用のファイルは、App/View/ではなくApp/Template/に作るようになっています。

コントローラでfind()して得られた$articlesをループしているTemplate/Articles/index.ctpをみてみると、配列ではなくオブジェクトのメンバ変数を参照して表示していることが分かります。findの返値である$articlesはCake\ORM\Query、$articleはさっきbakeしたApp\Model\Entity\Articleクラスのオブジェクトとなっています。

また、日時のcreatedやmodifiedはオブジェクト(Cake\Utility\Time)になっています。Utility/Timeは内部的にDateTimeの拡張であるCarbonを使っています(https://github.com/briannesbitt/Carbon)。いままではビューで配列内のcreatedの文字列をいったんDateTimeクラスのオブジェクトのしてからformatとかしてたのですが、卒業できそうです。

 Controller

コントローラです。フォームから送信されたデータを保存する部分を見てみます。連想配列のデータをsave()する今までとは違い、TableクラスのnewEntity()やpatchEntity()メソッドで生成したEntityクラスをsave()の引数に渡すようになっています。

ViewCells

CakePHP3からViewCellが追加されています。これは既存のCakePHPの概念を使って簡単に表現すると、小さいController付きelementのような機能で、RailsのコンポーネントのCellからアイデアを得ています。

bakeすると、App/Template/Cell/Article/display.ctpとApp/View/Cell/ArticleCell.phpが生成されます。

上記のようにCellクラスとデフォルトのdisplayを実装したら、他のビューからは次用のように呼ぶことができます。

http://book.cakephp.org/3.0/en/views/cells.html のマニュアルを見てみると、オーバーヘッドの少ないリクエストコンテナとして、既存のrequestAction()を置き換える機能になるだろうとされています。

いままで、Viewの共通部分はelementやViewBlockにまとめることができましたが、より疎結合にしようとするとそのなかでClassRegistoryするロジックをPHPタグを開始して冒頭に書いてしまったりしたので、cellを使うとすっきりまとまりそうです。

また、CakePHPのCoreDeveloperであるJoseさんのエントリを見ると、うまくやるとプレゼンテーションロジックの実装用途でCellが使えそうです。最近RailsをやっていてDraper(https://github.com/drapergem/draper)がとても便利で感動したので、この流れはいいなぁと思います。

まとめ

CakePHP3はとても素晴らしい進化をしていると思います。ウェブアプリケーションフレームワークとして非常に敷居が低く初心者にはとても優しいままで、シンプルかつフルスタックで、プラグインによる拡張性も高く、中級者以上も使いやすいと思います。今回やったように、環境構築も簡単です。

Railsはとても良いですが、CakePHPもかなり良いですよ!