Ребят, всем привет. Есть такая БД:
Следующая функция возвращает данные, которые берутся из этих таблиц:
public static function getProductByName($link) {
$db = Db::getConnection();
$sql = 'SELECT p.*,
cat.name AS category_name,
cat.link AS category_link,
prop.title AS property_title,
pr_prop.value AS property_value
FROM products AS p
JOIN category AS cat ON cat.id = p.category_id
JOIN product_prop AS pr_prop ON pr_prop.product_id = p.id
JOIN properties AS prop ON prop.id = pr_prop.property_id
WHERE p.link = :link';
$result = $db->prepare($sql);
$result->bindParam(':link', $link, PDO::PARAM_INT);
$result->setFetchMode(PDO::FETCH_ASSOC);
$result->execute();
return $result->fetch();
}
Проблема - данная функция возвращает лишь первые строки из таблиц prod_prop и properties, т.е. если в таблице prod_prop указано 3 свойства для 1 товара, он возвращает лишь одно.
Вопрос: как сделать, чтобы свойства из данных таблиц возвращались в виде ассоциативного массива (т.е. чтобы попарно шло, пример массива, который хотелось бы видеть, будет ниже)? Нужно для вывода на страничке товара через цикл foreach.
Заранее спасибо!
Пример массива:
array(
array(
'title' => 'Длина',
'value' => '40',
),
array(
'title' => 'Страна',
'value' => 'Эквадор',
),
array(
'title' => 'Цена',
'value' => '100',
)
);
UPD сделал следующее:
$product = Product::getProductByName($link);
var_dump($product);
Ничего дельного не вышло, в БД 3 записи по этому ID, выводится лишь одна, вот дамп:
array(16) {
["id"]=>
string(1) "6"
["link"]=>
string(10) "sweetbox-5"
["title"]=>
string(44) "Коробка со сладостями #5 "
["description"]=>
string(1) "0"
["meta_keywords"]=>
string(1) "0"
["meta_description"]=>
string(1) "0"
["price"]=>
string(4) "5799"
["is_discount"]=>
string(1) "1"
["discount_price"]=>
NULL
["category_id"]=>
string(1) "3"
["is_recommended"]=>
string(1) "1"
["params"]=>
NULL
["category_name"]=>
string(40) "Коробки со сладостями"
["category_link"]=>
string(8) "sweetbox"
["property_title"]=>
string(29) "Количество букв"
["property_value"]=>
string(1) "5"
}
UPD2: Поменял на fetchAll. Получается следующее:
array(3) {
[0]=>
array(15) {
["id"]=>
string(1) "6"
["link"]=>
string(10) "sweetbox-5"
["title"]=>
string(44) "Коробка со сладостями #5 "
["description"]=>
string(1) "0"
["meta_keywords"]=>
string(1) "0"
["meta_description"]=>
string(1) "0"
["price"]=>
string(4) "5799"
["is_discount"]=>
string(1) "1"
["discount_price"]=>
NULL
["category_id"]=>
string(1) "3"
["is_recommended"]=>
string(1) "1"
["category_name"]=>
string(40) "Коробки со сладостями"
["category_link"]=>
string(8) "sweetbox"
["property_title"]=>
string(29) "Количество букв"
["property_value"]=>
string(1) "5"
}
[1]=>
array(15) {
["id"]=>
string(1) "6"
["link"]=>
string(10) "sweetbox-5"
["title"]=>
string(44) "Коробка со сладостями #5 "
["description"]=>
string(1) "0"
["meta_keywords"]=>
string(1) "0"
["meta_description"]=>
string(1) "0"
["price"]=>
string(4) "5799"
["is_discount"]=>
string(1) "1"
["discount_price"]=>
NULL
["category_id"]=>
string(1) "3"
["is_recommended"]=>
string(1) "1"
["category_name"]=>
string(40) "Коробки со сладостями"
["category_link"]=>
string(8) "sweetbox"
["property_title"]=>
string(33) "Количество цветов"
["property_value"]=>
string(2) "23"
}
[2]=>
array(15) {
["id"]=>
string(1) "6"
["link"]=>
string(10) "sweetbox-5"
["title"]=>
string(44) "Коробка со сладостями #5 "
["description"]=>
string(1) "0"
["meta_keywords"]=>
string(1) "0"
["meta_description"]=>
string(1) "0"
["price"]=>
string(4) "5799"
["is_discount"]=>
string(1) "1"
["discount_price"]=>
NULL
["category_id"]=>
string(1) "3"
["is_recommended"]=>
string(1) "1"
["category_name"]=>
string(40) "Коробки со сладостями"
["category_link"]=>
string(8) "sweetbox"
["property_title"]=>
string(10) "Длина"
["property_value"]=>
string(3) "100"
}
}
UPD3: Цикл while:
$i = 0;
while ($row = $result->fetchAll()) {
$productList['product']['id'] = $row[$i]['id'];
$productList['product']['link'] = $row[$i]['link'];
$productList['product']['title'] = $row[$i]['title'];
$productList['product']['description'] = $row[$i]['description'];
$productList['product']['meta_keywords'] = $row[$i]['meta_keywords'];
$productList['product']['meta_description'] = $row[$i]['meta_description'];
$productList['product']['price'] = $row[$i]['price'];
$productList['product']['is_discount'] = $row[$i]['is_discount'];
$productList['product']['discount_price'] = $row[$i]['discount_price'];
$productList['product']['category_id'] = $row[$i]['category_id'];
$productList['product']['is_recommended'] = $row[$i]['is_recommended'];
$productList['properties'][] = ['title' => $row[$i]['property_title'], 'value' => $row[$i]['property_value']];
$i++;
}
Результат цикла:
array(2) {
["product"]=>
array(11) {
["id"]=>
string(1) "6"
["link"]=>
string(10) "sweetbox-5"
["title"]=>
string(44) "Коробка со сладостями #5 "
["description"]=>
string(1) "0"
["meta_keywords"]=>
string(1) "0"
["meta_description"]=>
string(1) "0"
["price"]=>
string(4) "5799"
["is_discount"]=>
string(1) "1"
["discount_price"]=>
NULL
["category_id"]=>
string(1) "3"
["is_recommended"]=>
string(1) "1"
}
["properties"]=>
array(1) {
[0]=>
array(2) {
["title"]=>
string(29) "Количество букв"
["value"]=>
string(1) "5"
}
}
}
вот получили вы $product
с помощью fetchAll
. В результате имеете 3 строки, в каждой строки первые несколько значений одинаковы, два последних - ваши свойства - разные.
Упрощенно представим это так:
$product = [
[ 'id' => 1, 'title' => 'товар', 'property_title' => 'длина', 'property_value' => 100],
[ 'id' => 1, 'title' => 'товар', 'property_title' => 'высота', 'property_value' => 200],
[ 'id' => 1, 'title' => 'товар', 'property_title' => 'ширина', 'property_value' => 300],
];
А вы хотите получить массив вида
$product = [
'id' => 1,
'title' => 'товар',
'properties' => [
['title' => 'Длина', 'value' => 100],
['title' => 'высота', 'value' => 200],
['title' => 'ширина', 'value' => 300],
],
];
Для этого все повторяющиеся данные возьмите из первой строки. Дальше циклом выберите значения свойств.
$item = $product[0];
foreach($product as $p){
$item['properties'][] = [
'title' => $p['property_title',
'value' => $p['property_value']
];
}
при желании удалите исходные property_title
и value
из $item
:
unset($item['property_title']);
unset($item['property_value']);
в результате получите приведенный выше массив $item
со вложенными массивом свойств.
Вместо такого цикла можно и другие варианты привести, например, array_map
. А также задачу можно решить с помощью двух запросов вместо одного. Первый извлечет нужную информацию о товаре (1 строка), а второй 3 строки его свойств. С одной стороны лишний запрос, с другой нет дополнительного джойна и передачи большего объема данных, который впрочем тут не критичен.
Добрый день!
Иcпользуйте fetch, результаты запроса обрабатывайте циклом while (не foreach). Т.е. вместо:
return $result->fetch();
Используйте:
while ($row = $result->fetch(PDO::FETCH_LAZY))
{
echo $row->name; //Ну или что вы там с этим хотели делать?
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Только начал изучать phpСоздаю чат
Всем привет, не так давно начал использовать ORM RedBeanPhpИ по итогам двух дней, копания в доках не могу понять как прописать двойное условие для...
Сейчас практикуюсь со Spring Boot + Hibernate 5 + mysqlНе получается сохранить объект в бд