HelloWorld
第1日目で試したMyvVendor\HelloWorld
アプリは最小構成のアプリケーションです。
実行可能なBEAR.Sundayアプリケーションの最小構成です。PHPファイルが4つあります。
-
Index.php ページリソース
-
AppModule アプリケーションモジュール
-
www/index.php アプリケーションスクリプト
-
App.php アプリケーションクラス
リソース
はMVCフレームワークでいうとモデル
に近いものですが、ページリソース
はwebのページに対応します。アプリケーションモジュール
がDIとAOPの設定を持ちオブジェクトの構成を決定します。
アプリケーションの実行に必要なサービスオブジェクトはアプリケーションオブジェクト
が保持しているのでスクリプトはそのサービスを使いアプリケーションを実行します。
アプリケーションスクリプト
アプリケーションの実行手順が記述してあります。
<?php
use BEAR\Resource\Request;
use BEAR\Sunday\Extension\Application\AbstractApp;
use BEAR\Sunday\Extension\Application\AppInterface;
use MyVendor\HelloWorld\AppModule;
use Ray\Di\Injector;
require dirname(__DIR__) . '/vendor/autoload.php';
$app = (new Injector(new AppModule))->getInstance(AppInterface::class);
/** @var $app AbstractApp */
$request = $app->router->match($GLOBALS);
try {
// resource request
$page = $app->resource
->{$request->method}
->uri($request->path)
->withQuery($request->query)
->request();
/** @var $page Request */
// representation transfer
$page()->transfer($app->responder);
} catch (\Exception $e) {
$code = $e->getCode() ?: 500;
http_response_code($code);
echo $code;
error_log($e);
}
順に見ていきましょう。5つのステップがあります。
1.オートローダーの登録
require dirname(__DIR__) . '/vendor/autoload.php';
composer
のオートロードを利用します。
2.アプリケーションインスタンスの生成
$app = (new Injector(new AppModule))->getInstance(AppInterface::class);
アプリケーションは1つの変数に格納されています。BEAR.Sunday
アプリケーションは全体を通してDI
が利用されるので、実クラス名がほとんど登場しません。全ての依存の束縛を知るのがAppModule
です。インジェクターはそれを利用しアプリケーションクラスからアプリケーションのインスタンスを生成します。
アプリケーションクラス名ですらもここに登場しないのに注目してください。AppInterface
に束縛されたアプリケーションクラスが使用されます。
基本的なアプリケーションクラスはこのようなものです。
<?php
namespace BEAR\Sunday\Extension\Application;
use BEAR\Resource\ResourceInterface;
use BEAR\Sunday\Extension\Router\RouterInterface;
use BEAR\Sunday\Extension\Transfer\TransferInterface;
class AbstractApp implements AppInterface
{
/**
* @var RouterInterface
*/
public $router;
/**
* @var TransferInterface
*/
public $responder;
/**
* @var ResourceInterface
*/
public $resource;
/**
* @param RouterInterface $router
* @param TransferInterface $responder
* @param ResourceInterface $resource
*/
public function __construct(
RouterInterface $router,
TransferInterface $responder,
ResourceInterface $resource
) {
$this->router = $router;
$this->responder = $responder;
$this->resource = $resource;
}
}
アプリケーションの振舞いはスクリプトで記述するので、このクラスでは記述されてなく単にスクリプトで使用するサービスオブジェクトを3つ保持しているだけです。
クラスは単純ですが、実際に生成されるインスタンスは複雑です。
http://bearsunday.github.io/readme/print_o/app.html
http://bearsunday.github.io/readme/print_o/app_array.html (詳細)
BEAR.Sundayは適切なDIを使ったオブジェクト指向のアプリケーションでもあります。
オブジェクト指向のアプリケーションは相互に関係のある複雑なオブジェクト網を含んでいます。オブジェクトはあるオブジェクトから所有されているか、他のオブジェクト(またはそのリファレンス)を含んでいるか、そのどちらかでお互いに接続されています。このオブジェクト網をオブジェクトグラフと呼びます。
上記のリンクのオブジェクトグラフの中から検索してMyVendor\HelloWorld\App
を探してみてください。3つのオブジェクトに依存しているルートオブジェクトが見つかるでしょう。それがAppInterface
に束縛されていたアプリケーションクラスのインスタンスです。
明日はその3つのサービスオブジェクトを使ってアプリケーションを実行するところに続きます。