
别把 Collection 当数组用,它不支持 $col[0]
Collection 是对象,不是数组封装;直接用下标访问会报错,比如 $users[0] 或 isset($col['name']) 都会失败。这是新手最常撞墙的地方。
- 取首项必须用
first(),末项用last(),空时默认返回null(可传默认值) - 判断是否存在某键?别用
array_key_exists,改用containsStrict('key', $value)或has('key')(后者只检查顶层键) - 想遍历并修改原集合?别在
foreach里改$item—— Collection 的元素是值传递,原集合不会变
filter()、where()、reject() 到底该选谁
三者语义和性能不同,混用容易逻辑翻车或漏匹配。
-
filter():任意逻辑,比如filter(fn($u) => $u['score'] > 80 && $u['active']),适合复杂条件 -
where():快捷字段匹配,支持操作符('age', '>=', 18)、点号路径('profile.phone')、松散比较;但where('score', null)会同时匹配null和0,要严格判空请用whereNull('score') -
reject():不是filter()的语法糖,它是独立优化过的反向过滤,语义清晰且少一次回调调用 —— 别写filter(fn($x) => !$x['active']),直接用reject('active', false)
map() 和 transform():改原集合还是生成新集合
Collection 默认不可变,绝大多数方法(包括 map、filter、sortBy)都返回新实例。只有少数明确设计为“就地修改”的方法才动原数据。
-
map():安全、推荐,返回新集合,原集合完全不受影响 -
transform():直接改当前实例,返回$this;仅当你确定后续不再需要原始数据,且想复用变量名时才用,比如批量格式化请求参数后直接提交 - 误用风险:链式调用中中途赋值给变量,比如
$active = $users->where('active', true); $active->transform(...);,这不会影响$users,但如果你以为它会影响,就会出逻辑 bug
合并多个集合并按 key 聚合求和,别用 merge()
merge() 是键覆盖或追加,不聚合;union() 去重但不累加。要实现“同 name 合并 score”,得走三步流水线:
- 先用
concat()把所有集合堆成一个($all = $a->concat($b)->concat($c)) - 再用
groupBy('name')分组,得到以name为键的子集合 - 最后
map()每个分组:用sum('score')累加,并构造新结构,例如map(fn($group) => ['name' => $group->first()['name'], 'score' => $group->sum('score')])
这个模式在处理多来源报表、订单汇总、权限合并等场景里反复出现,记牢这三步比背十个方法更实用。










