コアポイント
リクエスト/ルーティング/スケジューリング/応答サイクルを分析します
最初に解決する必要があるタスクは、典型的なHTTP要求/応答サイクルのデータと動作をシミュレートする責任のあるいくつかのクラスを定義することです。これは最初のクラスであり、それが実装するインターフェイスです:
<code>class Request { public function __construct($uri, $params) { $this->uri = $uri; $this->params = $params; } public function getUri() { return $this->uri; } public function setParam($key, $value) { $this->params[$key] = $value; return $this; } public function getParam($key) { if (!isset($this->params[$key])) { throw new \InvalidArgumentException("The request parameter with key '$key' is invalid."); } return $this->params[$key]; } public function getParams() { return $this->params; } }</code>
<code>class Response { public function __construct($version) { $this->version = $version; } public function getVersion() { return $this->version; } public function addHeader($header) { $this->headers[] = $header; return $this; } public function addHeaders(array $headers) { foreach ($headers as $header) { $this->addHeader($header); } return $this; } public function getHeaders() { return $this->headers; } public function send() { if (!headers_sent()) { foreach($this->headers as $header) { header("$this->version $header", true); } } } }</code>
予想されるように、機能的なルーティングメカニズムを実装する際には多くのオプションがあります。少なくとも私の意見では、上記の方法は実用的で直接的です。特定の操作コントローラーへのパスをバインドする個別のルートクラスと、責任が特定のリクエストオブジェクトに関連付けられたURIと一致するかどうかを確認することに責任が限定されている単純なルーターを定義します。最後に問題を解決するには、前のクラスと並んで使用できるクイックスケジューラを設定する必要があります。これは、次のクラスがどのように行うかです:
<code>class Route { public function __construct($path, $controllerClass) { $this->path = $path; $this->controllerClass = $controllerClass; } public function match(RequestInterface $request) { return $this->path === $request->getUri(); } public function createController() { return new $this->controllerClass; } } class Router { public function __construct($routes) { $this->addRoutes($routes); } public function addRoute(RouteInterface $route) { $this->routes[] = $route; return $this; } public function addRoutes(array $routes) { foreach ($routes as $route) { $this->addRoute($route); } return $this; } public function getRoutes() { return $this->routes; } public function route(RequestInterface $request, ResponseInterface $response) { foreach ($this->routes as $route) { if ($route->match($request)) { return $route; } } $response->addHeader("404 Page Not Found")->send(); throw new \OutOfRangeException("No route matched the given URI."); } }</code>
ディスパッチャーをスキャンすると、2つのことがわかります。第一に、それはいかなる状態でもありません。第二に、各操作コントローラーがexecute()メソッドの表面の下で実行されることを暗黙的に想定しています。これは、必要に応じてやや柔軟なパターンにリファクタリングできます(最初に頭に浮かぶのは、ルートクラスの実装を微調整することです)が、簡単にするために、スケジューラを変更せずに保ちます。これまでのところ、以前のすべてのクラスを組み合わせることができるフロントエンドコントローラーをどのように配置するか疑問に思うかもしれません。心配しないでください、次はそうです!
<code>class Dispatcher { public function dispatch($route, $request, $response) $controller = $route->createController(); $controller->execute($request, $response); } }</code>
以上がフロントコントローラーパターンの紹介、パート2の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。