Laravel/PHP中如何将表单提交的数组按成员分组重组?
实现Laravel表单提交后家庭成员数据重组
问题背景
通过循环生成的家庭成员收集表单提交后,Laravel控制器接收到的是按字段(如fname、lname)分组的数组,需要将其重组为以每个家庭成员为独立对象的结构化数组。
表单代码
// Family Members form //this family form will add 3 more times as the total member in this fmaily are 4 who are still living @for($i=1;$i<= $totalMembs;$i++) <input type="hidden" name="id[]" value="{{$i}}" > <input type="text" name="fname[]" value="" > <input type="text" name="lname[]" value="" > <input type="date" name="dob[]" value="" > <input type="radio" name="gender[{{$i}}]" id="genderM" value="male" > <input type="radio" name="gender[{{$i}}]" id="genderF" value="female"> <select name="nationality[]" id="nationality{{$i}}"> <option value="">Please select</option> <option value="India">Indian</option> <option value="USA">USA</option> <option value="UK">UK</option> <option value="AUS">AUS</option> </select> <input type="text" name="birthPlace[]" value=""> <select name="state[]" id="state{{$i}}"> <option value="">Please select</option> <option value="MH">Maharashtra</option> <option value="GJ">Gujrat</option> <option value="DL">Delhi</option> <option value="MP">Madya Pradesh</option> </select> <select name="device[]" id="device{{$i}}"> <option value="">Please select</option> <option value="Mobile">Mobile</option> <option value="Landline">Landline</option> </select> <input type="text" name="countryCallingCode[]" value="+91"> <input type="text" name="telnumber[]" value=""> <input type="email" name="email[]" value=""> @endfor
当前控制器接收的数据格式
{ "_token": "8p8hu86Oi4FMZnak0si3wK629dDejyB07abxJIpJ", "fname": [ "Kunal", "Manisha", "Vinay", "Rishi" ], "lname": [ "Parekh", "Sevani", "Parekh", "Parekh" ], "email": [ "kunal@gmail.com", "manisha@icloud.com", "vinay@gmail.com", "rishi@icloud.com" ], "state": [ "MH", "MH", "MH", "MH" ], "countryCallingCode": [ "+91", "+91", "+91", "+91" ], "telnumber": [ "0439378608", "0778777767", "0790123223", "048293023" ], "dob": [ "1981-10-18", "1976-11-17", "2009-04-12", "2004-07-03" ], "birthPlace": [ "Mumbai", "Mumbai", "Mumbai", "Rajkot" ], "gender": { "1": "male", "2": "female", "3": "male", "4": "male" }, "nationality": [ "Indian", "Indian", "Indian", "Indian" ], "device": [ "Mobile", "Mobile", "Mobile", "Mobile" ], "id": [1,2,3,4] }
期望的结构化数据格式
{ "family": [ { "id": 1, "dateOfBirth": "1981-10-18", "gender": "male", "name": { "firstName": "Kunal", "lastName": "Parekh" }, "currentplace": { "nationality": "INDIAN", "birthPlace": "Mumbai" }, "contact": { "state": "MH", "phones": { "deviceType": "MOBILE", "countryCallingCode": "+91", "number": "0439378608" }, "emailAddress": "kunal@gmail.com" } }, { "id": 2, "dateOfBirth": "1976-11-17", "gender": "female", "name": { "firstName": "Manisha", "lastName": "Sevani" }, "currentplace": { "nationality": "INDIAN", "birthPlace": "Mumbai" }, "contact": { "state": "MH", "phones": { "deviceType": "MOBILE", "countryCallingCode": "+91", "number": "0778777767" }, "emailAddress": "manisha@icloud.com" } }, { "id": 3, "dateOfBirth": "2009-04-12", "gender": "male", "name": { "firstName": "Vinay", "lastName": "Parekh" }, "currentplace": { "nationality": "INDIAN", "birthPlace": "Mumbai" }, "contact": { "state": "MH", "phones": { "deviceType": "MOBILE", "countryCallingCode": "+91", "number": "0790123223" }, "emailAddress": "vinay@gmail.com" } }, { "id": 4, "dateOfBirth": "2004-07-03", "gender": "male", "name": { "firstName": "Rishi", "lastName": "Parekh" }, "currentplace": { "nationality": "INDIAN", "birthPlace": "Rajkot" }, "contact": { "state": "MH", "phones": { "deviceType": "MOBILE", "countryCallingCode": "+91", "number": "048293023" }, "emailAddress": "rishi@icloud.com" } } ] }
实现方法
在Laravel控制器中,通过遍历成员数量,将对应索引的字段值组合成单个成员对象,最终整理成结构化数组:
public function store(Request $request) { // 获取提交的表单数据,排除_token $data = $request->except('_token'); // 获取家庭成员总数(以id数组长度为准) $totalMembers = count($data['id']); $family = []; for ($i = 0; $i < $totalMembers; $i++) { // 获取当前成员的id(注意表单中id是从1开始,数组索引从0开始) $memberId = $data['id'][$i]; $family[] = [ 'id' => $memberId, 'dateOfBirth' => $data['dob'][$i], 'gender' => $data['gender'][$memberId], // 因为gender是按id作为键的关联数组 'name' => [ 'firstName' => $data['fname'][$i], 'lastName' => $data['lname'][$i] ], 'currentplace' => [ 'nationality' => strtoupper($data['nationality'][$i]), 'birthPlace' => $data['birthPlace'][$i] ], 'contact' => [ 'state' => $data['state'][$i], 'phones' => [ 'deviceType' => strtoupper($data['device'][$i]), 'countryCallingCode' => $data['countryCallingCode'][$i], 'number' => $data['telnumber'][$i] ], 'emailAddress' => $data['email'][$i] ] ]; } // 最终的结构化数据 $structuredData = ['family' => $family]; // 后续可以将数据存入数据库或返回响应 // return response()->json($structuredData); return $structuredData; }
关键说明
- 遍历次数以
id数组的长度为准,确保覆盖所有家庭成员 - 性别字段
gender是关联数组,键为成员的id,所以通过$memberId直接取值 - 使用
strtoupper()将nationality和deviceType转为大写,匹配期望输出格式 - 排除
_token字段,只处理业务相关数据
内容的提问来源于stack exchange,提问作者Kunal Parekh
相关产品推荐
相关产品推荐

