Lesson 2

CakePHPの基本的な仕組み

Lesson 2 Chapter 1
Webフレームワークに必要な機能

PHPのWEBアプリケーションには様々な種類がありますが、基本的にはユーザーの入力に対して、様々な応答をデータとして返す「リクエスト&レスポンス」が繰り返されることで成り立っています。

では、送られたデータはどこでどのように処理され、WebフレームワークであるCakePHPにはどのような機能が必要となるのでしょうか?「リクエスト&レスポンス」を基本とするWeb上のシステムがどういった作りになっているのか、順を追って見ていきましょう。

サーバに直結する機能

まず、アプリケーションが実行されるWEB上のシステムは以下の3つが様々なデータをやりとりすることで成り立っています。

  • クライアント(WEBブラウザ)
  • WEBサーバー
  • DBサーバー

2_1_1.png

HTMLやCSSのみの静的なページを表示するだけであったり、入力された内容をファイルに書き込むのみといった簡素なアプリケーションであれば、DBサーバーは必要ないかもしれませんが、データを保持しつつ、ユーザーからのアクション(リクエスト) によって様々なレスポンスを返す「動的なページ」が必要な場合には、上記の3点は必ず登場することになります。

リクエストとレスポンス

WEBブラウザでユーザーが入力やクリックを行うと、そのデータは「リクエスト」としてWEBサーバーへと送信されます。この時、「リクエスト」データはWeb上での通信に使用される「HTTPプロトコル」という規約に従って送信されます。

また、WEBサーバーで処理されたデータは「レスポンス」としてWEBブラウザに返りますが、こちらも同様に「HTTPプロトコル」が使用されます。

リクエストには「GET・POST・PUT・DELETE」といったHTTPメソッドの値や、URL、ヘッダー情報、ボディ情報が含まれており、レスポンスには、ステータスコード、ヘッダー情報、ボディ情報といったものが含まれています。「HTTPプロトコルの規約に従って送信される」というのは、データが上記の内容として送信されることを意味します。

2_1_2.png

WEBサーバーの役割

WEBサーバーには様々なシステムのデータを格納することが出来ますが、それ単体ではあくまで「送受信可能な入れ物」でしかありません。そのため、リクエストの内容によって様々なレスポンスを生成する「動的」な処理を行うには、WEBサーバーの中に「WEBサーバーソフトウェア」と呼ばれるものを入れる必要があります。

「WEBサーバーソフトウェア」として、よく知られているものには「Apatch」や「nginx」などがあります。WEBサーバーソフトウェアは「リクエストを受け取り、その処理を外部のプログラムを呼び出して行わせる」ことが出来ます。そして、今回学ぶ CakePHP はその「外部のプログラム」の1つにあたります。つまりは、WEBサーバが受け取ったリクエストデータはWEBサーバーソフトウェア経由でCakePHPへと渡り、処理されるということになります。

その後、外部のプログラムによって処理されたデータはWEBサーバーソフトウェアに戻され、レスポンスとしてブラウザに送信されます。

2_1_3.png

また、アプリケーションサーバーと呼ばれる動的な処理を目的としたサーバーが、WEBサーバーの代わりに、もしくは同時に使われることもありますが、不特定多数による大量のリクエストを捌くことに向いていなかったり、ApatchなどのWEBサーバーソフトウェアが外部プログラムと連携することで動的な処理を実現しているため、PHPにおける開発で使われることはあまりありません。

注意してほしいこと

この教材ではApatchやnginxは使用せず、CakePHPのもつビルトインウェブサーバーを使用してアプリケーションの作成をおこないます。

まとめると、WEBサーバーは「WEBサーバーソフトウェア」を使用してCakePHPなどの外部プログラムと直結し、連携することで「リクエスト&レスポンス」による「動的なWEBアプリケーション」を成立させているということになります。

レスポンスの生成

ここからは、WEBサーバーソフトウェアからリクエストデータを受け取ったCakePHPが、フレームワークとして行っている基本的な処理について見ていきます。

まずは画面の表示に直結する、「レスポンスの生成」についてです。レスポンスにはページの表示に必要な「ボディの情報」が含まれており、これはMVCのV(ビュー)が管理をしている「ビューテンプレート」というものを使って作られています。

ビューテンプレートは動的な処理に対応するため、変数の値を使うことが出来るようになっており、コントローラから受け取ったデータを「変数」として当て込むことで1つのページを完成させます。

