$loop 变量仅在 Blade 模板的 @foreach 中由编译器自动注入,控制器中纯 PHP 的 foreach 无此变量;嵌套时 $loop->parent 可访问外层循环状态,但仅支持一级;$loop->index 从 0 开始,$loop->iteration 从 1 开始;避免循环内高频调用 count() 或 pluck()。

$loop 变量只在 Blade 的 @foreach 里有效,控制器或普通 PHP 文件中直接用 foreach($items as $item) { $loop->last } 会报 Undefined variable: $loop
为什么 $loop 在控制器里用不了
Blade 编译器会在解析 @foreach 时自动注入 $loop 变量,它不是 PHP 原生、也不是 Collection 自带的属性。你在控制器里写 foreach ($users as $user),本质是纯 PHP 循环,没有 Blade 解析环节,自然没有 $loop。
- 报错示例:
Undefined variable: $loop或Trying to get property 'last' of non-object - 替代方案:用
count($users)+ 当前索引手动判断首尾,或改用array_key_first()/array_key_last()(PHP 7.3+) - 如果非要在逻辑层做类似判断,推荐把首尾标识提前算好传进视图,比如
'is_first' => true,别硬套$loop
嵌套循环中 $loop->parent 怎么用
当有两层 @foreach 嵌套时,内层的 $loop 有自己的 index、first 等,而 $loop->parent 指向外层循环的 $loop 实例,可读取外层状态。
- 典型场景:渲染课程表,外层是学生,内层是课程,想在每行开头显示学生名,且只显示一次——用
@if($loop->parent->first) - 注意:
$loop->parent是对象,不是数组;访问$loop->parent->index安全,但$loop->parent->undefined_prop仍会报错 - 深度超过 2 层时,
$loop->parent->parent不可用;Blade 只暴露一级父级,更深层需靠变量传递或重构结构
$loop->iteration 和 $loop->index 的区别别搞混
$loop->index 从 0 开始,$loop->iteration 从 1 开始——这俩常被误用,尤其在分页 offset 计算或 CSS nth-child 选择器里。
- 需要「第几个」语义(如“这是第 3 条记录”)→ 用
$loop->iteration - 需要数组下标或数据库 offset(如
skip=2对应第三条)→ 用$loop->index -
$loop->remaining=$loop->count - $loop->iteration,不是$loop->count - $loop->index - 在
@forelse中,$loop->empty为 true 时,$loop->count是 0,此时访问$loop->iteration会出错(没迭代发生),要先判空
别在循环里反复调用 count() 或 pluck()
Collection 的 count()、pluck() 等方法在大集合上高频调用会显著拖慢渲染速度,因为它们可能触发重求值或全量遍历。
- 错误写法:
@foreach($users as $user) <p>{{ $users->count() }} users total</p>→ 每次迭代都重新算总数 - 正确做法:提前计算并传参,如
'total_users' => $users->count(),或在视图顶部用@php $total = $users->count(); @endphp -
pluck()返回新 Collection,若只需一次取字段值,放在循环外;若需按当前 $user 动态取,用$user->name直接访问,别写$users->pluck('name')->toArray()[$loop->index]
真正容易被忽略的是:$loop 的所有属性都是运行时动态生成的,不缓存、不复用;嵌套层级一多,$loop->depth 超过 3 就该考虑拆分组件了——Blade 不是万能的循环引擎,复杂逻辑扔到服务类里更稳。


















