php 网页提交数据用的是 foreach ,出现重复提交,产生两条一样的数据。

小小白刚接触php好多想问的。俺是小白请说详细点。


问题描述:

新增数据(可以单个提交,也可以批量提交),提交数据会重复一模一样的数据


提交数据代码:,这个没有问题的

<form action="action.php" method="post" name="add">
<tr bgcolor="#FFFFFF"> 
<td>
<table cellpadding="3" cellspacing="1" >
<tr style="background: #c4f6fc; font-weight: bold; color: #555555">
<td align="center">ID</td><td align="center">名 称</td>
</tr>
<tr>
<td><input type="text" name="id[]" /></td>
<td><input type="text" name="name[]" /></td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF"> 
<td height="25">
<input type="submit" name="Submit" value="批 量 添 加"> <br /></td>
</tr>
</form>


问题代码:下面的代码有问题

foreach ($add['name'] as $key => $val) {
    $val = trim(RepPostStr($val)); //获取提交的名称


    foreach ($add['id'] as $valid ){
        $valid = trim(RepPostStr($valid)); //获取提交新增的ID
        if ($val) {
            //扩展字段数组
            $ziduanval = '';
            $i = 0;
            foreach ($ziduanarr as $val2) {
                $i++;
                if ($add['more']) { //快速批量添加组合扩展字段
                    $ziduanval.= ',\'' . trim(RepPostStr($datearr[$key][$i])) . '\'';
                } else {
                    $ziduanval.= ',\'' . trim(RepPostStr($add[$val2][$key])) . '\'';
                }
            }
            
            
            $valnum[$key] = 1; //过滤空白后实际添加数量
            $sql = $empire->query("insert into {$dbtbpre}extend_linkage(id,name,parentid,type,myorder,path{$ziduanname}) values('$valid','$val','$parentid','$type','$myorder','$path'{$ziduanval});");
        }}
    }


    if ($sql) {
        printerror2("成功添加" . count($valnum) . "个菜单", "list.php?type=" . $type . "&parentid=" . $parentid . $ecms_hashur['href']);
    } else {
        printerror2('数据库出错,请稍后再提交', '');
    }
}

你这个代码不完整。初步判断是嵌套循环问题;假设前端设置了一条数据,循环就执行一次;如果前端提交了2个id和2个name,那么循环就是4次,比预计多了2次,所有这里嵌套循环有问题。


应该循环id,然后name字段都通过下标获取


后端完整的代码,看看啥原因。

