laravel没有“条件属性”概念,需用required_if等验证规则处理表单必填逻辑,或用select()+when()动态查询字段,二者不可混用。

直接说结论:Laravel 没有叫“条件属性”的内置概念,你真正需要的是 required_if、required_unless、required_with 这类条件验证规则,或在查询时用 select() + when() 动态拼字段 —— 两者解决的是完全不同的问题,别混用。
required_if 等规则用于表单验证,不是模型属性
很多人搜“条件属性”,其实是想让某个字段只在特定条件下才必填。这属于验证层逻辑,和 Eloquent 模型的属性无关。Laravel 的 required_if 规则就是干这个的:
- 它只在 Form Request 的
rules()方法里生效,不是模型上的 getter 或 attribute - 语法是
'field' => ['required_if:other_field,value'],注意 value 是字符串匹配(比如'1'、'true',不是布尔值true) - 若
other_field是复选框,HTML 提交的是字符串'on'或'1',后端接收后需统一处理,否则required_if:company,on才能命中 - 多个条件用
required_if:company,1|required_if:company,true不行 —— 应改用required_unless:company,0或自定义规则
select() + when() 用于动态指定返回字段
如果你实际想要的是“根据请求参数决定查哪些字段”,那得用查询构建器的 when() 方法,配合 select():
$query = User::query();
if ($request->has('minimal')) {
$query->select('id', 'name', 'email');
} else {
$query->select('*');
}
$users = $query->get();
更优雅写法(推荐):
$users = User::when($request->has('minimal'), function ($q) {
return $q->select('id', 'name', 'email');
})
->when(!$request->has('minimal'), function ($q) {
return $q->select('*');
})
->get();
-
when()是链式条件入口,避免 if 块污染查询逻辑 - 不要在
select('*')后再调addSelect()想“追加字段”——它会覆盖,不是合并 - 字段名必须真实存在,
select('name as display_name')可以,但结果中键名是display_name,不是name
别把验证规则和 API 响应结构搞混
有人试图用 required_if 控制 JSON 返回里是否包含某个字段,这是错的。验证规则只管入参,不管出参。要控制输出字段,该用:
- Eloquent 的
$hidden/$visible属性(静态控制) - API Resource 的
toArray()方法里加条件判断(动态控制) - 不要在控制器里手动
unset()数组字段 —— 容易漏、难测试、不复用
比如 carrier 字段只在 $user->company == true 时返回,就在 UserResource 里写:
public function toArray(Request $request): array
{
$arr = [
'id' => $this->id,
'name' => $this->name,
];
if ($this->company) {
$arr['carrier'] = new CarrierResource($this->whenLoaded('carrier'));
}
return $arr;
}
最常被忽略的一点:条件验证的字段值类型必须和表单提交一致。required_if:company,1 对不上 <input type="checkbox" name="company" value="true">,这种 mismatch 会导致规则静默失效,连错误都不报。











