$loop 变量仅在 blade 模板的 @foreach 中可用,是 blade 编译器注入的上下文变量,非 php 原生或 collection 自带;在控制器等非 blade 环境使用会报错 undefined variable: $loop。

直接用 foreach 遍历集合时,$loop 变量能用吗?
能,但仅限 Blade 模板里。Laravel 的 $loop 是 Blade 编译器注入的上下文变量,不是 PHP 原生或 Collection 自带的属性。
常见错误是以为在控制器或普通 PHP 文件里写 foreach ($collection as $item) { if ($loop->last) { ... } } 也能跑——这会报错 Undefined variable: $loop。
- 只在 Blade 中有效:@foreach 语法糖由 Blade 解析,自动注入
$loop -
$loop提供的属性如first、last、index、iteration都基于当前循环层级,嵌套时各自独立 - 如果在非 Blade 环境(比如命令行、API 控制器)需要判断首尾,得手动用
count()和索引比对,或转成数组后用array_key_first()/array_key_last()
chunk() 不是分页,别拿它替代 paginate()
chunk() 是内存内切块,不触碰数据库;paginate() 是 SQL 分页,带 offset/limit 和总数查询。两者解决的问题完全不同。
典型误用:用 $items->chunk(10) 渲染“第 2 页”,结果发现所有数据都已加载进内存,毫无性能优势,还浪费资源。
-
chunk()适合视图层布局控制(如多列网格)、批量处理小数据集(Collection -
paginate()必须配合 Eloquent 或 Query Builder 使用,底层执行SELECT COUNT(*)和带LIMIT/OFFSET的主查询 - 大数据量下,
chunk()+each()可避免内存溢出,但无法跳转任意页;真要分页,必须用paginate()或手写 cursor 分页
循环中修改另一个集合,不加 & 就等于白改
用 each() 或 map() 遍历一个集合,同时想从另一个集合里移除元素?默认传参是值传递,$tickets = $tickets->except($id) 这行代码只改了闭包内的副本。
现象是:每次循环都从原始未变的 $tickets 里随机选,导致重复分配、漏删、逻辑崩坏。
- 必须写
use (&$tickets),让引用穿透闭包作用域 - 注意
except()接收的是 key(不是 ID 字段值),确保你传的是集合的键名,比如$winner->getKey()而非$winner->id(除非 ID 正好是键) - 更安全的做法是用
filter()替代except():$tickets = $tickets->filter(fn($t) => $t->id !== $winner->id);,语义更清晰且不依赖键名
别在循环里反复调用 count() 或 pluck()
Collection 方法多数返回新实例,且部分操作(如 pluck()、count())会触发求值。在大集合循环中高频调用,性能损耗明显。
比如写 @foreach($users as $user) { $names = $users->pluck('name'); ... },每轮都重新提取全部 name,O(n²) 时间复杂度。
- 提前计算:把
$names = $users->pluck('name');放在循环外 - 慎用
count()判断空:Collection 有isEmpty()方法,不触发求值;count()在 LazyCollection 或带 where 的链式调用中可能强制执行整个管道 -
pluck('relation.name')深层点号取值失败时不报错,静默返回 null,建议先用map()+optional()显式处理缺失字段
filter()->map() 是惰性的,但中间插一句 dd() 就全求值了。这些细节不盯紧,调试时根本看不出哪步悄悄吃掉了内存或丢了数据。











