【问题标题】:PHP - loop & lastInsertId()PHP - 循环 & lastInsertId()
【发布时间】:2015-04-06 06:52:23
【问题描述】:

我有这段代码可以插入问题、选择和多项选择表。我设法完成了插入问题和选择表,我没有做的是多选表。

require("dbOption/Db.class.php");
$question       =   new Db();
$choice         =   new Db();
$multichoice    =   new Db();
$entries = array(
    0 => '1. What foo?',
    1 => 'a. foo1',
    2 => 'b. foo2',
    3 => 'c. foo3',
    4 => 'd. foo4',
    5 => '2. 2 + 2 is?',
    6 => 'a. test1',
    7 => 'b. test2',
    8 => 'c. test3',
    9 => 'd. test4',
);

$answerIDs    = "";
$questionID   = "";

$multipleChoice = array();

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        echo "<pre>";
            var_dump($entry);
        echo "<pre>";
        $question->query("INSERT INTO question(q_name) VALUES(:question)",array("question"=>$entry));
        $questionID = $question->lastInsertId();
    } else {
        echo "<pre>";
            var_dump($entry);
        echo "<pre>";
        $answer->query("INSERT INTO choice(choices,question) VALUES(:choices, :question)",array("choices"=>$entry, "question"=>$questionID));
        if ($answerIDs === "")
            $answerIDs = $choice->lastInsertId();
        else
            // store last inserted ids in choice table and separate it with ","
            $answerIDs .= ("," . $choice->lastInsertId());
    }
}

这是数据库中的示例输出。

问题表

id     q_name
1   1. What foo?
2   2. 2 + 2 is?

选择表

id   choices    question  correct
1   a. foo1        1       0
2   b. foo2        1       0
3   c. foo3        1       0
4   d. foo4        1       0
5   a. test1       2       0
6   b. test2       2       0
7   c. test3       2       0
8   d. test4       2       0
选择表中的

问题问题表

中的id

我想在多选表中实现什么。

多选表

 id  question  mc_answers
  1    1        1,2,3,4
  2    2        5,6,7,8

question multichoice tablequestion table

中的 id

我对如何做到这一点感到困惑,我想向你们咨询。我应该怎么做才能做到这一点?

【问题讨论】:

  • 听起来设计很糟糕。您已经可以通过查找问题 id 找到问题的所有答案,因此现在您希望以错误(逗号分隔)的方式存储冗余信息。
  • 没有区别,我只是编辑了我的问题并添加了一些细节......
  • 其实我是在模仿 Moodle db 中的某个设计,多选题。我为糟糕的设计道歉......

标签: php mysql arrays pdo


【解决方案1】:

就像我说的,我认为您根本不应该存储这些列表。存储逗号分隔值通常被认为是不好的设计,而且您已经在数据库中拥有所需的所有信息,因此这些信息也将是多余的。

如果你还是想这样做,我认为有四种解决方案。

1) 开始新问题时插入答案。 缺点是您必须在循环后再次执行相同操作以保存最后一个问题的选择。代码的结构看起来像这样(为简洁起见)。

$answerIDs = "";

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        if ($answerIDs !== "") {
            // First insert multi select answers

            // Reset the answers for the new question.
            $answerIDs = "";
        }

        // Then insert question as you do now.
    } else {
        // Insert answers and store ID in $answerIDs as you do now.
    }
}

if ($answerIDs !== "") {
    // Store answers (again).
}

2) 将 ID 保存在一个大数组中,然后再存储它们。 您可以将答案保存在嵌套数组中。主级别的关键是问题ID。每个问题你存储一个数组(或一个字符串,但我认为数组更容易)的答案。插入问题和答案后,可以循环遍历数组,插入所有的多项选择。

这应该可以正常工作,除非您有数百万个问题。最终$allAnswerIDs 可能会变得太大而无法存储,但我认为在这种情况下它不会很快成为问题。

$allAnswerIDs = array();

foreach ($entries as $entry) {
    if(is_numeric(substr($entry, 0, 1)) === true) {
        // Insert question as you do now.

        // Store the question ID in the array.
        $allAnswerIDs[$questionId] = array();
    } else {
        // Insert answer.

        // Store ID in $answerIDs as an array (or as a string, if you like).
        $allAnswerIDs[$questionID][] = $answerID;
    }
}

foreach ($allAnswerIDs as $questionID => $questionAnswerIDs) {
    // Build a string of the answers per question.
    $answerIDs = implode(',', $questionAnswerIDs);

    // Insert the multiple choice row using $questionID and $answerIDs.
}

3) 在循环之后使用批量插入。 您可以编写一个稍微复杂一点的 SQL 语句,一次插入所有这些语句,例如:

INSERT INTO multichoice(question, mc_answers)
SELECT
  question,
  GROUP_CONCAT(choices) as AnswerIDs
FROM
  Choice

您可以在脚本结束时执行该语句一次,它将使数据库一次生成多选表的全部内容。

4) 制作视图。 如您所见,方法 3 中的(相对简单的)select 显示了您希望在多选表中拥有的所有信息,因此您可以考虑将其设置为视图而不是将其插入到表中,而不是在数据库中.这样,您根本不必存储信息。你的 PHP 代码会更简单,你的数据库更干净,你可以像从表中一样从视图中查询。

【讨论】:

  • 这真的很有帮助!非常感谢您提供的详细信息!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
相关资源
最近更新 更多