<?php
require ('../../class/connect.php');
require ('../../class/db_sql.php');
require ('../../class/functions.php');
$link = db_connect();
$empire = new mysqlquery();
$editor = 1;
//验证用户
$lur = is_login();
$logininid = $lur['userid'];
$loginin = $lur['username'];
$loginrnd = $lur['rnd'];
$loginlevel = $lur['groupid'];
$loginadminstyleid = $lur['adminstyleid'];
//ehash
$ecms_hashur = function_exists('hReturnEcmsHashStrAll') ? hReturnEcmsHashStrAll() : array();
$enews = $_GET['enews'];
//提交联动菜单
function user_addlinkage($add) {
    global $empire, $dbtbpre, $public_r, $ecms_hashur;
    $name = RepPostStr($add['name']);
    $id = RepPostStr($add['id']);
    $parentid = 0;
    $type = 0;
    $myorder = 0;
    $path = "0,";
    if (!$name) {
        printerror2('请输入联动名称', '');
    }
    if (!$id) {
        printerror2('请输入联动名称', '');
    }
    $sql = $empire->query("insert into {$dbtbpre}extend_linkage(id,name,parentid,type,myorder,path) values('$id','$name','$parentid','$type','$myorder','$path');");
    //$myorder=$empire->lastid();
    if ($sql) {
        printerror2("添加菜单成功", 'linkage.php' . $ecms_hashur['whhref']);
    } else {
        printerror2('数据库出错,请稍后再提交', '');
    }
}
//批量添加联动子菜单
function user_addmore($add) {
    global $empire, $dbtbpre, $public_r, $ecms_config, $ecms_hashur;
    $parentid = (int)$add['parentid'];
    $type = (int)$add['type'];
    $myorder = 0;
    //一行一个的添加方式获取数据
    if ($add['more']) {
        $addarr = explode(PHP_EOL, $add['more']);
        foreach ($addarr as $key => $val) {
            $datearr[$key] = explode('##', $val);
            $add['name'][$key] = $datearr[$key][0];
        }
    }
   
    //扩展字段
    $systemfield = array('id', 'parentid', 'name', 'type', 'path', 'myorder'); //系统字段
    $query = "select COLUMN_NAME from information_schema.COLUMNS where table_name = '{$dbtbpre}extend_linkage' and table_schema = '{$ecms_config['db']['dbname']}'"; //获取字段用的
    $sql = $empire->query($query);
    $ziduanarr = array();
    while ($r = $empire->fetch($sql)) {
        if (!in_array($r['COLUMN_NAME'], $systemfield)) { //只显示扩展字段
            $ziduanname.= ',' . $r['COLUMN_NAME']; //要插入的字段名
            $ziduanarr[$r['COLUMN_NAME']] = $r['COLUMN_NAME']; //循环出扩展字段的POST值所用的数组
            
        }
    }


            $val3 = trim(RepPostStr($val3)); //获取提交的名称
    $rf = $empire->fetch1("select id,path from {$dbtbpre}extend_linkage where id='$parentid'"); //查找父分类
    $path = $rf['path'] . $rf['id'] . ','; //路径格式0,1,5,8,9,
            
    foreach ($add['name'] as $key => $val) {
    $val = trim(RepPostStr($val)); //获取提交的名称


        if ($val) {
            //扩展字段数组
            $ziduanval = '';
            $i = 0;
            foreach ($ziduanarr as $val2) {
                $i++;
                if ($add['more']) { //快速批量添加组合扩展字段
                    $ziduanval.= ',\'' . trim(RepPostStr($datearr[$key][$i])) . '\'';
                } else {
                    $ziduanval.= ',\'' . trim(RepPostStr($add[$val2][$key])) . '\'';
                }} 
                foreach ($add['id'] as $keyid => $valid) {
                $valid = trim(RepPostStr($valid)); //获取提交的名称


            $valnum[$key] = 1; //过滤空白后实际添加数量
    $sql = $empire->query("insert into {$dbtbpre}extend_linkage(id,name,parentid,type,myorder,path{$ziduanname}) values('$id','$val','$parentid','$type','$myorder','$path'{$ziduanval});");
        }
    }
     } }


    if ($sql) {
        printerror2("成功添加" . count($valnum) . "个菜单", "list.php?type=" . $type . "&parentid=" . $parentid . $ecms_hashur['href']);
    } else {
        printerror2('数据库出错,请稍后再提交', '');
    }
}
//批量修改联动菜单
function user_editmore($add) {
    global $empire, $dbtbpre, $public_r, $ecms_config, $ecms_hashur;
    $name = $add['name'];
    $myorder = $add['id'];
    //扩展字段
    $systemfield = array('id', 'parentid', 'name', 'type', 'path', 'myorder'); //系统字段
    $query = "select COLUMN_NAME from information_schema.COLUMNS where table_name = '{$dbtbpre}extend_linkage' and table_schema = '{$ecms_config['db']['dbname']}'"; //获取字段用的
    $sql = $empire->query($query);
    $ziduanarr = array();
    while ($r = $empire->fetch($sql)) {
        if (!in_array($r['COLUMN_NAME'], $systemfield)) { //只显示扩展字段
            $ziduanarr[$r['COLUMN_NAME']] = $r['COLUMN_NAME']; //循环出扩展字段的POST值所用的数组
            
        }
    }
    for ($i = 0;$i < count($name);$i++) {
        $newname = RepPostStr($name[$i]);
        $myorder = (int)$add['myorder'][$i];
        foreach ($ziduanarr as $val) {
            $ziduanval.= ',' . $val . '=\'' . RepPostStr(trim($add[$val][$i])) . '\''; //要更新的扩展字段名
            
        }
        $usql = $empire->query("update {$dbtbpre}extend_linkage set name='$newname',myorder='$myorder'{$ziduanval} where id='$myorder[$i]'");
    }
    printerror2("批量修改菜单名称成功", $_SERVER['HTTP_REFERER']);
}
//删除联动菜单
function Dellinkage($myorder) {
    global $empire, $dbtbpre, $ecms_hashur;
    $myorder = (int)$myorder;
    $path = ',' . $myorder . ',';
    $sql = $empire->query("delete from {$dbtbpre}extend_linkage where id='$myorder' or path like '%$path%'");
    if ($sql) {
        printerror2("删除成功", $_SERVER['HTTP_REFERER']);
    } else {
        printerror2("数据库出错", "history.go(-1)");
    }
}
//删除整个联动菜单
function DelAll($myorder) {
    global $empire, $dbtbpre, $ecms_hashur;
    $myorder = (int)$myorder;
    $sql = $empire->query("delete from {$dbtbpre}extend_linkage where id='$myorder' or type='$myorder'");
    if ($sql) {
        $filename = ECMS_PATH . 'e/extend/yl_linkage/data/linkage_cache_' . $myorder . '.php';
        if (file_exists($filename)) {
            unlink($filename); //删除缓存文件
            
        }
        printerror2("删除成功", $_SERVER['HTTP_REFERER']);
    } else {
        printerror2("数据库出错", "history.go(-1)");
    }
}
//修改菜单顺序
function EditListorder($myorder, $id) {
    global $empire, $dbtbpre, $ecms_hashur;
    for ($i = 0;$i < count($myorder);$i++) {
        $newmyorder = (int)$myorder[$i];
        $usql = $empire->query("update {$dbtbpre}extend_linkage set myorder=$newmyorder where id='$myorder[$i]'");
    }
    printerror2("修改菜单顺序成功", $_SERVER['HTTP_REFERER']);
}
//修改单个联动菜单--包含批量修改父ID
function Editlinkage($add) {
    global $empire, $dbtbpre, $ecms_config, $ecms_hashur;
    $id = (int)$add['id'];
    $type = (int)$add['type'];
    $parentid = (int)$add['parentid'];
    $newparentid = (int)$add['newparentid'];
    $myorder = (int)$add['myorder'];
    $name = RepPostStr($add['name']);
    $newspath = RepPostStr($add['path']);
    //批量更改父ID
    if ($newparentid !== $parentid) {
        if (!$newparentid || $newparentid == $myorder) {
            printerror2('父ID不能为空且不能是当前ID!', '', 9);
        }
        $f = $empire->fetch1("select * from {$dbtbpre}extend_linkage where id='$newparentid'");
        $type = $f['type'] ? $f['type'] : $f['id'];
        if (strrpos($f['path'], ',' . $myorder . ',')) {
            printerror2('父ID不能是自己的子菜单!', '', 9);
        } elseif ($f) {
            $newspath = $f['path'] . $f['id'] . ',';
            $queryzcd = "select * from {$dbtbpre}extend_linkage where parentid !='$parentid' and path like '$path%'";
            $sqlzcd = $empire->query($queryzcd);
            while ($zcd = $empire->fetch($sqlzcd)) {
                $newspathzcd = str_replace($path, $newspath, $zcd['path']);
                $upzcd = $empire->query("update {$dbtbpre}extend_linkage set path='$newspathzcd',type='$type' where id='$zcd[id]]'");
            }
        }
    }
    //扩展字段
    $systemfield = array('id', 'parentid', 'name', 'type', 'path', 'myorder'); //系统字段
    $query = "select COLUMN_NAME from information_schema.COLUMNS where table_name = '{$dbtbpre}extend_linkage' and table_schema = '{$ecms_config['db']['dbname']}'"; //获取字段用的
    $sql = $empire->query($query);
    while ($r = $empire->fetch($sql)) {
        if (!in_array($r['COLUMN_NAME'], $systemfield)) { //只显示扩展字段
            $ziduanname.= ',' . $r['COLUMN_NAME'] . '=\'' . RepPostStr(trim($add[$r['COLUMN_NAME']])) . '\''; //要插入的字段名
            
        }
    }
    $upsql = $empire->query("update {$dbtbpre}extend_linkage set name='$name',parentid='$newparentid',path='$newspath',type='$type',myorder='$myorder'{$ziduanname} where id='$myorder'");
    if ($upsql) {
        printerror2("修改菜单成功", '/e/extend/yl_linkage/list.php?type=' . $type . '&parentid=' . $newparentid . $ecms_hashur['href']);
    }
}
//判断enews值
$ecms = $_POST['enews'];
if ($ecms == 'Addlinkage') {
    user_addlinkage($_POST);
}
if ($ecms == 'addmorelinkage') {
    user_addmore($_POST);
}
if ($ecms == 'Editmore') {
    user_editmore($_POST);
}
if ($enews == 'Dellinkage') {
    $myorder = (int)$_GET['id'];
    Dellinkage($myorder);
}
if ($enews == 'DelAll') {
    $myorder = (int)$_GET['id'];
    DelAll($myorder);
}
if ($enews == 'Shengcheng') {
    $myorder = (int)$_GET['id'];
    Shengcheng($myorder);
}
if ($ecms == "EditListorder") {
    EditListorder($_POST['id'], $_POST['myorder']);
}
if ($ecms == 'Editone') {
    Editlinkage($_POST);
}
db_close();
$empire = null;
?>

