PHP システムアーキテクチャ

← 戻る

PHP Omikuji アーキテクチャ

システム概要

PHP Omikujiは、PHPエンジニア向けのおみくじアプリケーションです。伝統的な日本のおみくじをPHPプログラミングのテーマでアレンジし、運勢をPHPコードとして表示します。

アーキテクチャ図

システム全体構成

graph TB subgraph "Client Side" Browser[ブラウザ] QRReader[QRコードリーダー] end subgraph "Docker Container" subgraph "Nginx Container" Nginx[Nginx<br/>Port: 8080] end subgraph "PHP-FPM Container" Laravel[Laravel Application<br/>PHP 8.2] end subgraph "Redis Container" Redis[Redis<br/>Cache & Session] end end subgraph "Storage" SQLite[(SQLite Database)] FileSystem[File System<br/>Views/Assets] end Browser --> Nginx QRReader --> Nginx Nginx --> Laravel Laravel --> Redis Laravel --> SQLite Laravel --> FileSystem

アプリケーション層構成

graph LR subgraph "Presentation Layer" Routes[Routes<br/>web.php] Controller[OmikujiController] Views[Blade Views<br/>- index<br/>- result<br/>- print] end subgraph "Business Layer" Service[OmikujiService] DataClass[Data Classes<br/>- FortuneData<br/>- FortuneMessages] end subgraph "Data Layer" Models[Eloquent Models<br/>- Fortune<br/>- FortuneCategory<br/>- FortuneResult<br/>- LuckCategory<br/>- LuckDetail<br/>- FortuneLuckMapping] Database[(SQLite)] end Routes --> Controller Controller --> Service Controller --> Views Service --> DataClass Service --> Models Models --> Database

データベース構造

erDiagram fortune_categories ||--o{ fortunes : has fortune_categories ||--o{ fortune_luck_mappings : has fortunes ||--o{ fortune_results : generates luck_categories ||--o{ luck_details : contains luck_categories ||--o{ fortune_luck_mappings : mapped_to luck_details ||--o{ fortune_luck_mappings : mapped_by fortune_categories { bigint id PK string key UK string name string description decimal probability integer sort_order timestamps timestamps } fortunes { bigint id PK bigint fortune_category_id FK text code string description timestamps timestamps } fortune_results { bigint id PK bigint fortune_id FK string session_id UK string ip_address string user_agent timestamps timestamps } luck_categories { bigint id PK string key UK string name string icon integer sort_order timestamps timestamps } luck_details { bigint id PK bigint luck_category_id FK text message integer message_index timestamps timestamps } fortune_luck_mappings { bigint id PK bigint fortune_category_id FK bigint luck_category_id FK bigint luck_detail_id FK timestamps timestamps }

画面遷移図

stateDiagram-v2 [*] --> TOP画面 TOP画面 --> おみくじを引く : QRコードスキャン<br/>または<br/>「おみくじを引く」クリック TOP画面 --> 印刷画面 : 「印刷用ページ」クリック おみくじを引く --> 結果画面 : 自動リダイレクト<br/>(運勢抽選後) 結果画面 --> TOP画面 : 「もう一度引く」クリック 結果画面 --> Xシェア画面 : 「Xでシェア」クリック 結果画面 --> 結果画面 : 「実行」ボタンクリック<br/>(PHPコード実行アニメーション) Xシェア画面 --> 結果画面 : ブラウザバック 印刷画面 --> TOP画面 : ブラウザバック state "TOP画面 [/]" as TOP画面 { QRコード表示 -- おみくじを引くボタン -- 印刷用ページリンク } state "おみくじを引く [/fortune]" as おみくじを引く { 運勢抽選処理 -- データベース保存 -- セッションID生成 } state "結果画面 [/result/{key}]" as 結果画面 { 運勢表示 -- PHPコード表示 -- 各種運勢詳細 -- 実行ボタン -- シェアボタン } state "印刷画面 [/print]" as 印刷画面 { 8枚のおみくじカード -- 印刷レイアウト } state "Xシェア画面 [外部]" as Xシェア画面 { twitter.com/intent/tweet }

画面詳細

graph TD subgraph "1. TOP画面 [/]" A1[QRコード<br/>大きく中央に表示] A2[おみくじを引くボタン] A3[印刷用ページリンク] end subgraph "2. おみくじ実行 [/fortune]" B1[運勢を抽選] B2[データベースに保存] B3[セッションID生成] end subgraph "3. 結果画面 [/result/{key}]" C1[運勢カテゴリ表示<br/>大吉・中吉など] C2[PHPコード表示<br/>シンタックスハイライト付き] C3[実行ボタン<br/>アニメーション機能] C4[8つの運勢詳細<br/>カード形式で表示] C5[Xシェアボタン] C6[もう一度引くリンク] end subgraph "4. 印刷画面 [/print]" D1[8枚のカードレイアウト] D2[QRコード付き] D3[切り取り線表示] end A1 -->|QRスキャン| B1 A2 -->|クリック| B1 A3 -->|クリック| D1 B3 -->|リダイレクト| C1 C6 -->|クリック| A1 C5 -->|外部リンク| E[X投稿画面]

リクエストフロー

sequenceDiagram participant User participant Browser participant Nginx participant Laravel participant Service participant Database User->>Browser: QRコードをスキャン Browser->>Nginx: GET /fortune Nginx->>Laravel: リクエスト転送 Laravel->>Service: drawFortune() Service->>Database: 運勢カテゴリ取得 Service->>Service: 確率に基づいて選択 Service->>Database: 運勢詳細取得 Service->>Database: 結果を保存 Database-->>Service: セッションID Service-->>Laravel: FortuneResult Laravel-->>Browser: リダイレクト /result/{key} Browser->>Nginx: GET /result/{key} Nginx->>Laravel: リクエスト転送 Laravel->>Service: getFortuneResult() Service->>Database: 結果取得 Database-->>Service: 運勢データ Service-->>Laravel: フォーマット済みデータ Laravel-->>Browser: 結果画面表示

ディレクトリ構造

graph TD Root[php-omikuji/] Root --> App[app/] Root --> Config[config/] Root --> Database[database/] Root --> Docker[docker/] Root --> Public[public/] Root --> Resources[resources/] Root --> Routes[routes/] App --> Controllers[Controllers/<br/>OmikujiController.php] App --> Models[Models/<br/>6 Eloquent Models] App --> Services[Services/<br/>OmikujiService.php] App --> Data[Data/<br/>FortuneData.php<br/>FortuneMessages.php] Database --> Migrations[migrations/<br/>テーブル定義] Database --> Seeders[seeders/<br/>初期データ] Docker --> DockerPHP[php/<br/>Dockerfile] Docker --> DockerNginx[nginx/<br/>設定ファイル] Resources --> Views[views/omikuji/<br/>- index.blade.php<br/>- result.blade.php<br/>- print.blade.php] Resources --> Assets[css/ & js/] Routes --> Web[web.php<br/>4つのルート定義]

主要コンポーネント

1. プレゼンテーション層

2. ビジネスロジック層

- 確率に基づく運勢選択 - セッションID生成 - 結果のフォーマット

3. データ層

4. インフラ層

技術スタック

特徴的な実装

1. PHPテーマの運勢: 運勢がPHPコードとして表示される 2. QRコード連携: イベント会場での配布を想定 3. 印刷機能: 物理的なおみくじカードの生成 4. VSCodeテーマUI: 開発者に親しみやすいダークテーマ 5. ソーシャルシェア: X(Twitter)への投稿機能

セキュリティ考慮事項

  • CSRF保護(Laravel標準)