Неправильный модуль отображается на следующей странице при использовании $_SESSION
Ниже у меня есть php-скрипт, где он отображает выпадающее меню "Курс" и выпадающее меню "Модуль". Предполагается, что пользователь сначала выбирает курс из раскрывающегося меню "Курс", а затем в раскрывающемся меню "Модули" появляется список модулей, принадлежащих выбранному курсу. Ниже приведен код для этого:
create_session.php
$sql = "SELECT CourseId, CourseNo, CourseName FROM Course";
$sqlstmt=$mysqli->prepare($sql);
$sqlstmt->execute();
$sqlstmt->bind_result($dbCourseId, $dbCourseNo, $dbCourseName);
$courses = array(); // easier if you don't use generic names for data
$courseHTML = "";
$courseHTML .= '<select name="courses" id="coursesDrop">'.PHP_EOL;
$courseHTML .= '<option value="">Please Select</option>'.PHP_EOL;
while($sqlstmt->fetch())
{
$courseno = $dbCourseNo;
$course = $dbCourseId;
$coursename = $dbCourseName;
$courseHTML .= "<option value='".$course."'>" . $courseno . " - " . $coursename . "</option>".PHP_EOL;
}
$courseHTML .= '</select>';
?>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<table>
<tr>
<th>Course: <?php echo $courseHTML; ?>
<input id="courseSubmit" type="submit" value="Submit" name="submit" />
</th>
</tr>
</table>
</form>
<?php
if (isset($_POST['submit'])) {
$submittedCourseId = $_POST['courses'];
$query = "SELECT cm.CourseId, cm.ModuleId, c.CourseNo, m.ModuleNo,
c.CourseName,
m.ModuleName
FROM Course c
INNER JOIN Course_Module cm ON c.CourseId = cm.CourseId
JOIN Module m ON cm.ModuleId = m.ModuleId
WHERE
(c.CourseId = ?)
ORDER BY c.CourseName, m.ModuleId";
$qrystmt=$mysqli->prepare($query);
// You only need to call bind_param once
$qrystmt->bind_param("s",$submittedCourseId);
// get result and assign variables (prefix with db)
$qrystmt->execute();
$qrystmt->bind_result($dbCourseId,$dbModuleId,$dbCourseNo,$dbModuleNo,$dbCourseName,$dbModuleName);
$qrystmt->store_result();
$num = $qrystmt->num_rows();
if($num ==0){
echo "<p style='color: red'>Please Select a Course</p>";
} else {
$dataArray = array();
while ( $qrystmt->fetch() ) {
// data array
$dataArray[$dbCourseId]['CourseName'] = $dbCourseName;
$dataArray[$dbCourseId]['CourseNo'] = $dbCourseNo;
$dataArray[$dbCourseId]['Modules'][$dbModuleId]['ModuleName'] = $dbModuleName;
$dataArray[$dbCourseId]['Modules'][$dbModuleId]['ModuleNo'] = $dbModuleNo;
// session data
$_SESSION['idcourse'] = $dbCourseNo;
$_SESSION['namecourse'] = $dbCourseName;
$_SESSION['idmodule'] = $dbModuleNo;
$_SESSION['namemodule'] = $dbModuleName;
}
foreach ($dataArray as $foundCourse => $courseData) {
$output = "";
$output .= "<p><strong>Course:</strong> " . $courseData['CourseNo'] . " - " . $courseData['CourseName'] . "</p>";
$moduleHTML = "";
$moduleHTML .= '<select name="module" id="modulesDrop">'.PHP_EOL;
$moduleHTML .= '<option value="">Please Select</option>'.PHP_EOL;
foreach ($courseData['Modules'] as $moduleId => $moduleData) {
$moduleHTML .= "<option value='$moduleId'>" . $moduleData['ModuleNo'] . " - " . $moduleData['ModuleName'] ."</option>".PHP_EOL;
}
}
$moduleHTML .= '</select>';
echo $output;
?>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<table>
<tr>
<th>Course: <?php echo $moduleHTML; ?>
<input id="courseSubmit" type="submit" value="Submit" name="submit" />
</th>
</tr>
</table>
</form>
Допустим, я выбрал курс INFO101 - Information Communication Technology
в раскрывающемся меню "Курс" в раскрывающемся меню "Модуль" отображаются следующие модули, соответствующие этому курсу:
CHI2520 - Advanced Web Programming
CHI2220 - Systems Strategy
CHI2350 - Interactive Systems
Теперь это проблема, которая у меня есть. Если я выберу модуль CHI2520 - Advanced Web Programming
и затем перейдите на страницу ниже, он отображает этот модуль вместо CHI2350 - Interactive Systems
,
QandATable.php:
<?php
if (isset($_POST['idmodule'])) {
$_SESSION['idmodule'] = $_POST['idmodule'];
}
if (isset($_POST['namemodule'])) {
$_SESSION['namemodule'] = $_POST['namemodule'];
}
if (isset($_POST['idcourse'])) {
$_SESSION['idcourse'] = $_POST['idcourse'];
}
if (isset($_POST['namecourse'])) {
$_SESSION['namecourse'] = $_POST['namecourse'];
}
$outputDetails = "";
$outputDetails .= "
<table id='sessionDetails' border='1'>
<tr>
<th>Course:</th>
<th>{$_SESSION['idcourse']} {$_SESSION['namecourse']}</th>
</tr>
<tr>
<th>Module:</th>
<th>{$_SESSION['idmodule']} {$_SESSION['namemodule']}</th>
</tr>
</table>
";
echo $outputDetails;
?>
Мой вопрос заключается в том, почему он отображает неправильный номер модуля и имя на другой странице? Обе страницы включают session_start();
Ниже приведена форма, которая переходит к QandATable.php:
<form action="QandATable.php" method="post" id="sessionForm">
<table><tr><th>6: Module:</th>
<td><?php echo $moduleHTML; ?></td>
</tr>
</table>
<p><strong>11: </strong><input class="questionBtn" type="submit" value="Prepare Questions" name="prequestion" /></p>
</form>
2 ответа
Вы не можете назначать сессии php, когда страница уже загружена! Ну, вы могли бы, но не только с самим PHP! позволь мне объяснить:
первый запрос (форма загружается - модули не отображаются)
второй запрос (загружается новая форма - в зависимости от отправленного курса вы отображаете нужные модули)
третий запрос (на основе представленного moduleid вы должны заполнить сессии php для последующего использования)
То, что вы пытались сделать, это заполнить переменные сеанса во время второго запроса... однако, вы никогда не сможете получить правильный moduleid, сделав это! Только браузер и в конечном итоге javascript знают, что выбрано в тот конкретный момент времени, когда страница живет только внутри браузера!
Как вы только что сказали, вы на самом деле написали свои сессии во втором запросе. Это означает, что вы написали свои сессии сессии до выбора модуля пользователя! И то, что вы поместили в сессию, было не чем иным, как последней строкой результатов в цикле! Вот почему у вас всегда был последний модуль в вашей сессии, который в вашем случае был Interactive Systems
!
Давайте найдем решение сейчас
При условии, что ваш селектор курса / модуля работает правильно, отображая правильные модули, как только пользователи выбирают его курс, вам просто нужно сделать третий запрос!
<form name="moduleid" [...] >
<option value="[moduleid]> [moduleno] - [modulename] </option>
[...]
</form>
Основываясь на такой структуре... я просто предполагаю, что именно так может выглядеть форма вашего модуля... вы должны выполнить третий запрос к серверу, который может быть либо на той же странице, что вы делали для добавления модулей выберите или по другому! код подсказки здесь похож на приведенный ниже... вам даже не нужно генерировать какие-либо выходные данные;)
if ( isset($_POST['moduleid']) )
{
$stmt = $mysqli->prepare('select moduleno, modulename from module where moduleid = ?');
$stmt->bind_param('s', $_POST['moduleid'] );
if ( $stmt->execute() )
{
$stmt->bind_result($moduleno, $modulename); $stmt->fetch();
$_SESSION['moduleid'] = $_POST['moduleid'];
$_SESSION['moduleno'] = $moduleno;
$_SESSION['modulename'] = $modulename;
}
}
если ваш курс / модуль выбора не работает должным образом... обратитесь к моему другому ответу;)
Я не знаю, что вы пропустили из исходного скрипта, но ваша проблема, кажется, подтверждает, что использование сессий и post-var может быть сложным, если не будет выполнено должным образом! каждый из двух методов имеет действительно конкретную цель, как вы можете прочитать здесь. Тем не менее, для информации, которую вы нам предоставили, было бы более чем достаточно опубликовать сообщение:)
в вашем скрипте есть место, где вы переопределяете сеансовые переменные каждый раз, когда цикл повторяется. это означает, что в вашем сеансе будет храниться только последний "модуль":
$_SESSION['idcourse'] = $dbCourseNo;
$_SESSION['namecourse'] = $dbCourseName;
$_SESSION['idmodule'] = $dbModuleNo;
$_SESSION['namemodule'] = $dbModuleName;
Однако, с другой стороны, вы нигде не используете сессии в этом коде... поэтому они могут быть бесполезными или неуместными (по крайней мере, на этих страницах)!
кроме этого нет необходимости делать странные вещи в вашем действии!
<form action="" method="post">
это делает то же самое;) и не включает в себя php!
что еще... ну, проблема может быть и в вашем запросе, получающем искаженную информацию из вашей базы данных!
Вот быстрое решение
Там могут быть некоторые ошибки... я еще не запустил скрипт! У меня нет веб-сервера, мой плохой... но вы можете воспользоваться одним из способов сделать это! Это просто для того, чтобы дать вам представление, потому что вам не нужны все эти накладные расходы для этого;) Я даже немного изменил ваш второй запрос... вполне вероятно, что вам также не нужно объединять три таблицы! На самом деле, course_modules и module предоставляют вам всю необходимую информацию, при условии, что вы получаете courseid из предыдущей отправки формы!
просто запускайте первый запрос каждый раз... объединение трех таблиц не быстрее, чем создание более простых запросов... тем не менее... вот код:P надеюсь, это помогло!
<?php $_courseid = isset($_POST['courseid']) ? $_POST['courseid'] : null; ?>
<!-- action filled only for validation purpose, all browsers will reload the same page by default -->
<form method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<!-- you should be using tables for tabular data only -->
Course:
<!-- using onchange is user friendly -->
<select name="courseid" id="coursesDrop" onchange="this.form.submit()">
<?php if ( !isset($_courseid) ): ?>
<option selected>Please Select</option>
<?php endif;
$result = $mysqli->query('select courseid, courseno, coursename from course');
while( list($courseid, $courseno, $coursename) = $result->fetch_array() ): ?>
<option value="<?php echo $courseid ?>" <?php if ($_courseid == $courseid) echo "selected" ?>>
<?php echo "{$courseno} - {$coursename}" ?>
</option>
<?php endwhile; $result->free(); ?>
</select>
<?php if ( isset($_courseid) ): ?>
<select name="module" id="modulesDrop">
<option selected>Please Select</option>
<?php $stmt = $mysqli->prepare('select m.moduleid, moduleno, modulename form `course_module` join `module` m using(moduleid) where courseid = ? order by m.moduleid');
$stmt->bind_param('s', $_courseid);
$stmt->execute();
$result = $stmt->store_result();
while( list($moduleid, $moduleno, $modulename) = $result->fetch_array() ): ?>
<option value="<?php echo $moduleid ?>"><?php echo "{$moduleno} - {$modulename}" ?></option>
<?php endwhile; $result->free(); $stmt->close(); ?>
</select>
<? endif; ?>
</form>