Я новичок в phpmysqli. Вот что у меня есть и чего я пытаюсь достичь: я обновлю это на основе рекомендаций; Образцы данных базы данных
Я хочу отображать данные на одной странице с отдельными таблицами для каждого ученика на основе их sid. Это то, что я пробовал до сих пор;
<?php
include_once 'dbcon.php';
$results = $MySQLiconn->query('SELECT * FROM activitybook');
$students = [];
foreach ( $results->fetch_array() as $activity ) {
$students[$activity['sid']][] = $activity;
}
foreach($students as $sid=>$activities) {
foreach($activities as $activity) {
echo
"<table><tr>
<th>SID</th>
<th>Date</th>
<th>FName</th>
<th>LName</th>
<th>activity</th>
<th>time</th>
<th>score</th>
</tr>
<tr>
<td>" . $sid . "</td>
<td>" . $activity['fname'] . "</td>
<td>" . $activity['lname'] . "</td>
<td>" . $activity['activity'] . "</td>
<td>" . $activity['atime'] . "</td>
<td>" . $activity['ascore'] . "</td>
</tr></table>";
}
}
?>
То, что я пытаюсь достичь, - это отдельные таблицы для каждого sid.
Это образец того, что я хочу заархивировать
Вам не хватает эхо <table> и </table>
@Kamal по таблице я имею в виду на странице php не в базе данных,
Да, я понял это, но вы не используете тег таблицы для повторения таблицы.
@mickmackusa, Да, помощь - это первичный ключ, и да, у sid есть дубликаты, поскольку студенты возвращают студентов, и извините, таблица базы данных назовите свою книгу действий, позвольте мне опубликовать, что я получаю, и ожидаемый результат






