跳转到主要内容

什么是 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 提供:
$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()
$legacy = request()->get('search');  // 兼容用方法(推荐使用 input())

Laravel 核心中的主要实现示例

直接 use InteractsWithData 的类

用途
Illuminate\Http\Concerns\InteractsWithInputRequest 的输入访问 API
Illuminate\Support\ValidatedInputvalidated() / safe() 的返回值包装
Illuminate\Support\Fluent配置或任意属性的流畅操作
Illuminate\Support\UriQueryStringUri 的查询字符串操作
Illuminate\View\ComponentAttributeBagBlade 组件属性的操作

承担相近职责的相关实现

  • Illuminate\Session\Store 独立实现了 has()get()only()except() 等类似 API
  • Illuminate\Validation\Concerns\ValidatesAttributes 提供验证判定逻辑,输入访问 API 本身与 InteractsWithData 是不同职责

trait 与主要类的关系

在包开发中集成到自定义类

InteractsWithData 适合在包内部「持有输入数组,并想要提供 Laravel 风格获取 API」的类。
1

创建数据容器类

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);
    }
}
2

用类型化访问器安全读取

$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

实战用例

  • 外部 API 客户端的 Option Bag
  • Webhook payload 的规范化层
  • 包配置覆盖解析类
只要实现 all()data(),就无需每次自造输入访问 API,可显著降低维护成本。

相关页面

最后修改于 2026年7月13日