应使用 $request->exists('tags') && is_array($tags = $request->get('tags')) && !empty($tags) 判断 GET 数组参数是否非空,因 Laravel 对未传参数返回 null、对空数组返回 [],语义不同,需区分处理。

直接用 empty() 或 isset() 判断 GET 传来的数组参数是否为空,大概率会出错——因为 Laravel 的 $request->get('xxx') 即使没传值,也默认返回 null,而一旦你传了空数组(如 ?tags=[]),它又会返回一个空数组 [],两者行为不一致,不能一招通吃。
GET 参数是数组但未提交时返回 null
Laravel 默认把未出现的查询参数当作 null 处理。比如请求 /search?name=abc,$request->get('tags') 就是 null,不是空数组。
- 别写
if (empty($request->get('tags')))——它对null和[]都返回true,但语义不同:一个是“用户根本没填”,一个是“用户明确填了个空数组” - 想区分这两种情况,得先判断是否为
array类型:is_array($request->get('tags')) - 如果确定是数组,再用
count($tags) === 0或!$tags(注意:PHP 中空数组是 falsy,但显式写count()更直白)
GET 参数带 [] 后缀被解析成数组但可能为空
当 URL 是 /search?tags[]&colors[]=red 或 /search?tags=[],Laravel 会把 tags 解析为数组,但内容可能是 [null]、[] 或 [''],取决于客户端怎么发。
-
$request->get('tags')在?tags[]场景下返回[null],count()是 1,不是空 - 若前端发的是 JSON 格式字符串如
?tags=[](即[]URL 编码),$request->get('tags')返回字符串"[]",需手动json_decode() - 稳妥做法:先
$tags = $request->get('tags', [])设默认值,再判断is_array($tags) && count($tags) > 0
用 request()->filled() 和 request()->exists() 区分语义
filled() 和 exists() 是 Laravel 提供的语义化方法,比手写判断更可靠。
-
$request->exists('tags')→ 只要 URL 里出现了tags这个 key,不管值是null、''还是[],都返回true -
$request->filled('tags')→ 要求 key 存在且值不为null、''、0、"0"、false、[](注意:它把空数组也当成“未填充”) - 真正要校验“用户传了非空数组”,推荐组合:
$request->exists('tags') && is_array($tags = $request->get('tags')) && !empty($tags)
验证规则里用 array|required|array.*.required 更准
如果走 Form Request 验证,别只依赖 PHP 层判断,交给 Validator 更稳。
-
'tags' => 'required|array':确保必须传且是数组类型(拒绝string或null) -
'tags.*' => 'required|string|min:1':确保每个元素非空字符串(过滤掉null或''元素) - 注意:
array规则本身不拒绝空数组[];要排除它,加自定义规则或用size:1/min:1(后者对数组表示最少 1 个元素)
最易被忽略的一点:前端 JavaScript 拼接 URL 时,tags=[] 和 tags 不带等号,后端收到的完全不是一回事;调试时务必 dd($request->all()) 看原始结构,而不是凭感觉猜。


















