> ## 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。

它本身只要求 `all()` 与 `data()` 两个抽象方法，将实际数据获取逻辑委托给各个类。作为补偿，它统一提供了以下高频方法：

* 存在性判断：`has()`、`hasAny()`、`exists()`、`missing()`
* 空值判断：`filled()`、`isNotFilled()`、`anyFilled()`
* 条件执行：`whenHas()`、`whenFilled()`、`whenMissing()`
* 抽取：`only()`、`except()`
* 类型转换：`string()`、`boolean()`、`integer()`、`float()`、`date()`、`enum()`、`collect()`

## 与 Request 系方法的关系

`request()` 辅助函数所取得的 `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 核心中的主要实现示例

### 直接 use `InteractsWithData` 的类

| 类                                             | 用途                              |
| --------------------------------------------- | ------------------------------- |
| `Illuminate\Http\Concerns\InteractsWithInput` | `Request` 的输入访问 API             |
| `Illuminate\Support\ValidatedInput`           | `validated()` / `safe()` 的返回值包装 |
| `Illuminate\Support\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 客户端的 Option Bag
* Webhook payload 的规范化层
* 包配置覆盖解析类

只要实现 `all()` 与 `data()`，就无需每次自造输入访问 API，可显著降低维护成本。

## 相关页面

* [Macroable trait](/zh/advanced/macroable)
* [Conditionable trait](/zh/advanced/conditionable)
* [tap() 辅助函数与 Tappable trait](/zh/advanced/tap)


## Related topics

- [SessionEvent](/zh/packages/laravel-copilot-sdk/session-event.md)
- [InteractsWithTime trait](/zh/advanced/interacts-with-time.md)
- [Fluent 类](/zh/advanced/fluent.md)
- [广播](/zh/broadcasting.md)
- [PHP 属性](/zh/advanced/php-attributes.md)
