Как бы я использовал PDO + PHP для извлечения данных из таблицы, связанной отношением «многие ко многим», используя первичный ключ из первой таблицы? - PullRequest
3 голосов
/ 07 марта 2020

Я настроил базу данных mysql через PHPMyAdmin и могу получить доступ к данным через одну таблицу, используя PDO в PHP. Однако я не знаю, с чего начать при попытке извлечь данные из отношения «многие ко многим».

Вот моя структура таблицы: изображение структуры

продуктов -> один / много -> productImages <- много / один <- images </p>

Таблица productImages содержит идентификатор PK и два внешних ключа - идентификатор PK из двух других таблиц.

Я знаю, как использовать PDO для извлечения информации из таблицы продуктов в простом решении. Вот сокращенный фрагмент кода, показывающий это:

<?php
$products = $mypdo->prepare('SELECT * FROM products');
$products->execute();
$products_ids[] = array();
$products_names[] = array();
$products_prices[] = array();

$i = 0;
$columnCount = 1;

foreach($products as $product)
{
    $products_ids[$i] = $product['product_ID'];
    $products_names[$i] = $product['product_Name'];
    $products_prices[$i] = $product['product_Price'];
    ?>
        //output product data in styled HTML
        <div class="example"><?php echo $products_names[$i];?></div>
    <?php

    $i++;
    $columnCount++;

    if($columnCount > 3)
    {
        $columnCount = 1;
    ?>
        //start new row using HTML/CSS
    <?php
    }
}
?>

Однако я хочу извлечь image_filename и image_extension из таблицы изображений, используя только product_id из таблицы products. Product_id - это ключ Foreign_key в таблице productImages (я думаю, что это правильный способ сделать это), который также связан с image_id из таблицы изображений. В настоящее время все изображения имеют одну запись в productImages, и все они ссылаются на одно «изображение-заполнитель» в таблице изображений.

У меня есть mysql пример:

select *
from products inner join productImages
on productImages.product_ID=product_ID

И Я думаю, что он берет все записи из таблиц productImages и products. Мои основные проблемы с этим решением:

  1. Если он действительно принимает все записи из 2 таблиц, мне также нужны записи из третьей таблицы
  2. Я не уверен, как PDO Объект хранит подготовленный оператор, поэтому не знаю правильный синтаксис для доступа к информации из каждой таблицы. Например, product_ID имеет одинаковое имя в 2 разных таблицах и поэтому не знает, как различать одну или другую таблицу при использовании $product['product_ID'].

Что мне нужно сделать, это получить соответствующие данные image_name и image_extension для каждого продукта в отдельные (или зацикленные массивы) переменные, чтобы их можно было выводить по отдельности на страницу.

Я на правильном пути и поэтому смог бы разработать свой код дальше отсюда? Или я делаю что-то в корне неправильно и мне нужно изменить свой подход?

Обновление:

Я обновил свой код, используя ответ от Ашера Ганзая. Доступ к данным из третьей таблицы теперь работает! К сожалению, l oop этого не делает, а конечный результат состоит в том, что отображаются только первое изображение продукта, его название и цена, а потом ничего. Мой код (отредактирован для уменьшения размера и сохранения предыдущего соглашения об именах):

<?php
$products = $mypdo->prepare('
SELECT
products.product_name as product_name,
products.product_price as product_price,
images.image_fileName as image_fileName ,
images.image_fileExtension as image_fileExtension 
FROM
products
JOIN
productsimages on productsimages.product_ID = products.product_ID
JOIN
images on images.image_ID = productsimages.image_ID
');
$products->execute();
$i = 0;
$columnCount = 1;

foreach($products as $product)
{
    ?>
        //output product data in styled HTML
        <div class="example"><?php echo $product['product_name'];?></div>
        <div class="exampl2"><?php echo $product['image_fileName'];?></div>
    <?php

    $i++;
    $columnCount++;

    if($columnCount > 3)
    {
        $columnCount = 1;
    ?>
        //start new row using HTML/CSS
    <?php
    }
}
?>

Я также пробовал вариант, более похожий на мой исходный код:

<?php
$products = $mypdo->prepare('
SELECT
products.product_name as product_name,
products.product_price as product_price,
images.image_fileName as image_fileName ,
images.image_fileExtension as image_fileExtension 
FROM
products
JOIN
productsimages on productsimages.product_ID = products.product_ID
JOIN
images on images.image_ID = productsimages.image_ID
');
$products->execute();

$products_names[] = array();
$products_prices[] = array();
$images_fileNames[] = array();

$i = 0;
$columnCount = 1;

foreach($products as $product)
{
    $products_names[$i] = $product['product_name'];
    $products_prices[$i] = $product['product_price'];
    $images_fileNames[$i] = $product['image_fileName'];
    ?>
        //output product data in styled HTML
        <div class="example"><?php echo $products_names[$i];?></div>
        <div class="exampl2"><?php echo $images_fileNames[$i];?></div>
    <?php

    $i++;
    $columnCount++;

    if($columnCount > 3)
    {
        $columnCount = 1;
    ?>
        //start new row using HTML/CSS
    <?php
    }
}
?>

Однако оба фрагмента кода имеют одну и ту же проблему : только первый Отображается продукт из таблицы продуктов. Как это исправить?

Обновление 2: Код работает нормально. Я забыл добавить больше записей в мою таблицу productImages. Ниже я опубликовал свой собственный ответ, показывающий окончательное рабочее решение с использованием моих соглашений об именах, в сочетании с ответом Ашера Ганзея.

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Для mysql, просто продолжайте добавлять соединения.

SELECT 
  A.attribute as attribute, B.otherAttribute as otherAttribute, C.more as more
FROM
  A
JOIN
  AB on AB.aId = A.id
JOIN
  B on B.id = AB.bId
JOIN
  BC on BC.bId = B.id
JOIN
  C on C.id = BC.cId
...

Делая это таким образом, вы можете обращаться к переменным точно так же, как обычно.

// Loop through rows with each as $row
$row['attribute']; // Corresponds to A.attribute
$row['otherAttribute']; // Corresponds to B.otherAttribute
$row['more']; // And so on
0 голосов
/ 07 марта 2020

Для справки, ответ, который я использовал, сочетал мои соглашения об именах с решением, предложенным Ашером Гансей в его ответе и комментариях:

<?php
$products = $mypdo->prepare('
SELECT
products.product_name as product_name,
products.product_price as product_price,
images.image_fileName as image_fileName ,
images.image_fileExtension as image_fileExtension 
FROM
products
LEFT JOIN
productsimages on productsimages.product_ID = products.product_ID
LEFT JOIN
images on images.image_ID = productsimages.image_ID
');
$products->execute();

$columnCount = 1;

foreach($products as $product)
{
    ?>
        //output product data in styled HTML
        <div class="example"><?php echo $product['product_name'];?></div>
        <div class="exampl2"><?php echo $product['image_fileName'];?></div>
    <?php

    $i++;
    $columnCount++;

    if($columnCount > 3)
    {
        $columnCount = 1;
    ?>
        //start new row using HTML/CSS
    <?php
    }
}
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...