また、このように指定のフォーマットに対して、変数を当て込み、ページとして完成させることを「レンダリング」といいます。

ビューテンプレートが対応しているフォーマットには、HTMLの他に XML や JSON などがあり、それぞれ適切なレンダリングを行うことができます。

まとめると、V(ビュー)はコントローラから変数を受け取り、ビューテンプレートのフォーマットに合わせてレンダリングしページを完成。そのデータをレスポンスとしてクライアント側へ返すことで、ページの表示が行われます。

2_1_4.png

ビジネスロジック

動的な処理を行うには、リクエストとして送られてきたデータを受け取ったのち、その内容に合わせて適切な処理を行われなければなりません。この「適切な処理」をするために必要となるのがMVCのCにあたるコントローラーが担当する「ビジネスロジック」です。

ここでの「ビジネスロジック」とは、受け取ったデータがどのような条件・順番で処理を進めていけば過不足なく必要な処理を行うことが出来るのか?という問題を解決するためのロジックを指します。

例えば、コントローラがリクエストを受け取り、ビューへとデータを渡すまでの流れは以下のようになります。

  1. コントローラがクライアントから送信されてきたリクエストデータを受け取る
  2. リクエストデータに含まれるURLやリクエストメソッドを元に、指定された処理を呼び出す。
  3. 処理内容に応じて、必要があればモデルとCoCによる紐づきを利用してデータの受け渡しを行う。
  4. モデルから受け取ったデータや、リクエストのデータを使い、改めて必要な処理があれば実行。
  5. 処理結果をCoCに従って紐づいているビューへ変数として渡す。

2_1_5.png

このように、送信されてきたリクエストデータを受け取るだけでなく、どのように処理を進めていくのか?を解決するための「ビジネスロジック」がフレームワークには必要であり、MVCモデルを採用するCakePHPのコントローラーは、CoC(設定より規約)による連携を利用してモデル、ビューとデータの受け渡しを行いながら処理を行う「ビジネスロジック」を持っています。

データベースアクセス

動的な処理を行うことを前提としたフレームワークには、データベースへとアクセスし、連携する機能も必要となります。CakePHPではその役割をMVCのM(モデル)が持ちます。

CakePHPのモデルはテーブルとエンティティと呼ばれる2つから成っており、DBのデータのCRUD(取得・作成・更新・削除)を行うことができます。(テーブルとエンティティについては次のチャプターで詳しく説明を行います。)

本来、DBのデータを操作するには「データベースサーバ専用の言語」である SQL を記述する必要がありますが、CakePHPのモデルには、この SQL を簡単に発行することのできる様々なメソッド用意されています。SQLを発行するメソッドに関してはLesson6で解説を行います。

認証機能

多くのWEBアプリケーションでは、個々のユーザーデータを管理したり、利用できる機能の制限をするためにログイン・ログアウトなどの「認証機能」を実装する必要性が出てきます。

そのため、「認証機能」を簡単に実装できるようにすることは開発効率を大きく高めることにつながります。

CakePHPでは、この「認証機能」を容易に実装できるように「Authentication プラグイン」というものが用意されています。プラグインとはアプリケーションに追加機能を実装するプログラムを持ち、再利用できるようにまとめられたものを指します。「Authentication プラグイン」はそのうちの1つであり、ダウンロードをして使用します。

この「Authentication プラグイン」を既存のアプリケーションが持つ、MVCを基本としたプログラムに組み込むことで、比較的容易に「認証機能」を実装することができるようになっています。

後のLesson8 で認証機能を実装していくため、「Authentication プラグイン」 のより詳しい内容などはそちらで説明をしていきます。

Lesson 2 Chapter 2
モデル

この先のChapter2,3,4では MVC にフォーカスし、それぞれの持つ役割や機能についてより詳しく見ていきます。最初はモデルからです。PHPで作られているアプリケーションがデータベースとスムーズな連携をとるために、CakePHPがどのような仕組みや機能を用意しているのか学んでいきましょう。

ORM (Object-relational Mapping)

MVCのM(モデル)がデータベースとの連携を担当していることは、前チャプターでも触れました。

しかし、データベースではデータを「テーブル」という形で管理しているため、そのままの状態ではデータ形式の違いからPHPで表すことが出来ません。そのためモデルは、「テーブル」というデータをPHPで扱えるようにするため、形式変換する機能を持つ必要があります。

