PHPでウェブアプリケーションを開発する場合、フルスクラッチで書くことはほとんどなくなり、なんらかのフレームワークを使うことが一般的になってきました。
今回はCakePHPという、PHPフレームワークでは長く開発され続けていて、利用者も多いフレームワークをご紹介します。
過去に利用経験があって、しばらく遠のいていた人も多いフレームワークのように思いますので、そういう方にも今後のAPI開発で使ってみようかなと思えるポイントもご紹介できればと思っています。
目次
Ruby on Rails の流れを汲むPHPフレームワーク
CakePHPが存在しなかった当時、PHPとは別のプログラミング言語のRubyで「Ruby on Rails」というフレームワークがありました。
開発効率の良さとRubyの書き心地の良さ、Gemというパッケージツールから取得できる多くの便利なライブラリ群などの理由で開発者の心を掴んで、とても流行した時期がありました。
そんなRuby on Railsの良さをPHPでも体験できないかということで開発されたのが、CakePHPです。
開発当初からかなり時間も経過していますが、両者の根本的なMVCの考え方は変わっていませんし、どのフレームワークを選択してもおおよそ変わらない部分です。
CakePHPから開発手法を学んでから、Ruby on Railsも使ってみるとプログラミングの幅も広がるかと思います。
また、取っ掛かりとしては日本語ドキュメントも充実していて習得しやすく、困った時の検索も利用者が多く、たくさんの記事が公開されていますので情報収集にも事欠きません。
CakePHPはメジャーバージョンによって大きく使い方が変わる部分もありますので、情報収集の際はバージョンの確認をしてから内容を確認した方がいいでしょう。
また、ノウハウが貯まって記事を公開する側になった時も、検索してきたユーザーがわかりやすいよう、バージョン表記は忘れずに!
CakePHPのメリット
先にも少し書きましたが、CakePHPのメリットとして大きなものが3つあると思います。
- 日本語ドキュメントが豊富(公式ドキュメントはほぼ翻訳されている)
- 開発者が多く、コミュニティが活発に活動している
- PSR準拠
日本語ドキュメントが豊富
日本語ドキュメントは大変ありがたいですね。
公式ドキュメントは概ね翻訳されていますし、翻訳の精度も高く読みやすいと思います。
ドキュメント量も多く基本的なことは網羅しているようなので、困ったことがあったらまず公式ドキュメントを最初に調べてみることをオススメします。
検索するのもいいですが、利用者が多いフレームワークは検索で得られる情報も玉石混交なので、初めのうちは公式ドキュメントをあたるのが正解への近道と言えます。
【CakePHP 公式ドキュメント】https://book.cakephp.org/3.0/ja/index.html
開発者が多く、コミュニティが活発に活動している
CakePHPの開発者が多く、コミュニティが活発に活動しているということは、CakePHPのバージョンアップや機能追加、バグフィックスに要する時間が短くなる傾向が強く、新しい機能をより安定して利用できるということで、利用者にとってはメリットしかありません。
PSR準拠
PSR(*)準拠というのが、あまり馴染みのない言葉かも知れませんが、PHPでコーディングを行う際の規約を取りまとめたものです。
極論を言うと動けば正解、という部分もあるのですが、チーム開発をする場合、各人が好きなように書いてしまってはチームで開発するメリットが最大限に活かせません。
各々が書いたコードを簡単に理解し合えるよう、クラス名の付け方や、メソッド名の付け方、改行の位置、行の長さなど割と細かい決まりがあります。
慣れないうちは手錠でも掛けられたような息苦しさを感じたりするものですが、最近のPHPフレームワークでは当たり前のように取り入れられていることが多いので、慣れておいて損はないでしょう。
(*)PSRとは、PHP Standards Recommendationsの略で、PHPフレームワークやツール、ライブラリなどの開発者が集まって形成されているPHP-FIG(PHP Framework Interop Group)が定めているPHPコーディング規約。
CakePHPでHello World APIを作成してみる
CakePHPはチュートリアルがしっかり作られているので、これを写経すればフレームワーク初心者でも概要が掴めます。
チュートリアルは簡単なブログシステムなので、ここではCakePHPの導入から、簡単なAPIを作成してみるところをやってみようと思います。
CakePHPは執筆時点での最新版となる、3.6を使用しています。
導入方法
過去のバージョンでは、git cloneでプロジェクトをコピーしてくる方法が一般的でしたが、今はcomposerを使ったインストールにもしっかり対応しているようです。
composerを使ったインストールで開発環境を手早く作ってみます。
システム要件にある「intl PHP 拡張」というのは、普段あまり要求されることはないライブラリです。
補足しておくと、国際化対応に必要なフォーマットや情報をまとめたライブラリで、時刻表記やサマータイムなどの日時操作や通貨や数値のローカライズなどをするものです。
Linuxの場合、PHPのバージョンに対応したphp-intlをインストールする必要があります。
以下はremiリポジトリを利用してインストールしたPHP7.1に対応したphp-intlのインストールコマンドです。
【bash】
yum install --enablerepo=remi-php71 php-intl
プロジェクトを作成
composerが未導入に場合は、以下のコマンドでカレントディレクトリにcomposer.pharが配置されます。
【bash】
curl -s https://getcomposer.org/installer | php
続いて、composer経由で、CakePHPをセットアップします。
【bash】
php composer.phar create-project --prefer-dist cakephp/app caketest
tmpやlog関係のディレクトリの書き込み権限がないというエラーが表示されたら、書き込み権限の追加やSELinuxなどの設定を確認してみてください。
この時点ではデータベースへの接続情報を登録していないので、エラーが出ていると思います。
config/app.php を編集し、データベースへの接続情報を追記します。
HelloWorldコントローラーを作成
まず始めに、リクエストを送ると「hello world」と返すAPIを実装してみたいと思います。
DBは利用しないので、コントローラーの実装だけです。
【php】
# src/Controller/HelloController.php <?php namespace App\Controller; class HelloController extends AppController { public function world() { $this->set([ 'message' => 'hello world', '_serialize' => ['message'], ]); } }
jsonでレスポンスを返すためには、ルーティングの設定でそのように指定してあげる必要があります。
以下のコードを、Router::scope()メソッドの前に挿入してみてください。
【php】
# config/route.php Router::extensions(['json']);
【json】
{ "message": "hello world" }
既に実装されているものを使えば、開発者が書かなければいけないコード量はわずか10行程度でした。
モデルを作成
データベースを使わないAPIは皆無なので、CakePHPに搭載されているORMを使ってデータベースとのやり取りをしてみたいと思います。
前回Symfonyの記事でも使いましたが、今回もアメリカ人にありがちな名前男女トップ10のデータが格納されたテーブルを用意します。
【sql】
CREATE TABLE `names` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `sex` varchar(6) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
【sql】
INSERT INTO names (`name`, `sex`) VALUES ("Noah", "male"),("Liam", "male"),("Mason", "male"),("Jacob", "male"),("William", "male"),("Ethan", "male"),("James", "male"),("Alexander", "male"),("Michael", "male"),("Benjamin", "male"),("Emma", "female"),("Olivia", "female"),("Sophia", "female"),("Ava", "female"),("Isabella", "female"),("Mia", "female"),("Abigail", "female"),("Emily", "female"),("Charlotte", "female"),("Harper", "female");
テーブルができたところで、モデルファイルを作成します。
と言いたいところですが、CakePHPではテーブルがCakePHPの規約に準拠している場合に限ってモデルファイルを書かなくてもテーブルにアクセスできる仕組みになっています。
もちろん、書くこともできますし、むしろ独自メソッドを追加したり、テーブル同士を結合するための設定を追加する場合はモデルファイルを書かなくてはいけません。
今回のように、特に難しいことをしない場合に限ってのことです。
続いてコントローラーにデータを取得する処理を追加します。
CakePHPの慣例で、コントローラーと同じ名前を持つモデルは、起動時に $this のオブジェクトとして登録されています。
今回の例では、helloテーブルが存在すれば自動的に登録され、すぐに使える状態になっています。
ただし、今回のようにコントローラー名とモデル名が異なる場合は、TableRegistryクラスを通じて接続用のオブジェクトを取得する必要があります。
データベース接続処理を追加したコントローラーファイルは以下のようになります。
【php】
# src/Controller/HelloController.php <?php namespace App\Controller; use Cake\ORM\TableRegistry; class HelloController extends AppController { public function world() { $names = TableRegistry::getTableLocator()->get('Names'); $this->set([ 'message' => $names->find(), '_serialize' => ['message'], ]); } }
$names->find()の戻り値は、Namesクラスのインスタンスを配列にまとめたものです。
JSONデータに変換される際、Namesインスタンスはインスタンス内に保持しているテーブルのレコード情報を配列のように出力する振る舞いをするので、上のコードのように、messageキーの値として指定しても、問題なくJSON化されます。
結果、以下のようなJSONデータが出力されます。
【json】
{ "message": [ { "id": 1, "name": "Noah", "sex": "male" }, { "id": 2, "name": "Liam", "sex": "male" }, { "id": 3, "name": "Mason", "sex": "male" }, { ...(以下略) }, ] }
限定的ではありますが、モデルを書かずにデータベースとやり取りできるのは、手間が省けていいですね。
まとめ
今回は、Ruby on Railsの流れを汲むPHPフレームワーク、CakePHPを紹介しました。
過去のバージョンから見事に洗練されてモダンに使えるようになったので、バージョン1、2系辺りを利用していた人から見ると、最近のPHPフレームワークのようにインスタンスを使ってしっかり型付けされる設計になっていて、まるで別のフレームワークのようです。
また、モデルを書かずにデータベース接続ができる機能は便利ですね。
この機能は昔からありますが、似たような機能を他のフレームワークで見かけたことがありません。
便利な半面、プログラムの規模が大きくなると、モデルファイルがないというのが混乱を生む元になってくるので過信は禁物です。
次回は、これまで5回連載でご紹介したPHPフレームワーク「Laravel」「Phalcon」「FuelPHP」「Symfony」「CakePHP」の比較をお送りします。