下面我有一个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>
答案 0 :(得分:1)
一旦页面加载,您就无法分配php sessions!那么你可以,但不只是与PHP本身!让我解释一下:
第一次请求(表格下载 - 没有显示模块)
第二个请求(新表单下载 - 根据已提交的courseid显示正确的模块)
第三个请求(基于提交的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;
}
}
如果您的课程/模块选择器无法正常工作......请回答我的其他答案;)
答案 1 :(得分:0)
我不知道你在这里从原始脚本中省略了什么,但是你的问题似乎强调了如果做得不好,使用会话和发布变量可能会很棘手!这两种方法中的每一种都有一个非常特定的目的as you can read here。对于你给我们的信息,发布变量就足够了:))
在脚本中的某个位置,每次循环时都会重新分配会话变量。这意味着只有最后一个“模块”将存储在您的会话中:
$_SESSION['idcourse'] = $dbCourseNo;
$_SESSION['namecourse'] = $dbCourseName;
$_SESSION['idmodule'] = $dbModuleNo;
$_SESSION['namemodule'] = $dbModuleName;
然而,另一方面,你没有在这段代码中的任何地方使用会话...所以它们可能是无用的或不相关的(至少在这个页面上)!
除此之外,你的行动中不需要做任何奇怪的事情!
<form action="" method="post">
完全相同的事情;)并且不涉及任何php!
还有什么......问题也可能在您的查询中,从您的数据库中检索损坏的信息!
可能有一些错误......我还没有运行脚本!我没有可用的网络服务器,我的不好......但你可能会抓住这种方式的一种方式!它只是为了给你一个想法,因为你真的不需要整个会话开销;)我甚至改变了你的第二个查询...很可能你也不需要加入三个表!实际上 course_modules 和模块会为您提供所需的所有信息,前提是您从之前的表单提交中获得了该过程!
每次只运行第一个查询...加入三个表并不比简单查询更快..那说...这是代码: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>