そこでCakePHPでは「ORM」という技法を採用しています。

ORMはObject-relational Mappingの略で、以下のような意味合いとなります。

  • Object→オブジェクト指向プログラミング言語
  • Relational→リレーショナルデータベース
  • Mapping→objectとRelationalを対応づける

これは、データベースの「テーブル」というデータ形式と、オブジェクト指向が扱う「クラスとオブジェクト」という互換性の無い2つのデータ形式に「関連性」をもたせることで「片方に変更を加えれば、もう片方にも同様の変更が自動的に加わるようにする」ことを意味しています。この状態を「対応付けられた」、もしくは「マッピングされた」状態と言います。

ではいったい、どのように「関連性」を持たせているのかですが、まず前提として CakePHP のモデルはデータベース上の1つのテーブルに対して、「テーブル」と「エンティティ」という二つのクラスを作成して対応します。

この際、2つのクラスの名前をCoCによる命名規則に従って付けることで、データベース上のテーブルとの間に関連が生まれ、マッピングされた状態となります。そのため、この状態でクラスから生成したオブジェクトを操作すると、自動的にデータベース上のテーブルにも操作が加わるという仕組みが出来上がります。

また、CakePHPの「テーブル」と「エンティティ」のクラスにはデータの検索や、オブジェクトに変更を加えるためのメソッドがあらかじめ用意されており、容易にオブジェクトを通してデータベースからデータを取り出したり、変更を加えることが可能となっています。

このように、ORMを使用することでSQL言語を使用せずに、PHPのオブジェクトとメソッドを通してデータベースのテーブルにアクセスし操作することが可能となります。

テーブルとエンティティ

CakePHPのモデルはデータベース上の1つのテーブルに対して、「テーブル」と「エンティティ」という二つのクラスを作成して対応しているということは、上記「ORM」の説明の中でも触れました。ここでは、なぜ2つに分けているのか、エンティティとは何を指しているのか?といった部分を中心に解説していきます。

まず、データベース上のテーブルとは「列」にあたる「カラム(フィールド)」と、「行」にあたる「レコード」から出来ています。このうち、テーブル全体とカラムを「テーブル」のクラスが対応しており、レコードの部分を「エンティティ」のクラスが対応しています。つまり「エンティティ」とはレコードとマッピングされているデータのこととなります。

「テーブル」のクラスには、新規レコードを作成して保存をしたり、テーブル全体からデータの検索を行うなどのメソッドが用意されており、SQLを使用してテーブルを操作するのと同様のことが出来るようになっています。

そして「エンティティ」のクラスは、レコードとマッピングをするために、レコード1行につき1つのオブジェクトを自動的に生成します。

また、レコードの持つフィールド名もプロパティとして持っているため、レコードとフィールド名を指定して、レコード内の全てのデータにアクセスすることが出来るようになっています。

2_2_1.png

このように、「テーブル」のクラスでテーブル全体とSQLによる操作を表し、「エンティティ」のクラスが1行ごとのレコードと、レコードの持つ値を表すことで、データベース上のテーブルとのマッピングが完成されるということになります。

規約による定義

CakePHPにおいて、データベースを使うために必要な設定は configフォルダにある app_local.php(CakePHP3まではapp.php)にて、データベース接続に使用するユーザー名、パスワード、データベース名などを書き換えるだけとなります。(実際のデータベース接続はLesson4で行います)

このように容易にデータベースが扱えるのは、CakePHPのコンセプトである「設定より規約」に基づき、データベースに作成するテーブルにも命名規約を設けているためとなります。

命名規約はデータベース上のテーブルから始まり、モデルの持つ「テーブル」のクラスや「エンティティ」のクラス、またそれらを管理するファイル名までもが規約によって全て紐づけられるように出来ています。そのため、このモデルはどのテーブルと対応付けられているかなどの設定を行う必要はなく、規約によって自動的に対応するファイルやテーブルが定義されていきます。

例として、データベース上にユーザーを管理するための「users」というテーブルを作成した場合、対応するモデルとなる「テーブル」のクラス名とそのファイル名は UsersTable とし、「エンティティ」のクラス名とそのファイル名には Userという命名をしておきます。これだけで usersテーブルに対応するモデルが UsersTableクラス と Userクラスであるということが定義されます。

2_2_2.png

