# 機能設計書 54-String

## 概要

本ドキュメントは、Symfony Stringコンポーネントの機能設計を記述する。Stringコンポーネントは文字列操作のオブジェクト指向APIを提供し、バイト列、UTF-8コードポイント、書記素クラスタの3種類の文字列表現を統合的に処理する。

### 本機能の処理概要

Stringコンポーネントは、PHP標準の文字列関数をオブジェクト指向で包み込み、イミュータブルなAPIでチェーン呼び出し可能な文字列操作を提供する。Unicode対応、スラッグ生成、ランダム文字列生成など多様な文字列処理機能を含む。

**業務上の目的・背景**：PHPの文字列関数はマルチバイト対応が不統一であり、mbstring拡張とintl拡張で異なるAPIが存在する。Stringコンポーネントは、バイト列(ByteString)、コードポイント(CodePointString)、書記素クラスタ(UnicodeString)の3つの抽象レベルを統一されたAPIで提供し、開発者が文字列の種類を意識せずに安全な文字列操作を行えるようにする。

**機能の利用シーン**：URLスラッグ生成(AsciiSlugger)、文字列の検索・分割・結合・トリミング、キャメルケース/スネークケース変換、文字列の切り詰め(truncate)、正規表現マッチング、ランダム文字列生成(ByteString::fromRandom)、遅延評価文字列(LazyString)。

**主要な処理内容**：
1. 3種類の文字列クラス(ByteString, CodePointString, UnicodeString)によるイミュータブルな文字列操作
2. AsciiSluggerによるURLスラッグ生成(Unicode正規化、アクセント除去、音訳)
3. Inflectorによる英語/フランス語/スペイン語等の単数形/複数形変換
4. ランダム文字列生成(cryptographically secure)
5. LazyStringによる遅延評価文字列の提供
6. 正規表現操作(match, matchAll, replace)
7. 文字列切り詰め(truncate)と切り詰めモード(TruncateMode)

**関連システム・外部連携**：PHP intl拡張(UnicodeString、AsciiSlugger使用時)、mbstring拡張(CodePointString使用時)。

**権限による制御**：権限制御は実装されていない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面はない。アプリケーション全体の文字列処理基盤として機能 |

## 機能種別

データ変換 / テキスト処理 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| string | string | Yes | 操作対象の文字列 | ByteString: 任意バイト列、UnicodeString: 有効なUTF-8文字列 |
| length | int | Yes(fromRandom) | ランダム文字列の長さ | 1以上の整数 |
| alphabet | string|null | No(fromRandom) | ランダム文字列のアルファベット | 2^1から2^56文字の範囲 |
| locale | string | No(AsciiSlugger) | スラッグ生成時のロケール | 有効なロケール文字列 |

### 入力データソース

PHPコード内の文字列リテラル、ユーザー入力、データベースからの取得値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | static(ByteString/CodePointString/UnicodeString) | 操作結果の文字列オブジェクト(イミュータブル) |
| slug | AsciiSlugger返却値 | URL安全なスラッグ文字列 |
| randomString | ByteString | 暗号的に安全なランダム文字列 |

### 出力先

呼び出し元のアプリケーションコード。

## 処理フロー

### 処理シーケンス

```
1. 文字列オブジェクト生成
   └─ new ByteString($str) / new UnicodeString($str) / new CodePointString($str)
2. UnicodeStringの場合はNFC正規化
   └─ normalizer_normalize()によるUnicode正規化
3. チェーン操作の実行(各操作はクローンを返却)
   └─ lower(), upper(), camel(), snake(), trim(), replace()等
4. スラッグ生成(AsciiSlugger)
   └─ Unicode正規化 -> 音訳(Transliterator) -> アクセント除去 -> ASCII化 -> セパレータ結合
5. 結果の取得
   └─ __toString()またはtoString()
```

### フローチャート

