Как генерировать динамический контент из двух таблиц с помощью PHP - PullRequest
0 голосов
/ 01 октября 2019

Решено !! Спасибо, ребята. Это был мой первый вопрос здесь. Дайте мне знать, если я не форматирую это правильно или что-то. Вот мой готовый код:

Ответ:

$sql = 'SELECT a.*, GROUP_CONCAT(t.name) as track_name FROM albums AS a LEFT JOIN tracks AS t ON a.album_id = t.album_id GROUP BY a.album_id';

foreach ($conn->query($sql) as $row) { ?>
    <div class="container">
     <div class="row">
     <div class="col-6">
      <img src="../images/<?= $row['album_cover']?>" alt="Card image cap" style="width:100%;">
    <!--shadow-->
      <div class="shadow-lg p-3 mb-5 bg-white rounded">
      <div class="card-body" style="padding-left:10px;">
      <h4 class="card-title"><?= $row['album_name'] ?></h4>


    <b><?= print_r($row['album_name'] . ' (' . $row['record_label'] . ') (' . $row['year_released'] . ')', true); ?><br><br></b>
     <ul class="list-group list-group-flush">
        <?php
        $tracks = explode(",", $row['track_name']);
        $numTracks = count($tracks);
        $i = 0;
        while ($i < $numTracks) { ?>
        <li class="list-group-item">
            <?php 
            echo $tracks[$i]; 
            $i++;
            ?>
            </li>
        <?php } ?>
      </ul>
     </div>
    </div>
    </div>
    </div>
    </div>
<?php } ?>

Вопрос (решен): Я работаю над проектом для школы. Я должен обновить существующий сайт дискографии (Queen), используя php. Часть, над которой я застрял, - это извлечение информации об альбоме из базы данных и использование ее для заполнения страницы каждым альбомом вместе с названиями треков для альбома. У меня есть информация об альбоме в одной таблице, называемой альбомами, и все дорожки для каждого альбома в другой таблице, называемые дорожками, с идентификатором альбома в качестве внешнего ключа.

Я могу добраться до того момента, когда он генерирует название альбома изтаблица альбомов в моей базе данных, но я не знаю, как получить дорожки для каждого альбома.

Это мой запрос SQL:

$sql = '
SELECT a.album_id
     , a.album_name
     , a.year_released
     , a.record_label
     , a.album_cover
     , t.name
     , t.album_id
  FROM albums AS a 
  LEFT 
  JOIN tracks AS t 
 USING (album_id)
';

И вот часть, котораядолжен генерировать альбомы:

<?php
foreach ($conn->query($sql) as $row) { ?>
     <div class="col-6">
      <img src="../images/<?= $row['album_cover']?>" alt="Card image cap" style="width:100%;">
    <!--shadow-->
      <div class="shadow-lg p-3 mb-5 bg-white rounded">
      <div class="card-body" style="padding-left:10px;">
      <h4 class="card-title"><?= $row['album_name'] ?></h4>


    <b><?= print_r($row['album_name'] . ' (' . $row['record_label'] . ') (' . $row['year_released'] . ')', true); ?><br><br></b>
     <ul class="list-group list-group-flush">
        <li class="list-group-item">Innuendo</li>  <!-- these are just placeholders for the tracks because I don't know what to do here! -->
        <li class="list-group-item">I'm Going Slightly Mad </li>
        <li class="list-group-item">Headlong</li>
        <li class="list-group-item">I Can't Live With You</li>
        <li class="list-group-item">Don't Try So Hard </li>
        <li class="list-group-item">Ride The Wild Wind</li>
        <li class="list-group-item">All God's People</li>
        <li class="list-group-item">These Are The Days Of Our Lives</li>
        <li class="list-group-item">Delilah</li>
        <li class="list-group-item">The Hitman</li>
        <li class="list-group-item">Bijou</li>
        <li class="list-group-item">The Show Must Go On </li>
      </ul>
     </div>
    </div>
    </div>
    <?php
    }
?>

В существующем состоянии, моя страница заполняется одной и той же информацией об альбоме снова и снова, потому что foreach выполняет итерацию по каждой строке в обеих таблицах. Как генерировать конкретные треки на основе уникальных альбомов?

Ответы [ 4 ]

0 голосов
/ 01 октября 2019

