它的输出细节在 php/html 中不正确
Posted
技术标签:
【中文标题】它的输出细节在 php/html 中不正确【英文标题】:Its outputs details incorrectly in php/html 【发布时间】:2013-01-01 04:48:24 【问题描述】:当用户从问题下拉菜单中选择All
并在下方输出时,我想显示下拉菜单中的所有问题。问题是它没有这样做,更糟的是,它给了我未定义的偏移错误,说明:
Notice: Undefined offset: ... in .... on line 605
第 605 行是:
echo '<p><strong>Question:</strong> ' .htmlspecialchars($arrQuestionNo[$key]). ': ' .htmlspecialchars($arrQuestionContent[$key]). '</p>' . php_EOL;
如果用户选择All
选项,我的问题是如何修复错误并显示所有问题?
我有一个演示,你可以通过:DEMO
按照以下步骤操作:
在模块下拉菜单中,选择系统策略并提交 当评估下拉菜单出现时,选择 POKUB1 并提交 您将看到学生和问题下拉菜单。如果打开下拉菜单,您会看到有 3 个学生和 2 个问题。请选择一个学生和All
问题并提交。当我真的想在此处显示所有问题的详细信息时,您会在这里看到错误。
代码:
问题下拉菜单:
<select name="question" id="questionsDrop">
<option value="0">All</option>
<option value=23">1</option>
<option value=32">1</option>
</select>
以下是根据从问题下拉菜单中选择的选项确定显示的代码。
function StudentAnswers()
$selectedstudentanswerqry = "
SELECT
sa.StudentId, StudentAlias, StudentForename, StudentSurname, q.SessionId,
QuestionNo, QuestionContent, o.OptionType, q.NoofAnswers,
GROUP_CONCAT( DISTINCT Answer ORDER BY Answer SEPARATOR ',' ) AS Answer, r.ReplyType, QuestionMarks,
GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime, MouseClick, StudentMark
FROM Student st
INNER JOIN Student_Answer sa ON (st.StudentId = sa.StudentId)
INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId)
INNER JOIN Question q ON (sa.QuestionId = q.QuestionId)
INNER JOIN Answer an ON q.QuestionId = an.QuestionId
LEFT JOIN Reply r ON q.ReplyId = r.ReplyId
LEFT JOIN Option_Table o ON q.OptionId = o.OptionId
";
// Initially empty
$where = array('q.SessionId = ?');
$parameters = array($_POST["session"]);
$parameterTypes = 'i';
// Check whether a specific question was selected
$p_question = empty($_POST["question"])?'':$_POST["question"];
switch($p_question)
case 0:
//dont' add where filters
break;
default:
$where[] = 'q.QuestionId = ?';
$parameters[] .= $_POST["question"];
$parameterTypes .= 'i';
// If we added to $where in any of the conditionals, we need a WHERE clause in
// our query
if(!empty($where))
$selectedstudentanswerqry .= ' WHERE ' . implode(' AND ', $where);
global $mysqli;
$selectedstudentanswerstmt=$mysqli->prepare($selectedstudentanswerqry);
// You only need to call bind_param once
if (count($where) == 1)
$selectedstudentanswerstmt->bind_param($parameterTypes, $parameters[0]);
else if (count($where) == 2)
$selectedstudentanswerstmt->bind_param($parameterTypes, $parameters[0], $parameters[1]);
$selectedstudentanswerqry .= "
GROUP BY sa.StudentId, q.QuestionId
ORDER BY StudentAlias, q.SessionId, QuestionNo
";
// get result and assign variables (prefix with db)
$selectedstudentanswerstmt->execute();
$selectedstudentanswerstmt->bind_result($detailsStudentId,$detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname,$detailsSessionId,$detailsQuestionNo,
$detailsQuestionContent,$detailsOptionType,$detailsNoofAnswers,$detailsAnswer,$detailsReplyType,$detailsQuestionMarks,$detailsStudentAnswer,$detailsResponseTime,
$detailsMouseClick,$detailsStudentMark);
$selectedstudentanswerstmt->store_result();
$selectedstudentanswernum = $selectedstudentanswerstmt->num_rows();
$question = array();
while ($selectedstudentanswerstmt->fetch())
$arrQuestionNo = array();
$arrQuestionContent = array();
$arrQuestionNo[ $detailsStudentId ] = $detailsQuestionNo;
$arrQuestionContent[ $detailsStudentId ] = $detailsQuestionContent;
$questions[] = $arrQuestionNo;
$questions[] = $arrQuestionContent;
$selectedstudentanswerstmt->close();
?>
...........................................................................................
<h2>STUDENT'S ANSWERS</h2>
<?php
foreach ($questions as $key=>$question)
echo '<p><strong>Question:</strong> ' .htmlspecialchars($arrQuestionNo[$key]). ': ' .htmlspecialchars($arrQuestionContent[$key]). '</p>' . PHP_EOL;
?>
更新:
学生表结构:
CREATE TABLE `Student` (
`StudentId` int(10) NOT NULL AUTO_INCREMENT,
`StudentForename` varchar(25) NOT NULL,
`StudentSurname` varchar(25) NOT NULL,
`StudentAlias` varchar(15) NOT NULL,
`StudentEmail` varchar(50) NOT NULL,
`StudentUsername` varchar(20) NOT NULL,
`StudentPassword` varchar(50) NOT NULL,
`StudentDOB` date NOT NULL,
`Year` int(2) NOT NULL,
`CourseId` int(6) NOT NULL,
`Active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`StudentId`),
KEY `FK_Course` (`CourseId`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8
问题表结构:
CREATE TABLE `Question` (
`QuestionId` int(10) NOT NULL AUTO_INCREMENT,
`SessionId` int(10) NOT NULL,
`QuestionNo` int(3) NOT NULL,
`QuestionContent` varchar(5000) NOT NULL,
`NoofAnswers` int(2) NOT NULL,
`ReplyId` int(1) NOT NULL,
`QuestionMarks` int(4) NOT NULL,
`OptionId` int(2) NOT NULL,
PRIMARY KEY (`QuestionId`)
) ENGINE=InnoDB AUTO_INCREMENT=357 DEFAULT CHARSET=utf8
【问题讨论】:
你不是在一小时前就问过这个问题了吗?并且...尽量复制更少的代码,更重要的是sn-ps,没有人愿意阅读几页代码来查找(例如)错字。 @VladPreda 这是相似的代码但不同的问题。我被告知要分开我的问题,所以我在一个问题中问一个问题,在这个问题中问这个问题。我会减少代码,我只是想让大家知道我的代码结构 在 Helios 计算与工程学院,他们需要教您如何调试和理解您编写的代码。您正在解释问题,就好像您是网站用户(“我选择”,“它显示”),而不是编写代码的程序员。程序员必须能够遵循程序逻辑并将实际结果与预期结果进行比较。在变量值和控制流方面,而不是像“它没有出现”这样的文学术语。 可能重复***.com/questions/14610396/… @user1914374 您需要重构代码以使其更易于调试(将 DAL、逻辑和视图相互分离,忘记过程脚本并使用 OO 结构(尤其是 single responsibility principle,使用已经存在的设计模式,如MVC)。顺便说一句,如果你只想隐藏通知,你可以简单地检查是否定义了索引:...htmlspecialchars((isset($arrQuestionNo[$key])?$arrQuestionNo[$key]:''))...
【参考方案1】:
试试这个......
$question = array();
while ($selectedstudentanswerstmt->fetch())
// assuming you don't need the StudentId
$questions[] = array('no' => $detailsQuestionNo,
'content' => $detailsQuestionContent);
和
foreach ($questions as $key => $question)
echo '<p><strong>Question:</strong> ' .
htmlspecialchars($question['no']) .
': ' .
htmlspecialchars($question['content']) .
'</p>' .
PHP_EOL;
已编辑
或者,如果您按问题分组,您可以试试这个:
$question = array();
while ($selectedstudentanswerstmt->fetch())
if (true === isset($questions[$detailsQuestionId]))
$questions[$detailsQuestionId]['students'][] = $detailsStudentId;
else
$questions[$detailsQuestionId] = array();
$questions[$detailsQuestionId]['no'] = $arrQuestionNo;
$questions[$detailsQuestionId]['content'] = $arrQuestionContent;
$questions[$detailsQuestionId]['students'] = array();
$questions[$detailsQuestionId]['students'][] = $detailsStudentId;
foreach ($questions as $questionId => $question)
// $question['no']
// $question['content']
foreach($question['students'] AS $key => $studentId)
// $studentId
或者如果您按用户 ID 分组...
$students = array();
while ($selectedstudentanswerstmt->fetch())
if (false === isset($students[$detailsStudentId]))
$students[$detailsStudentId] = array();
$students[$detailsStudentId][$detailsQuestionId] =
array('no' => $arrQuestionNo,
'content' => $arrQuestionContent;
foreach ($students AS $studentId => $questions)
// $studentId
foreach ($questions AS $questionId => $question)
// $questionId
// $question['no']
// $question['content']
【讨论】:
【参考方案2】:您的foreach
循环正在遍历questions
数组,该数组填充有:
$questions[] = $arrQuestionNo;
$questions[] = $arrQuestionContent;
这意味着它是一个索引数组,而不是一个关联数组;键是 0 和 1。
然后你回显$arrQuestionNo[$key]
和$arrQuestionContent[$key]
。这些是关联数组,其键是学生 ID,而不是从 0 开始的索引(除非您碰巧有具有这些 ID 号的学生)。
此外,您每次通过 fetch 循环将 $arrQuestionNo
和 $arrQuestionContent
初始化为一个空数组。因此,当您在最后回显结果时,这些仅包含提取的最后一行中的问题。
你应该使用多维数组:
while ($selectedstudentanswerstmt->fetch())
$questions[$detailsStudentId][$detailsQuestionNo] = $arrQuestionContent;
那么你的打印循环应该是:
foreach ($questions as $studentId => $studentQuestions)
echo '<h2>Student '.htmlspecialchars($studentId).' Answers</h2>'. PHP_EOL;
foreach ($studentQuestion as $questionNo => $content)
echo '<p><strong>Question:</strong> ' .htmlspecialchars($questionNo). ': ' .htmlspecialchars($content). '</p>' . PHP_EOL;
【讨论】:
An array in PHP is actually an ordered map.
所以从技术上讲,PHP 中的任何数组都是关联的,不是吗?
是的,它们在技术上是相同的,但它们在概念上是不同的。
@Barmar 我假设我需要将$arrQuestionNo[ $detailsStudentId ] = $arrQuestionNo
更改为$arrQuestionNo[] = $detailsQuestionNo;
。 $arrQuestionContent
也一样吗?
不需要这些数组。问题是他们只允许每个学生回答一个问题。这就是你很多问题的根源。一切都在$questions
。
例如,对于$arrQuestionNo
,要识别$detailsQuestionNo
属于$arrQuestionNo
,我需要在while 循环中包含什么?我只是在$questions[$detailsStudentId][$detailsQuestionNo] = $arrQuestionNo;
之后做$arrQuestionNo[] = $detailsQuestionNo
吗?以上是关于它的输出细节在 php/html 中不正确的主要内容,如果未能解决你的问题,请参考以下文章