ActionはControllerとModelの間で実行され、ユーザーからの入力の妥当性検査を行いビジネスロジックの実行を管理する、とても重要なアーキテクチャです。

この章では、Actionのライフサイクルふるまいを制御する設定値等、アーキテクチャの詳細についてご紹介します。

※この記事は執筆・公開から1年以上経過しています。記事の情報が古くなっている場合がありますのでご注意ください。

公開日時:2019/12/10 16:59 最終更新:2021/06/10 13:13   Pine Framework

Actionの詳細

ActionはControllerとModelの間で実行され、ユーザーからの入力の妥当性検査を行いビジネスロジックの実行を管理する、とても重要なアーキテクチャです。

ユーザーからのリクエストはURLを元に、要求されている処理をRouterが判断して妥当なControllerを1つ選定して処理を移譲しますが、ControllerはRouterの判断を元に、妥当なActionを1つ選定して処理を移譲します。

最もシンプルなパターンとしては、下記のようなURL

https://domain/some/command/some_action

は、

command: some/command
action: some_action

のようにURLが分解され、commandに対応するController、actionに対応するActionが選定されます。

事前処理

事前処理

Controllerから処理を移譲されたActionはまず、ユーザーからのリクエストの妥当性を検査します。この処理は通常、Actionの設定値として規定されたUME(User-request Manipulate Engine)に移譲され、UMEの設定値によって自動でヴァリデーションが行われます。

このヴァリデーションが行われた後、必要であればActionはユーザーから送られたワンタイムチケットの検査も行います。

実装者は必要であれば、この後に追加の入力検査やモデル実行に先立った事前処理を追加で行うことができます。

これらの処理の課程でExceptionがthrowされた場合、ActionはAction::deficient()を実行した後、Modelの実行を行わず最終工程であるAction::closer()を実行して処理を終了します。

モデルの実行

事前処理

通常はModelの実行に先立ち、トランザクションが開始され、この後に実装者が規定したModelの実行が行われます。

このModelの実行はAction::logic()内に記述されますが、このメソッド内でExceptionがthrowされるとActionはトランザクションをロールバックし、Action::fail()を実行します。また、Action::logic()内でfalseがreturnされた場合も同様にトランザクションのロールバックとAction::fail()を実行します。

Action::logic()が正常終了しtrueがreturnされた場合はトランザクションがコミットされ、Action::done()が実行されます。

Action::fail()とAction::done()のいずれが実行された場合でも、Action::always()が実行されます。

終端処理

Actionの実行にあたって最後にAction::closer()が実行され、Actionのライフサイクルは終了します。

Actionに規定されたレスポンスタイプがHTMLの場合、処理はControllerに返されますが、JSONの場合は蓄積されているレスポンスをJSONエンコードした後、ブラウザに出力されます。

レスポンスタイプがFILEの場合、Actionは基底では何もせずPHPの実行を終了します。このため、出力するデータはAction::done()内等で適切に出力を行ってください。

Actionに設定するパラメター

Actionは設定値駆動であり、実装者が個別にコードを記述する必要なしにメンバプロパティによって自動で動作が決定されます。

以下が、設定値の例です。

protected $static_page                  = false;
protected $ume_class                    = "GetIndexUME";
protected $validate_ticket              = true;
protected $validate_ticket_on_get       = false;
protected $validate_ticket_by           = pine\TICKET::BY_POST;
protected $regenerate_ticket_after_post = true;
protected $transaction                  = false;
protected $response_type                = pine\ResponseType::HTML;

protected $static_page

静的ページか、動的ページかを設定します。通常はfalseですがtrueが設定されている場合、ページの振る舞いは常に一定であると判断され、ControllerはActionを一切実行せずに処理をViewに移譲します。

protected $ume_class

そのActionがデフォルトで使用するUMEクラスを定義します。nullが指定されている場合、ActionはUMEによる入力値の自動検査を行いません。

protected $validate_ticket

ワンタイムチケットの検査を行うかどうかを定義します。

protected $validate_ticket_on_get

GETメソッドの場合でもワンタイムチケットの検査を行うかどうかを定義します。この値がfalseの場合は、$validate_ticketがtrueであってもワンタイムチケットの検査を行いません。

protected $validate_ticket_by

どのメソッドで渡されたワンタイムチケットの検査を行うかを定義します。pine\TICKET::BY_POST、pine\TICKET::BY_GETの他、pine\TICKET::BY_COOKIEも利用できます。

protected $regenerate_ticket_after_post

POSTメソッドリクエストでAction::logic()の実行結果が正常終了した場合に、ワンタイムチケットを再生成するかどうかを設定します。これは、二重投稿やCSRFの対策などに寄与します。

古いワンタイムチケットは無効になるため、Ajaxでの非同期通信などでPOSTを行っている場合は必要に応じて、返却されたワンタイムチケットでフロント側のワンタイムチケットの値を適切に更新してください。

protected $transaction

モデルの実行に先立ってデータベース操作に対してトランザクションを発行するかどうかを定義します。

protected $response_type

Action実行後のレスポンスのタイプを定義します。pine\ResponseType::HTMLが設定されている場合はAction実行後はControllerに処理が返され、その後にViewに処理が移譲されてHTMLが出力されます。

pine\ResponseType::JSONが設定されている場合はAction::$responseに蓄積されているデータをJSONエンコードし、ブラウザにFlushします。

pine\ResponseType::FILEが設定されている場合はActionは何も出力せずにPHPの処理を終了します。このため、ファイルをブラウザに出力したい場合はAction::done()等のメソッド内で適切にファイル出力を行ってください。

Actionのライフサイクル

Actionのライフサイクルの全体は以下のようになっています。

事前処理

記事リンク