# 機能設計書 41-replace_every_ci

## 概要

本ドキュメントは、Hack Standard Library (HSL) の `Str\replace_every_ci` 関数の機能設計を記載する。この関数は文字列内の複数の検索パターンを対応する置換文字列で一括置換する機能を、大文字小文字を区別せずに提供する。

### 本機能の処理概要

**業務上の目的・背景**：テキスト処理において、複数のパターンを大文字小文字を区別せずに一括で置換する必要性は頻繁に発生する。ユーザー入力の正規化、テンプレート変数の置換、データクレンジングなど、多くの場面でこの機能が必要とされる。本機能は、これらの要件を効率的かつ型安全に実現するために提供されている。

**機能の利用シーン**：
- HTMLテンプレート内の変数を実際の値で置換する際、大文字小文字のバリエーションに対応
- ユーザー入力テキスト内の特定キーワードを統一的に置換
- ログデータ内の機密情報をマスキングする際、大文字小文字を問わず処理
- 多言語対応アプリケーションでの文字列変換処理

**主要な処理内容**：
1. 入力文字列（haystack）と検索/置換ペア（replacements）を受け取る
2. replacementsの各キーを大文字小文字を区別せずに検索
3. マッチした箇所を対応する値で置換
4. 置換は順序通りに適用され、置換後の新しい値も再度検索対象となる（再帰的）
5. 複数のオーバーラップするマッチがある場合、replacements内で先に定義されたものが優先される

**関連システム・外部連携**：HSL内部の `_Private\_Str\replace_every_ci_l` 関数に処理を委譲。ロケール対応版として `Str\replace_every_ci_l` も提供されている。

**権限による制御**：本機能は純粋関数であり、権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 画面なし | - | 本プロジェクト（Hack Standard Library）はUIを持たないライブラリプロジェクトのため、画面機能マッピングは該当しません。 |

## 機能種別

文字列変換処理（Transform）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $haystack | string | Yes | 検索/置換対象の文字列 | なし |
| $replacements | KeyedContainer<string, string> | Yes | 検索文字列をキー、置換文字列を値とするコンテナ | なし |

### 入力データソース

関数呼び出し時の引数として直接渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | string | 置換処理が適用された結果文字列 |

### 出力先

関数の戻り値として返却される。

## 処理フロー

### 処理シーケンス

```
1. 引数の受け取り
   └─ $haystack（対象文字列）と$replacements（置換ペア）を受け取る
2. 内部関数への委譲
   └─ KeyedContainerをdictに変換
3. _Str\replace_every_ci_lの呼び出し
   └─ ロケールなしで大文字小文字無視の置換を実行
4. 結果の返却
   └─ 置換後の文字列を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数を受け取る]
    B --> C[replacementsをdictに変換]
    C --> D[_Str\replace_every_ci_l呼び出し]
    D --> E[置換後の文字列を返却]
    E --> F[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | 大文字小文字無視 | 検索は大文字小文字を区別せずに行われる | 常時 |
| BR-41-02 | 再帰的置換 | 置換後の新しい値も後続の検索対象となる | 常時 |
| BR-41-03 | オーバーラップ時の優先順位 | 複数マッチがオーバーラップする場合、replacements内で先に定義されたものが優先 | オーバーラップ発生時 |
| BR-41-04 | 順序依存性 | dict['a'=>'b', 'b'=>'c']はdict['a'=>'c']と同等だが、dict['b'=>'c', 'a'=>'b']は異なる結果となる | 常時 |

### 計算ロジック

特になし（文字列のパターンマッチングと置換のみ）

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は通常エラーをスローしない | - |

### リトライ仕様

該当なし（同期的な純粋関数）

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

該当なし（データベース操作なし）

## パフォーマンス要件

- 時間計算量: O(n * m)、n = haystack長、m = replacementsのキー数の合計長
- 空間計算量: O(n)、結果文字列のサイズ

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

- 入力文字列のサニタイズは呼び出し側の責任
- 本関数自体は副作用を持たない純粋関数

## 備考

- ロケール対応が必要な場合は `Str\replace_every_ci_l` を使用すること
- 再帰的な置換が不要な場合は `Str\replace_every_nonrecursive_ci` を使用すること

---

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

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

### 推奨読解順序

#### Step 1: 公開API関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | transform.php | `src/str/transform.php` | 公開関数replace_every_ciの定義とドキュメンテーション |

**主要処理フロー**:
1. **244-249行目**: replace_every_ci関数の定義。KeyedContainerを受け取り、dictに変換して内部関数に委譲

**読解のコツ**: Hackの`KeyedContainer`型は`dict`や`Map`などの連想配列型の親インターフェース。`dict()`で明示的にdict型に変換している。

#### Step 2: ロケール対応版を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | transform_l.php | `src/str/transform_l.php` | ロケール対応版replace_every_ci_lの定義 |

**主要処理フロー**:
- **218-224行目**: ロケールを第一引数として受け取り、内部関数に渡す

#### Step 3: テストケースで挙動を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StrTransformTest.php | `tests/str/StrTransformTest.php` | replace_every_ciのテストケースを確認 |

**主要処理フロー**:
- **408-478行目**: provideReplaceEveryCIとtestReplaceEveryCIで様々な入力パターンと期待結果を確認可能

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

```
Str\replace_every_ci($haystack, $replacements)
    │
    └─ _Str\replace_every_ci_l($haystack, dict($replacements))
           │
           └─ [HHVM内部実装]
```

### データフロー図

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

$haystack (string) ─────┐
                        ├──▶ dict変換 ──▶ _Str\replace_every_ci_l ──▶ 置換後文字列
$replacements (dict) ───┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transform.php | `src/str/transform.php` | ソース | 公開API関数の定義 |
| transform_l.php | `src/str/transform_l.php` | ソース | ロケール対応版の定義 |
| StrTransformTest.php | `tests/str/StrTransformTest.php` | テスト | 単体テスト |
