更新数据库中的多选复选框

时间:2011-04-13 08:55:42

标签: php mysql forms checkbox multiple-choice

多选选项

例如,ID为“10”的用户可以选择他说的语言。 他使用“多选”或“多个复选框”选择每种语言,如下所示:

<input name="lang[]" value="en" type="checkbox" />
<input name="lang[]" value="es" type="checkbox" />
<input name="lang[]" value="jp" type="checkbox" />

我想知道的是,存储这些选项的db表是如何看起来的以及服务器端如何插入/更新它们?

到目前为止我的猜测

我想象的是桌子看起来像这样:

CREATE TABLE user_langs (id INT AUTO_INCREMENT PRIMARY KEY, lang VARCHAR, fk_user INT);

在将值插入新用户时,php会执行一个简单的插入循环:

$stmt = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt->execute(array($lang, $user_id));
}

我得到的问题是UPDATES,最简单的方法是删除该用户的所有现有条目,并插入新的条目。

$stmt1 = $pdo->prepare('DELETE FROM user_langs WHERE fk_user=?');
$stmt1->execute(array($user_id));
$stmt2 = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt2->execute(array($lang, $user_id));
}

但我认为如果积极使用它会过快地增加主要ID,即使id的上限是天文数字我不喜欢污染我的数据库的想法,所以我猜我是做错了,所以我想知道专业人士如何处理它。

2 个答案:

答案 0 :(得分:1)

你也可以使用某种差异。

算法:

  1. 用户发布了包含所选语言的表单
  2. 您选择当前语言
  3. 使用array_diff()两次(新旧之间的差异,以及相反的差异),您将获得需要删除的2种语言数组,以及需要添加的语言
  4. 根据3中的数组,您执行一次INSERT和一次DELETE查询

答案 1 :(得分:0)

这个问题似乎来自于以上示例中的id是人为的,解决方案是使用multi-column primary keys也称为Compound key,我在问这个问题时并不知道。{ / p>

然后解决方案变成使用这样的表:

CREATE TABLE user_langs (
  lang VARCHAR, 
  fk_user INT, 
  PRIMARY KEY(lang,fk_user)
);

这可以提高数据完整性,因为单个用户不能再使用同一种语言的2个条目。

要插入值,请执行相同的操作:

$stmt = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt->execute(array($lang, $user_id));
}

处理更新的最简单方法是删除绑定到此用户的所有条目,并以相同的方式再次插入正确的条目:

$stmt1 = $pdo->prepare('DELETE FROM user_langs WHERE fk_user=?');
$stmt1->execute(array($user_id));
$stmt2 = $pdo->prepare('INSERT INTO user_langs (lang,fk_user) VALUES(?,?)');
foreach($_POST['lang'] as $lang){
    $stmt2->execute(array($lang, $user_id));
}

您也可以像zerkms建议的那样,选择所有语言,然后运行array_diff查找旧值和新值,删除旧值并插入新值,但这意味着运行3个查询并且比较结果,而在语言的情况下,用户说话超过3是非常罕见的,这就是为什么再次删除和插入似乎是最好的选择。