Вы должны немного изменить свой дизайн. Сначала вы получите первый ряд, получите данные альбома и первый трек

После этого вы захватите оставшуюся часть трека и закроете html-теги

$sql = 'SELECT a.album_id, a.album_name, a.year_released, a.record_label
        ,a.album_cover, t.name, t.album_id
        FROM albums AS a LEFT JOIN tracks AS t USING (album_id)';
  $result = $conn->query($sql) // get a result from the mysql server
  $row = $result->fetch_assoc();
?>
 <div class="col-6">
  <img src="../images/<?= $row['album_cover']?>" alt="Card image cap"  style="width:100%;">
<!--shadow-->
  <div class="shadow-lg p-3 mb-5 bg-white rounded">
    <div class="card-body" style="padding-left:10px;">
     <h4 class="card-title"><?= $row['album_name'] ?></h4>
       <b><?= print_r($row['album_name'] . ' (' . $row['record_label'] . 
        ') (' . $row['year_released'] . ')', true); ?><br><br></b>
       <ul class="list-group list-group-flush">
         <li class="list-group-item"><?= $row['name']?></li>
         <?php
         //get the rest of teh tracks
         while($row = $result->fetch_assoc()) {?>
        <li class="list-group-item"><?= $row['name']?></li>
        <?php
         }  //end if While
        ?>
     </ul>
    </div>
 </div>
 </div>
0 голосов
/ 01 октября 2019

Попробуйте использовать ON вместо USING:

$sql = 'SELECT * FROM albums AS a LEFT JOIN tracks AS t ON a.album_id = t.album_id';

Это должно правильно объединить две таблицы. Если для каждого альбома есть несколько треков, вам нужно будет запросить их отдельно или объединить треки в группу, используя GROUP_CONCAT. Вот запрос для достижения этой цели:

$sql = 'SELECT a.*, GROUP_CONCAT(t.name) as track_name FROM albums AS a LEFT JOIN tracks AS t ON a.album_id = t.album_id GROUP BY a.album_id';

Так же, как примечание, я НАСТОЯТЕЛЬНО рекомендую использовать PDO для всех связанных с SQL вещей. Вот ссылка для его настройки и использования для более безопасных SQL-запросов: https://www.w3resource.com/php/pdo/php-pdo.php

ДОБАВЛЕНО ДЛЯ ПЕРЕДАЧИ ЧЕРЕЗ ТРАКИ

Сначала вам нужно будет взять переменнуюи взорвать его в массив (место внутри цикла):

$tracks = explode(',',$row['track_name']);
foreach($tracks as $track_name){
   echo $track_name;
}

Теперь вы сможете делать с этими треками все, что захотите. Вы можете легко разместить их на столе или в шкафу.

0 голосов
/ 01 октября 2019

Два способа решения этой проблемы:

  1. Есть 2 цикла - сначала цикл с простым запросом к таблице альбомов (без объединений), затем в этом цикле выполнитьвторой запрос к базе данных, чтобы получить все треки. (Недостатком является то, что вы будете делать больше запросов к базе данных)

  2. В качестве альтернативы, измените свой запрос, так что вы выбираете из таблицы треков, а затем объединение находится в таблице альбомов. Чтобы сделать так, чтобы название альбома печаталось только один раз для каждого альбома, вам нужно будет отсортировать дорожки по альбому, а затем иметь оператор if, чтобы проверить, когда цикл начал обрабатывать другой альбом.

0 голосов
/ 01 октября 2019

Вы вызываете $conn->query($sql) каждый цикл, который снова возвращает весь набор результатов. Также используйте цикл while, как показано ниже, а не цикл foreach, так как $conn->query() возвращает объект mysqli_reuslt, а не массив.

$sql = 'SELECT a.album_id, a.album_name, a.year_released, a.record_label, a.album_cover, t.name, t.album_id
    FROM albums AS a LEFT JOIN tracks AS t USING (album_id)';
$result = $conn->query($sql) // return a mysqli_result object
while($row = $result->fetch_assoc()) {
    // Your loop content
}

Если вы настаиваете на использовании цикла foreach:

$result = $conn->query($sql) // return a mysqli_result object
$rows=$result->fetch_all(MYSQLI_ASSOC); //return an array
foreach($rows as $row) {
      //content
} 
...