如何修复foreach循环报错?动态表单数据无法插入第二张表
动态表单数据插入MySQL两张表失败问题
我用动态表单实现数据插入功能,需要把数据插入两张不同的MySQL表。目前第一张表tbl_family_profiling数据插入正常,但第二张表twofamilyprofiling_family_members插入失败,这张表的数据来自动态表单,我用foreach循环处理。
我通过echo输出SQL排查,得到的SQL语句如下:
INSERT INTO `tbl_family_profiling`(`family_number`, `date_of_interview`,`interviewer`, `interviewee`, `barangay`, `residence`, `length_of_residency`, `address`, `primarycare_provider`, `primarycare_provider_no`, `travel_time`, `mode_of_transportation`) VALUES ('020001911','2022-11-10','dwqdqd','Anna Biat',' sandiego', 'Male','','',' ',' ','',' ')
同时出现错误提示:
Warning: foreach() argument must be of type array|object, string given in C:\xampp\htdocs\HMO_Home\insert_familyprofiling.php on line 34
我的PHP代码
if(isset($_POST['submit'])){ $fserial = $_POST['familyserial']; $doi = $_POST['date_of_interview']; $intvwer = $_POST['interviewer']; $intvwee = $_POST['interviewee']; $barangay = $_POST['barangay']; $residence = $_POST['residence']; $lghtresidence = $_POST['residencylenght']; $address = $_POST['address']; $pcareprovider = $_POST['primarycareprovider']; $pcareno = $_POST['primarycareno']; $ttime = $_POST['traveltime']; $mode_transportation = $_POST['mode_of_transportation']; echo $sql = "INSERT INTO `tbl_family_profiling`(`family_number`, `date_of_interview`,`interviewer`, `interviewee`,`barangay`, `residence`, `length_of_residency`, `address`, `primarycare_provider`, primarycare_provider_no`, `travel_time`, mode_of_transportation`) VALUES ('$fserial','$doi','$intvwer','$intvwee',' $barangay','$residence','$lghtresidence','$address',' $pcareprovider',' $pcareno','$ttime','$mode_transportation')"; // $query = $con->query($sql) or die ($con->error); $student_id = $con->insert_id; foreach ($_POST['familymember'] as $key => $value) { echo $query1 = "INSERT INTO twofamilyprofiling_family_members(user_id,family_member,family_position,sex,birthday,marital_status,blood_type,disability,highest_education_attainment,occupation,contact_no, religion, nhip)VALUES ('" . $student_id . "','" . $_POST['familymember'][$key] . "','" . $_POST['familyposition'][$key] . "','" . $_POST['sex'][$key] . "','" . $_POST['birthday'][$key] . "','" . $_POST['maritalstatus'][$key] . "','" . $_POST['bloodtype'][$key] . "','" . $_POST['disability'][$key] . "','" . $_POST['educationalattainment'][$key] . "','" . $_POST['occupation'][$key] . "','" . $_POST['contactno'][$key] . "','" . $_POST['religion'][$key] . "','" . $_POST['nhip'][$key] . "')"; // $query = $con->query($query1) or die ($con->error); } }
前端动态表单代码
<h4 class="ITRtitle justify-content-center text-center shadow">I. Assesment of the Family, Home and Environmental Conditions</h4> <div id="dynamic_field"> <div class="FProfile row"> <div class="col-sm-2"> <label for="inputfamilymember" class="form-label">Family Member</label> <input type="text" class="form-control mt-4" name="familymember[]" id="inputfamilymember"> </div> <div class="col-sm-2" style="width: 10rem; margin-left: -20px;"> <label for="inputfamilyposition" class="form-label ">Family Position</label> <input type="text" style="width: 5rem;" class="form-control mt-4" name="familyposition[]" id="inputfamilyposition"> </div> <div class="col-sm-2" style="width: 5rem; margin-left: -50px;"> <label for="inputsex" class="form-label">Sex</label> <select id="inputsex" name="sex[]" class="form-select mt-4" style="width: 4rem;"> <option>F</option> <option>M</option> </select> </div> <div class="col-sm-2" style="width: 10rem; margin-left: -15px;"> <label for="inputbirthday" class="form-label">Birthday</label> <input type="date" class="form-control mt-4" name="birthday[]" id="inputbirthday"> </div> <div class="col-sm-2" style="width: 6rem; margin-left: -20px;"> <label for="inputmaritalstatus" class="form-label">Marital status</label> <select id="inputmaritalstatus" name="maritalstatus[]" class="form-select"> <option>S</option> <option>W</option> <option>Sep</option> <option>CL</option> </select> </div> <div class="col-sm-2" style="width: 5.5rem; margin-left: -22.5px;"> <label for="inputBloodType" class="form-label">Blood Type</label> <input type="text" class="form-control" name="bloodtype[]" id="inputBloodType"> </div> <div class="col-sm-2" style="width: 8rem; margin-left: -22.5px;"> <label for="inputdisability" class="form-label">Disability</label> <input type="text" class="form-control mt-4" name="disability[]" id="inputdisability"> </div> <div class="col-sm-2" style="width: 8rem; margin-left: -22.5px;"> <label for="inputEducationAttainment" class="form-label">Educational Attainment</label> <select id="inputEducationAttainment" name="educationalattainment[]" class="form-select"> <option>No Formal Education</option> <option>Elementary</option> <option>HighSchool</option> <option>Vocational</option> <option>College</option> <option>Post Graduate</option> </select> </div> <div class="col-sm-2" style="width: 7rem; margin-left: -22.5px;"> <label for="inputoccupation" class="form-label">Occupation</label> <input type="text" class="form-control mt-4" name="occupation[]" id="inputoccupation"> </div> <div class="col-sm-2" style="width: 9rem; margin-left: -22.5px;"> <label for="inputcontactno" class="form-label">Contact No.</label> <input type="text" class="form-control mt-4" name="contactno[]" id="inputcontactno"> </div> <div class="col-sm-2" style="width: 6rem; margin-left: -22.5px; fontweight: 0.5px;"> <label for="inputreligion" class="form-label">Religion</label> <select id="inputreligion" name="religion[]" class="form-select mt-4"> <option>Roman Catholic</option> <option>Iglesia</option> <option>Born Again</option> <option>Muslim</option> <option>Seven Adventist</option> <option>Others</option> </select> </div> <div class="col-sm-2" style="width: 7rem; margin-left: -22.5px;"> <label for="inputNHIP" class="form-label">NHIP</label> <select id="inputNHIP" name="nhip[]" class="form-select mt-4"> <option>write direct</option> <option>indirect</option> <option>dependent</option> <option>non-member</option> </select> </div> <div class="col" style="width: 7rem; margin-left: -22.5px;"> <td><button type="button" name="add" id="add" class="btn btn-success"><i class="fa fa-plus"></i></button></td> </div> </div> </div>
问题原因及解决办法
foreach错误根源
错误提示说明$_POST['familymember']不是数组,而是字符串,常见原因:- 动态添加表单行的JS代码有问题,新添加的表单元素
name属性未保持familymember[]的数组格式; - 仅存在单个
familymember输入框时,PHP配置导致数组被转成字符串(PHP5.4+极少出现)。
- 动态添加表单行的JS代码有问题,新添加的表单元素
关键修复步骤
- 检查动态添加JS代码:确保新增表单行的所有相关输入框
name属性都带[]后缀,PHP才会解析为数组; - 增加数组校验:在foreach循环前判断变量类型,避免报错:
if(is_array($_POST['familymember'])){ foreach ($_POST['familymember'] as $key => $value) { // 原有插入逻辑 } } - 启用第一张表插入语句:你注释掉了
$query = $con->query($sql) or die ($con->error);,导致$student_id无法获取正确自增ID,必须取消注释; - 修复SQL注入风险:直接拼接用户输入存在漏洞,改用预处理语句:
// 第一张表插入预处理 $stmt = $con->prepare("INSERT INTO `tbl_family_profiling`(`family_number`, `date_of_interview`,`interviewer`, `interviewee`, `barangay`, `residence`, `length_of_residency`, `address`, `primarycare_provider`, `primarycare_provider_no`, `travel_time`, `mode_of_transportation`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); $stmt->bind_param("ssssssssssss", $fserial, $doi, $intvwer, $intvwee, $barangay, $residence, $lghtresidence, $address, $pcareprovider, $pcareno, $ttime, $mode_transportation); $stmt->execute(); $student_id = $stmt->insert_id; $stmt->close(); // 第二张表插入预处理 if(is_array($_POST['familymember'])){ $stmt = $con->prepare("INSERT INTO twofamilyprofiling_family_members(user_id,family_member,family_position,sex,birthday,marital_status,blood_type,disability,highest_education_attainment,occupation,contact_no, religion, nhip) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"); foreach ($_POST['familymember'] as $key => $value) { $fm = $_POST['familymember'][$key]; $fp = $_POST['familyposition'][$key]; $s = $_POST['sex'][$key]; $bd = $_POST['birthday'][$key]; $ms = $_POST['maritalstatus'][$key]; $bt = $_POST['bloodtype'][$key]; $d = $_POST['disability'][$key]; $ea = $_POST['educationalattainment'][$key]; $oc = $_POST['occupation'][$key]; $cn = $_POST['contactno'][$key]; $r = $_POST['religion'][$key]; $n = $_POST['nhip'][$key]; $stmt->bind_param("issssssssssss", $student_id, $fm, $fp, $s, $bd, $ms, $bt, $d, $ea, $oc, $cn, $r, $n); $stmt->execute(); } $stmt->close(); }
- 检查动态添加JS代码:确保新增表单行的所有相关输入框
额外注意点
- 确认前端表单包含在
<form>标签内,且method="post"; - 动态添加的表单元素不要重复
id属性,避免DOM冲突; - 测试时用
var_dump($_POST);输出所有POST数据,确认familymember等字段是否为数组。
- 确认前端表单包含在
内容的提问来源于stack exchange,提问作者Joe Rick
相关产品推荐
相关产品推荐

