> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# InteractsWithData trait

> 說明 Illuminate\Support\Traits\InteractsWithData 的設計，以及在套件開發中為自訂類別實作資料存取 API 的方法。

## 什麼是 InteractsWithData trait

`Illuminate\Support\Traits\InteractsWithData` 是彙整了「對於類陣列輸入資料的共通 API」的 trait。

此 trait 本身僅要求 `all()` 與 `data()` 兩個抽象方法，將實際資料的取得邏輯委派給各類別。取而代之，其提供如下的高頻使用方法。

* 存在判定：`has()`, `hasAny()`, `exists()`, `missing()`
* 空判定：`filled()`, `isNotFilled()`, `anyFilled()`
* 條件執行：`whenHas()`, `whenFilled()`, `whenMissing()`
* 擷取：`only()`, `except()`
* 型別轉換：`string()`, `boolean()`, `integer()`, `float()`, `date()`, `enum()`, `collect()`

## 與 Request 系方法的關係

以 `request()` helper 取得的 `Illuminate\Http\Request`，透過 `Concerns\InteractsWithInput` 引入 `InteractsWithData`。

因此下列日常的輸入存取都經由 trait 提供。

```php theme={null}
$search = request()->input('search');

if (request()->has('search')) {
    $filters = request()->only(['search', 'status']);
}

$payload = request()->except(['_token']);
```

`Request::get()` 是位於 `Request` 類別本體的 Symfony 相容方法。於 Laravel 13 的原始碼上也明確標示 `@deprecated use ->input() instead`，建議使用 `input()`。

```php theme={null}
$legacy = request()->get('search');  // 相容用途方法（推薦 input()）
```

## Laravel Core 的主要實作範例

### 直接 use `InteractsWithData` 的類別

| 類別                                            | 用途                                    |
| --------------------------------------------- | ------------------------------------- |
| `Illuminate\Http\Concerns\InteractsWithInput` | `Request` 的輸入存取 API                   |
| `Illuminate\Support\ValidatedInput`           | `validated()` / `safe()` 回傳值的 wrapper |
| `Illuminate\Support\Fluent`                   | 設定值或任意屬性的 fluent 操作                   |
| `Illuminate\Support\UriQueryString`           | `Uri` 的查詢字串操作                         |
| `Illuminate\View\ComponentAttributeBag`       | Blade 元件屬性的操作                         |

### 具相近職責的相關實作

* `Illuminate\Session\Store` 自行實作了 `has()`, `get()`, `only()`, `except()` 等相近 API
* `Illuminate\Validation\Concerns\ValidatesAttributes` 提供驗證判斷邏輯，輸入存取 API 本身於設計上與 `InteractsWithData` 分屬不同職責

## trait 與主要類別的關係

```mermaid theme={null}
flowchart TD
    IWD["InteractsWithData<br>共通資料存取 API"] --> IWI["InteractsWithInput<br>Request 用的 Concern trait"]
    IWI --> REQ["Request<br>input()/has()/only()/except()"]
    IWD --> VIN["ValidatedInput<br>safe()/validated()"]
    IWD --> FLU["Fluent"]
    IWD --> UQS["UriQueryString"]
    IWD --> CAB["ComponentAttributeBag"]
    REQ -.相似 API 模式.-> SES["Session Store<br>自行實作 has()/get()/only()/except()"]
    REQ -.相關領域（非直接相依）.-> VAL["ValidatesAttributes<br>驗證判斷邏輯"]
```

## 於套件開發中整合至自訂類別

`InteractsWithData` 適用於套件內「保持輸入陣列並提供 Laravel 風格取得 API」的類別。

<Steps>
  <Step title="建立資料容器類別">
    ```php theme={null}
    namespace Vendor\Package\Support;

    use Illuminate\Support\Arr;
    use Illuminate\Support\Traits\InteractsWithData;

    class OptionBag
    {
        use InteractsWithData;

        /**
         * @param  array<string, mixed>  $items
         */
        public function __construct(
            protected array $items = [],
        ) {}

        public function all($keys = null): array
        {
            if (! $keys) {
                return $this->items;
            }

            $result = [];

            $keyList = is_array($keys) ? $keys : [$keys];

            foreach ($keyList as $key) {
                Arr::set($result, $key, Arr::get($this->items, $key));
            }

            return $result;
        }

        protected function data($key = null, $default = null): mixed
        {
            return data_get($this->items, $key, $default);
        }
    }
    ```
  </Step>

  <Step title="以型別化的存取子安全讀取">
    ```php theme={null}
    $options = new OptionBag([
        'feature.enabled' => 'true',
        'retry.max' => '5',
        'channels' => ['mail', 'slack'],
    ]);

    $enabled = $options->boolean('feature.enabled'); // true
    $retryMax = $options->integer('retry.max');      // 5
    $channels = $options->collect('channels');       // Collection
    $public = $options->except(['secret']);          // 排除 secret
    ```
  </Step>
</Steps>

## 實務使用情境

* 外部 API Client 的選項 bag
* Webhook payload 的正規化層
* 套件的設定 override 解析類別

只要實作 `all()` 與 `data()`，就無需每次自行撰寫輸入存取 API，可降低維護成本。

## 相關頁面

* [Macroable trait](/zh-TW/advanced/macroable)
* [Conditionable trait](/zh-TW/advanced/conditionable)
* [tap() helper 與 Tappable trait](/zh-TW/advanced/tap)


## Related topics

- [SessionEvent](/zh-TW/packages/laravel-copilot-sdk/session-event.md)
- [InteractsWithTime trait](/zh-TW/advanced/interacts-with-time.md)
- [Fluent 類別](/zh-TW/advanced/fluent.md)
- [进阶主题](/zh-CN/advanced/index.md)
- [廣播](/zh-TW/broadcasting.md)