この後のチャプターで説明を行うコントローラやテンプレートもまた、この命名規約によるつながりを作っていく形となります。その都度、簡単に命名や規約について触れますが、詳しくはLesson5で説明を行います。

Lesson 2 Chapter 3
コントローラ

コントローラーにはリクエストの受け取りや、MとVの間でのデータの受け渡しなど「ビジネスロジック」としての役割があることについてはChapter1で説明をしました。ここではそのロジックの流れだけでなく、より具体的な仕組みについても見ていきましょう。

最初にコントローラーの作成ですが、CakePHPのコントローラーフォルダの中にUserController.php のように先頭大文字のアッパーキャメルケースで命名をしたphpファイルを作成し、ここにコントローラとしてのクラスと、そのメソッド(アクション)を定義していきます。

リクエストを受け取る

クライアントから送信されてきたリクエストに含まれるURLは、呼び出すコントローラーとアクションを指定しており、以下のような形をとります。

①アプリケーションのパス/②コントローラー/③アクション

①アプリケーションのパスというのは、例えばローカル環境などでは
localhost/アプリケーション名/
までの部分となり、絶対パスの場合に明記され、相対パスでリクエストが送られてきた場合には省略されています。

②のコントローラー部分によって呼び出すコントローラー名が指定され、③アクションによって、コントローラー内にあるアクションのどれを実行するのか指定されます。

注意してほしいこと

指定するアクションが index の場合には③アクションは省略できます。

2_3_1.png

このように、URLが持つ規約によってコントローラのクラスが持つアクションが呼び出され、その内容に沿った処理が行われていきます。(アクションとは、リクエストに対して実行されるメソッドのことを指しています。)

モデルとの連携

モデルとデータベース上のテーブルが「命名規約」によるつながりを持っていたのと同じように、コントローラのファイルとクラス名も、紐づけるモデルのテーブル名に合わせて命名を行います。

例えば、モデルにUsersTable.phpがあった場合には、紐づくコントローラの命名はUsersController.phpとします。

このように命名規約によって紐づいている場合には、コントローラのメソッド内で $this->Users とするだけでUsersTableクラスを参照することが可能となり、モデルとデータのやり取りをすることが出来ます。

ビューとの連携

ビューが管理している「ビューテンプレート」はコントローラから渡された変数を使ってページを完成させるため、コントローラは最終的に「ビューテンプレート」へと変数を渡します。

このとき、命名規約によって「ビューテンプレート」とコントローラの持つ「アクション」が紐づいている場合には、アクション内でset()というメソッドを使用して、簡単に変数の値をビューテンプレート側に渡すことが出来ます。

2_3_2.png

Lesson 2 Chapter 4
テンプレート

ユーザーが実際に目にする部分となる、ビューテンプレートについてより詳しく見ていきましょう。

htmlのひな型

CakePHPでは効率的にWebページを作成し表示する仕組みとして「テンプレート」が用意されています。

このテンプレートはビューテンプレートとレイアウトという2つに大きく分けられ、どちらもマークアップ言語とPHPで構成する.phpファイルとなります。

レイアウトには各画面共通の表示を行う部分などをまとめておき、画面ごとに表示の異なってくる部分をビューテンプレートとして作成していきます。レイアウトが大枠であり、そこにテンプレートを当てはめるイメージです。この教材ではCakePHPが持つデフォルトのレイアウトのみを使用していくため、ビューテンプレートに絞って説明をしていきます。

注意してほしいこと

ビューテンプレートの拡張子は.phpで作成します。CakePHP3.xまでは.ctpだったので注意して下さい。

コントローラとの連携

ビューテンプレートは規約に沿うことで、コントローラーのクラスとそのアクションに対応させることが出来ます。

規約の内容は、ビューテンプレート用のフォルダ内にコントローラのクラス名と同じフォルダをつくり、更にその中にアクション名と同じ名前のビューテンプレートファイルを作成することとなります。

例えばUsarsContollerクラスがあり、その中に新しいユーザーデータを追加する「add」というアクションがある場合には、ビューテンプレート用のフォルダ内にUsersフォルダを作成し、更にその中にadd.phpファイルを作成することでコントローラとビューテンプレートが自動的に紐づきます。

このようにビューテンプレートとコントローラーを連携させておくことで、コントローラー側でのset()メソッドのみで簡単にビューテンプレートへとデータを渡すことが出来るようになります。

