ФорумПрограммированиеPHP для идиотов → Создание каталога.

Создание каталога.

  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 6:51

    Доброго времени суток ув.форумчане!
    только начинаю осваивать php и вообще программирование.
    И на данный момент делаю что то наподобие каталога(пример каталог интернет-магазина).
    Вообщем моя задача такова, есть список стран и городов, и список тип и список видов. Виды принадлежать конкретным типам. Мне нужно организовать вывод следующего типа:
    Тип 1
       Вид 1
           Страна 1
               город1
               …
               городN
           Страна 2
               город1
               …
               городN
           …
           Страна N
               город1
               …
               городN
       …
       Вид N(далее понятно)
    Тип 2
       Вид 1
           Страна 1
               город1
               …
               городN
           Страна 2
               город1
               …
               городN
           …
           Страна N
               город1
               …
               городN
       …
       Вид N(далее понятно)

    Тип N

    У меня получилось сделать это следующим способом.
    Создал две таблицы:
    geo_tree - таблица со списком стран и городов:
    id; country_id; name, где country_id это id страны, если равен нулю то это название страны.
    catalog_tree - таблица со списком типов и видов:
    id; type_id; name, где type_id это id типа и если равен нулю то это есть тип.
    И вот сам код функций.

    $dbLink = mysql_connect('name-bd', 'user_bd', 'user-bd_pass');
    mysql_select_db('name-table', $dbLink);
    function CityGeoTree ($country_id,$typen,$viewn,$countryn) {
    $sql = "SELECT `id`, `country_id`, `name` FROM `geo_tree` WHERE `country_id` = $country_id ORDER BY `name`";
    $result = mysql_query($sql);
    if (mysql_num_rows($result) > 0) {
    echo '<ul>';
    while ($row = mysql_fetch_array($result)) {
    echo '<li class="city_tree"><a href="?type='.$typen.'?view='.$viewn.'?country='.$countryn.'?city='.$row['id'].'">'.$row['name'].'</a></li>';
    }
    echo '</ul>';
    }
    }

       function CountryGeoTree ($country_id,$typen,$viewn) {
       $country_id=0;
    $sql = "SELECT `id`, `country_id`, `name` FROM `geo_tree` WHERE `country_id` = $country_id ORDER BY `name`";
    $result = mysql_query($sql);
    if (mysql_num_rows($result) > 0) {
    echo '<ul>';
    while ($row = mysql_fetch_array($result)) {
    echo '<li class="country_tree"><a href="?type='.$typen.'?view='.$viewn.'?country='.$row['id'].'">'.$row['name'].'</a></li>';
    CityGeoTree ($row['id'],$typen,$viewn,$row['id']);
    }
    echo '</ul>';
    }
    }

    function ViewTree ($type_id,$typen) {
    $sql = "SELECT `id`, `type_id`, `name` FROM `catalog_tree` WHERE `type_id` = $type_id ORDER BY `id`";
    $result = mysql_query($sql);
    if (mysql_num_rows($result) > 0) {
    echo '<ul>';
    while ($row = mysql_fetch_array($result)) {
    echo '<li class="view_tree"><a href="?type='.$typen.'?view='.$row['id'].'">'.$row['name'].'</a></li>';
    CountryGeoTree (0,$typen,$row['id']);
    }
    echo '</ul>';
    }
    }

    function CatalogTree () {
    $type_id=0;
    $sql = "SELECT `id`, `type_id`, `name` FROM `catalog_tree` WHERE `type_id` = $type_id ORDER BY `id`";
    $result = mysql_query($sql);
    if (mysql_num_rows($result) > 0) {
    echo '<ul class="tree">';
    while ($row = mysql_fetch_array($result)) {
    echo '<li class="type_tree"><a href="?type='.$row['id'].'">'.$row['name'].'</a></li>';
       ViewTree ($row['id'],$row['id']);
    }
    echo '</ul>';
    }
    }
    CatalogTree ();

    Перед собой поставил задачу:
    1. Удобный интрфейс администратирования:
    1.1.Управления типами и видами, т.е. удаление, редактирование, перенос.
    1.2.Управление списом стран и городов, удаление, редактирование.
    2. Что бы можно было перейти в категорию по ссылке с GET-запросом, и показать все объекты которые принадлежать этой категории
    3. Создать красивые ссылки(mod_rewrite) но пока не разберусь, как его связывать с бд(что бы брать имя, или создать доп.поле url в котором храниться название ссылки в eng формате.) :(
    4. Создовать объекты которые фактически закрплены за конкретными типом, видом, страной и городом.
    Собственно думаю для меня этого будет достаточно.
    Вопрос у меня к вам следующий, правильно ли я оргранизовал БД, точнее таблицы. И насколько адекватен мой код?
    PS В наличии имеется книга "Разработка web-приложений с помощью php и mysql(Л.Веллинг, Л.Томсон)", её прочел. И мини вопрос(по моему мнению) в проессе прочтения книги наблюдал картину где авторы в одной главе используют функции, в следующей ооп, а потом снова функции, до меня не дошло, когда же применять ооп, или функции. И вообще что лучше.
  • ubica

    Сообщения: 530 Репутация: N Группа: Кто попало

    Spritz 28 марта 2009 г. 6:54, спустя 2 минуты 53 секунды

    прочитай про nested trees
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 7:01, спустя 7 минут 1 секунду

    а nested trees только на английском?
    нашел вот http://phpwiki.ru/Tree/Ns по русски. а гугль не выручает… :(
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 28 марта 2009 г. 7:07, спустя 5 минут 45 секунд

    http://www.getinfo.ru/article610.html

    не верю что гугль не помогает
    Сапожник без сапог
  • Givi

    Сообщения: 2284 Репутация: N Группа: Адекваты

    Spritz 28 марта 2009 г. 7:10, спустя 3 минуты 12 секунд

    ubica, ну вообще нестеды - довольно трудная штука. Хотя и очень полезная + шустрая :)
    Сам я до сих пор никак не них перейти не могу.

    mario
    1. имя УРЛа будет браться из БД.  заноситься туда может как отдельным полем при создании категории, так и транслитерацией названия категории. Лучше всего предоставить оба варианта: если поле урла пустое, то транслитерация будет.
    2. Функция CatalogTree () содержит в себе цикл с подключением функции ViewTree(), которая содержит запрос. Следовательно, у тебя получаеться запросы в цикле - очень плохая вещь. Если будет 200 категорий (к примеру), то у тебя будет минимум 201 запрос к БД. А это есть очень плохо.
    Лучше сделать примерно так, ИМХО:
    Делаем запрос на выборку всех активных категорий (если в твоей таблице есть флаг активности категорий), и заносим данные в массив. После этого циклом отображаем все главные категории, а внутри каждого отображения будет цикл по выборке подкатегорий из массива.
    С последним методом может и не прав, но я делаю примерно так :)
  • Givi

    Сообщения: 2284 Репутация: N Группа: Адекваты

    Spritz 28 марта 2009 г. 7:11, спустя 1 минуту 28 секунд

    phpdude, вообще трабла в том, что Гугля отлично отдает результаты по запросу nested sets, а по nested trees немного не то :)
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 28 марта 2009 г. 7:12, спустя 43 секунды

  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 28 марта 2009 г. 7:13, спустя 1 минуту 27 секунд

    И вообще рекомендуется почитать http://phpclub.ru/faq/Tree


       *  Списки смежности (Adjacency List)
       * Вложенные множества (Nested Sets)
       * Вложенные интервалы (Nested Intervals)
       * Материализованные пути (Materialized Path)
       * Другие способы представления деревьев


    + поюзать поиск по форуму, обсуждалось не раз уже
    adw/0
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 7:17, спустя 3 минуты 25 секунд

    Givi
    по первому вроде бы понятно.
    а вот по второму, не могли бы вы разживать, мне неопытному :)
    данные заносим в ассоциативный масив. потом уже этот масив прогоняем через цикл?
    А как нам тогда подключить к ним список стран и городов(он просто как бы один) и объекты выделяются по четырем параметрам тип, вид, страна, город. Я не уловлю суть :(
    adw0rd
    поиском пользовался, в разделе пхп не чего не нашел на тему каталога. А как то про дерево не додумался, не бейте сильно… :)

    PS: спасибо за линки
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 7:32, спустя 15 минут 9 секунд

    мне кажется Nested Sets сюда не подходит, может я не правильно излагаю свою мысыль?
    вот изобразил на картинке
    http://s42.radikal.ru/i096/0903/ed/03afba241225.jpg
  • Givi

    Сообщения: 2284 Репутация: N Группа: Адекваты

    Spritz 28 марта 2009 г. 7:59, спустя 26 минут 45 секунд

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

    $type1 = array('id'=>'1','name'=>'New Category1','parent_id'=>'0'); // это массив каждой строки из БД
    $type2 = array('id'=>'2','name'=>'Sub Category1.1','parent_id'=>'1'); // это массив каждой строки из БД
    $type3 = array('id'=>'3','name'=>'Sub Category1.2','parent_id'=>'1'); // это массив каждой строки из БД

    $type_vid = array($type1,$type2,$type3); // это общий массив всех выбранных строк из одной таблицы БД
    foreach($type_vid as $k=>$arr) {
    if($arr['parent_id'] == 0) { // Если парент = 0, то категория главная
    $id_cat = $arr['id']; // цепляем её АйДишку
    echo $arr['name']; // Выводим её на экран
    foreach($type_vid as $k=>$arr) {
    if($arr['parent_id'] == $id_cat) { // ищем циклом все подкатегории. То есть, если их парент будет равен АйДишке главной категории, то они подкатегории.
    echo $arr['name']; // Выводим их на экран.
    }
    }
    } // Окончание проверки на парент = 0, и после этого будет переход на новый цикл (новый круг в цикле) о выводу второй категории.
    }
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 8:15, спустя 16 минут 21 секунду


    $type1 = array('id'=>'1','name'=>'New Category1','parent_id'=>'0'); // это массив каждой строки из БД
    $type2 = array('id'=>'2','name'=>'Sub Category1.1','parent_id'=>'1'); // это массив каждой строки из БД
    $type3 = array('id'=>'3','name'=>'Sub Category1.2','parent_id'=>'1'); // это массив каждой строки из БД

    я вот не пойму вот этого? ты перед этим зделал запрос в бд?
  • Givi

    Сообщения: 2284 Репутация: N Группа: Адекваты

    Spritz 28 марта 2009 г. 8:22, спустя 6 минут 56 секунд

    mario, да, это типа результаты запроса к БД
    То есть, по сути:

    $res = mysql_query('Tut zapros');

    for($k=0,$type_vid=array();$type = mysql_fetch_array($res);$k++) {
    $type_vid[$k] = $type;
    }


    В результате имеем массив $type_vid с вложенными в него массивами. То есть, то же, что я написал выше, только данные получаем из БД (у меня выше мы данные сами назначали).
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 8:59, спустя 36 минут 46 секунд

    Вот что вышло…

    $dbLink = mysql_connect('name-bd', 'user-bd', 'pass-bd');
    mysql_select_db('name-tamble', $dbLink);
    $Ssql1 = "SELECT `id`, `country_id`, `name` FROM `geo_tree` ORDER BY `country_id`";
    $result1 = mysql_query($Ssql1);
    for($k=0,$geoTree=array();$geo_tree = mysql_fetch_array($result1);$k++) {
      $geoTree[$k] = $geo_tree;
    }
    $Ssql2 = "SELECT `id`, `parent_id`, `name` FROM `catalog_tree` ORDER BY `parent_id`";
    $result2 = mysql_query($Ssql2);
    for($k=0,$type_vid=array();$type = mysql_fetch_array($result2);$k++) {
      $type_vid[$k] = $type;
    }
    //–СТАРТ——Типы и виды.——СТАРТ–
    foreach($type_vid as $k=>$arr) {
       if($arr['parent_id'] == 0) { // Если парент = 0, то это ТИП
           $id_cat = $arr['id'];
           echo '<big><big>'.$arr['name'].'</big></big><br />'; // Выводим ТИП на экран
           foreach($type_vid as $k=>$arr) {
               if($arr['parent_id'] == $id_cat) {
                   echo '<big>'.$arr['name'].'</big><br />'; // Выводим ВИД на экран.
                   //–СТАРТ——Страны и города.——СТАРТ–
                   foreach($geoTree as $z=>$arz) {
       if($arz['country_id'] == 0) { // Если country_id = 0, то страна
           $id_catz = $arz['id']; // цепляем её АйДишку
           echo '<small>'.$arz['name'].'</small><br />'; // Выводим СТРАНУ на экран
           foreach($geoTree as $z=>$arz) {
               if($arz['country_id'] == $id_catz) {
                   echo '<small><small>'.$arz['name'].'</small></small><br />'; // Выводим ГОРОДА на экран.

               }
           }
       } // Окончание проверки на country_id = 0, и после этого будет переход на новый цикл (новый круг в цикле) о выводу второй категории.
    }//–КОНЕЦ——Страны и города.——КОНЕЦ–
               }
           }
       } // Окончание проверки на парент = 0, и после этого будет переход на новый цикл (новый круг в цикле) о выводу второй категории.
    }//–КОНЕЦ——Типы и виды.——КОНЕЦ–

    from UPDATE
    вот щас пробую реализовывать следующее:
    1. Т.к. у нас 2 таблицы создаю два запроса к БД:
    $result1
    SELECT `id`, `country_id`, `name` FROM `geo_tree` ORDER BY `country_id`

    $result2.
    SELECT `id`, `type_id`, `name` FROM `catalog_tree` ORDER BY `country_id`

    2. Помещаю их в ассоциативный массив через функцию mysql_fetch_array
    3. И уже только потом гоняю их в цикле правильно?
    правильно ли поступаю?

    Работаю дальше +)))) спасибо.
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 28 марта 2009 г. 10:08, спустя 1 час 9 минут 26 секунд

    Givi Большое спасибо! Двигаюсь дальше —-> +)))
    phpdude, ubica, adw0rd И вам большое спасибо, за эти деревья, уже приметил где мне их использовать, вот теперь разбираться надо :)

Пожалуйста, авторизуйтесь, чтобы написать комментарий!