CakePHP3系の便利なTips

CakePHP3系の便利なTips

はじめに
私は CakePHP3 系のリリースの頃から CakePHP3 を使い続けていますが、友人から質問を受けたり MeetUpイベントでお話しすることが多くなってきました。そこで感じたことですが、CakePHP3 系の便利機能を使っておらず、場合によっては CakePHP2 系の頃のようなコードを書いて苦労されている印象に思いました。
本投稿では、便利な機能を利用してコードの再利用性・可読性をあげて、少しでも幸せな CakePHP ライフを送れるように願いを込めて色々と書きます。

Helper 編

まずは気軽に試せれる便利な Template 側の機能になります。CakePHP 3 系では、sec/Template ディレクトリ内に Html に関するファイルを作成します。そのファイル内で CakePHP 標準の便利なヘルパーを利用します。

POST ボタン、POST リンク

見た目はただのボタンやリンクなんだけど、実際には form の POST で値を送りたいなんて要求に応えた機能です。標準の Form ヘルパーには 1 行で POST 送信させるボタンやリンクを書くことができます。
公式マニュアル

POST ボタンの場合

POST リンクの場合

リンククリック時の確認ダイアログ表示

地味にありがたい機能で、見た目を気にせずに確認ダイアログを表示させたい場合、リンクのヘルパーに引数を渡すことで実現できます。これを知らずに独自で js の confirm() を実装されている方は是非一度お試しください。
公式マニュアル

自動リンク化

限定的な利用範囲に限った方がいいかと思いますが、テキストを自動でリンクさせる諸刃の剣のような機能になります。テキストを全部渡すと、その中から email アドレスと url を自動でリンクに変換してくれます。文字列の区切りを伝えるために私は半角スペースを利用しました。私は管理画面からニュースを登録する場合に利用しています。
公式マニュアル

テキストの段落化

こちらも管理画面からのニュースなどに利用していますが、1 行の改行は br タグ、2 行の改行は p タグでくくられます。以前は CKEditor 等を利用していましたが、サイトのお知らせやニュース等では改行とパラグラフとリンクくらいしか利用しなくなってきたため、こちらで十分になりました。実利用は DB にお知らせを保存して利用しています。

テキストの切り詰め

この機能はいろんなところでよく使っています。「…続きを読む」みたいな表現は色々な場面で登場するので必須です。

Table (Model) 編

CakePHP2 系ではモデルクラスにテータ取得処理やバリデーション、また、取得したデータの加工などを記述して、これをビジネスロジックと呼んでコントローラーから呼び出していましたが、CakePHP3 系では、モデルはテーブルとエンティティに分かれました。テーブルでは DB 接続に関することや取得条件、値のバリデーション、スキーマに関するルールなどを実装します。エンティティは後述します。

カスタムファインダー

会員制サイトを構築する際、例えばユーザに関して以下の条件が加わることがあります。

  • メールや電話番号などの疎通確認済みかどうか
  • 有料プランユーザかどうか

こういった場合、カスタムファインダーで以下のように実装するとコードの再利用性が高まります。

このようにいろんな条件を繋ぐことができるので、ある条件に追加で別の条件を加えたい場合は、簡単に実装ができます。また、コードのメンテナンス性が上がるので、システムの仕様変更に合わせて柔軟に組み合わせることが可能です。

validationDefault(バリデーション)と buildRules(ルール)の使い分け

ちょっと横道にそれますが、よく聞かれることなのでこのタイミングで使い分けについて記述します。

バリデーションには DB 保存時の値に関する条件を記述し、ルールには schema に関する条件を記述します。例えば nickname カラムを varchar(255) とした場合、バリデーションには nickname の文字数や半角英数のみなど、値に関する条件を記述します。ここで、nickname にユニーク制限をかけたい場合、ルールにユニーク制限を記述します。こうすることで、DB アクセスが必要なエラーチェックと不要なエラーチェックを分けることができ、DB へアクセスする回数を減らすことが可能になります。

Entity (Model) 編

こちらは DB から取得した値(1レコード)に関する処理を主に書きます。仮想プロパティや自動オブジェクト変換機能を使うと、値に関する処理が非常に簡単になります。

仮想プロパティ

短縮した値の受け取りや初期値のセット

例えば以下のようにコードを書くと、UUIDの短縮表示などを表現できます。管理画面でのお問い合わせの一覧表示など、値を丸めて視認性をあげたい時に私は使ったりしてます。
(表示上ユニークではなくなる可能性がありますが、値を上書きするわけではないです)

また、nullを許可しているけど明確に「–」と表示したい場合などには、初期値をセットすることでテンプレート内に条件分岐を書く必要がなくなります。DB から取得した値に関する処理はエンティティに書くことでコードの可読性が上がります。

enum っぽい利用方法

また、ちょっとこんな感じで実装するのは良くないかもしれませんが、あり・なしなどのフラグやマスタデータ化するほどではないなと思うものには enum っぽい使い方をしています。

日付オブジェクトの利用

仮想プロパティのコード内にさらっと書きましたが、created や modified など datetime 型にセットしたものは自動で Timeオブジェクトに変換されます。したがって、好きなフォーマットに表示させることができます。

Controller 編

利用方法は上記と合わせて書いたので、特記することは少なくなりますが、CakePHP2 系を利用されていた方からよく「ビジネスロジックはどこに書きますか?」と聞かれます。上記 Table クラスと Entity クラスを適切に利用し、controller で条件分岐させることで、そもそも以前行っていたモデルファイルにビジネスロジックを書くといったことをしなくなりました。DB アクセス(スキーマ関連)に関するものが Table クラス、値(取得したレコード 1 行)に対する処理が Entity クラスと認識すればわかりやすいかもしれません。

異なるハッシュ化方法のパスワードのシームレスな移行は私が実に便利と感じたものなので再度紹介します。
シームレスなパスワードハッシュ化の移行

終わりに
最初は Tips 集をかく予定でしたが、後半では CakePHP3 系を使うと便利だよというただの紹介文になってしまったかもしれません。書き忘れたことや MeetUpイベントでよく聞かれることなど、また何かあれば随時情報を公開していきます。みなさま楽しい CakePHP ライフを送り下さいませ。

そして来年は CakePHP の国際イベントが日本で開催されます。ぜひ会場でお会いしましょう〜。

Enjoy && Happy New Year!!