GET参数为空字符串时,request('field')返回''而非null,最易忽略;应使用filled()判断非空,避免where误查空值记录。

GET参数为空字符串时,request('field') 会返回 '' 而不是 null
这是最常被忽略的 PHP 类型陷阱:HTML 表单提交空 <select> 或清空的 <input>,后端收到的是 ''(空字符串),不是 null。而 request('status') 在值为 '' 时仍算“存在”,直接用于 where('status', request('status')) 就会查出所有 status = '' 的记录——这通常不是你想要的。
正确判断方式是用 request()->filled('status'),它只在参数存在且非空字符串、非零数字、非 false、非 null 时才返回 true。比 has() 更严格,比手动 !== '' 更安全。
-
request()->has('status')→ 只看参数是否存在(哪怕值是''或'0'都返回true) -
request()->filled('status')→ 排除''、0、'0'、false、null等 falsy 值 -
request()->present('status')→ 只排除null,保留''和0(极少用)
多条件动态查询别堆 when(),先判空再链式拼接
when() 看似简洁,但它的闭包执行依赖参数“truthy”,而 '0' 是 falsy —— 这会导致下拉选中 “No”(value="0")时条件被跳过。真实业务里,“0” 往往是合法值(比如启用/禁用开关),不能被 when() 误杀。
更可控的做法是显式判断并拼条件:
$query = Post::query();
if (request()->filled('status')) {
$query->where('status', request('status'));
}
if (request()->filled('category_id')) {
$query->where('category_id', request('category_id'));
}
$posts = $query->get();
- 每个
if独立判断,不相互干扰 - 支持
'0'、'1'这类字符串值,也兼容整数字段 - 避免
when(fn() => ..., fn() => ...)嵌套过深导致逻辑难读
表单提交空值时,value="" 必须对应后端 is_null(request()->input('x')) 判断
前端下拉菜单的 “All” 选项,推荐用 value=""(空字符串),而不是 value="all" 或 value="null"。这样后端可用统一逻辑处理:只有当参数值真正为 null(即没传)或 ''(显式提交空)时,才跳过该条件。
但注意:request()->input('featured') 提交 value="" 时返回 '',不是 null;只有参数完全未提交时才是 null。所以模板里判断选中状态得写成:
<option value="" {{ request()->input('featured') === '' ? 'selected' : '' }}>All</option>
- 别用
empty()或!request()->input('x'),它们会把'0'也当成空 - 前端保持
value="",后端用filled()或=== ''显式比对,语义清晰 - 如果必须区分“未提交”和“提交了空字符串”,就用
request()->has('x')+request('x') === ''组合判断
数据库字段为 TINYINT(1) 时,where('featured', '0') 和 where('featured', 0) 行为不同
MySQL 的 TINYINT(1) 实际是整数类型,但 Laravel 默认把 GET 参数当字符串处理。如果你写 where('featured', request('featured')),而用户提交的是 featured=0,那实际执行的是 WHERE featured = '0' —— MySQL 会隐式转换,但某些 strict mode 下可能报错或不匹配。
稳妥做法是显式 cast:
if (request()->filled('featured')) {
$query->where('featured', (int) request('featured'));
}
- 对布尔字段(
TINYINT(1)或BOOLEAN),强制转int再查,避免字符串比较歧义 - 对枚举或字符串字段(如
status VARCHAR),保持原样即可 - 别依赖 Laravel 自动类型推断,尤其在跨环境部署时,MySQL 配置差异会导致行为不一致
null、''、'0'),每种都得按业务语义单独处理。漏掉任意一种,线上就容易出现“点了 No 却查出全部数据”这类问题。


















