Laravel中request()->get()可直接获取嵌套数组参数,前提是前端按user[name]、tags[0]等格式传值或发送JSON且设置Content-Type: application/json;否则需json_decode处理字符串。

用 request()->get() 拿数组参数最直接
Laravel 的 request() 对象默认就支持嵌套数组解析,只要前端传的是合法的数组格式(比如 user[name]、tags[0]、meta[config][timeout]),后端不用额外配置就能取到结构化数组。
常见错误是前端用 JSON 字符串传数组但没设 Content-Type: application/json,结果 Laravel 当普通表单解析,request()->get('data') 拿到的是字符串而非数组——这时候得先 json_decode(request()->get('data'), true)。
- 表单提交或 URL 查询参数中带方括号(如
?filters[status]=active&filters[type]=admin)→request()->get('filters')直接返回['status' => 'active', 'type' => 'admin'] - AJAX 发送 JSON:
fetch('/api/users', { body: JSON.stringify({ ids: [1,2,3] }) }),且 header 设了Content-Type: application/json→request()->get('ids')就是 PHP 数组[1,2,3] - 如果没设 JSON header,即使 body 是 JSON,Laravel 也会当 raw string 处理,
request()->get('ids')返回的是字符串"[1,2,3]"
request()->validate() 验证数组字段要写点语法糖
验证数组参数时,规则写法和普通字段不同:不能只写 'items' => 'required|array' 就完事,得明确子项规则,否则验证会跳过内部元素。
比如想验证 items 是数组,且每个元素是整数、大于 0:
request()->validate([
'items' => 'required|array',
'items.*' => 'required|integer|min:1',
]);
注意 items.* 这个通配写法,它告诉 Validator 对数组每一项单独应用规则。漏掉 .*,哪怕数据里有非法值(比如 items[0] = "abc"),验证也会通过。
-
'tags.*.name'适用于二维数组,如tags[0][name] - 如果数组键名固定(如
profile[first_name]、profile[last_name]),可写成'profile.first_name' => 'required|string' -
array规则本身不递归验证内容,必须配合.*或具体路径才能校验子项
批量赋值(fill() / create())时数组字段容易被忽略
模型的 $fillable 只控制字段是否允许批量赋值,不控制结构。如果数据库字段是 JSON 类型(如 MySQL 的 JSON 列或 PostgreSQL 的 jsonb),你得确保传进去的是 PHP 数组,而不是字符串。
典型翻车场景:前端传 settings={"theme":"dark"}(字符串),模型里 $fillable = ['settings'],结果数据库存进去的是字符串,不是可查询的 JSON。
- 手动处理:在控制器里先
$data['settings'] = json_decode($request->settings, true) ?: [];再Model::create($data) - 用 cast:在模型里加
protected $casts = ['settings' => 'array'];,Laravel 会自动把入库前的数组转 JSON、查出后转回数组 - 别依赖
request()->all()直接扔进create(),尤其是含 JSON 字段时,先检查类型
调试时用 request()->all() 看不清结构?换 dd(request()->toArray())
request()->all() 在遇到深层嵌套或 JSON 输入时,有时会显示为 Illuminate\Http\ParameterBag 对象,看不出真实结构;而 request()->toArray() 强制展开所有层级,更接近最终可用的数据形态。
另一个坑是:如果你在中间件或全局作用域里提前调用了 request()->json(),再调 request()->all() 可能拿不到表单数据——因为 Laravel 的 request 实例对不同输入源(form、json、query)做了互斥缓存,读过一次 json 后,不会再尝试解析 form。
- 调试首选:
dd(request()->toArray())或dump(request()->all())+ 点开对象看parameters属性 - 避免混用:
request()->json()和request()->post()不要交替调,选一个主入口统一处理 - API 开发建议:统一要求前端发 JSON,并在内核里用
protected $middleware = [\App\Http\Middleware\ConvertJsonToForm::class];统一转格式(如有必要)
dd(request()->toArray()),比查文档更快定位问题。


















