It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have a jsfiddle here: http://jsfiddle.net/ybZvv/58/
Please follow steps in fiddle:
1: When you open fiddle, click on "Add Question" button twice, this will append 2 rows.
2: In first row select answer buttons "A" and "C", in second row select answer buttons "A", "B" and "E". The text input values for each answer button selected is displayed underneath.
Now what I want to do is post the question number and the answer values into the database.
The database should look like this below when posted:
Question Table:
QuestionId (Question Number)
1
2
Answer Table:
AnswerId (auto) QuestionId Answer
1 1 A
2 1 C
3 2 A
4 2 B
5 2 E
What my question is that how do I post the answers and the correct question numbers in my mysqli code below so that it inserts those Answers and Question Numbers in the "Question" and "Answer" Tables?
Below I have set up the mysqli/php code, but it needs retweaked so it can insert the answers and the relevant question numbers correctly.
$i = 0;
$c = count($_POST['numQuestion']); //count number of rows
for($i = 0; $i < $c; $i++ ){
$questionsql = "INSERT INTO Question (QuestionId)
VALUES (?)";
if (!$insert = $mysqli->prepare($questionsql)) {
// Handle errors with prepare operation here
}
$insert->bind_param("i", $_POST['numQuestion'][$i]);
$insert->execute();
if ($insert->errno) {
// Handle query error here
}
$insert->close();
$lastID = $mysqli->insert_id;
$answersql = "INSERT INTO Answer (QuestionId, Answer)
VALUES (?, ?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
}
$insertanswer->bind_param("is", $lastID, $_POST['value'][$i]);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
}
$insertanswer->close();
}
I have done a var_dump($_POST) for the above scenario and this is what it outputs:
array(2) {
["numQuestion"]=> array(2) {
[0]=> string(1) "1"
[1]=> string(1) "2"
}
["submitDetails"]=> string(14) "Submit Details"
["value"]=> array(4) {
["answerARow"]=> string(1) "A"
["answerCRow"]=> string(1) "C"
["answerBRow"]=> string(1) "B"
["answerERow"]=> string(1) "E"
}
}
I am receiving 2 errors which are identical:
Warning: mysqli_stmt::execute(): (23000/1048): Column 'Answer' cannot
be null in /.../ on line 257 Warning: mysqli_stmt::execute():
(23000/1048): Column 'Answer' cannot be null in /.../ on line 257
UPDATE:
I have updated fiddle to include the multi-dimensional array, sorry I forgot to put it in but the line of code for this is below:
var $newBtn = $(("<input class='answerBtnsRow answers' type='button' style='display:%s;' onclick='btnclick(this, " + gQuestionIndex + ");' />").replace('%s',$this.is(':visible')?'inline-block':'none')).attr('name', "value[" + gQuestionIndex + "][]").attr('value', $this.val()).attr('class', $this.attr('class')).attr('id', $this.attr('id')+'Row');
My suggestion is to use a multi-dimensional array in this format: value[n][], where n is the question number. With this new setup, you should end up with the following input fields:
<input type="hidden" value="A" name="value[1][]">
<input type="hidden" value="B" name="value[1][]">
<input type="hidden" value="A" name="value[2][]">
<input type="hidden" value="C" name="value[2][]">
<input type="hidden" value="E" name="value[2][]">
Note that the selected value is encoded in the value attribute. The name attribute only contains the question to which the value belongs.
It seems like the $POST does not have all the information, i suggest you to change the post structure to relation the question to the answer, something like this:
array(2) {
["numQuestion"]=> array(2) {
[0]=> string(1) "1"
[1]=> string(1) "2"
}
["submitDetails"]=> string(14) "Submit Details"
["question_1"] => array(2) {
[0] => string(1) "A"
[1] => string(1) "C"
}
["question_2"] => array(2) {
[0] => string(1) "A"
[1] => string(1) "B"
[2] => string(1) "E"
}
}
Now, if the post would have that structure, you could do something like this to insert the data:
$numQuestionArray = $_POST["numQuestion"];
for($i =0; $i < count($numQuestionArray);$i++)
{
$questionId = $numQuestionArray[$i];
$questionsql = "INSERT INTO Question (QuestionId) VALUES (?)";
if (!$insert = $mysqli->prepare($questionsql)) {
// Handle errors with prepare operation here
}
$insert->bind_param("i", $questionId);
$insert->execute();
if ($insert->errno) {
// Handle query error here
}
$insert->close();
$lastID = $mysqli->insert_id;
$questionAnswerPostStr = "question_".$questionId;
$answerArray = $_POST[$questionAnswerPostStr];
for($j =0; $j < count($numQuestionArray);$j++)
{
$answer = $numQuestionArray[$j];
$answersql = "INSERT INTO Answer (QuestionId, Answer) VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
}
$insertanswer->bind_param("is", $lastID, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
}
$insertanswer->close();
}
}
However, i still think the question_id should be auto incremented on the table instead of inserting the $POST value.
Related
I am trying to insert each answer for each question in the database. Problem is that there is a possibility that a question may have no answers, so I tried the code below but it does not insert a db row if a question has no answer, what I was trying to do is that if no answer then display the string No Answer under the Answer column for that question:
$answersql = "INSERT INTO Answer (QuestionId, Answer)
VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
if( $insert && $insertanswer)
{
$c = count($_POST['numQuestion']);
$question_ids = array();
for($i = 0; $i < $c; $i++ )
{
... //Question INSERT goes here
$questionId = $mysqli->insert_id;
$question_ids[$questionNo] = $questionId;
}
$results = $_POST['value'];
foreach($results as $id => $value)
{
$answer = $value;
$quesid = (int)$question_ids[$id];
foreach($value as $answer)
{
if($answer == '' || $answer === null){
$answer = 'No Answer';
}
$insertanswer->bind_param("is", $quesid, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
echo __LINE__.': '.$insertanswer->error;
break 7;
}
}
}
//close your statements at the end
$insertanswer->close();
}
The ['value'] comes from an input:
var $newBtn = $(("<input class='answerBtnsRow answers' type='button' style='display:%s;' onclick='btnclick(this, " + gQuestionIndex + ");' />").replace('%s', $this.is(':visible') ? 'inline-block' : 'none')).attr('name', "value[" + gQuestionIndex + "][]").attr('value', $this.val()).attr('class', $this.attr('class')).attr('id', $this.attr('id') + 'Row');
UPDATE:
Below is the SHOW CREATE TABLE for the Answer Table:
CREATE TABLE `Answer` (
`AnswerId` int(10) NOT NULL AUTO_INCREMENT,
`QuestionId` int(10) NOT NULL,
`Answer` varchar(10) DEFAULT NULL,
PRIMARY KEY (`AnswerId`)
) ENGINE=InnoDB AUTO_INCREMENT=280 DEFAULT CHARSET=utf8
Below is a var dump where if I set question 1 to have answers B and C and set question 2 to have no answers at all, it outputs the following:
var_dump($question_ids);
var_dump($results);
array(2) {
[1]=> int(247)
[2]=> int(248)
}
array(1) {
[1]=> array(2) {
[0]=> string(1) "B"
[1]=> string(1) "C" }
}
You can tell from your var_dumps that you have two questions, but only one set of answers. your design flaw doesn't link the answers to the questions, from what I can see.
no second index in $results, means no second set of answers, therefore no insert ...
but if you have three questions, and two answer sets, do those answers belong to question 1&2 or 2&3, or 1&3. I am not see how you mach your question id to the result set.
I am trying to insert each answer for each question in the database. Problem is that there is a possibility that a question may have no answers, so I tried the code below but it does not insert a db row if a question has no answer, what I was trying to do is that if no answer then display the string No Answer under the Answer column for that question:
$answersql = "INSERT INTO Answer (QuestionId, Answer)
VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
if( $insert && $insertanswer)
{
$c = count($_POST['numQuestion']);
$question_ids = array();
for($i = 0; $i < $c; $i++ )
{
... //Question INSERT goes here
$questionId = $mysqli->insert_id;
$question_ids[$questionNo] = $questionId;
}
$results = $_POST['value'];
foreach($results as $id => $value)
{
$answer = $value;
$quesid = (int)$question_ids[$id];
foreach($value as $answer)
{
if($answer == '' || $answer === null){
$answer = 'No Answer';
}
$insertanswer->bind_param("is", $quesid, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
echo __LINE__.': '.$insertanswer->error;
break 7;
}
}
}
//close your statements at the end
$insertanswer->close();
}
The ['value'] comes from an input:
var $newBtn = $(("<input class='answerBtnsRow answers' type='button' style='display:%s;' onclick='btnclick(this, " + gQuestionIndex + ");' />").replace('%s', $this.is(':visible') ? 'inline-block' : 'none')).attr('name', "value[" + gQuestionIndex + "][]").attr('value', $this.val()).attr('class', $this.attr('class')).attr('id', $this.attr('id') + 'Row');
Below is the SHOW CREATE TABLE for the Answer Table:
CREATE TABLE `Answer` (
`AnswerId` int(10) NOT NULL AUTO_INCREMENT,
`QuestionId` int(10) NOT NULL,
`Answer` varchar(10) DEFAULT NULL,
PRIMARY KEY (`AnswerId`)
) ENGINE=InnoDB AUTO_INCREMENT=280 DEFAULT CHARSET=utf8
Below is a var dump where if I set question 1 to have answers B and C, question 2 to have no answers, question 3 to have answer B and question 4 to have no answer, it outputs the following from var dump:
var_dump($question_ids);
var_dump($results);
array(4) {
[1]=> int(265)
[2]=> int(266)
[3]=> int(267)
[4]=> int(268)
}
[1]=> array(2) {
[0]=> string(1) "B"
[1]=> string(1) "C"
}
[3]=> array(1) {
[0]=> string(1) "B"
}
So it outputs those set of answers in questions 1 and 3. But does not post No Answer for question 2 and 4.
If all questions had an answer as thisL
question 1: B C
question 2: A
question 3: B
question 4: A C
Then the var dump displays this in var dump:
array(4) {
[1]=> int(277)
[2]=> int(278)
[3]=> int(279)
[4]=> int(280)
}
array(4) {
[1]=> array(2) {
[0]=> string(1) "B"
[1]=> string(1) "C" }
[2]=> array(1) {
[0]=> string(1) "A"
}
[3]=> array(1)
{
[0]=> string(1) "B"
}
[4]=> array(2)
{
[0]=> string(1) "A"
[1]=> string(1) "C"
} }}
As you can see for each question is inserts the relevant answers. So the issu is if the question has no answers that it does not insert a db row and state No Answer. My question is how to include a No Answerfor each question in the db that has no answers selected in those questions?
Simply do not insert anything into Answer table when there is no answer. Rest of your solution is basically correct.
When displaying questions with answer, check if there is answer (empty select result or null in left joined column) to show and if not, show "No answer". But there is no "No answer" in database.
When your code get to $results = $_POST['value'];, $question_ids is populated with the ids of questions that must be included in the table.
My suggestion is to remove elements from this array right after including the first answer to the related question. This way, after the foreach($results as $id => $value) loop, this array will contain only questions without explicit answers. The next step is just to include these pseudo-answer "No answer" in the DB.
The relevant code for you (inserted lines are //* commented):
$notAnswered = $question_ids; //* Make a copy
$results = $_POST['value'];
foreach ($results as $id => $value) {
$answer = $value;
$quesid = (int)$question_ids[$id];
$pos = array_search($quesid, $notAnswered); //* Search for it
if ($pos !== false) //* It's in the array
array_splice($notAnswered, $pos, 1); //* Delete it from the array
foreach ($value as $answer) {
$insertanswer->bind_param("is", $quesid, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
echo __LINE__.': '.$insertanswer->error;
break 7;
}
}
}
//* Insert 'No Answer' for each question not answered
foreach ($notAnswered as $id) {
$insertanswer->bind_param('is', $id, 'No Answer');
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
echo __LINE__.': '.$insertanswer->error;
break 7;
}
}
// Close your statements at the end
$insertanswer->close();
One important thing to note here: array_splice is very slow in PHP for big arrays (>100 elements). But I don't think this is the case here.
Lets say I have 3 questions:
QuestionNo Video
1
2 wildlife.mp4
3
4 colors.mp4
sports.mp4
Now what I am doing is insert each question into database giving each question its own automatic QuestionId so it now looks like this technically:
QuestionId QuestionNo Video
123 1
124 2 wildlife.mp4
125 3
126 4 colors.mp4
sports.mp4
Now below is the Question Table in db:
QuestionId (pk auto) QuestionNo
123 1
124 2
125 3
126 4
Now each video is stored in its own id in the Video Table:
VideoId (auto pk) VideoFile
12 wildlife.mp4
13 colors.mp4
14 sports.mp4
Now finally and this is where the issue is, I have a Video_Question Table which we use to know which video goes into which question. Now the issue is that the way I have set up the insert for this is that it retrieves the last QuestionId insert and then find the first videoId it finds and displays it with that QuestionId. This is incorrect as that it means video is stored in wrong question. In db for above example it will display it like this:
Video_Question Table:
VideoQuestionId (auto pk) QuestionId VideoId
4 123 12
5 124 13
6 124 14
The above is incorrect as that VideoId 12 should not belong in QuestionId 123, it should be in 124 and VideoId 13 and 14 should be in 126, not 124 like below:
Video_Question Table:
VideoQuestionId (auto pk) QuestionId VideoId
4 124 12
5 126 13
6 126 14
My question is that looking at above example, how can I get the videoid to be inserted with the correct QuestionId? I believe the issue is that it does not recognise that a question has possibility of no video but I am not sure and hence why I am asking for help>
Below is code where it does the insert Question table and Video_Question tables:
// Prepare your statements ahead of time
$questionsql = "INSERT INTO Question (SessionId, QuestionNo,
QuestionContent, NoofAnswers, ReplyId, QuestionMarks, OptionId)
VALUES (?)";
if (!$insert = $mysqli->prepare($questionsql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
$videoquestionsql = "INSERT INTO Video_Question (VideoId, QuestionId)
VALUES (?, ?)";
if (!$insertvideoquestion = $mysqli->prepare($videoquestionsql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
//make sure both prepared statements succeeded before proceeding
if( $insert && $insertvideoquestion)
{
$c = count($_POST['numQuestion']);
$question_ids = array();
for($i = 0; $i < $c; $i++ )
{
$questionNo = $_POST['numQuestion'][$i];
$insert->bind_param("i", $questionNo);
$insert->execute();
if ($insert->errno)
{
// Handle query error here
echo __LINE__.': '.$insert->error;
break 1;
}
$questionId = $mysqli->insert_id;
$question_ids[$questionNo] = $questionId;
}
$vidresults = $_POST['vidid'];
foreach($vidresults as $videoid => $vidvalue)
{
$video = $vidvalue;
$vidquesid = (int)$question_ids[$videoid];
foreach($vidvalue as $video)
{
$insertvideoquestion->bind_param("ii",$video, $vidquesid);
$insertvideoquestion->execute();
if ($insertvideoquestion->errno) {
// Handle query error here
echo __LINE__.': '.$insertvideoquestion->error;
break 5;
}
}
}
$insertvideoquestion->close();
$insert->close();
}
UPDATE:
Below are the var_dumps which match with the example mentioned above, only difference is the file names and id numbers. There are 4 questions as mentioned in example mentioned above:
var_dump($question_ids);
array(4) {
[1]=> int(277)
[2]=> int(278)
[3]=> int(279)
[4]=> int(280)
}
var_dump($_POST['vidid']);
array(3) {
[1]=> array(1) {
[0]=> string(3) "148"
}
[2]=> array(1) {
[0]=> string(3) "149"
}
[3]=> array(1) {
[0]=> string(3) "150"
} }
Combined the above var_dumps together looks like this:
array(4) {
[1]=> int(289)
[2]=> int(290)
[3]=> int(291)
[4]=> int(292)
}
array(3) {
[1]=> array(1) {
[0]=> string(3) "148"
}
[2]=> array(1) {
[0]=> string(3) "149"
}
[3]=> array(1) {
[0]=> string(3) "150"
} }
EXTRA DETAILS:
By using this line of code:
$('.hiddenvid').append('<input type="hidden" name="vidid[' + videocounter + '][]" id="'+videoID+'" value="' + videoID + '" />');
It is able to retrieve and display the VideoId inserted into the VideoTable for each uploaded video. So for example if Wildlife.mp4 has VideoId which is 32, then in the hidden input it will displat the number 32 in the hidden input for that video in the application.
Then by using a multidimensional array and using videocounter which is a variable which starts with 0 and increments for each question using ++, - name="vidid[' + videocounter + '][]", each input belongs to a question number depending on which question the video was uploaded in. So for example if the video was uploaded in question 2, the input recgnises that the video id retrieved belongs to question 2. If I do it for question 4, then it will recognise that input belongs to question 4 etc.
HERE IS A DEMO I JUST MEAD UP WHICH YOU CAN USE TO SEE HOW IT WORKS (I changed the hidden input to text input so you can see what is happening): DEMO
UPDATE:
At moment it is displaying 0 for QuestionId when inserting data in Video_QuestionId, is the code below correct:
function stopVideoUpload(success, videoID, videofilename){
var result = '';
videocounter++;
var questionNum = $(this).closest('td').siblings('.qid').find('input.num_questionsRow').val();
if (success == 1){
result = '<span class="videomsg'+videocounter+'">The file was uploaded successfully</span>';
$('.hiddenvid').append('<input type="text" name="vidid['+questionNum+'][]" id="'+videoID+'" value="' + videoID + '" />');
$('.listVideo').eq(window.lastUploadVideoIndex).append('<div>' + htmlEncode(videofilename) + '<button type="button" class="deletefilevideo" data-videoID="'+videoID+'" data-video_file_name="' + videofilename + '" value="'+videoID+'">Remove</button><br/><a href="previewvideo.php?filename='+ videofilename +'" title="Click to view in New window" target="_blank">Test Video<hr/></div>');
}
....
}
I don't see anywhere in your front-end that connects the uploaded videos to the question they're meant to be related to. So when you submit the form it basically just sends two unrelated lists numQuestion: (q1, q2, q3...) and vidid: (videos1[], videos2[], videos3[]...). The array keys are just the order they were added which is not what you wanted.
There are many different ways you could approach this but the most direct is to change the way you build those hidden fields for the videos so that they are keyed on the questions' ids.
Instead of:
<input type="text" name="vidid[]" id="'+videoID+'" value="' + videoID + '" />
You want this to be something like
<input type="text" name="vidid['+questionNum+'][]" id="'+videoID+'" value="' + videoID + '" />
Where questionNum is the question the video is meant for.
EDIT:
You won't be able to determine this at call-time for your stopVideoUpload() function so you need to make a new parameter to that function and pass this value in. That means of course the PHP code for video upload needs to know what value to pass to stopVideoUpload(). You should be able to do this easily enough by changing the Add Question behavior to put the question number in a field in the video upload form.
It maybe trying to insert two values as primary keys. Set database fields to non-auto-increment if this is the case. Then---parent as videoid to match each question with its own individual id. You cant properly insert into a row that's already been created if this is the case.,,use update for them. Also some tables will not do as you wish when using auto-incrementing. If this is the case turn off auto-incrementing and place--max(id2)+1--in place of all your Primary $id's value-entry's.
---------------select max(id)+1, "'.$AnswerId.'", etc. Also Each table should have each corresponding parent-id.
video-table
------------pid------
questions-table
------------qid-----pid----id
video-question-table
------------id------qid----pid
if(mysql_query('insert into questions (id, parent, questionContent, NoofAnswers,
ReplyId, AnswerId) select "'.$id.'", "'.$res['parent'].'", "'.$questionCont.'",
"'.$Noofanswers.'", "'.$ReplyId.'", "'.$AnswerId.'" from questions where
id="'.$id.'"') and mysql_query('update videos_questions set VideoId="'.$vid.'"and set
QuestionId="'.$qid where id="'.$id.'" and parent=1')) etc.
I am having trouble being able to insert QuestionId into the Answer Table.
The Question inserts with no problem, but I am trying to retrieve the QuestionId from the Question Table which is an auto increment into the Answer Table by finding the SessionId and QuestionNo that particular QuestionId belongs to. Instead it keeps displaying 0 for QuestionId when inserted into Answer Table.
Now I know the query which tries to perform the select for each QuestionId from the Question Table is correct as this has been tested. I think the problem is where I have placed my code but I am not sure?
Here are the db tables:
Question Table
QuestionId (auto) SessionId QuestionNo
4 2 1
5 2 2
6 2 3
Answer Table at moment:
AnswerId (auto) QuestionId Answer
7 0 A
8 0 C
9 0 A
10 0 B
11 0 True
What Answer Table should look like:
AnswerId (auto) QuestionId Answer
7 4 A
8 4 C
9 5 A
10 5 B
11 6 True
Below is the code:
$questionsql = "INSERT INTO Question (SessionId, QuestionNo)
VALUES (?, ?)";
if (!$insert = $mysqli->prepare($questionsql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
$answersql = "INSERT INTO Answer (QuestionId, Answer)
VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
//make sure both prepared statements succeeded before proceeding
if( $insert && $insertanswer)
{
$sessid = $_SESSION['id'] . ($_SESSION['initial_count'] > 1 ? $_SESSION['sessionCount'] : '');
$c = count($_POST['numQuestion']);
for($i = 0; $i < $c; $i++ )
{
$insert->bind_param("ii", $sessionid, $_POST['numQuestion'][$i]);
$insert->execute();
if ($insert->errno)
{
// Handle query error here
echo __LINE__.': '.$insert->error;
break 1;
}
}
$results = $_POST['value'];
foreach($results as $id => $value)
{
$answer = $value;
$lastID = $id;
$questionidquery = "SELECT QuestionId FROM Question WHERE (QuestionNo = ? AND SessionId = ?)";
if (!$questionidstmt = $mysqli->prepare($questionidquery)) {
// Handle errors with prepare operation here
echo __LINE__.': '.$mysqli->error;
}
// Bind parameter for statement
$questionidstmt->bind_param("ii", $lastID, $sessionId);
// Execute the statement
$questionidstmt->execute();
if ($questionidstmt->errno)
{
// Handle query error here
echo __LINE__.': '.$questionidstmt->error;
break 2;
}
// This is what matters. With MySQLi you have to bind result fields to
// variables before calling fetch()
$questionidstmt->bind_result($quesid);
// This populates $optionid
$questionidstmt->fetch();
$questionidstmt->close();
foreach($value as $answer)
{
$insertanswer->bind_param("is", $quesid, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
echo __LINE__.': '.$insertanswer->error;
break 3;
}
}
}
//close your statements at the end
$insertanswer->close();
$insert->close();
}
?>
UPDATE:
Results from var_dump($_POST);
array(8) {
["numberAnswer"]=> array(2) {
[0]=> string(1) "1"
[1]=> string(1) "1"
}
["numQuestion"]=> array(2)
{
[0]=> string(1) "1"
[1]=> string(1) "2"
}
["questionText"]=> array(2) {
[0]=> string(12) "What is 2+2?"
[1]=> string(12) "What is 4+4?"
}
["gridValues"]=> array(2) {
[0]=> string(1) "4"
[1]=> string(1) "4"
}
["reply"]=> array(2) {
[0]=> string(6) "single"
[1]=> string(6) "single"
}
["textWeight"]=> array(2) {
[0]=> string(1) "5"
[1]=> string(1) "5"
}
["submitDetails"]=> string(14) "Submit Details" ["value"]=> array(2) {
[1]=> array(1) {
[0]=> string(1) "B"
}
[2]=> array(1) {
[0]=> string(1) "D"
}
}
}
Right now your QuestionID is coming from $_POST['value'], which is probably not what you want... you need to get the automatically generated QuestionID from mysql after each question is inserted.
You can retrieve the last generated ID using $mysqli->insert_id. Do this after each call to $insert->execute();, then use those IDs when you go to insert your answers.
Edit 1:
You should be using $mysqli->insert_id, because insert_id is only valid on a connection object (yours is called $mysqli).
You also need to assign the insert_id to something. I'm having trouble following your code but I think what you want is to store question IDs in an array for later use, something like this:
$question_ids[$i] = $mysqli->insert_id
I'm at a loss for what you're trying to do after this, I guess you pull in some answers with a corresponding question number but... perhaps if you can post the output of var_dump($_POST) we will understand a bit better. In any case you will need some kind of a loop that inserts the answers for each question, and you can (hopefully) use the array $question_ids[$i] to retrieve the QuestionIDs.
Edit 2:
Here is some sample code (untested), try to get this working before getting fancy with $_POST and $_SESSION
<?php
$questions = array(
array(2, 1),
array(2, 2),
# etc
);
$answers = array(
array(A, C),
array(A, B),
);
$questionsql = "INSERT INTO Question (SessionId, QuestionNo) VALUES (?, ?)";
if (!$insert = $mysqli->prepare($questionsql)) {
die('couldn\'t prepare statement 1');
}
$answersql = "INSERT INTO Answer (QuestionId, Answer) VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
die('couldn\'t prepare statement 2');
}
$c = count($questions);
for($i = 0; $i < $c; $i++)
{
$insert->bind_param("ii", $questions[$i][0], $questions[$i][1]);
$insert->execute();
if ($insert->errno)
{
die("Error inserting question $i");
}
$lastID = $mysqli->insert_id;
foreach ($ans in $answers[$i])
{
$insertanswer->bind_param("is", $lastID, $ans);
$insertanswer->execute();
if ($insertanswer->errno) {
die("Error inserting answer to question $i");
}
}
}
$insertanswer->close();
$insert->close();
?>
I want use a multi-dimensional array in this format: value[n][], where n is the question number. With this new setup, you should end up with the following input fields:
<input type="hidden" value="A" name="value[1][]">
<input type="hidden" value="B" name="value[1][]">
<input type="hidden" value="A" name="value[2][]">
<input type="hidden" value="C" name="value[2][]">
<input type="hidden" value="E" name="value[2][]">
Note that the selected value is encoded in the value attribute. The name attribute only contains the question to which the value belongs.
So what the above inputs are stating is this:
question 1: answer: A
question 1: answer: B
question 2: answer: A
question 2: answer: C
question 2: answer: E
I want to insert these details into "Question" and "Answer" database tables below:
Question Table:
SessionId QuestionId
MUL 1
MUL 2
Answer Table:
AnswerId (auto) SessionId QuestionId Answer
1 MUL 1 A
2 MUL 1 B
3 MUL 2 A
4 MUL 2 C
5 MUL 2 E
Now I have attempted writing the mysqli/php code below to insert these values into the database but I am receiving errors and failing badly in wanting to acheive what I want to achieve. I need help being able to correctly insert the correct values in the relevant tables.
Below is the php/mysqli code:
var_dump($_POST);
$i = 0;
$c = count($_POST['numQuestion']);
for($i = 0; $i < $c; $i++ ){
/*
switch ($_POST['gridValues'][$i]){
case "3":
$selected_option = "A-C";
break;
case "4":
$selected_option = "A-D";
break;
case "5":
$selected_option = "A-E";
break;
default:
$selected_option = "";
break;
}
*/ needed later on when I insert grid values
$results = $_POST['value'];
foreach($results as $id => $value) {
$answer = implode(':', $value);
$questionsql = "INSERT INTO Question (SessionId, QuestionId)
VALUES (?, ?)";
$sessid = $_SESSION['id'] . ($_SESSION['initial_count'] > 1 ? $_SESSION['sessionCount'] : '');
if (!$insert = $mysqli->prepare($questionsql)) {
// Handle errors with prepare operation here
}
$insert->bind_param("si", $sessid, $id);
$insert->execute();
if ($insert->errno) {
// Handle query error here
}
$insert->close();
$lastID = $id->insert_id;
foreach($value as $answer) {
$answersql = "INSERT INTO Answer (SessionId, QuestionId, Answer)
VALUES (?, ?)";
if (!$insertanswer = $mysqli->prepare($answersql)) {
// Handle errors with prepare operation here
}
$insertanswer->bind_param("sis" $sessid, $lastID, $answer);
$insertanswer->execute();
if ($insertanswer->errno) {
// Handle query error here
}
$insertanswer->close();
}
}
}
The var_dump($_POST) outputs this below:
array(3) {
["numQuestion"]=> array(2) {
[0]=> string(1) "1"
[1]=> string(1) "2" }
["submitDetails"]=> string(14) "Submit Details"
["value"]=> array(4) {
["answerARow"]=> string(1) "A"
["answerCRow"]=> string(1) "C"
["answerBRow"]=> string(1) "B"
["answerERow"]=> string(1) "E" }
}
Below are the errors I am receiving and the line of code each error is linked to:
Warning: implode(): Invalid arguments passed in /.../ on line 226
$answer = implode(':', $value);
Notice: Trying to get property of non-object in /.../ on line 250
$lastID = $id->insert_id;
Warning: Invalid argument supplied for foreach() in /.../ on line 252
foreach($value as $answer) {
Warning: mysqli_stmt::execute(): (23000/1062): Duplicate entry
'MUL-0' for key 'PRIMARY' in /.../ on line 242
The Above Error Points to the $insert query
MORE INFO:
The structure I really want to acheive after posting the text inputs is below:
array(2) {
["numQuestion"]=> array(2) {
[0]=> string(1) "1"
[1]=> string(1) "2"
}
["submitDetails"]=> string(14) "Submit Details"
["1"] => array(2) {
[0] => string(1) "A"
[1] => string(1) "C"
}
["2"] => array(2) {
[0] => string(1) "A"
[1] => string(1) "B"
[2] => string(1) "E"
}
}
When the user posts the text input values, it should insert the question numbers and the answers which belongs to their relevant question number.
A few things:
$result / $_POST['value'] is a one-dimensional array, so $value in your foreach
loop is a string that you cannot use implode on;
$lastID = $id->insert_id; should be $insert->insert_id and I'm not sure if you can close the connection already before you call
that statement;
$value is a string (see first point) so you cannot use foreach there (third warning).