パーフェクトPHP 7章 8章 フレームワーク

##内容
パーフェクトPHP7章8章で扱うフレームワークがどのようなフレームワークなのかざっくりした説明と学習した際の感想などを書いてます。
技術的なことは特に記載されていません。
あらかじめご了承の上、記事をお読みになってください。

また、フレームワークの内部 と オブジェクト指向 を理解することを目的とされている方は
beginner001 (@beginner001) さんの[『パーフェクトPHP』をデバッグしました](https://qiita.com/beginner001/items/dae34b6fefb1c4c152f1) を参照されてください。

####記事の構成

- MVCのそれぞれの役割
- 7章 フレームワークの構成
- 各クラスと他ファイルの役割
- 各クラスの関係と処理の流れ
- 8章 ミニブログアプリケーション
- 学習中の戸惑いなど
- 理解するために
- あとがき
- 脚注

##MVCのそれぞれの役割[^1]
####モデル
アプリケーションのビジネスロジックを担うのがモデルです。Webアプリケーションでは主に、データベースへアクセスしてデータの取得や変更を行う機能をモデルに記述します。

####ビュー
出力を担うのがビューです。Webアプリケーションでは主にHTMLを出力しますので。ビューはHTMLの組み立てや情報の出力を行います。

####コントローラ
ユーザのリクエストを制御し、モデルから情報を取得してビューに橋渡しするのがコントローラです。

##7章 フレームワークの構成
パーフェクトPHPの7章のフレームワークは以下のように構成されます。

```html:

application/
  controllers/
  core/
    Application.php
    ClassLoader.php
    Controller.php
    DbManager.php
    DbRepository.php
    HttpNotFoundException.php
    Request.php
    Response.php
    Router.php
    Session.php
    UnauthorizedActionException.php
    View.php
  models/
  views/
  web/
    .htaccess
    index.php
  bootstrap.php
```

※フレームワークのコードについては[技術評論社Webサイト](https://gihyo.jp/book/2010/978-4-7741-4437-5/support)を参照してください。
>ライセンス
The MIT License
Copyright (c) 2010 Katsuhiro Ogawa
https://github.com/kenjis/perfect-php-mini-blog/blob/master/LICENSE

##各クラスと他ファイルの役割[^2]
####Application.php
アプリケーション全体を表すクラスです。RequestクラスやSessionクラスの初期化、コントローラの実行などアプリケーションの全体の流れを管理します。
####ClassLoader.php
オートロードに関する処理をまとめたクラスです。
####Controller.php
モデルやビューの制御を行うコントローラです。今回はこのControllerクラスの中にアクションと呼ばれるメソッドを定義していきます。
####DbManager.php
データベースへの接続情報や次に説明するDbRepositoryを管理するクラスです。
####DbRepository.php
実際にデータベースへのアクセスを伴う処理を管理するクラスです。実施にはデータベース上のテーブルごとにDbRepositoryクラスの子クラスを作成します。今回のフレームワークではモデルに相当します。
####HttpNotFoundException.php
ページが存在しないことを表す例外クラスです。
####Request.php
ユーザのリクエストを表すクラスです。ユーザがリクエストした際のGETやPOSTパラメータ、URLなどの情報を管理します。
####Response.php
リクエストに対するレスポンスです。最終的にユーザへ返すレスポンスの情報を管理します。
####Router.php
ユーザがアクセスしてきたURLをRequestクラスから受け取り、どのコントローラを呼び出すかを決定します。これにより物理的なディレクトリ構造に縛られないURLの制御を可能にします。
####Session.php
セッションを管理するクラスです。
####UnauthorizedActionException.php
例外を用いたログイン画面への遷移のための例外クラスです。
####bootstrap.php
オートロードを設定するためのファイル。
####.htaccess
Apacheの設定を変更するためのファイル。
####index.php
フロントコントローラにあたるファイル。

##各クラスの関係と処理の流れ
それぞれのクラスの関係については以下の図 [^3]で表されます。
これらのクラスを使用したフレームワークをもとに8章ではミニブログアプリケーションを作成します。

![フレームワーク BASE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439258/a2bca06a-4355-44fb-d73c-1ef1b84b4185.png)


以下は先ほどの画像にApplicationクラスでの処理の流れを記載したものです。
処理を追っていたときに迷子になることがあったので目印の変わりに処理の流れを記載してます。

![フレームワーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439258/69f81578-df53-ec87-d448-463fcd91e655.png)
(※表現を変えている箇所がいくつかあるので注意。例『$this->request』を『Request』と表記)

実際の処理の流れは以下の通りです。
まずはRequestクラスでリクエストを受け取りRouterでコントローラ名やアクション名などを取得します。
取得した値をもとにApplicationクラスのrunAction()メソッドでAccountControllerやStatusControllerといった使用するコントローラの決定とインスタンス化を行います(8章のミニブログアプリケーションで出てきます)。
次にControllerクラスのrun()メソッドで実行するメソッドの決定を行います。
実行したメソッド内でSessionクラスやDbManagerクラス(+DbRepositoryクラス)、Viewクラスとのやりとりが行われ見た目を構成していきます。
最後にResponseクラスのsend()メソッドにより出力されます。
以上が一連の処理の流れです。

###8章 ミニブログアプリケーション
構成は以下の通り。

```html:

mini-blog.localhost/
  controllers/
    AccountController.php
    StatusController.php
  core/
    Application.php
    ClassLoader.php
    Controller.php
    DbManager.php
    DbRepository.php
    HttpNotFoundException.php
    Request.php
    Response.php
    Router.php
    Session.php
    UnauthorizedActionException.php
    View.php
  models/
    FollowingRepository.php
    StatusRepository.php
    UserRepository.php
  views/
    account/
      index.php
      inputs.php
      signin.php
      signup.php
    status/
      index.php
      show.php
      status.php
      user.php
    errors.php
    layout.php
  web/
    css/
      style.css
    .htaccess
    index_dev.php
    index.php
  bootstrap.php
  MiniBlogApplication.php
```

controllersディレクトリ、modelsディレクトリ、viewディレクトリ、webディレクトリやルート直下にクラスファイルが増えてます。
controllersディレクトリのクラスはControllerクラスを継承、modelsディレクトリはDbRepositoryクラスを継承、MiniBlogApplicationクラスはApplicationクラスを継承し、viewsのaccountディレクトリやそのファイルたちはControllerやメソッドに対応し、共通のレイアウトについてはlayout.phpとerrors.phpとして分けられています。
コードを見たい方は[技術評論社Webサイト](https://gihyo.jp/book/2010/978-4-7741-4437-5/support)を参照してください。

###学習中の戸惑いなど
- クラスやメソッドについて知識がほとんどないため、写経中は理解に努めてもぼんやりとしか意味がわからなかった。
（「引数とメソッド内の処理の関係などについてわかっていなかったこと」と「メソッドが他のメソッドとどう関連しているのかが全くわからず宙に浮いた処理の塊に見えたこと」が原因。今思うと不思議。）
- 今までは比較的単純なコードを写経して実行すればすぐに実行結果が見れていたのに対し、なかなか実行に移せない写経に少し飽きる。
- 様々な内部関数などが出てきて面食らう。(40近くありました。全ての関数に比べるとわずかですが初見ではこんなにいろんな関数などがあるんだと驚いてました。)
- ->や::に慣れない。
- ところで$thisとselfの違いって...
- 実際に動いたけど、どんな処理の流れなんだ。
- RouterクラスのcompileRoutes()メソッドとresolve()メソッドの正規表現に関する処理がよくわからない。(var_dump()で値が見られずに「なんで？」となってました。)
- Controllerクラスのrender()メソッドとViewクラスのrender()メソッドちょっとややこしいッ。

こんな感じで色々と戸惑ったりなかなか理解できなかったり「向いてないかもなぁ」と嘆きつつ学習してました。

###理解するために
ひたすら処理の途中途中で値を出力しては処理を止めて記録する持久戦で理解に努め、以下のGIFにあるようにスプレッドシートに記録してました。(var_dump();exit()をかなり多用しました)
![記録の流れsmooth.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439258/d1ea9ba1-48b4-ea09-2f9e-3792f4e1345b.gif)

縦にカラフルな線があるのは処理の途中で他のメソッドの処理に移ったり戻ったりすることによってどこの処理をしているのかわからなくなるため階層と色を分けて表現することでどのクラスで処理しているのか少しわかりやすくなるかなと考えた結果です。
右側の薄い緑や紫の塗りつぶしは取得した配列の値などを記録している箇所です。
これらを出力される画面毎に記録していました。

![取得した配列の値](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439258/9578276c-9a1b-e8fd-2c02-baf4d0c0eac1.png)
　(↑文章の表現が怪しいですが当時そのままのものです。)
![記録したシート.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439258/1edca0a5-378f-6008-127a-1a49b6286e0f.gif)


時間はかかりますし要領を得ていないと自覚していましたが、おかげでコードに対する苦手意識は軽減されましたし、当初に比べるとコードを読めるようになり処理の流れもわかるようになったので結果オーライだと思っています。

###あとがき
ここまで読んでくださった方ありがとうございます。
冒頭にもあるように大したことは書いていないので技術目的の方ごめんなさい。
あとはパーフェクトPHPを選んだ理由などを少し書いています。
グダグタですのでご注意ください。

#####パーフェクトPHPを選んだ理由
パーフェクトPHPについては初版が2010年12月10日なので、記事を書いている現在ですでに約9年弱前のものになります。実際パーフェクトPHPの内容は古いという評価も見かけることはあります。
それでも私はパーフェクトPHPでフレームワークについて学ぼうと思いました。

理由は２つあります。

１つは古いという評価があるにも関わらず現在に到るまで出版され書店でも取り扱われ続けているということです。つまり現在でも十分に通用する基礎が記載されていると判断したためです。

２つめの理由は「Laravelなどのフレームワークが便利」ということを実感したかったからです。おそらく初めからLaravelなどのフレームワークを利用して勉強を始めると「みんな便利っていうけど一体何が便利なの？」とズレた基準が自身の中に生まれたり、自身の性格上、他にも残念な思い違いをしてしまうだろうと考えたためです。

まだLaravelをちゃんと学んでいないので実際に扱った際にどのように感じるかはわかりません。
できれば「え...めちゃくちゃ便利やん。初めから使えばよかった。」と感じることができたらと願っています。

**beginner001 (@beginner001) さん がおすすめする理由(追記 2019.9.1)**
>この学習用フレームワークで、「フレームワーク」と「オブジェクト指向」の 考え方 が分かります。
PHP の書き方や使い方は、後からでも対応できます。(PHP 7.x.x)

>この 考え方 について書かれたサイトや本が、いまだに在りません。
これが、パーフェクトPHP が支持される理由だと思います。(７章、８章、サンプルコード のみ)
他の本は、断片的な情報が列挙されたものばかりです。

#####7章8章を終えて
この章を通して学んだことを今後に活かすことができたらと願うと同時に活かすことができるよう努めようと思います。

#####これからプログラミングを学び始め方へ

これからプログラミングを学び始める方、学び始めたばかりの方はいきなりパーフェクトPHPを手に取らない方が良いと思います。
それよりも入門書であったり(シンプルなコードでお買い物機能実装できるものとか)、Progateのようなサービスを利用して慣れてきてから自分で何かしらのサービスを作るときや、もっと詳しいことを知りたいと思ったときに手に取ると良いかと思います。

以上です。

最後までお付き合いありがとうございました。

###デバッグについて(追記2019.9.1)
**beginner001 (@beginner001) さんよりアドバイスをいただきました。**
####IDE デバッグ機能

>どんなツールも初めは大変ですが、すぐに慣れます。
特に、初心者の方 には効果が大きいです。
(パソコンの初心者ではなく、PHPの初心者です)

>初心者の方 こそ、パーフェクトPHP (７章 ８章) を選ぶべきです。
初心者が IDE デバッグ機能 を使う学習方法 は、実証済 です。

#####ツール
######差分ツール WinMerge
>例 サンプルコードと写経したコードの比較

######検索ツール Devas
Devas 以外にも同様なツールはたくさんあります
一部の IDE にも同じ機能があります
　
>例 サンプルコード全体を検索します (文字列 「PDO」 の検索など)

※ Windows のツールです (Mac にも同様なツールはあります)
Mac純正のファイル差分確認ツール「FileMerge」が使いやすい


###脚注
[^1]: （出典： 小川雄大、柄沢聡太郎、橋口誠、「パーフェクトPHP」「第7章 フレームワークによる効率的な開発」『7.2.2 MVCモデル』2018年第8刷発行、200ページ）

[^2]: （出典： 小川雄大、柄沢聡太郎、橋口誠、「パーフェクトPHP」「第7章 フレームワークによる効率的な開発」『7.2.3 フレームワークの構造』200ページ、201ページ、『7.2.7 ClassLoaderクラス』204ページ、『7.2.8 bootstrap.php』206ページ、『7.2.9 フロントコントローラと.htacess』207、208ページ、『7.2.22 例外の活用』239ページ、『7.2.31 ログイン状態の制御』257ページ）

[^3]: （出典： 小川雄大、柄沢聡太郎、橋口誠、「パーフェクトPHP」「第7章 フレームワークによる効率的な開発」『7.2.4 フレームワークの処理の流れ』2018年第8刷発行、202ページ）