for循环嵌套有问题,可以调试一下

这明显就是前端问题。嵌套的问题

name和id是平级关系,被你写成了上下嵌套关系。你应该把id的foreach放外面与name的foreach平级。然后再提交请求。
foreach ($add['name'] as $key => $val) {
    $val = trim(RepPostStr($val)); //获取提交的名称


    foreach ($add['id'] as $valid ){
        $valid = trim(RepPostStr($valid)); //获取提交新增的ID
        if ($val) {
            //扩展字段数组
            $ziduanval = '';
            $i = 0;
            foreach ($ziduanarr as $val2) {
                $i++;
                if ($add['more']) { //快速批量添加组合扩展字段
                    $ziduanval.= ',\'' . trim(RepPostStr($datearr[$key][$i])) . '\'';
                } else {
                    $ziduanval.= ',\'' . trim(RepPostStr($add[$val2][$key])) . '\'';
                }
            }
            
            
            $valnum[$key] = 1; //过滤空白后实际添加数量
            $sql = $empire->query("insert into {$dbtbpre}extend_linkage(id,name,parentid,type,myorder,path{$ziduanname}) values('$valid','$val','$parentid','$type','$myorder','$path'{$ziduanval});");
        }}
    }

没用的,早试过了。ID放外面就会多个ID,名称二次循环是空的。反正都是重复一组。反之name 放外面也是一样。


