-
Notifications
You must be signed in to change notification settings - Fork 0
04 State and Storage
Woof は「純粋関数」としての堅牢性を維持しながらも、Web アプリケーションに不可欠な 「セッション管理」や「レスポンスのキャッシュ」といった動的なデータを安全かつ予測可能な形でコントロールする仕組みを提供します。
この章では、Woof 特有のセッション永続化のライフサイクルと、高度なキャッシュ制御について解説します。
一般的な PHP アプリケーションでは $_SESSION['key'] = 'value';
と記述した瞬間にデータが暗黙的にグローバルな状態として書き換わります。
しかし、この挙動は処理の途頃でエラーや例外が発生した際に「中途半端にセッションが保存されてしまう」という不整合を招く原因になります。
Woof では、安全性を担保するため、明示的に永続化を指示しない限りセッションデータが物理ストレージに書き込まれない設計を採用しています。
Controller の内部では Operator クラスを介してセッションの読み書きを行います。
// セッションから値を読み込む
$userId = $operator->getSession("user_id");
// セッションに値をセットする (この時点ではメモリ上の一時変化)
$operator->setSession("is_logged_in", true);重要なのは setSession() を呼び出しただけでは、まだファイルやデータベースなどのストレージには一切保存されていないという点です。
もしビジネスロジックの途中で例外がスローされたり処理が中断されたりした場合、
そのリクエスト内でのセッションの変更は自動的に破棄 (ロールバック) されます。
変更を完全に確定させて保存するには、必ず saveSession() メソッドを明示的に呼び出す必要があります。
// 処理がすべて正常に完了したため、セッションの変更を永続化ストレージに書き込む
$operator->saveSession();
return $operator
->setView(new DashboardView())
->build();この明示的な永続化サイクルにより、アプリケーションの状態管理が劇的に安全になります。
Web アプリケーションのパフォーマンスを向上させるため、Woof はレンダリング結果をキャッシュする VariantStorage 機構をサポートしています。
View の章で解説した「View には純粋な値だけを渡す」というルールが守られているからこそ、 Woof はリクエストの条件に応じて完全に安全なビューキャッシュを生成・再利用できます。
Woof では、安全性を最優先するため デフォルト状態ではキャッシュ機能が完全に無効化 されています。
もしキャッシュが常に自動で有効になっていると、ログイン必須の会員専用ページなどで、 あるユーザーのためにレンダリングされた個人情報 (マイページなど) が誤ってキャッシュされ、 他のユーザーに表示されてしまうといった重大な事故に繋がりかねません。
そのため、そのページがキャッシュ可能であり 304 Not Modified などの恩恵を受けたい場合は
Controller 内部で Operator に対して明示的に setEnableCache(true) を呼び出す必要があります。
// Operator を使ってレスポンスを構築する
$operator = new Operator($request, $env);
// 安全のためデフォルトは OFF なので、キャッシュを適用したいページでは明示的に有効化します。
// 生成された View とクライアントのキャッシュ状態 (If-None-Match や If-Modified-Since)
// をもとに、内部で自動的に「304 Not Modified」の空レスポンスを組み立てる判定も行われます。
return $operator
->setEnablesCache(true)
->setView(new ProfileView($userData))
->build();これらのセッションデータやキャッシュファイル、あるいはアプリケーションのログ群は
Environment から取得できる DataStorage を通じて管理されます。
デフォルトの Web 環境では FileDataStorage が実態として割り当てられており、
サーバー内のローカルディスク上の指定されたディレクトリに対して動的なファイルの入出力を行います。
これらはインタフェースとして完全に抽象化されているため、将来的に Redis や外部の分散 KVS に保存先を切り替える際も、
ビジネスロジック (Controller) 側のコードを 1 行も書き換えることなく対応可能です。