如何将含动态字段的HTML表单转换为指定嵌套JSON格式?
解决方案
一、先修正表单字段命名(最省心的方案)
原来的命名方式items_${itms++}xdescription会让每个字段的索引独立,没法直接分组。改成数组式命名,同一组的字段共享同一个索引,不管JS还是PHP处理都能直接得到结构化数据:
修改PHP动态表单代码:
<?php $itemIndex = 0; ?> <?php foreach($i->items as $item) : ?> <tr> <td class="col-md-6"> <div> <input class="form-control" type="text" value="<?php echo $item->description; ?>" name="items[<?php echo $itemIndex; ?>][description]"> </div> </td> <td class="col-md-1"> <div> <input class="form-control" type="text" value="<?php echo $item->quantity; ?>" name="items[<?php echo $itemIndex; ?>][quantity]"> </div> </td> <td class="col-md-1"> <div> <input class="form-control" type="text" value="<?php echo $item->rate; ?>" name="items[<?php echo $itemIndex; ?>][rate]"> </div> </td> <td class="text-end col-md-1"> <div class=""> <input class="form-control" type="text" value="<?php echo "$". $item->amount ?>" name="items[<?php echo $itemIndex; ?>][amount]"> </div> </td> </tr> <?php $itemIndex++; ?> <?php endforeach; ?>
1. JavaScript处理(修正命名后)
直接解析序列化后的数组就行:
function convertFormToJSON() { const form = $('#editForm'); const formData = form.serializeArray(); const json = {}; $.each(formData, function() { // 匹配items[0][description]这种格式的字段名 const nameMatch = this.name.match(/(\w+)\[(\d+)\]\[(\w+)\]/); if (nameMatch) { const [, parentKey, itemIdx, fieldKey] = nameMatch; // 初始化数组和对象 if (!json[parentKey]) json[parentKey] = []; if (!json[parentKey][itemIdx]) json[parentKey][itemIdx] = {}; json[parentKey][itemIdx][fieldKey] = this.value || ''; } else { // 普通字段直接赋值 json[this.name] = this.value || ''; } }); console.log(json); return json; }
2. PHP处理(修正命名后)
提交到PHP后,$_POST直接就是结构化数据,转成JSON就行:
<?php // 获取所有表单数据 $formData = $_POST; // 去掉金额里的$符号(如果需要) if (!empty($formData['items'])) { foreach ($formData['items'] as &$item) { $item['amount'] = ltrim($item['amount'], '$'); } } // 转成格式化后的JSON输出 echo json_encode($formData, JSON_PRETTY_PRINT); ?>
二、不修改表单命名的兼容方案
如果不想改现有表单的命名,就只能通过解析items_Nxkey的格式来分组:
1. JavaScript版本
function convertFormToJSON() { const form = $('#editForm'); const formData = form.serializeArray(); const json = {}; const items = []; $.each(formData, function() { if (this.name.startsWith('items_')) { // 拆分字段名:items_0xdescription → ['items', '0', 'description'] const [prefix, indexPart, key] = this.name.split(/[_x]/); // 每组4个字段,索引除以4取整得到分组序号 const groupIdx = Math.floor(parseInt(indexPart) / 4); // 初始化分组对象 if (!items[groupIdx]) items[groupIdx] = {}; items[groupIdx][key] = this.value || ''; } else { json[this.name] = this.value || ''; } }); json['items'] = items; console.log(json); return json; }
2. PHP版本
<?php $formData = $_POST; $json = []; $items = []; foreach ($formData as $fieldName => $fieldValue) { if (str_starts_with($fieldName, 'items_')) { // 拆分字段名:items_0xdescription → ['items_0', 'description'] [$indexPrefix, $fieldKey] = explode('x', $fieldName); // 取出序号部分:items_0 → 0 $rawIndex = explode('_', $indexPrefix)[1]; // 每组4个字段,计算分组序号 $groupIdx = (int)floor($rawIndex / 4); // 处理金额的$符号 if ($fieldKey === 'amount') { $fieldValue = ltrim($fieldValue, '$'); } // 初始化分组对象 if (!isset($items[$groupIdx])) { $items[$groupIdx] = []; } $items[$groupIdx][$fieldKey] = $fieldValue; } else { $json[$fieldName] = $fieldValue; } } // 重置数组索引为连续数字 $json['items'] = array_values($items); // 输出格式化后的JSON echo json_encode($json, JSON_PRETTY_PRINT); ?>
内容的提问来源于stack exchange,提问作者Meselhy
相关产品推荐
相关产品推荐