这个功能是,系统字段(ID和名称)+扩展字段的单个提交或者批量提交。



先搞清楚foreach嵌套循环原理吧

已经解决了,嵌套循环太绕人了。

研究了半天,要把第二个 foreach 放到下面的扩展字段 if ($val){}里面进行循环。不过还是要感谢各位的解答

if ($val) {
            //扩展字段数组
            $ziduanval = '';
            $valid = '';
            $i = 0;
            foreach ($ziduanarr as $val2) {
                $i++;
                if ($add['more']) { //快速批量添加组合扩展字段
                    $ziduanval.= ',\'' . trim(RepPostStr($datearr[$key][$i])) . '\'';
                } else {
                    $ziduanval.= ',\'' . trim(RepPostStr($add[$val2][$key])) . '\'';
                }
            }
           
     

回答如果对你有用,可以点一下采纳

这是批量或者单独提交 ID 和 name 的数据到数据库里。单独提交的我可以解决。但批量提交搞不定,还在学中

我简单写了一下批量的示例代码,你可以参考一下,基本就是这个思路:

<?php




$fromData = ['id'=>[1,2], 'name'=>['a', 'b']]; //模拟前端表单提交的数据

$insertData = []; //需要写入数据库的数据

//组装需要写入数据库的数据

foreach ($fromData['id'] as $key => $id){ //注意这里,只能循环一次,循环一次组装一条待插入数据库的数据

    $tmp['id'] = $id;

    $tmp['name'] = $fromData['name'][$key];

    $insertData[] = $tmp;

}

/**

 * 把组装好的数据插入数据

 */

//插入数据库操作

<td><input type="text" name="data[key][id]" /></td>

<td><input type="text" name="data[key][name]" /></td>

key是动态赋值,这样循环一次不就可以了吗