====== 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でのネーミングに準じています。
\\