2_4_1.png

表示するデータ

ビューテンプレート内ではPHPの制御構文(if , while , for , foreach , switchのこと)を使うことができます。そのため、コントローラから受け取った変数の値を当てはめるだけでなく、if文での条件分けや、配列データをforeachで処理したりと、様々な動的処理をしながらページの生成を行うことができます。

Lesson 2 Chapter 5
CakePHPのその他の機能

CLI コマンド

CLIとはCommand Line Interface(コマンドラインインターフェイス)の略です。例えばLinuxなどはユーザーインターフェースではなくCLIでのコマンド操作となります。

CakePHPにはCLIで使うことのできるコマンドが用意されており、重要なものに「bakeコマンド」があります。

bakeコマンドはデータベース上に作成したテーブルを元に、命名規則とMVCモデルに従ったWEBアプリケーションのひな型を自動的に生成する機能を持ちます。

MVCとしてのmodel、controller、template のひな形をそれぞれ個別に作成することもできますし
”bake all テーブル名”を使用して、一括で作成することもできます。

自動生成されたひな形は最初から CRUD(生成、読み取り、更新、削除)の機能を持っており、効率的にWEBアプリケーションの土台を作成することが可能となります。bakeコマンドについてはLesson7でより詳しく見ていきます。

機能を拡張する機能

ここまでCakePHPの基本となる機能や役割について見てきましたが、それらの機能をさらに拡張し柔軟な開発を手助けしてくれる機能についても簡単に紹介していきます。

Lesson10以降で それぞれより詳しく説明していくので、ここでは「こういったものもあるんだな」と頭の片隅にいれておいて下さい。

ヘルパー

ヘルパーはビューテンプレートを効率よく作成するために使われる処理をまとめたもので、htmlヘルパーやformヘルパー、textヘルパーなど様々なヘルパーが用途に分けられて用意されています。

例えばhtmlのヘルパーではビューテンプレートにて

echo $this->Html->charset();
とするだけで出力結果は以下のようになります。
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

他にもcssやjavascriptの読み込みや、リンク、画像の埋め込みなど、さまざまな出力をさせることが可能です。

コンポーネント

コンポーネントとは複数のコントローラー間で共有して使うことのできる、再利用可能な機能をまとめたものです。

例えば、CakePHPが持つ既存のコンポーネントに「フラッシュ」というものがあり、一度限りのメッセージを表示させてユーザーに結果の確認や、注意などを端的に表示出来る便利な機能を持っています。

コンポーネントのメリットとして、例えば「この処理の後にはフラッシュを出したい。」と考えたときに、「フラッシュを出す」という処理はどのクラスで行うときも共通のものとなるため、コンポーネントとして再利用可能な状態にまとめておくことで、ほかのクラスで再び使用する場合に簡単に対応可能となることなどが挙げられます。

ビヘイビア

ビヘイビアとは、複数のモデル間で再利用可能な機能を追加するための仕組みです。

例えば、多くのテーブルが必要とするタイムスタンプ(特定のイベントが起こった時に日時を保存する機能)がありますが、それぞれのテーブルで全く異なるロジックを持っているというわけではありません。「どのカラムにスタンプするか」などの部分はテーブルごとに異なるかもしれませんが、現在時刻を取得してタイムスタンプを押す、という機能自体は変わりません。そのためCakePHPではタイムスタンプビヘイビアとして再利用可能な状態にまとめられています。

また、ビヘイビアの特徴として、タイムスタンプのように特定のイベントが起こった時に自動的に処理をおこなう「イベントリスナー」としての役割を持った機能がある、という点があげられます。

middleware(ミドルウェア)

ミドルウェアとは一般にOSとアプリケーションの間で様々な役割を果たす機能のことを言います。

CakePHPにおいては、リクエストをコントローラが受け取るまでの間や、レスポンスをユーザーに返すまでの間で処理を行うことが出来ます。

わかりやすい例としては、リクエストやレスポンスの送信中に何かしらの不具合が起こった場合に、ミドルウェアがその不具合を捉えて、例外処理としてエラー画面を返すといったものがあります。

プラグイン

プラグインはアプリケーションに追加の機能を組み込むためのもので、CakePHPではcomposerを使って様々なプラグインをダウンロードし利用可能となっています。認証機能を追加することのできるAuthenticationプラグインなどがあります。