[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Цикл, вложенный в цикл
asdf27
Такая задача... Есть города, есть относящиеся к ним поселки. У городов rang=1, у поселков = 2. Хочу вывести по типу "Город -> поселки", т.е. каталог.

Попробовал так:

<?php

require 'sql.php';
$result = mysql_query("SELECT * FROM places WHERE rang=1");
while ($row = mysql_fetch_assoc($result)) {
echo $row[title];
$result2 = mysql_query("SELECT * FROM places WHERE rang=2");
while ($row2 = mysql_fetch_assoc($result2)) {
echo '<br>' . $row2[title];
}
}

?>


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



Спустя 2 часа, 51 минута, 45 секунд (17.08.2012 - 05:23) kamanch написал(а):
А у поселков, помимо rang=2 есть привязка к городам?
Как определить, какой поселок относится к какому городу?
Переделай таблицу следующим образом:

id // первичный индекс.
title // наименование населенного пункта.
parent // родитель. У городов = 0, у поселков = id города, к которому они относятся.

Выбирай из таблицы только необходимые тебе поля. Не нужно насиловать сервер.

И тогда, первый запрос у тебя будет
"SELECT `id`, `title` FROM `places` WHERE `parent`=0";

а второй:
"SELECT `title` FROM `places` WHERE `parent` = " . $row['id'];


Есть еще второй вариант - немного посложней, но он правильный с точки зрения архитектуры базы данных.
Делаешь 2 таблицы:
cyty // города
c_id // первичный индекс.
c_name // наименование города

village // посёлки
v_id // первичный индекс.
v_name // наименование посёлка
c_id // id города, к которому данный посёлок принадлежит

Разница в том, что в первом варианте у нас для всех городов значение parent = 0
И для каждого этого значения, в базе зарезервировано место. Это нерациональное использование базы.

Помимо этого:
имена таблиц и полей необходимо заключать в обратные апострофы
// неправильно
"SELECT * FROM places WHERE parent=0";

// правильно
"SELECT * FROM `places` WHERE `parent`=0";

Индексы масивов необходимо заключать в кавычки
// неправильно
$row[title]

// правильно
$row['title']

Нельзя просто так брать и выводить данные из базы, их необходимо обрабатывать функцией htmlspecialchars();
Мало-ли, в базе окажутся команды JavaScript...
echo htmlspecialchars($row['title']);

Одиночные теги, которые не имеют закрывающего тега (<br /> <img /> <input /> и т.д.) необходимо закрывать обратными слешами.

Все это сэкономит тебе много времени на отлов непонятных ощибок, взломов сайта и недопонимая со стороны поисковиков.

Привыкай сразу к правильному, потом рефлекторно уже делать будешь.

Спустя 10 часов, 24 минуты, 6 секунд (17.08.2012 - 15:47) asdf27 написал(а):
Точно, упустил))))

Если родитель есть, то он пишется в ячейку parent, изначально сделал, но условие не уточнил smile.gif

Спасибо за решение и советы. +

Спустя 4 минуты, 50 секунд (17.08.2012 - 15:52) killer8080 написал(а):
Цитата (kamanch @ 17.08.2012 - 06:23)
Одиночные теги, которые не имеют закрывающего тега (<br /> <img /> <input /> и т.д.) необходимо закрывать обратными слешами.


А откуда ты знаешь какой доктайп он использует? Наобум такое советовать нельзя wink.gif

Спустя 46 минут, 45 секунд (17.08.2012 - 16:39) Krevedko написал(а):
Не стоит запросы в цикл сувать. Тут можно обойтись одним запросом, причем сделать любого уровня вложенность типа Страна - Область - Город - Поселки

Спустя 2 часа, 35 минут, 43 секунды (17.08.2012 - 19:15) asdf27 написал(а):
Пока сделал так, запросы еще не выносил

while ($row = mysql_fetch_assoc($result)) {

echo '<div id="parent">' .$row[title].'</div>';
$result2 = mysql_query("SELECT * FROM places WHERE parent = '$row[title]'");
while ($row2 = mysql_fetch_assoc($result2)) {
echo $row2[title];
}

echo '<br><br>';
}


Оптимизировать смысла особого нет, количество городов менее 10, поселков менее 100. Посещалка до 10к.

Спустя 30 минут, 43 секунды (17.08.2012 - 19:45) Krevedko написал(а):
Ну вот 10к умножте на 10 запросов.
Я сделал так:

function generate_menu($cat_menu, $level, $url = '')
{
foreach($cat_menu[$level] as $id => $category)
{
$description = ($category['description'])? $category['description'] : $category['name'];
if(isset($cat_menu[$id]))
{
$url .= $category['alt_name'] . '/';
echo '<li>'. HTML::anchor($category['alt_name'], $category['name'], array('title' => $description)) ."\n"
.'<ul>'."\n";
generate_menu($cat_menu, $id, $url);
echo '</ul></li>'."\n";
$url = '';
}
else
echo '<li>'. HTML::anchor($url . $category['alt_name'], $category['name'], array('title' => $description)) . '</li>'."\n";
}
}


$cat_menu = array();
foreach($categories as $category)
{
$id = $category->id;
$cat_menu[$category->parent_id][$id]['name'] = $category->name;
$cat_menu[$category->parent_id][$id]['alt_name'] = $category->alt_name;
$cat_menu[$category->parent_id][$id]['description'] = $category->description;
}

generate_menu($cat_menu, 0);



$categories получился одним запросом типа SELECT * FROM `categories`

Ну и в итоге получается вот такое вот симпатичное меню:
user posted image

Уровней вложенности - сколько угодно. Порядок следования - любой.

Спустя 10 часов, 15 минут, 31 секунда (18.08.2012 - 06:01) asdf27 написал(а):
Спасибо, завтра буду "курить", голова уже туго соображает smile.gif

Ограничу запрос LIMIT 7, немного уменьшу нагрузку.

Посещалка 10к - это в идеале. Когда приближусь к этой цифре, появится стимул взять сервак по-мощнее и переписать часть кода.

Спасибо.

Спустя 17 часов, 25 минут (18.08.2012 - 23:26) kamanch написал(а):
Цитата
А откуда ты знаешь какой доктайп он использует? Наобум такое советовать нельзя

эээ... о чем речь? о доктайпах 80х? Или я не ту литературу читаю? smile.gif

Спустя 1 час, 46 минут, 49 секунд (19.08.2012 - 01:13) killer8080 написал(а):
Цитата (kamanch @ 19.08.2012 - 00:26)
эээ... о чем речь? о доктайпах 80х? Или я не ту литературу читаю?

А что, в 80-х они были biggrin.gif
Закрывающий слеш в не парных тегах нужен только в xhtml, который кстати уже не последний пик моды smile.gif

Спустя 1 час, 9 минут, 50 секунд (19.08.2012 - 02:23) kamanch написал(а):
killer8080
Черт его знает, я не SEOшник, но они в один голос кричат, что гугль за незакрытые теги бъет по попе.


Спустя 8 часов, 13 минут, 41 секунда (19.08.2012 - 10:36) killer8080 написал(а):
Цитата (kamanch @ 19.08.2012 - 03:23)
killer8080
Черт его знает, я не SEOшник, но они в один голос кричат, что гугль за незакрытые теги бъет по попе.

Причем здесь SEO? Это вопрос валидности документа. Проверить свою разметку всегда можно на официально валидаторе от веб консорциума.
Вообще правильно делает, если бьёт. Лояльная всеядность браузеров, поощряет говнокодерство среди верстальщиков. Я то же сторонник жесткой стандартизации smile.gif
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.