====== Apricot レスポンスクラス ====== --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-05-04 // [[apricot:top|Apricot に戻る]] 関連記事 * [[apricot:configuration|Apricot プロジェクトの作成]] * [[apricot:public|Apricot 公開フォルダ]] * Apricot コア * [[apricot:core:top|Apricot コア作成の準備]] * [[apricot:core:application-class|Apricot アプリケーションクラス]] * [[apricot:core:basic-class|Apricot 各種基本コアクラス]] * [[apricot:core:request-class|Apricot リクエストクラス]] * Apricot レスポンスクラス * [[apricot:core:base-controller|Apricot ベースコントローラ]] * [[apricot:core:completion|Apricot コアの完成]] * [[apricot:app:top|Apricot アプリ]] * [[apricot:ext:middleware|Apricot 拡張]] HTTPレスポンスには以下の3ケースがあります。 * 正常レスポンス * HTMLレンダリング --- (Case.1) * リダイレクト --- (Case.2) * エラーレスポンス --- (Case.3) ここでは、正常レスポンスについて扱います。エラーレスポンスは[[apricot:core:basic-class#集約例外ハンドラー|集約例外ハンドラー]]経由で処理されます。 ---- ===== Responseクラス ===== Responseクラスはレスポンスのベースクラスで、その目的はHTMLヘッダーとフラッシュデータの管理です。後述の RenderResponse(レンダリング用) と RedirectResponse(リダイレクト用) はResponseクラスから派生します。Responseクラスは以下のメソッドを持ちます。 ^メソッド^機能^ |addHeader($headers):Response|HTMLヘッダーの追加| |hasFlash(string $key):bool|フラッシュデータの存在確認| |addFlash(string $key, $value):Response|フラッシュデータの追加| |commit(int $response_code=null)|レスポンスの確定| {{fa>folder-open-o}} ** /apricot/core/Foundation ** headers[] = $header; } return $this; } /** * Check if a flash value is present * @param string $key * @return bool */ public function hasFlash(string $key):bool { return array_key_exists($key, $this->flashes); } /** * Add a value to flash * @param string $key * @param mixed $value * @return Response */ public function addFlash(string $key, $value):Response { $this->flashes[$key] = $value; return $this; } /** * Commit Response Data * @param int $response_code */ public function commit(int $response_code=null) { // Set Http response code if (isset($response_code)) { http_response_code($response_code); } // Output headers foreach($this->headers as $header) { header($header); } // Save old URL Path $this->addFlash(self::FLASH_KEY_BACK, $_SERVER['REQUEST_URI']); // Output flashes foreach($this->flashes as $key=>$value) { Session::flash()->set($key, $value); } } } \\ ===== RenderResponseクラス ===== RenderResponseクラスはResponseクラスから派生します。HTMLレンダリングを行うレスポンス用のクラスで、以下のメソッドを持ちます。addHeader()などのResponseクラスのメソッドも使用できます。 ^メソッド^機能^ |__construct(string $html=null)|RenderResponseの生成| |setHtml(string $html=null):RenderResponse|HTMLテキストの設定| |commit(int $response_code=null)|レスポンスの確定| {{fa>folder-open-o}} ** /apricot/core/Foundation/Response ** setHtml($html); } /** * Set Html * @param string $html * @return RenderResponse */ public function setHtml(string $html=null) : RenderResponse { if (isset($html)) $this->html = $html; return $this; } /** * commit * {@inheritDoc} * @see \Core\Foundation\Response::commit() */ public function commit(int $response_code=null) { // headersに'Content-type'がなければ出力する $matchs= preg_grep('/^content-type.*?:/i', $this->headers); if(empty($matchs)) { $this->addHeader("Content-type: text/html; charset=utf-8"); } parent::commit($response_code); // HTMLのレンダリング echo $this->html; flush(); } } \\ ===== RedirectResponseクラス ===== RedirectResponseクラスはResponseクラスから派生したリダイレクト用のクラスです。リダイレクトではフラッシュデータを使ってリダイレクト先のページにデータを送ることが多いので、フラッシュ用のメソッドが追加されています。RedirectResponseクラスは以下のメソッドを持ちます。addHeader()などのResponseクラスのメソッドも使用できます。 ^メソッド^機能^ |__construct(string $url)|RedirectResponseの生成| |with(string $key, $value):RedirectResponse|フラッシュデータの追加| |withInputs():RedirectResponse|入力データをフラッシュに追加する| |withErrors(ErrorBag $errorBag):RedirectResponse|エラーバッグをフラッシュに追加する| |withOldErrors():RedirectResponse|前回のエラーバッグを次のフラッシュに転送する| 以下は、レスポンスで使用するフラッシュデータのキーとその内容です。特に _old_inputs と errors はHTMLテンプレートで良く使用されます。 ^フラッシュキー^内容^ |_old_inputs|前回の入力データ| |_old_path|前回のURIパス| |errors|[[apricot:core:basic-class#errorbagクラス|エラーバッグ]]| {{fa>folder-open-o}} ** /apricot/core/Foundation/Response ** addHeader("Location: {$url}"); } /** * with * @param string $key * @param mixed $value * @return RedirectResponse */ public function with(string $key, $value):RedirectResponse { $this->addFlash($key, $value); return $this; } /** * withInputs * @return RedirectResponse */ public function withInputs():RedirectResponse { $this->addFlash(self::FLASH_KEY_OLD, \Core\Input::getRawData()); return $this; } /** * withErrors * @param \Core\Foundation\ErrorBag $message * @return RedirectResponse */ public function withErrors(ErrorBag $errorBag):RedirectResponse { $this->addFlash(self::FLASH_KEY_ERRORS, $errorBag); return $this; } /** * withOldErrors * @return RedirectResponse */ public function withOldErrors():RedirectResponse { if (Flash::has(self::FLASH_KEY_ERRORS)) { $this->addFlash(self::FLASH_KEY_ERRORS, Flash::get(self::FLASH_KEY_ERRORS)); } return $this; } } \\ ===== ヘルパー関数 ===== レスポンス処理用のヘルパー関数を追加します。render()とredirect()はコントローラアクションで、その他はHTMLテンプレートでよく使われる関数です。 ^ヘルパー関数^機能^ |render\\ (string $view=null, array $variables=[])\\ :RenderResponse|[[#RenderResponseクラス|RenderResponse]]の生成 \\ テンプレート名とテンプレート変数を指定します| |redirect\\ (string $url)\\ :RedirectResponse|[[#RedirectResponseクラス|RedirectResponse]]の生成\\ リダイレクトURLを指定します| |old\\ (string $key, $default = null)|キーを指定して前回の入力値を取得します| |back():string|前回のURIを取得します| |errors():ErrorBag|前回のエラーバッグを取得します| {{fa>folder-open-o}} ** /apricot/core/helpers ** /** * render * @param string $view テンプレート名 * @param array $variables テンプレート変数のハッシュ * @return \Core\Foundation\Response\RenderResponse */ function render(string $view=null, array $variables=[]):Core\Foundation\Response\RenderResponse { $variables['errors'] = errors(); $html = isset($view) ? Core\View::run($view, $variables) : null; return new Core\Foundation\Response\RenderResponse($html); } /** * redirect * @param string $url URL * @return \Core\Foundation\Response\RedirectResponse */ function redirect(string $url):Core\Foundation\Response\RedirectResponse { return new Core\Foundation\Response\RedirectResponse($url); } /** * Get old request inputs * @param string $key * @param mixed $default * @return string */ function old(string $key, $default = null) { $old_inputs = flash(Core\Foundation\Response::FLASH_KEY_OLD); return isset($old_inputs) && array_key_exists($key, $old_inputs) ? $old_inputs[$key] : $default; } /** * Get old URL Path * @return string URL */ function back():string { if (array_key_exists('HTTP_REFERER', $_SERVER) && isset($_SERVER['HTTP_REFERER'])) { $url = '/'; $info = parse_url($_SERVER['HTTP_REFERER']); if (array_key_exists('path',$info)) $url = $info['path']; if (array_key_exists('query',$info)) $url .= '?'.$info['query']; if (array_key_exists('fragment',$info)) $url .= '#'.$info['fragment']; return $url; } else { return flash(Core\Foundation\Response::FLASH_KEY_BACK, '/'); } } /** * Get response errors * @return \Core\Foundation\ErrorBag */ function errors():Core\Foundation\ErrorBag { $errors = Core\Flash::has(Core\Foundation\Response::FLASH_KEY_ERRORS) ? flash(Core\Foundation\Response::FLASH_KEY_ERRORS) : new Core\Foundation\ErrorBag(); return $errors; } * render()関数の中で、テンプレート変数 $errors を自動生成している点に注意して下さい。 * HTMLテンプレートで使用する関数名はなるべるLaravelでのネーミングに準じています。 \\