BEARで新しくページを作成する場合、通常次の2つを作成します。
- ページクラス
- ページテンプレート
BEARにはフロントコントローラー、ルーターがありません。ページコントローラーであるページクラスを直接web公開エリアに設置します。
Note:
フロントコントローラーとページコントローラーとあり、ほとんどのMVCのフレームワークはフロントコントローラーを採用していますがBEARではページもリソースとしてとらえページコントローラを採用しています。サイトは1つのアプリケーションというより、原則独立した各リソースの集合体と考えます。
Note:
一方、認証/ACL/などのアプリケーション全体としての振る舞いの変更は共通ページクラスのコンストラクタやインジェクタを利用してページコントローラのデメリットを補います。ページコントローラの利点に構成の単純化と先に主導権を持つのをアプリケーション側にするというのがあると考えています。
MVCのコントローラにあたる部分はBEARではページです。リソースリクエストを行い結果をviewにsetします。web公開エリアに以下のindex.phpを設置します。
<?php
require_once 'App.php';
class Page_Index extends App_Page
{
public function onInject()
{
$this->_resource = BEAR::dependency('BEAR_Resource');
}
public function onInit(array $args)
{
$params = array(
'uri' => 'Post',
'options' => array('template' => 'post')
);
$this->_resource->read($params)->set('post');
}
public function onOutput()
{
$this->display('index.tpl');
}
}
App_Main::run('Page_Index');
?>
ページの各メソッドは、onInject、onInit、onOutputの順で呼ばれます。
1 | onInject() | このページが必要とするサービスオブジェクトを準備 |
---|---|---|
2 | onInit() | リソースアクセスしページにセット |
3 | onOutput | セットされたリソースを表現 |
Postリソースをreadリクエストし、その結果(array)をpostテンプレートにアサインしてレンダリングしHTML(string)にしたものをindex.tplテンプレートにアサインしています。
Note:
記事リソースへのアクセスはreadというメソッドとPostというURIだけで行われている事に注目してください。Postリソースが実際にはDBアクセスをしてデータを取り出しているのか、CSVファイルを読んでいるのか、あるいはPHPがランダムで適当に値をかえしているのかページからはわかりません。つまりリソースリクエストを利用するときにリソース側の特定技術の依存がなく疎結合です。ページ、リソースはそれぞれ別々の人が作る事も容易です。
Note:
リソースリクエストの結果をviewにセットしていますが、実はこの段階では実リソースリクエストは行われていません。例えばこのPostリソースの他に10のリソースを読み込みその影響でリダイレクトする可能性があるならその最初のリソースリクエストのコストは無駄になってしまいます。標準ではonOutputでそのリソースリクエストが行われますが、viewでそのリソースが出現するまで実リソースリクエストが行われない'lazy'オプションもあります。
Note:
リソースリクエストをHTTP出力後に行う事も可能です。例えば「足跡リソース」の更新を考えてみましょう。訪問したことにより足跡リソースを更新しなければなりませんが、ユーザーを待たせて(=表示の前に)DBをupdateする必要はありません。表示を終えてからupdateすればページ出力の高速化に貢献するでしょう。
Note:
onOutputでページのHTML出力をしているように見えますが、実はこれもこの段階では出力していません。変わりに出力予定のHTTPを変数に格納してページにセットしています。通常クライアントがそれをHTTP出力するわけですが、変数として扱えばPHPUnitテストで便利です。またページHTMLレンダリングするのではなく、ページにセットされたリソースを直接値として返す事もクライアントからの要求で可能です。その場合、この内部のdisplay()などの出力を返る必要はありません。実際に出力をしないで値としてページに保持してるのはそのためです。
Note:
ページは他のページやリソースからもリクエストすることができ、ページもリソースと言えます。レイヤリング可能で例えばwebブラウザ -> ページA -> リソース -> ページBとページBを利用するリソースを利用するページAをブラウザに表示できます。その場合キャッシュもレイヤリングされそれぞれの粒度で持ちます。
Note:
原則的には1ページ、1クラス、1ファイルですが、1ファイルで複数のクラスを切り替えたり、ユーザーがフロントコントローラを作成するのは容易でしょう。
コードの入力が完了したら、ブラウザで/index.php にアクセスしてみてください。記事リストが表示できたでしょうか?