跳转到主要内容

什么是高阶消息

高阶消息(Higher-order Messages)是以属性访问形式调用集合方法的语法。无需编写回调即可对每个元素调用方法或取属性。
$users->map->name 表示「取出每个用户的 name 属性并进行 map」。

机制 — HigherOrderCollectionProxy

当以属性方式访问 $collection->map 时,会触发 EnumeratesValues trait 的 __get()
若该键在 $proxies 列表中,则返回一个 HigherOrderCollectionProxy 实例。这个代理会同时持有集合与方法名。

通过 __get 代理属性访问

继续访问属性(->name)时,会调用代理的 __get()
因此 $users->map->name 等价于:

通过 __call 代理方法调用

如果继续调用方法(->activate()),会触发代理的 __call()
$users->each->activate() 等价于:

支持的方法一览

可作为高阶消息使用的方法在 $proxies 数组中定义。
要新增自定义方法,使用 Collection::proxy()

实战用例

Eloquent 模型集合

高阶消息在 Eloquent 集合中尤其方便。

过滤

聚合

分组与排序

flatMap 展平嵌套

条件判定

字符串集合

值为字符串的集合也可以使用。代理的 __call() 在字符串时以静态方法方式调用。
字符串集合的高阶消息要求方法在字符串类型上是静态定义的。通常在 Eloquent 模型或自定义类的集合中使用更自然。

与常规闭包的对比

高阶消息简洁,但并不适用于所有场景。
「从每个元素取相同属性」「对每个元素调用相同方法」时,高阶消息可读性更佳。条件复杂或参数需要动态传入时,请使用闭包。

在自定义类中使用高阶消息

若希望通过 EnumeratesValues trait 使用 HigherOrderCollectionProxy 机制,可以调用 Collection::proxy() 将方法加入代理列表。

下一步

Conditionable trait

学习 when() / unless() 的内部实现,以及在 QueryBuilder 与自定义类中的应用方法。
最后修改于 2026年7月18日