stijn0713 Posted August 26, 2012 Share Posted August 26, 2012 I know it's really not done to ask for just fixing a problem but i've been trying to debug this piece for ages and i can't seem to get it figured out. It's a piece of code to display questions and belonging options from a survey. I will include the php code and 2 mysql tables which are quered against. The displaying goes wrong when i add AND NOT EXISTS(SELECT poll_answers.ID FROM poll_answers WHERE poll_answers.ID_question = poll_questions.ID AND poll_answers.respondent_id = "'.$_SESSION['Respondent_Username'].'") to the query for preventing the display of questions that are already answered by the person that is logged in for the survey. Without this subquery, the question are retrieved nicely, and when submitting an answer, it goes to the next question. With the subquery, it seems that mysql_fetch_assoc always retrieves every second question, skipping a question... Here is the code: <!DOCTYPE html> <html> <head> <title>Enquete</title> <link rel="stylesheet" type="text/css" href="stylesheet_enquete.css" /> </head> <script src="jquery/jquery-1.7.js"></script> <script> $(document).ready(function(){ $('#link_vorige').click(function(e) { e.preventDefault(); alert('het is niet toegelaten terug te keren in deze enquete'); }) }); // deze validatie moet nog sterk verbeterd worden! $(document).ready(function(){ $("#form_enquete").submit(function(e) { var checked = $("#form_enquete input:checked").length > 0; if(!checked) { e.preventDefault(); alert('controleer of je een antwoord hebt gegeven!'); } }) }); </script> <?php require_once('/connect/qualifield.php'); if (!isset($_SESSION)) { session_start(); } /* $MM_restrictGoTo = "./loginrespondent.php"; if (!(isset($_SESSION['Respondent_Username']))) { $_SESSION['PrevUrl'] = $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']; header("Location: ". $MM_restrictGoTo); exit; } */ $_SESSION['Respondent_Username'] = 1; // get the id of the survey if(isset($_GET['ID'])){ $_SESSION['poll_id'] = $_GET['ID']; } // if post is set, register answer for the question if(isset($_POST['register_answer'])){ switch($_POST['vraag_type']) { case "1": // radio mysql_query("INSERT INTO poll_answers (ID_option, ID_question, ID_poll, respondent_id) VALUES ('".$_POST['answer_radio']."','".$_POST['register_vraag']."', '".$_POST['register_enquete']."', '".$_SESSION['Respondent_Username']."')"); break; case "2": // checkbox foreach (array_keys($_POST['answer_cb'],'on') as $k) { mysql_query("INSERT INTO poll_answers (ID_option, ID_question, ID_poll, respondent_id) VALUES ('".$k."','".$_POST['register_vraag']."', '".$_POST['register_enquete']."', '".$_SESSION['Respondent_Username']."')"); } break; case "3": // schaal $option = explode('&', $_POST['answer_schaal']); mysql_query("INSERT INTO poll_answers (ID_option, ID_question, ID_poll, respondent_id, option_label_case_schaal) VALUES ('".$option[0]."','".$_POST['register_vraag']."', '".$_POST['register_enquete']."', '".$_SESSION['Respondent_Username']."', '".$option[1]."')"); break; } } $start = (!empty($_GET['start'])) ? $_GET['start'] : '0'; $limit = 1; $vragen = mysql_query('SELECT SQL_CALC_FOUND_ROWS * FROM poll_questions WHERE ID_poll = "'.$_SESSION['poll_id'].'" AND NOT EXISTS(SELECT poll_answers.ID FROM poll_answers WHERE poll_answers.ID_question = poll_questions.ID AND poll_answers.respondent_id = "'.$_SESSION['Respondent_Username'].'") ORDER BY position ASC LIMIT '.$start.', '.$limit.''); $nbItems = mysql_result(mysql_query('SELECT FOUND_ROWS() AS nbr'), 0, 'nbr'); $currentPage = floor($start/$limit) + 1; if($nbItems !== 0){ $row_vraag = mysql_fetch_assoc($vragen); $content = "V $currentPage: " . $row_vraag['poll_question']; $getOptions = mysql_query("SELECT * FROM poll_options WHERE ID_question = '".mysql_real_escape_string($row_vraag['ID'])."' ORDER BY position ASC") or die(mysql_error()); $row_options = mysql_fetch_assoc($getOptions); $content .= '<form method="POST" action="survey.php?start='.$currentPage.'" id="form_enquete" >'; $content .= '<table>'; do { switch($row_vraag['question_type']){ case "1": // radio $content .= '<BR><tr><input type="radio" name="answer_radio" value="'.$row_options['ID'].'" />'.stripslashes($row_options['poll_option']).'</tr>'; break; case "2": // checkbox $content .= '<BR><tr><input type="checkbox" name="answer_cb['.$row_options['ID'].']" />'.stripslashes($row_options['poll_option']).'</tr>'; break; case "3": // schaal $content .= '<BR><tr>'.stripslashes($row_options['schaallabel_links']). " "; for($i =1; $i <= $row_options['poll_option']; $i++){ $content .= $i.' <input type="radio" name="answer_schaal" value="'.$row_options['ID'].'&'.$i.'" /> '; } $content .= " ".stripslashes($row_options['schaallabel_rechts']); $content .= "</tr>"; break; } } while ($row_options = mysql_fetch_assoc($getOptions)); $content .= '</table>'; if($start >= 1){ $content .= '<a href ="survey.php?start='.($currentPage-2).'" id="link_vorige"> vorige </a>'; } $content .= '<input type="hidden" name="register_enquete" value="'.$_SESSION['poll_id'].'" />'; $content .= '<input type="hidden" name="register_vraag" value="'.$row_vraag['ID'].'" />'; $content .= '<input type="hidden" name="vraag_type" value="'.$row_vraag['question_type'].'" />'; $content .= '<input type="submit" name="register_answer" value="Voeg antwoord toe" />'; } else $content = 'Einde, enquete. Bedankt voor het invullen van de enquete!'; ?> <body> <div id="bekijk_enquete" style="center"> <?php echo $content; ?> </div> </form> </body> </html> poll_questions table with a few sample questions: CREATE TABLE IF NOT EXISTS `poll_questions` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `ID_poll` int(11) NOT NULL, `poll_question` varchar(255) NOT NULL, `question_type` int(11) NOT NULL, `position` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=45 ; -- -- Gegevens worden uitgevoerd voor tabel `poll_questions` -- INSERT INTO `poll_questions` (`ID`, `ID_poll`, `poll_question`, `question_type`, `position`) VALUES (35, 7, 'Hou je van voetbal?', 1, 3), (36, 7, 'wat vind je van de speelstijl van barcelona?', 3, 2), (37, 7, 'wie is jouw favoriete club?', 2, 1), (43, 7, 'nog een vraag', 1, 4), (44, 7, 'nog 1', 1, 5); poll_options table with a few sample options: CREATE TABLE IF NOT EXISTS `poll_options` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `ID_question` int(11) NOT NULL, `ID_poll` int(11) NOT NULL, `poll_option` varchar(255) NOT NULL, `schaallabel_links` varchar(25) DEFAULT NULL, `schaallabel_rechts` varchar(25) DEFAULT NULL, `position` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=54 ; -- -- Gegevens worden uitgevoerd voor tabel `poll_options` -- INSERT INTO `poll_options` (`ID`, `ID_question`, `ID_poll`, `poll_option`, `schaallabel_links`, `schaallabel_rechts`, `position`) VALUES (35, 35, 7, 'ja', NULL, NULL, 2), (36, 35, 7, 'nee', NULL, NULL, 1), (37, 36, 7, '5', 'slecht', 'goed', 1), (38, 37, 7, 'gent', NULL, NULL, 2), (39, 37, 7, 'lierse', NULL, NULL, 1), (40, 37, 7, 'antwerpen', NULL, NULL, 3), (50, 43, 7, 'a', NULL, NULL, 1), (51, 43, 7, 'b', NULL, NULL, 2), (52, 44, 7, 'a', NULL, NULL, 1), (53, 44, 7, 'b', NULL, NULL, 2); It's 1 A4 of code, sorry for the little overhead but avanced readers probably read through it in a few minutes. If somebody could point me in a right direction, it would be very much appreciated! Quote Link to comment https://forums.phpfreaks.com/topic/267592-code-debugging/ Share on other sites More sharing options...
Christian F. Posted August 26, 2012 Share Posted August 26, 2012 I suspect it's because this bit here: SELECT poll_answers.ID From looking at the rest of the query, it seems that it should read SELECT poll_answers.ID_question instead. There are also a few other items which could need some clearing up in your code, such as the spotty use of output escaping, cleaning up the indenting, the unnecessary do-while loop (a simple while would suffice), script-tags being outside of the header, and a lot more small issues. The biggest issue is the intermittent use of output escaping, which is something you need to do for all user-provided data. It's also recommended to use output escaping for internal (presumed) safe data as well, as long as you know that you won't need to output actual control statements. Quote Link to comment https://forums.phpfreaks.com/topic/267592-code-debugging/#findComment-1372636 Share on other sites More sharing options...
stijn0713 Posted August 29, 2012 Author Share Posted August 29, 2012 ok, thanks for the advise. I'm reading about the security issues, though im relatively new in programming so i've hadn't looked at security things. Hope it will not surprise me in time and effort! Quote Link to comment https://forums.phpfreaks.com/topic/267592-code-debugging/#findComment-1373698 Share on other sites More sharing options...
Christian F. Posted August 29, 2012 Share Posted August 29, 2012 You're welcome. Learning about Output Escaping shouldn't be too hard, as it's relatively simple. Usually only one function/method per system you're sending data to. Input validation, however, will require a bit more reading up on. As you'll not only have to understand the principle and methods used, but also plan out exactly what your expected input is. White-list based validation is highly recommended. PS: Don't mix validation with sanitation, the former does not alter content while the latter does. Quote Link to comment https://forums.phpfreaks.com/topic/267592-code-debugging/#findComment-1373709 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.