Laravel 查询返回的“空”是空 Collection 实例而非 null 或空数组,故不能用 empty()、isset() 或 == null 判空,必须用 isEmpty()、isNotEmpty()、first() 或 exists() 等专用方法。

直接说结论:Laravel 查询返回的“空”不是 PHP 的 null 或空数组,而是一个非空的 Collection 实例,所以不能用 empty()、isset() 或 == null 判空——必须用 Eloquent/Query Builder 提供的专用方法。
为什么 empty($users) 总是 false?
Laravel 的 get() 永远返回 Illuminate\Support\Collection 对象,哪怕数据库一条记录没查到,它也是 Collection 实例(内部 items 是空数组)。PHP 的 empty() 对对象永远返回 false,这是根本原因。
-
$users = User::where('id', 999)->get();→ 返回Collection,empty($users)为false -
$user = User::where('id', 999)->first();→ 返回null,empty($user)才为true - 别对
Collection做== []或=== [],类型不匹配,结果不可靠
first() 和 get() 的判空逻辑完全不同
选哪个方法,取决于你预期的结果数量:
- 查单条(如根据 ID、邮箱、唯一字段)→ 用
first():返回模型实例或null,可直接if ($user) { ... } - 查多条(如列表页、带条件的批量查询)→ 用
get(),然后调用->isEmpty()或->isNotEmpty() - 只关心是否存在(不取数据)→ 用
exists(),性能更好:User::where('email', $email)->exists() - 需要总数 → 用
count(),但注意它会执行SELECT COUNT(*),比exists()重
视图里传 Collection 后怎么安全遍历?
Blade 中不能写 @if ($users),因为 $users 是对象,恒为 true:
- ✅ 正确:
@if ($users->isNotEmpty()) @foreach($users as $u) ... @endforeach @endif - ✅ 更简洁:
@forelse($users as $u) ... @empty @endforelse(@empty分支在Collection为空时触发) - ❌ 错误:
@if ($users) @foreach(...) ... @endif—— 永远进循环体 - ⚠️ 注意:
$users->count() > 0可用,但比isEmpty()多一次 count 查询(除非已缓存)
容易被忽略的边界:软删除 + 空结果
如果模型启用了软删除(SoftDeletes),get() 和 first() 默认不会返回已删除的记录——这本身没问题。但要注意:
-
withTrashed()或onlyTrashed()会改变结果集,判空逻辑不变,但数据来源变了 - 调试时用
dd(User::withTrashed()->where(...)->get())看真实结果,别只信业务逻辑预期 - 数据库里真没数据、查询条件写错、字段名拼错(比如
user_id写成userid)、大小写敏感(MySQL 表名/字段名在某些配置下区分大小写)——这些才是“空”的真正源头,判空方法只是帮你发现它,不是根因


















