初めてCakePHPで開発するときに気をつけたいMVC〜

CakePHP3のMVCの話をするので、フレームワークによっては少し違う部分があるかもしれません。

# MVCの流れと開発時の作成手順

まずはMVCの処理の流れを確認しましょう。
ブラウザからリクエストが発生し、ブラウザに返すまでの動きが以下の図で表せます。

![mvc1.png](https://qiita-image-store.s3.amazonaws.com/0/218491/0ebaae2d-2872-1d90-6c1a-710ed05f8eeb.png)

1. ブラウザからコントローラーとアクションを指名され、アクションが実行される。
1. アクション内でモデルが指定されていればモデルが実行される。
1. アクションの処理が終了したら、Templateフォルダ¥コントローラーと同名のフォルダ¥アクション名と同名のctpファイルを表示対象として生成する。
1. ブラウザに返す。

この流れを踏まえると、以下の順で作成を進めることをお勧めします。

1. Controllerとaction（とりあえずアクションの枠だけ）
1. View（Template）
1. Controllerのaction内の処理
1. 必要になったときにModel内各種

# ところでMVCとは？
## M
ModelのMです。
主に、CRUD(Create/Read/Update/Delete)処理を行ったり、入力チェックを行ったりします。

CakePHPでは、Modelフォルダ内の構成は以下のようになっています。

```
Model
|-Entity
|-Table　
|-Validation //自分で作る
```

### Entity

Table内のソースを動かすために必要なもの。
まだ使ったことないけど、投げれば計算とか、Selectしてきた結果のフラグを日本語に変えたりしてくれるようになる。

参考記事：[CakePHP3を触ってみました　&#12316;tableとentityはどう使い分けたらええねん&#12316;](https://norm-nois.com/blog/archives/3310)

### Table
CRUD処理はもちろん、入力チェックもここで実装できる。

CakePHPは（デフォルトでやろうとすると）１テーブル１ヴァリデーターになる。
もちろん、デフォルトでやろうとしないでヴァリデーターかけることはできる。（めんどくさかった）

Tableを動かすためにはEntityが必要です。
TableのinitializeでどのEntityを使用するか定義します。
initializeではEntity以外に、使用するDB名とテーブル名の定義、主キーの定義をします。

### Validation
自分でValidationをカスタマイズしようと思った場合はここにソースを配置しま
す。

参考記事：[CakePHP3のバリデーションをまとめてみた](https://qiita.com/satthi/items/5c523788a5b3372ff35a)

## V
一番馴染みやすいところだと思います。
拡張子が「ctp」でなんだ？と思いますが、中身はHTML with PHPです。
もちろん、JavaScript/CSSも記述可能です。普通にHTMLファイルだと思って編集すればいいと思います。
ここでは画面に生成されるHTMLファイルのソースです。

つまりViewのVです。
しかし実際にファイルを置く場所は`Template`フォルダ内です。
`View`フォルダもいるけど、MVCのVとして使うわけではないです、CakePHP3では。
ちょっと名前がややこしいな。

Templateフォルダ内の構成は以下のようになっています。

```
Template
|-Element
|-Error
|-Layout
//他は省略
```
### Element

めっちゃ便利。HTMLファイルをパーツごとに書き出すことができる。
ここで書き出したパーツを各Templateから呼び出せば同じパーツが使いまわせます。

たとえば、グローバルナビゲーション（全画面共通メニュー）とかテーブル上下に配置するページャーの`< << >> >`こういうやつとか。

全ての画面に表示したいわけじゃないけど、たくさんの画面に表示したい共通項目があれば、Element使ってみてください。

画面用の共通クラスみたいに使えます。

### Error
エラーの時に表示する画面はここに置いておきます。

参考記事：[【CakePHP3】エラー画面のカスタマイズ方法を徹底解説！](http://moblog.absgexp.net/cakeerr/)

### Layout

ASP.NETをやったことある人にはマスターと言えば通じやすいかも。

全画面共通で表示したいことを`default.ctp`で設定します。
もちろん個別で`default.ctp`を適応させない、とすることも可能です。

`default.ctp`の話になりますが、ここに画面上のヘッダーやフッターを書いたり、
JavaScriptやCSSの呼び出しをしたりすると、個別のTemplateで設定する必要がなくなるので、楽です。

## C

ControllerのCです。
よく使います。
Model呼んだり、Viewに値渡したり、大活躍です。
普通に処理書くところです。
普通にPHP書くところなので、馴染みやすいです。

# MVCと名前

CakePHPは命名規則が厳しいです。
あれ、動かないなあ？と思ったらまずは名前を疑ってみてください。
MとCは大文字からファイル名が始まります。
Vは全て小文字になります。

## Mの名前

TableとEntityにはDBの名前を使用します。
CakePHPが推奨するテーブル名は複数形であることとされていますが、単数形でも動作上の問題はないです。
単数形の場合はTableのinitializeで定義してください。

たとえば、CakePHP推奨のテーブル名は`employees`ですが、`m_employee`のテーブルを使用することは可能です。

Tableは`XxxTable.php`という名前でなければいけません。
最初は大文字で以降は小文字、`T`も大文字です。

たとえば`EmployeesTable.php`

`XxxTable.php`ファイル内のクラス名はファイル名同様に`XxxTable`となります。
しかし、ControllerでTableを呼ぶときは`Xxx`とだけ呼びます。

たとえば`TableRegistry::get('Employees');`
ひっかかるう〜。

ちなみにTable内のメソッド名は`xxxXxxx`のキャメル式です。

こんなかんじ

```php
class EmoloyeesTable extends Table
{

    public function initialize(array $config)
    {

    }

    public function getEmployeeDataByDepart()
    {

    }
}

```

Entityは`Employee.php`になります。単数形です。
多分、Tableのinitializeで定義しておけばどんな名前でも良さそうです。
わかりやすいほうがいいから、Tableと名前を揃えておくといい。

ちなみにValidationの名前は自由につけられるようです。

## Vの名前

すべて小文字から始めます。
`index.ctp`とか`list.ctp`とか
ちなみに`showList`というアクションで同名のViewを表示する場合は、`show_list.ctp`という名前になります。
大文字の文字の前にアンダーが入って全て小文字になります。
ここで突然アクション名について話が出ましたが詳細については次章で。

## Cの名前

Controller名は大文字から始めて`XxxController.php`になります。

一方Action名はキャメル式です。`xxxXxxx`です。
たとえば`showList`

Controllerと合わせるとこんな感じ。

```php
class ComparativeController extends Controller
{

    public function index()
    {

    }

    private function setHandlingData()
    {

    }
}
```

# CとVの関係

CakePHPのCとVの関係で難しいところが、ファイルの配置場所です。

Controllerフォルダ内にControllerファイルを設置します。
Templateフォルダ内にController単位でフォルダを作成し、その中にctpファイルを設置します。

たとえばこんなコードがあったとします。

```php
class EmployeeController extends Controller
{

    public function index()
    {

    }

    public function list()
    {

    }

    private function beforeUpdate()
    {

    }
}
```

この場合のTemplateフォルダは以下のようになります。

```
Template
 |-Employee
    |-index.ctp
    |-list.ctp
```

`before_update.ctp`がないのは`beforeUpdate`がプライベートだからです。

さて、CakePHPではテンプレート無指定の場合は、自分のController名と同じフォルダにある自分のAction名と同じctpファイルを出力使用とします。
なので、アクション単位でctpファイルが必要になります。

もちろん、全アクションに必要なわけではないです。必要になるのはブラウザからリクエストされたときのActionに必要になります。
そのため、プライベートファンクションである`beforeUpdate`はctpファイルがありません。

また、ctpファイル名を指定することも可能です。

# CとMの関係

CとVほどこれといったことがない。
MでできることはCでもできるということぐらい。