🔄 リクエストライフサイクル
すべてのリクエストは index.php から始まる
- 定数を定義(
ROOT、APP、CONFIG) - ヘルパー関数を読み込み
- インストール済みかチェック(
config/database.phpが存在するか?) - 未インストールの場合 →
/install/にリダイレクト - DB 設定 + ヘルパーを読み込み、セッション開始
- リクエストパスを計算(サブディレクトリへのインストールに対応)
app/router.phpでディスパッチ
ルーター
app/router.php はフラットなパターンマッチングのディスパッチテーブルです。パターンは正規表現にコンパイルされ、リクエストパスと照合されます。キャプチャグループはコントローラーメソッドの引数として渡されます。
認証
ほとんどのコントローラーは require_auth() を呼び出し、未認証ユーザーを /login にリダイレクトします。管理者専用エンドポイントは require_admin() を使用し、403 JSON を返します。
セッションはログイン時に user_id、workspace_id、role で設定され、セッション固定攻撃を防ぐために再生成されます。
データベース接続
PDO 接続は最初のクエリ時に遅延作成されます(シングルトン)。ERRMODE_EXCEPTION と実際のプリペアドステートメント(EMULATE_PREPARES = false)を使用します。
レスポンス形式
- HTML ページ: コントローラーが
$pageを設定し、layout.phpをインクルード - JSON API:
json_response()が Content-Type を設定、JSON を出力、終了 - SSE ストリーム:
text/event-streamによる持続的ループ、2 秒ごとに ping、55 秒後に終了