PHP

【CakePHP3】データベースのテーブルを使用せずにモデルを使用する方法

PHPのフレームワークとして非常に有名で使っている人が多いフレームワークであるCakePHP。

最近ではLaravelなどのフレームワークも登場してきましたが、やはりCakePHPが主流であると言っても過言ではないですよね。

CakePHPでは通常、ロジックを実装する際はModelを利用するのですが、

『データベースを使わずにロジックを実装したい!!』と思ったことがある方も当然いると思います。

というわけで、今回は『データベースのテーブルを使用せずにモデルを使用する方法』について紹介していきたいと思います。

CakePHP2.x の場合だと簡単に設定をすることができたけど・・

今回お話するのはCakePHP3.xを使用している人向けなのですが、CakePHP2.xでデータベースのテーブルを使用せずにモデルを使用する方法についても説明していきたいと思います。

CakePHP2.x での解決策

CakePHP2.xの場合はとっても簡単で、AppModelの$useTableというメンバ変数を無効化してあげます。

としてあげればいいです。

また、継承元のModelであるAppModelの$useTableをfalseにしてやればAppModelを継承している全てモデルでデータベースを使用しなくても作成できるようになります。

CakePHP3.xでも同じようにしてあげればテーブルを使用しなくてもモデルを使うことができるんじゃないの?と思う方もいるかもしれませんが、使用が変更されているので、なかなか簡単にはいかないんですね。

CakePHP3.x でテーブルを使用しないモデルを使う方法とは?

というわけで、本題のCakePHP3.xでのデータベースのテーブルを使用せずにモデルを使う方法について詳しく説明していきたいと思います。

外部APIを使用してデータのやりとりをするようなものや、データベースにアカウントを作成するほどではないけど簡単なログインを実現したい方などにとっては

これから説明する方法は非常に有効的な方法です。

解決するための方法としては、以下のようなものが挙げられます。

1. わざわざモデルを使用せず、コントローラーに処理を書く

そもそもデータベースとのせずをモデルを作成したいときって、どんな状況が多いでしょうか?

多くの人は外部APIを使用するときや簡単なデータ通信をしたいときくらいしかないと思います。

それなら、モデルでも大したコード量にならないので、いっそのこと全ての処理をコントローラーに書いてあげればすぐに解決しますよね。

2. プレーンなモデルを作成する(AppModelを継承しない)

二つ目の方法としては、AppModelを継承しないという方法があります。

というのも、モデルを実装するにあたってデータベースのテーブルが必須という性質はAppModelを継承しているからなので、

そんな性質いらないから、いっそのことをAppModelを継承しなければいいんじゃない?という話になるわけです。

コードにするとこんな感じです。

ただし、この方法だと他のAppModelを継承することによって得られた恩恵も無くなってしまうため、

書きたい処理がAppModelに依存した処理ではないのかを考えてから使う必要があります。

Model Less Form(モデルのないフォーム)を使う方法

最後に紹介する方法として、Model Less Form(モデルのないフォーム)を使う方法があります。

CakePHP3.xでのモデルは、そもそもデータベースのテーブルと紐付けて使用することが前提とされているので、テーブルなしで使うのはあまりオススメできません。

Model Less Form(モデルのないフォーム)は、ユーザー入力を検証して、そのデータが有効なものならば何らかのアクションを実行したいとき

例えば、

・お問い合わせフォーム

・Authコンポーネントやデータベースを使用しない簡単なログイン

などでは非常に有効な手段です。

というわけで、

バリデーションなどを使用したいだけなら、CakePHP公式サイト

にもあるようにModel Less Form(モデルのないフォーム)を使う方法を紹介します。

今回は、ログイン画面を作るときのフォームをモデルなしで作ってみることにします。

フォームを作成する

まずはプロジェクトのsrcディレクトリ直下にFormディレクトリを作成します(src/Form)

作成したら、以下のUserAuthForm.phpのようにphpファイルを書きます。

このコードを解説すると

・_buildSchema(): FormHelperを使ってHTMLでフォームを作るときに必要なスキーマデータで、このメソッドで、フィールド(usernameやpasswordのこと)のデータ型や長さなどを設定することができます、

・_buildValidator(): どうやってバリデーションをするかを設定することができ、例えばusernameは最小3文字で正しく入力されなかった場合は「無効な名前です」と表示されます。

・_execute(): HTMLフォームに入力されたデータが正しかった場合に実行される。この場合はあらかじめ設定しておいたユーザーネーム(hogehoge)とパスワード(hogehoge)が正しかった場合にtrueが返ってきます。

コントローラーでフォームを使う

フォーム作成したあとは、それを使用するコントローラーを作成します。

今回はログイン画面を実装するのでLoginController.phpのような名前にしました。

コードを解説すると、

・$this->request->is(‘post’): リクエストメソッドがPOSTであることを確認する。

・引数にPOSTで受け取ったクエリを入れて、$userAuth->execute()を実行。正しくバリデーションができたら「ログインに成功しました」とフラッシュメッセージを設定し、ホームにリダイレクトする。

また、入力されたデータが正しいかどうかだけを知りたい場合は

とすれば、正しい場合はTRUEが返ってきます。

実際にHTMLでフォームを使って見る

フォームと実際にそれを使うためのコントローラーができたので、最後はHTMLで実際に見えるフォームを作成してみましょう。

とはいっても、index.ctpに以下のコードを追加してあげるだけです。

HTMLでフォームを作成するときに、フォームに初期値を設定しておきたい場合があるかと思います。

そのようなときにはコントローラーを以下のように修正しましょう。

リクエストメソッド がGETのときに設定していますが、これはPOST送信されたときにまで追加したコードを適応してしまうと、ユーザーから入力されたPOSTデータが上書きされてしまうためです。

ユーザーがHTMLフォームに入力するときはリクエストメソッドがGETの状態なので、GETのときだけに設定するのが安全です。

Authコンポーネントを使用しないログイン認証をもっと知りたい方はこちらの記事も参考にしてみてはどうでしょうか?

不備な点や意味が理解しにくい点、間違っている点などがあれば、気軽にコメントをしていただけたら嬉しいです。