Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP&;Mysql使用复选框表单更新多对多关系_Php_Sql_Checkbox_Many To Many - Fatal编程技术网

PHP&;Mysql使用复选框表单更新多对多关系

PHP&;Mysql使用复选框表单更新多对多关系,php,sql,checkbox,many-to-many,Php,Sql,Checkbox,Many To Many,我有一个多对多表结构和更新复选框表单 目标是将users表与projects表以及users\u project表关联起来。这样,每个项目可以有多个用户,每个用户可以有多个项目 每个用户编辑页面上的表单看起来像这样 <form action="#" method="post"> <div> <input type="checkbox" name="project_id[]" id="1" value="1"> &l

我有一个多对多表结构和更新复选框表单

目标是将users表与projects表以及users\u project表关联起来。这样,每个项目可以有多个用户,每个用户可以有多个项目

每个用户编辑页面上的表单看起来像这样

<form action="#" method="post">
    <div>   
        <input type="checkbox" name="project_id[]" id="1" value="1">
        <label for="1">project 1</label>
        <br>

        <input type="checkbox" name="project_id[]" id="2" value="2">
        <label for="2">project 2</label>
        <br>
        <input type="hidden" name="editing">
        <input type="submit" id="submit" value="submit">
    </div>
</form>
项目表

+----+-----------+  
¦ id ¦ title     ¦
+----+-----------+  
| 1  ¦ project 1 ¦
| 2  ¦ project 2 ¦
+----+-----------+    
用户项目表

+----+-----------+  
¦ id ¦ title     ¦
+----+-----------+  
| 1  ¦ project 1 ¦
| 2  ¦ project 2 ¦
+----+-----------+    
此表根据其id将上述两个表关联起来

我制作了一个复选框表单来添加和编辑这些值。在每个用户页面上,它显示项目表中的所有项目。然后查询user_projects表并查找匹配项列表,以将复选框添加到复选框中

但是如何将这些值编辑到数据库中呢?我如何知道用户是否取消选中了以前选中的框或选中了空框并更新到数据库,而没有在用户表上循环查询project\u id和user\u id的匹配项

以下是我希望最终结果达到的大致概念

if ($_POST['editing']) { 
    $totalprojects = $_POST['editing']; 
    $query = " 
        SELECT *  
        FROM user_projects  
        WHERE user_id = user_id 
        AND project_id = project_id 
    "; 
    $result = $mysqli->query($query); 
    $count = $mysqli->affected_rows; 
    for($i=0; $i < $totalprojects; $i++) {  
        if ($count == 1) { 
            if ($box == checked){  
                //do nothing 
            } 
            else { 
                //delete from database 
            } 
        } 
        if ($count == 0) { 
            if ($box == checked){  
                //add to database 
            } 
            else { 
                //do nothing 
            } 
        } 
    } 
} 
if($_POST['editing']){
$totalprojects=$_POST['editing'];
$query=”
选择*
来自用户项目
其中user\u id=user\u id
而project\u id=project\u id
"; 
$result=$mysqli->query($query);
$count=$mysqli->受影响的_行;
对于($i=0;$i<$totalprojects;$i++){
如果($count==1){
如果($box==选中){
//无所事事
} 
否则{
//从数据库中删除
} 
} 
如果($count==0){
如果($box==选中){
//添加到数据库
} 
否则{
//无所事事
} 
} 
} 
} 
这似乎根本不是一个好主意,因为对于项目表中的每个项目,我必须至少查询一次数据库。对于我想象中的常见问题,必须有更好的解决方案。我知道我只是想错了

注意:我曾考虑过序列化一个数组并将其粘贴到用户列中,但这是不可接受的,因为我无法将项目与用户关联,只能将用户与项目关联起来,从而无法达到目的


我希望在实现时不要使用任何javascript技巧。

好吧,假设每个用户都有资格处理每个项目,在表单处理页面上,您希望执行以下操作:

$query = 'SELECT p.id AS project_id, u_p.id AS user_project_id '.
            'FROM projects AS p '.
                'LEFT JOIN user_projects AS u_p ON (u_p.project_id = p.id AND u_p.user_id = ?)';
通过左键连接,这将为您提供系统中所有项目的列表,并且只有当您正在编辑的用户已经在该项目上时,第二列才具有值。对于您给出的示例数据,这是查询
user\u id
1时得到的结果:

+------------+-----------------+
| project_id | user_project_id |
+------------+-----------------+
|          1 |                 |
|          2 |               2 |
+------------+-----------------+
然后循环此查询的结果,对于每个结果,检查是否为相应的
项目id
发送了
$\u POST
中的值。如果发送了值(复选框已选中),且行的
user\u project\u id
为空,请在
user\u projects
中插入一行以添加此链接。如果未发送值(复选框未选中),并且设置了行的
user\u project\u id
,请使用
user\u project\u id
作为键从
user\u projects
中删除该行。否则什么也不做,他们没有改变以前的方式


希望这是清楚的,如果您想让我了解更多细节,请告诉我。

您可以将操作分组,并将脚本减少为3个查询

使用Chad Birch anwser的左连接检索当前选定的选项

循环之前:

$delete_ids = array();
$add_ids = array();
// delete from database
$delete_ids[] = $project_id;
在循环内部:

$delete_ids = array();
$add_ids = array();
// delete from database
$delete_ids[] = $project_id;

在for循环之后:

if (count($delete_ids) > 0) {
  mysql_query('DELETE FROM user_projects WHERE user_id = '.$user_id.' AND project_id IN ('.implode(', ', $delete_ids).')'); 
}

if (count($add_ids) > 0) {
  mysql_query('INSERT INTO user_projects (user_id, project_id) VALUES '.implode($add_values)); 
}

由于您的项目数量小到可以在一个表中显示,我完全赞成在提交时重写
user\u projects
表的相关部分:

BEGIN TRANSACTION;
DELETE FROM user_projects WHERE user_id = $uid;
INSERT INTO user_projects (project_id, user_id)
    VALUES ($proj1, $uid), ($proj2, $uid), ...;
COMMIT TRANSACTION;
注意使用扩展的
INSERT
语法将关联写入一条语句


如果不需要,也可以删除
用户\u projects.id
,从而节省表中三分之一的空间。

这就是我解决此问题的方法:

  • 首先,我使用
    active
    列检查一个项目是否被删除(0)或不被删除(1),因为它比使用deletesql语句更安全

  • 接下来,您需要将user\u id和project\u id列定义为UNIQUE

    ALTER TABLE `user_projects` ADD UNIQUE INDEX(user_id, user_project_id)
    
  • 代码

    $uid = $_POST['uid'];
    $pids = $_POST['project_id'];
    
    // "deleting" all entries
    $chb = $db->prepare("UPDATE `user_projects` SET `active`=0 WHERE `user_id`=?");
    $chb->execute(array($uid));
    
    //updating checked checkboxes
    foreach ($pids as $pid) {
    $chb = $db->prepare("INSERT INTO `user_projects` VALUES (?, ?, 1) ON DUPLICATE KEY UPDATE `active`=1");
    $chb->execute(array($uid, $pid));
    
    }

  • -所有示例中都使用PDO