Вам нужно будет «сгруппировать» данные вашего набора результатов на основе значения sid. Во время итерации проверяйте, меняете ли вы группы или нет.
Я также добавил некоторые уточнения.
sid или начинаете новую (или, если это первая итерация, не записывайте </table>.implode() помогает избавиться от лишнего кода.Код:
$res = $conn->query("SELECT sid, fname, lname, activity, atime, ascore FROM activitybook ORDER BY sid");
$tmp = null;
$colheads = ['SID', 'FName', 'LName', 'activity', 'time', 'score'];
while ($row = $res->fetch_assoc()) { // don't produce more elements per row than needed
if ($tmp != $row['sid']) { // determine if a new group / sid value
if ($tmp !== null) {
echo '</table><br>'; // close the previous table
}
echo '<table border=1><tr><th>' , implode('</th><th>', $colheads) , '</th></tr>'; // start a new table & add headings
}
echo '<tr><td>' , implode('</td><td>', $row) , '</td></tr>'; // display the row data
$tmp = $row['sid']; // DUH, I FORGOT TO UPDATE $tmp!
}
if ($tmp !== null) {
echo '</table>'; // close the final table -- so long as there was at least one row in the result set
}
Сгруппируйте свои результаты по SID, затем зацикливайтесь на нем:
$results = $conn->query('SELECT * FROM activitybook');
$students = []
foreach ( $results->fetch_array() as $activity ) {
$students[$activity['sid']][] = $activity;
}
foreach($students as $sid=>$activities) {
foreach($activities as $activity) {
echo
"<table><tr>
<th>SID</th>
<th>Date</th>
<th>FName</th>
<th>LName</th>
<th>activity</th>
<th>time</th>
<th>score</th>
</tr>
<tr>
<td>" . $sid . "</td>
<td>" . $activity['fname'] . "</td>
<td>" . $activity['lname'] . "</td>
<td>" . $activity['activity'] . "</td>
<td>" . $activity['atime'] . "</td>
<td>" . $activity['ascore'] . "</td>
</tr></table>";
}
}
Несколько советов для вас:
$row? Занятия правильно? Так что назовите его $activity. И избегайте сокращений вроде $res.aid - не лучшая практика. Используйте только идентификатор для первичного ключа. Также sid должен стать student_id, чтобы люди, читающие ваш код, понимали, что это внешний ключ для таблицы студентов.спасибо за советы, я запомню их, я легко понял ваш код, но когда я попробую, я получаю отдельные таблицы для каждой строки с искаженными данными, например, у меня есть sid во всех столбцах таблицы, пожалуйста, посоветуйте и спасибо опять таки
@loem С момента первого ответа я внес некоторые изменения, попробуйте использовать текущий код. Я писал на мобильном телефоне, поэтому было несколько опечаток. Сейчас я на десктопе, протестировал здесь код и все нормально работаю.
По-прежнему получаю те же результаты, обновил вопрос скриншотами,
Вы можете создать отдельный массив идентификаторов студентов и каждый раз в цикле проверять, существует ли этот идентификатор в массиве, чем не создавать новую таблицу, иначе создайте новую таблицу. Используйте так:
<?php
$res = $conn->query("SELECT * FROM activitybook");
$sId = [];
echo "<table>";
while($row=$res->fetch_array())
{
if (count($sId) == 0) {
$sId[] = $row['sid'];
}
if (!in_array($row['sid'], $sId)) {
$sId[] = $row['sid'];
echo "</table><table>";
}
echo
"<tr>
<th>SID</th>
<th>Date</th>
<th>FName</th>
<th>LName</th>
<th>activity</th>
<th>time</th>
<th>score</th>
</tr>
<tr>
<td>" . $row['sid'] . "</td>
<td>" . $row['fname'] . "</td>
<td>" . $row['lname'] . "</td>
<td>" . $row['activity'] . "</td>
<td>" . $row['atime'] . "</td>
<td>" . $row['ascore'] . "</td>
</tr>";
}
?>
просто попробовал вашу версию, и я все еще получаю отдельные таблицы для каждой строки в таблице базы данных, а не отдельные таблицы для каждого sid.
Требования: обработать поток упорядоченных записей о студентах. Поток состоит из групп студенческих записей. Каждая группа обозначена столбцом «sid».
Мне нравится структурировать код в соответствии с данными. Данные структурированы следующим образом:
Итерация StudentRecordGroup
Каждая StudentRecordGroup состоит из последовательности:
Обратите внимание, что в этом процессе нет условных операторов!
Теперь, как нам структурировать код для этого. Вы не можете использовать петлю foreach! Это только чтение в конце цикла.
У нас две петли:
Это называется «читать вперед». И это именно то, что он говорит. Вы читаете первую запись перед запуском внешнего цикла.
Источник:
Выход:
SID Date FName LName activity time score
2 John Ppap 12 56 56
2 John Ppap 23 23 23
SID Date FName LName activity time score
3 Mito Mmito 34 12 12
3 Mito Mmito 45 45 45
SID Date FName LName activity time score
4 Uba Uuba 56 78 100
Код:
<?php // 53020396/how-to-display-grouped-data-in-separate-tables-with-a-php-loop
/* ---------------------------------------------------------------------------
* The input stream consists of an Ordered Iteration of:
* A collection of Individual Records for each Student (StudentRecordGoup)
*
* Each StudentRecordGoup consists of a Sequence of:
* Start of Group
* Iteration of Student records belonging to the group
* End of Group
*
* Notice: There is no 'IF' statement anywhere in the control logic for a group!
*
* Please note: There is exactly one place in the code to assign any appropriate action!
* i.e. The structure of the code exactly matched the structure of the data. :)
*
* This makes it easier to debug, maintain and amend?
*
* To do this we need 'state' information. Specifically that a record is part
* of the current 'student record group' group or not. How do we do this?
*
* We always need a record to test! Including at the start! We never read a record
* and then decide what to do with it. We always know where we are in the data
* structure and either the current record belongs to the group or not.
*
* We need to use a technique called 'Read Ahead'. Literally, There is always
* a record to process. You don't have to test it to know where you are.
* Once you process it then you immediately read the next record from the input.
* i.e. You end up reading a new record NOT JUST AT THE WND OF THE LOOP!
* You cannot use 'foreach' loops.
*
* We have to include Initialisation to setup code and any termination code.
*
* I will put all the 'action place holders' in functions. That way it avoids
* obscuring the high-level logic.
*/
// Get the ordered student detail records
$pdo = getPdoConnection();
$pdoResultSet = prepareAndExecuteQuery($pdo);
// Process all the students Record Groups - 'read ahead' of the row
$curStudentRecord = $pdoResultSet->fetch(); // is assoc array
while ($curStudentRecord !== false) { // process the student record groups
// process one complete student group...
$curStudentRecordGroupId = $curStudentRecord['sid'];
startStudendRecordGroup($curStudentRecordGroupId);
while ( $curStudentRecord !== false // check record belongs to the current group
&& $curStudentRecord['sid'] === $curStudentRecordGroupId) {
processStudentRecord($curStudentRecord);
$curStudentRecord = $pdoResultSet->fetch(); // read the next record
}
endStudendRecordGroup($curStudentRecordGroupId); // ignore the current record
// that is the next group!
}
// all groups have been processed
exit;
/* --------------------------------------------------------------------------
* Student record group processing
*/
function startStudendRecordGroup($curStudentRecordGroupId)
{
echo "<!-- new group: sid = $curStudentRecordGroupId -->";
echo "<table><tr><th>SID</th><th>Date</th><th>FName</th><th>LName</th>
<th>activity</th><th>time</th><th>score</th></tr>";
}
function processStudentRecord($curStudentRecord)
{
echo "<!-- group record: sid = {$curStudentRecord['sid']} -->";
echo "<tr>
<td>" . $curStudentRecord['sid'] . "</td>
<td>" . $curStudentRecord['fname'] . "</td>
<td>" . $curStudentRecord['lname'] . "</td>
<td>" . $curStudentRecord['col3'] . "</td>
<td>" . $curStudentRecord['col4'] . "</td>
<td>" . $curStudentRecord['col5'] . "</td>
</tr>";
}
function endStudendRecordGroup($curStudentRecordGroupId)
{
echo "<!-- end group: sid = $curStudentRecordGroupId -->";
echo "</table>";
}
/* --------------------------------------------------------------------------
* Database access
*/
// Execute query and return 'resultset'
function prepareAndExecuteQuery(\PDO $pdo)
{
$sql = 'SELECT id, sid, fname, lname, col3, col4, col5
FROM activity
ORDER BY sid, id';
$stmt = $pdo->prepare($sql);
$allOk = $stmt->execute();
return $stmt;
}
// DB Connection
function getPdoConnection()
{
$opt = array(
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
);
$pdo = new \PDO('mysql:host=localhost;dbname=notmydb;', 'notme', 'notme', $opt);
return $pdo;
}
У вас нет кода для печати таблицы снова и снова. Что вы имеете в виду под таблицей? Вы хотите повторить только строку?