# 帳票設計書 5-FilesystemAdapter download

## 概要

本ドキュメントは、Laravel FrameworkにおけるFilesystemAdapter::download()（ストレージダウンロード）機能の設計仕様を定義する。ストレージに保存されたファイルをダウンロード形式で出力する機能であり、Storage::download()で利用可能。

### 本帳票の処理概要

FilesystemAdapter::download()は、Laravelのファイルストレージ（Storage Facade）に保存されたファイルをダウンロード用のHTTPレスポンスとして送信する機能を提供する。response()メソッドとの主な違いは、Content-Dispositionヘッダーがattachmentに設定され、ブラウザがファイル保存ダイアログを表示することである。

**業務上の目的・背景**：業務システムでは、ストレージに保存されたレポートファイル、エクスポートされたデータ、アップロードされた添付ファイルなどを、ユーザーがダウンロードして保存できるようにする必要がある。download()メソッドを使用することで、ストレージの種類（ローカル、S3、FTP等）に関わらず、一貫したダウンロード体験を提供できる。

**帳票の利用シーン**：
- 生成されたレポートファイルのダウンロード
- アップロードされた添付ファイルの取得
- データエクスポートファイル（CSV、Excel等）のダウンロード
- アーカイブファイル（ZIP）のダウンロード

**主要な出力内容**：
1. ストレージからのファイルストリーミングレスポンス
2. Content-Disposition: attachment ヘッダー（ダウンロードモード）
3. 自動検出されたMIMEタイプヘッダー
4. ファイルサイズ情報（Content-Length）

**帳票の出力タイミング**：Storage::download()メソッドの呼び出し時にStreamedResponseが生成され、ファイル保存ダイアログとともにダウンロードが開始される。

**帳票の利用者**：アプリケーション開発者、ファイルをダウンロードするエンドユーザー

## 帳票種別

ストレージファイルダウンロード / ファイル出力

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | 任意の画面 | 開発者定義 | Storage::download()呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | ストレージ内ファイル形式に依存 |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | $nameパラメータまたはbasename($path) |
| 出力方法 | HTTPダウンロード（ファイル保存ダイアログ表示） |
| 文字コード | ファイル依存 |

### download()固有設定

| 項目 | 内容 |
|-----|------|
| Content-Disposition | attachment（固定） |
| Content-Type | mimeType()で自動検出 |
| Content-Length | size()で自動取得 |

## 帳票レイアウト

### レイアウト概要

FilesystemAdapter::download()はストレージ内ファイルをダウンロード用に出力するため、レイアウト構造はファイル自体に依存する。

```
┌─────────────────────────────────────┐
│          HTTPヘッダー部              │
│    (Content-Disposition: attachment) │
├─────────────────────────────────────┤
│          ファイルコンテンツ           │
│       （ストリーミング出力）          │
│                                     │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Content-Type | ファイルのMIMEタイプ | $this->mimeType($path) | application/pdf等 |
| 2 | Content-Length | ファイルサイズ | $this->size($path) | バイト数 |
| 3 | Content-Disposition | ダウンロードモード | 'attachment'固定 | attachment; filename="xxx" |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | ファイルコンテンツ | ストレージ内ファイル | readStream($path) | バイナリ | - |

### フッター部

フッター部は特に定義されない。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| path | ストレージ内のファイルパス | Yes |
| name | ダウンロード時のファイル名 | No（デフォルト: basename($path)） |
| headers | 追加HTTPヘッダー | No |

### ソート順

ファイル出力のため、ソート順は適用されない。

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| - | - | - |

### 改ページ条件

ファイル出力のため、改ページ条件は適用されない。

## データベース参照仕様

### 参照テーブル一覧

FilesystemAdapter::download()自体はデータベースを参照しない。

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| - | - | - |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| - | - | - | response()メソッドを内部呼び出し |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[download()メソッド呼び出し] --> B[response()メソッド呼び出し]
    B --> C[disposition='attachment'で実行]
    C --> D[StreamedResponse生成]
    D --> E[HTTPヘッダー設定]
    E --> F[readStream実行]
    F --> G[fpassthru出力]
    G --> H[fclose]
    H --> I[ブラウザでファイル保存ダイアログ表示]
    I --> J[ダウンロード完了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ファイル不存在 | ストレージにファイルがない | UnableToReadFile | ファイルパスを確認 |
| 読み取りエラー | ストリーム取得失敗 | UnableToReadFile | ストレージ設定確認 |
| 権限エラー | アクセス権限なし | AccessDenied | 権限設定確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 単一ファイル |
| 目標出力時間 | ファイルサイズ・帯域に依存 |
| 同時出力数上限 | サーバーリソースに依存 |

## セキュリティ考慮事項

- ダウンロード権限の認証・認可を適切に実装すること
- パス指定にユーザー入力を使用する場合は、パストラバーサル対策が必要
- 機密ファイルへのアクセスログを記録すること
- Content-Dispositionのファイル名にはサニタイズが必要

## 備考

- download()メソッドはresponse()メソッドのラッパーであり、disposition='attachment'を指定して呼び出す
- response()メソッドとの違いは、ブラウザ内表示（inline）かダウンロード（attachment）かのみ

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

download()メソッドはresponse()メソッドのラッパーであるため、まずresponse()の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FilesystemAdapter.php | `src/Illuminate/Filesystem/FilesystemAdapter.php` | クラス全体の構造を理解する |

**読解のコツ**: download()はresponse()を'attachment'モードで呼び出すだけのシンプルなラッパーメソッド。

#### Step 2: エントリーポイントを理解する

処理の起点となるdownload()メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FilesystemAdapter.php | `src/Illuminate/Filesystem/FilesystemAdapter.php` | download()メソッドの実装を確認 |

**主要処理フロー**:
1. **行371-382**: download()メソッドの実装
2. **行379-381**: response()メソッドを'attachment'パラメータで呼び出し

#### Step 3: 内部呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | FilesystemAdapter.php | `src/Illuminate/Filesystem/FilesystemAdapter.php` | response()メソッド（内部呼び出し先） |

**主要処理フロー**:
- **行318-353**: response()メソッドの実装（download()から呼び出される）
- **行327**: dispositionパラメータで'inline'または'attachment'を指定

### プログラム呼び出し階層図

```
FilesystemAdapter::download($path, $name, $headers)
    │
    └─ $this->response($path, $name, $headers, 'attachment')
           │
           ├─ new StreamedResponse()
           │
           ├─ $this->mimeType($path)
           │
           ├─ $this->size($path)
           │
           ├─ fallbackName($filename)
           │
           └─ setCallback()
                  ├─ readStream($path)
                  ├─ fpassthru($stream)
                  └─ fclose($stream)
```

### データフロー図

```
[入力]               [処理]                    [出力]

ストレージパス  ───▶ FilesystemAdapter    ───▶ HTTPレスポンス
$path                 ::download()            (attachment)
                          │
                          ▼
                    ::response()
                   (disposition='attachment')
                          │
                          ▼
                    StreamedResponse
                          │
                          ▼
                    ファイル保存ダイアログ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FilesystemAdapter.php | `src/Illuminate/Filesystem/FilesystemAdapter.php` | ソース | download()およびresponse()メソッドの実装 |
| Filesystem.php | `src/Illuminate/Contracts/Filesystem/Filesystem.php` | ソース | インターフェース定義 |
| Storage.php | `src/Illuminate/Support/Facades/Storage.php` | ソース | Facadeクラス |
| StreamedResponse.php | `vendor/symfony/http-foundation/StreamedResponse.php` | ソース | Symfony基底クラス |
