使用 PHP 处理多对多数据库关系并选择/插入多个复选框值 MYSQL

Posted

技术标签:

【中文标题】使用 PHP 处理多对多数据库关系并选择/插入多个复选框值 MYSQL【英文标题】:Deal with many to many database relationships and select/insert multiple checkbox values MYSQL using PHP 【发布时间】:2022-01-22 22:48:15 【问题描述】:

我的数据库中有以下表格:tbl_studentstbl_courses。 我有一个音乐学校的项目,学生可以报名参加一门或多门课程,例如,当我注册一个学生时,可以选择不止一门课程,比如吉他和钢琴,这取决于他的选择(现在我'我自己注册学生,所以这只是假设)。 我发现我必须处理多对多的关系,因为一个学生可以有很多课程,而在一个课程中,有很多学生刻在其中。 我所做的下一步是使用两个表的主键创建一个名为 tbl_students_courses 的中间表。 我的表格如下所示:tbl_students

+---------+---------+---------------+---------+
|  st_id  | st_name |    st_email   | st_code |
+---------+---------+---------------+---------+
|    1    |John Doe | doe@gmail.com |  55555  |
+---------+---------+---------------+---------+

tbl_courses

+---------+-----------+--------------------------+
|  cr_id  |  cr_name  |         cr_desc          |
+---------+-----------+--------------------------+
|    1    |   Guitar  | Guitar course description|
+---------+-----------+--------------------------+
|    2    |   Bass    | Bass course description  |
+---------+-----------+--------------------------+
|    3    |   Violin  | Violin course description|
+---------+-----------+--------------------------+
|    4    |   Drums   | Drums course description |
+---------+-----------+--------------------------+
|    5    |   Piano   | Piano course description |
+---------+-----------+--------------------------+

tbl_students_courses

+---------+---------+---------+
|  st_id  |  cr_id  |date_insc|
+---------+---------+---------+
|  -----  |  -----  |  -----  |
+---------+---------+---------+

现在我的问题是,我不知道如何将表格与我的 php 代码相关联。我假设如果我在注册学生时选择 2 门课程,它应该在中间表上创建 2 条记录,其中只有 cr_id 彼此不同。 另一个问题是通过 php 的复选框获取课程的 ID,因此当我选择例如钢琴和吉他复选框时,它应该返回两个课程的 ID,运行查询并插入记录。注意: 使用我的 php 代码,foreach 循环 显然只是获取字符串,而不是我想要的课程的 ID。 这是我的 html

<div class="form-group">
                   <label class="col-form-label">Select the courses</label>
                   <div class="form-check">
                       <div class="form-check form-check-inline">
                           <input class="form-check-input" name="course[]" type="checkbox" value="Guitar">
                           <label class="form-check-label" >Guitar</label>
                       </div>
                       <div class="form-check form-check-inline">
                           <input class="form-check-input" name="course[]" type="checkbox" value="Bass">
                           <label class="form-check-label" >Bass</label>
                       </div>
                       <div class="form-check form-check-inline">
                           <input class="form-check-input" name="course[]" type="checkbox" value="Violin">
                           <label class="form-check-label" >Violin</label>
                       </div>
                       <div class="form-check form-check-inline">
                           <input class="form-check-input" name="course[]" type="checkbox" value="Drums">
                           <label class="form-check-label" >Drums</label>
                       </div>
                       <div class="form-check form-check-inline">
                           <input class="form-check-input" name="course[]" type="checkbox" value="Piano">
                           <label class="form-check-label" >Piano</label>
                       </div>
                   </div>

这是我的 PHP:

 <?php

            if (isset($_POST['submit'])) 
                include_once '../includes/functions.php';
                $studentName     = addslashes($_POST['sname']);
                $studentEmail    = addslashes($_POST['semail']);
                $studentCode     = intval($_POST['scode']);   
                $studentcourse    = $_POST['course'];   
                $query  = "INSERT INTO tbl_students (st_name, st_id, st_code) "
                . "VALUES ('$studentName', '$studentEmail', '$studentCode')";
                $link   = connection_db(); 
                $result = mysqli_query($link, $query);
        
                if($result)
                    $sql = "SELECT LAST_INSERT_ID()";
                    $result = mysqli_query($link, $sql);
                    $last = mysqli_fetch_assoc($result);

                    foreach($studentcourse as $value)
                        $data = date('Y-m-d H:i:s');
                        $lastID =($last["LAST_INSERT_ID()"]);
                        $sql = "INSERT INTO tbl_students_courses (st_id, cr_id, date_insc) VALUES ($lastID, '$value', '$data')";
                        $result = mysqli_query($link, $sql);
                    
                    echo "<script>alert('Data saved successfully');</script>";
                    print "<script>top.location = 'index.php?id=2';</script>";
                 else 
                    echo "<script>alert('ERROR! Could not save data');</script>";
                   
            
        ?>

非常感谢任何有助于改进问题的帮助或建议。

【问题讨论】:

首先在 check_buttons 中给出课程的 ID,这样您就可以通过课程 ID 在 PHP 中选中复选框。将这些与学生证结合起来,您就完成了。并开始使用准备好的语句,因为您现在对 SQL 注入持开放态度。 您好,这是我问题的一部分。我如何根据数据库上的 id 将 id 赋予复选框...并且不用担心 sql 注入,它只是以后项目的原型。 好吧,我想您在显示页面时从数据库中选择了课程。选择他们的 id 并将它们放在 name 属性中。您应该立即开始使用准备好的语句。恕我直言,编写代码(甚至是原型)以及后来不得不更改所有内容都是没有意义的。 如果表单是硬编码的,你也可以在name属性中硬编码id。 我会查看准备好的语句。我在这里有疑问的是:如果我在注册学生时选择了 2 门课程,它是否应该在中间表上创建 2 条不同的记录,两者仅在课程 ID 上有所不同? 【参考方案1】:

如果您将 ID 作为值放入复选框中,您的代码实际上可以工作

所以宁可使用

 <input class="form-check-input" name="course[]" type="checkbox" value="Piano">

改为输入这个

 <input class="form-check-input" name="course[]" type="checkbox" value="5">

ofc 手动输入 ID 不会那么好,因此您必须从数据库中读取所有课程并根据您的数据生成复选框。

所以你可以创建函数来像这样从数据库中获取所有课程

function getAllCourses(mysqli $link)
    $sql ="SELECT cr_id,cr_name,cr_desc FROM tbl_courses";
    $result = mysqli_query($link, $sql);
    $courses = [];
    while($row = mysqli_fetch_assoc($result))
        $courses[]=$row;
    
    return $courses;

然后在你生成 HTML 代码之前的地方,你就可以得到所有这些

$courses = getAllCourses($link);

之后你可以像这样生成你的 HTML 代码

<div class="form-group">
    <label class="col-form-label">Select the courses</label>
    <div class="form-check">
        <?php
        foreach ($courses as $course): ?>
            <div class="form-check form-check-inline">
                <input class="form-check-input" name="course[]" type="checkbox" value="<?= $course['cr_id'] ?>">
                <label class="form-check-label"><?= $course['cr_name'] ?></label>
            </div>
        <?php
        endforeach; ?>
    </div>

此外,您的学生代码似乎是您学生的真实标识符,因此您的数据库中不需要具有自动递增的 ID。您还可以将学生代码行定义为学生表中的主键。

这样您就不需要获取最后的插入 ID,因为您已经有了学生。

我还看到你的 SQL 代码是不安全的,你只需将 POST 值放入 SQL 查询中,这样 SQL 注入是可能的,你需要在这里使用准备语句。您在其中准备带有占位符的 SQL 语句并使用值执行它们。

$query  = "INSERT INTO tbl_students (st_name, st_email st_code) "
                . "VALUES (?,?,?)";
$statement = mysqli_repapre($link, $query);
mysqli_stmt_bind_param($statement,"sis",$studentName,$studentEmail,$studentCode);
mysqli_stmt_execute($statement); 

此代码未经测试,但我希望它能给您一个想法。

【讨论】:

我正在考虑这个问题,但并不真正知道如何将我的想法放入代码中,这很有帮助! 最后一件事,学生代码用于学生登录他的帐户(像密码一样工作)以查看课程的内容,所以我真的不希望它成为标识符.我希望 ID 是真正的标识符,所以我可以保持原样(最后插入 id)对吗? @neptune17 啊,是的,然后使用正确的 id。顺便说一句,有一个名为 mysqli_insert_id 的函数可以更轻松地返回最后一个插入 ID 它工作得很好,但是它只是将我在创建更多记录的复选框中选择的第一门课程的 ID 存储在数据库中......我尝试使用我初始化的变量进行 while 循环在 foreach 循环中使用 autoincrement 并且当变量大于 1 时,它执行了查询。好吧,无论如何它都没有用,所以我认为问题出在 foreach 循环中。对于给您带来的任何不便,我深表歉意,我很高兴有人可以帮助我。 @neptune17 我需要更多信息,在这里我帮不上忙。代码现在是什么样子的?也许你误解了我的回答并解释了其他事情。也尝试 var_dump 你的 post 数组,看看你会得到什么样的值,并尝试遵循你的代码

以上是关于使用 PHP 处理多对多数据库关系并选择/插入多个复选框值 MYSQL的主要内容,如果未能解决你的问题,请参考以下文章

hibernate对象关系实现多对多实现

SQL 查询 - 加入多对多关系,有选择地过滤/加入

在 CloudKit 中处理多对多关系

通过 SQLAlchemy 选择多个多对多关系

具有多个多对多关系的休眠批处理事务

具有多个多对多关系的 SQLAlchemy