```mermaid
flowchart TD
    A[文字列入力] --> B{文字列種別の選択}
    B -->|バイト列| C[ByteString]
    B -->|コードポイント| D[CodePointString]
    B -->|書記素クラスタ| E[UnicodeString]
    E --> F[NFC正規化]
    C --> G[チェーン操作]
    D --> G
    F --> G
    G --> H[結果文字列オブジェクト]
    H --> I[__toString]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | イミュータブル | 全ての文字列操作は元のオブジェクトを変更せず、新しいオブジェクトを返却する | 全操作メソッド |
| BR-54-02 | NFC正規化 | UnicodeStringは常にUnicode NFC(Canonical Decomposition, followed by Canonical Composition)形式で保持される | UnicodeString生成時、append/prepend時 |
| BR-54-03 | fromRandomの暗号安全性 | ByteString::fromRandom()はRandomizer::getBytesFromString()を使用し、暗号的に安全なランダム文字列を生成する | fromRandom()呼び出し時 |
| BR-54-04 | 書記素クラスタ単位 | UnicodeStringのlength(), chunk()等は書記素クラスタ単位で計算される | UnicodeString使用時 |

### 計算ロジック

fromRandom()のアルファベットサイズのビット数は `ceil(log($alphabetSize, 2.0))` で算出。1以上56以下である必要がある(ByteString.php 54-56行目)。

## データベース操作仕様

本コンポーネントはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidArgumentException | fromRandom()のlengthが0以下の場合 | 1以上の正の整数を指定 |
| - | InvalidArgumentException | fromRandom()のalphabetサイズが範囲外の場合 | 2^1から2^56文字の範囲のアルファベットを指定 |
| - | InvalidArgumentException | UnicodeStringに無効なUTF-8文字列が渡された場合 | 有効なUTF-8文字列を入力 |

### リトライ仕様

リトライ機構は不要。

## トランザクション仕様

トランザクション管理は対象外。

## パフォーマンス要件

- ByteStringは単純なバイト操作で最も高速
- UnicodeStringはNFC正規化のオーバーヘッドがあるが、normalizer_is_normalized()による事前チェックで不要な正規化をスキップ(UnicodeString.php 37行目)
- LazyStringは実際に文字列化されるまで計算を遅延し、メモリ使用量を抑制

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

- fromRandom()はPHP Randomizer(CSPRNG)を使用しており、トークン生成等のセキュリティ用途に使用可能
- 文字列操作自体はXSS等のセキュリティ処理を行わないため、出力時のエスケープは別途必要

## 備考

Stringコンポーネントは `\Stringable` インターフェースと `\JsonSerializable` インターフェースを実装しており、文字列コンテキストとJSON変換で自動的に文字列に変換される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AbstractString.php | `src/Symfony/Component/String/AbstractString.php` | 基底クラス、\Stringable、\JsonSerializable実装、PREG定数群 |
| 1-2 | AbstractUnicodeString.php | `src/Symfony/Component/String/AbstractUnicodeString.php` | Unicode文字列の共通基底(CodePointStringとUnicodeStringの親) |
| 1-3 | TruncateMode.php | `src/Symfony/Component/String/TruncateMode.php` | 切り詰めモードのEnum定義 |

**読解のコツ**: AbstractStringの `$string` プロパティ(42行目)が実際の文字列値を保持し、`$ignoreCase`(43行目)が大文字小文字無視フラグ。全操作メソッドは `clone $this` でイミュータブル性を実現。

#### Step 2: 各文字列実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ByteString.php | `src/Symfony/Component/String/ByteString.php` | バイト単位の文字列操作、fromRandom()のCSPRNG実装 |
| 2-2 | UnicodeString.php | `src/Symfony/Component/String/UnicodeString.php` | 書記素クラスタ単位操作、NFC正規化、\X正規表現パターン |
| 2-3 | CodePointString.php | `src/Symfony/Component/String/CodePointString.php` | コードポイント単位操作、mb_string関数の利用 |
| 2-4 | LazyString.php | `src/Symfony/Component/String/LazyString.php` | 遅延評価文字列、__toString()時に初めて値を計算 |

**主要処理フロー**:
- **ByteString.php 46-60行目**: fromRandom() - Randomizerを使用した暗号安全ランダム生成
- **UnicodeString.php 35-46行目**: コンストラクタ - normalizer_is_normalized()チェックとnormalizer_normalize()

#### Step 3: スラッガーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SluggerInterface.php | `src/Symfony/Component/String/Slugger/SluggerInterface.php` | スラッガーインターフェース定義 |
| 3-2 | AsciiSlugger.php | `src/Symfony/Component/String/Slugger/AsciiSlugger.php` | URLスラッグ生成、Transliterator利用、ロケール対応音訳 |

#### Step 4: インフレクターを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Inflector/ | `src/Symfony/Component/String/Inflector/` | 単数形/複数形変換ルール |

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

```
AbstractString (基底)
    |
    +-- ByteString (バイト単位操作)
    |       +-- fromRandom() -> Randomizer::getBytesFromString()
    |
    +-- AbstractUnicodeString
            |
            +-- CodePointString (コードポイント単位)
            |       +-- mb_*関数
            |
            +-- UnicodeString (書記素クラスタ単位)
                    +-- normalizer_normalize() [NFC]
                    +-- grapheme_*関数 / \X正規表現

AsciiSlugger::slug($string)
    +-- Transliterator::transliterate() (音訳)
    +-- Unicode正規化・アクセント除去
    +-- preg_replace (ASCII以外除去)
```

### データフロー図

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

文字列 ──────────────────> new UnicodeString($str)     UnicodeString
                            |                           (NFC正規化済み)
                            v
                    normalizer_normalize()
                            |
                            v
                    チェーン操作 (lower, trim, etc.)
                            |
                            v
                    __toString() ──────────────> string
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractString.php | `src/Symfony/Component/String/AbstractString.php` | ソース | 文字列操作の抽象基底クラス |
| AbstractUnicodeString.php | `src/Symfony/Component/String/AbstractUnicodeString.php` | ソース | Unicode文字列の共通基底 |
| ByteString.php | `src/Symfony/Component/String/ByteString.php` | ソース | バイト単位文字列クラス |
| CodePointString.php | `src/Symfony/Component/String/CodePointString.php` | ソース | コードポイント単位文字列クラス |
| UnicodeString.php | `src/Symfony/Component/String/UnicodeString.php` | ソース | 書記素クラスタ単位文字列クラス |
| LazyString.php | `src/Symfony/Component/String/LazyString.php` | ソース | 遅延評価文字列 |
| TruncateMode.php | `src/Symfony/Component/String/TruncateMode.php` | ソース | 切り詰めモードEnum |
| AsciiSlugger.php | `src/Symfony/Component/String/Slugger/AsciiSlugger.php` | ソース | URLスラッグ生成器 |
| SluggerInterface.php | `src/Symfony/Component/String/Slugger/SluggerInterface.php` | ソース | スラッガーインターフェース |
