За последние 24 часа нас посетили 20798 программистов и 1137 роботов. Сейчас ищут 370 программистов ...

Категории и подкатегории

Тема в разделе "PHP для новичков", создана пользователем _ne_scaju_, 13 апр 2019.

  1. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @_ne_scaju_, тем что цикл в цикле - это надо заранее знать глубину вложенности, при глубине вложенности "без разницы" очень помогает рекурсия.
     
  2. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    PHP:
    1. class myRecursion {
    2.  
    3.     public function method_myRecursion($_element) {
    4.  
    5.         if (is_array($_element)) {
    6.  
    7.             foreach ($_element as $_value) {
    8.                 $this->method_myRecursion($_value);
    9.             }
    10.  
    11.         } else {
    12.  
    13.             echo '<div>'. $_element .'</div>';
    14.  
    15.         }
    16.  
    17.     }
    18.  
    19. }
    20.  
    21. $result = new myRecursion();
    22. $_myArray = array('1' =>
    23.    array('A', 'B', 'C'), '2' =>
    24.    array('D', 'E', 'F'), '3' =>
    25.    array('G', 'H', 'I')
    26. );
    27. $result -> method_myRecursion( $_myArray );
    28.  
    29. result:
    30. A
    31. B
    32. C
    33. D
    34. E
    35. F
    36. G
    37. H
    38. I
    нашел вот такую рекурсии, как она тебе, я смотрел примеры, вообще лучше пока не нашел.
     
    #52 _ne_scaju_, 18 апр 2019
    Последнее редактирование: 18 апр 2019
  3. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    ребята не когда не пользовался рекурсией пока не въеду как ее реализовать(
    пока накидал так но не чего не получается:
    PHP:
    1.     public function getCategoriesList()
    2.     {
    3.         return $this -> db -> sel('SELECT * FROM `game_categories` WHERE `category_status` = 1');
    4.     }
    5.  
    6.     # Получаем из бд массив вложенный массив
    7.    public function getTree( $dataset )
    8.     {
    9.         $tree = [];
    10.  
    11.         foreach ( $dataset = self::getCategoriesList() as $id => $test)
    12.         {
    13.             if ( !$test['parent_id'] )
    14.             {
    15.                 $tree[$id] = $test;
    16.             }
    17.             else
    18.             {
    19.                 $dataset[$test['parent_id']][$id]['category_id'] = $test;
    20.             }
    21.         }
    22.         return $tree;
    23.     }
    получается выводится опять же меню, а подменю не выводится.
    в шаблоне осталось так же.
    PHP:
    1. <?php foreach ( $listCategory as $key => $ctg ): ?>
    2.                   <div class="list-group-item list-group-item-action category-group-title" data-target="#collapse<?php echo $ctg['category_id']; ?>" data-toggle="collapse">
    3.                     <h5><?php echo $ctg['category_name']; ?></h5>
    4.                   </div>
    5.  
    6.                   <div class="collapse" id="collapse<?php echo $ctg['category_id']; ?>">
    7.                     <a style="color: red;" class="list-group-item list-group-item-action" href="/category/<?php echo $ctg['category_id']; ?>">
    8.                       { <?php echo $ctg['category_name'][$key]; ?> }
    9.                     </a>
    10.                   </div>
    11.                 <?php endforeach; ?>
    может что в шаблоне нужно изменить?
     
    #53 _ne_scaju_, 18 апр 2019
    Последнее редактирование: 18 апр 2019
  4. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    что я делаю не так?)
     
  5. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    А где ты показываешь что ты делаешь, кто знает содержание твоих переменных? ;)
    var_export() массивов, дамп базы, sql песочница с запросами - тогда может будет понятно.
     
  6. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @_ne_scaju_, как только ты начинаешь гуглить и качать скрипт, ты уже всё делаешь не так. Пиши все сам.
     
  7. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    ок, таблица:
    Код (Text):
    1. CREATE TABLE `game_categories` (
    2.   `category_id` int(11) NOT NULL COMMENT 'идентификатор категории',
    3.   `parent_id` int(11) NOT NULL COMMENT 'родительский id',
    4.   `category_name` varchar(255) NOT NULL COMMENT 'Название категории которое будет отображаться в меню',
    5.   `category_status` int(11) NOT NULL DEFAULT '1' COMMENT '1 отображать 0 не отображать категорию'
    6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Категория игр';
    7.  
    8. --
    9. -- Дамп данных таблицы `game_categories`
    10. --
    11.  
    12. INSERT INTO `game_categories` (`category_id`, `parent_id`, `category_name`, `category_status`) VALUES
    13. (1, 0, 'WORLD OF TANKS', 1),
    14. (2, 0, 'WORLD OF WARSHIPS', 1),
    15. (3, 0, 'ИГРЫ STEAM', 1),
    16. (4, 0, 'DOTA 2', 1),
    17. (5, 0, 'ROYAL QUEST', 1),
    18. (6, 0, 'CSGO', 1),
    19. (7, 0, 'ДРУГИЕ', 1),
    20. (8, 1, 'wot-1', 1),
    21. (9, 1, 'wot-2', 1),
    22. (10, 1, 'wot-3', 1),
    23. (11, 1, 'wot-5', 1),
    24. (12, 4, 'dota-1', 1),
    25. (13, 4, 'dota-2', 1),
    26. (14, 4, 'dota-3', 1),
    27. (15, 6, 'CS-1', 1),
    28. (16, 6, 'CS-2', 1),
    29. (17, 6, 'CS-3', 1),
    30. (18, 2, 'warship-1', 1),
    31. (19, 2, 'warship-2', 1),
    32. (20, 7, 'dr-1', 1),
    33. (21, 7, 'dr-2', 1),
    34. (22, 7, 'dr-3', 1);
    далее код повторяю, в моделе я делаю запрос, на вывод содержимого этой таблицы, дамп выше.
    и после того как выполнил запрос, передаю его в метод который переберает массив:
    PHP:
    1.     public function getCategoriesList()
    2.     {
    3.         return $this -> db -> sel('SELECT * FROM `game_categories` WHERE `category_status` = 1');
    4.     }
    5.    
    6.  
    7.     # Получаем из бд массива вложенный массив
    8.    public function getTree( $dataset )
    9.     {
    10.         $tree = [];
    11.    
    12.         foreach ( $dataset = self::getCategoriesList() as $id => $node )
    13.         {
    14.             if ( !$node['parent_id'] )
    15.             {
    16.                 $tree[$id] = $node;
    17.             }
    18.             else
    19.             {
    20.                 $dataset[$node['parent_id']][$id]['category_id'] = $node;
    21.             }
    22.         }
    23.         return $tree;
    24.     }
    далее контроллер просит модель, у метода getTree() отдать данные для вывода категорий и подкатегорий:
    PHP:
    1.     public function indexAction()
    2.     {
    3.         # Список категорий игровых для левого меню
    4.        $category = new CategoryGame();
    5.         $listCategory = $category -> getTree( null );
    6.  
    7.         //echo '<pre>';
    8.         //var_dump ( $listCategory );
    9.         //echo '</pre>';
    10.  
    11.         # Список последних игр
    12.        $product = new UserProductGame();
    13.         $listGame = $product -> getLatestProducts(8);
    14.  
    15.         # Список рекомендуемых игр для слайдера
    16.        $listSliderGame = $product -> getRecommendedProducts();
    17.        
    18.         # Подключаем вид
    19.        require_once('app/views/main/index.php');
    20.         return true;
    21.     }
    вардам мне выдает такое:
    Код (Text):
    1. array(7) {
    2.   [0]=>
    3.   array(4) {
    4.     ["category_id"]=>
    5.     string(1) "1"
    6.     ["parent_id"]=>
    7.     string(1) "0"
    8.     ["category_name"]=>
    9.     string(14) "WORLD OF TANKS"
    10.     ["category_status"]=>
    11.     string(1) "1"
    12.   }
    13.   [1]=>
    14.   array(4) {
    15.     ["category_id"]=>
    16.     string(1) "2"
    17.     ["parent_id"]=>
    18.     string(1) "0"
    19.     ["category_name"]=>
    20.     string(17) "WORLD OF WARSHIPS"
    21.     ["category_status"]=>
    22.     string(1) "1"
    23.   }
    24.   [2]=>
    25.   array(4) {
    26.     ["category_id"]=>
    27.     string(1) "3"
    28.     ["parent_id"]=>
    29.     string(1) "0"
    30.     ["category_name"]=>
    31.     string(14) "ИГРЫ STEAM"
    32.     ["category_status"]=>
    33.     string(1) "1"
    34.   }
    35.   [3]=>
    36.   array(4) {
    37.     ["category_id"]=>
    38.     string(1) "4"
    39.     ["parent_id"]=>
    40.     string(1) "0"
    41.     ["category_name"]=>
    42.     string(6) "DOTA 2"
    43.     ["category_status"]=>
    44.     string(1) "1"
    45.   }
    46.   [4]=>
    47.   array(4) {
    48.     ["category_id"]=>
    49.     string(1) "5"
    50.     ["parent_id"]=>
    51.     string(1) "0"
    52.     ["category_name"]=>
    53.     string(11) "ROYAL QUEST"
    54.     ["category_status"]=>
    55.     string(1) "1"
    56.   }
    57.   [5]=>
    58.   array(4) {
    59.     ["category_id"]=>
    60.     string(1) "6"
    61.     ["parent_id"]=>
    62.     string(1) "0"
    63.     ["category_name"]=>
    64.     string(4) "CSGO"
    65.     ["category_status"]=>
    66.     string(1) "1"
    67.   }
    68.   [6]=>
    69.   array(4) {
    70.     ["category_id"]=>
    71.     string(1) "7"
    72.     ["parent_id"]=>
    73.     string(1) "0"
    74.     ["category_name"]=>
    75.     string(12) "ДРУГИЕ"
    76.     ["category_status"]=>
    77.     string(1) "1"
    78.   }
    79. }
    ок, и в самом шаблоне который подключаю в контроллере стараюсь вывести категории с подкатегориями:
    HTML:
    1.         <div class="well">
    2.           <h3><span class="glyphicon glyphicon-th-list"></span> Категории</h3>
    3.           <hr>
    4.           <div class="row">
    5.             <div class="col-lg-12">
    6.               <div class="list-group">
    7.                 <?php foreach ( $listCategory as $key => $ctg ): ?>
    8.                   <div class="list-group-item list-group-item-action category-group-title" data-target="#collapse<?php echo $ctg['category_id']; ?>" data-toggle="collapse">
    9.                     <h5><?php echo $ctg['category_name']; ?></h5>
    10.                   </div>
    11.  
    12.                   <div class="collapse" id="collapse<?php echo $ctg['category_id']; ?>">
    13.                     <a style="color: red;" class="list-group-item list-group-item-action" href="/category/<?php echo $ctg['category_id']; ?>">
    14.                       { <?php echo $ctg['category_name'][$key]; ?> }
    15.                     </a>
    16.                   </div>
    17.                 <?php endforeach; ?>
    18.               </div>
    19.             </div>
    20.           </div>
    21.         </div>
    где в этот кусок должны выводиться подкатегории
    HTML:
    1.                 <div class="collapse" id="collapse<?php echo $ctg['category_id']; ?>">
    2.                     <a style="color: red;" class="list-group-item list-group-item-action" href="/category/<?php echo $ctg['category_id']; ?>">
    3.                       { <?php echo $ctg['category_name'][$key]; ?> }
    4.                     </a>
    5.                   </div>
    ну что я не правильно делаю, объясните мне пожалуйста, спасибо.
    --- Добавлено ---
    как можно писать самому если я даже не когда не пробовал делать рекурсию, с прочитанного понял, что это функция вызывающая саму себя, и не более.
     
  8. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @_ne_scaju_
    Я говорил var_export(), не var_dump()
    И заполнить базу можно было как-то осмысленне:
    категория - комп игры
    под-категория - военные
    под-под-категория - сухопутные
    под-под-под-категория - танки
     
  9. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    как можно писать самому если я даже не когда не пробовал делать рекурсию, с прочитанного понял, что это функция вызывающая саму себя и не более.
    ок вот:
    Код (Text):
    1. array (
    2.   0 =>
    3.   array (
    4.     'category_id' => '1',
    5.     'parent_id' => '0',
    6.     'category_name' => 'WORLD OF TANKS',
    7.     'category_status' => '1',
    8.   ),
    9.   1 =>
    10.   array (
    11.     'category_id' => '2',
    12.     'parent_id' => '0',
    13.     'category_name' => 'WORLD OF WARSHIPS',
    14.     'category_status' => '1',
    15.   ),
    16.   2 =>
    17.   array (
    18.     'category_id' => '3',
    19.     'parent_id' => '0',
    20.     'category_name' => 'ИГРЫ STEAM',
    21.     'category_status' => '1',
    22.   ),
    23.   3 =>
    24.   array (
    25.     'category_id' => '4',
    26.     'parent_id' => '0',
    27.     'category_name' => 'DOTA 2',
    28.     'category_status' => '1',
    29.   ),
    30.   4 =>
    31.   array (
    32.     'category_id' => '5',
    33.     'parent_id' => '0',
    34.     'category_name' => 'ROYAL QUEST',
    35.     'category_status' => '1',
    36.   ),
    37.   5 =>
    38.   array (
    39.     'category_id' => '6',
    40.     'parent_id' => '0',
    41.     'category_name' => 'CSGO',
    42.     'category_status' => '1',
    43.   ),
    44.   6 =>
    45.   array (
    46.     'category_id' => '7',
    47.     'parent_id' => '0',
    48.     'category_name' => 'ДРУГИЕ',
    49.     'category_status' => '1',
    50.   ),
    51. )
     
    #59 _ne_scaju_, 19 апр 2019
    Последнее редактирование: 19 апр 2019
  10. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    ну конечно зачем писать самому, если уже велосипеды есть?) просто в них нужно разбираться(
     
  11. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Хотя бы нормально вопросы формулировать нужно.
    PHP:
    1. SELECT category_name, games
    2. FROM (
    3. SELECT cat_id, GROUP_CONCAT(
    4.     CONCAT_WS(': status ',g.category_name,
    5.              g.category_status)) games
    6.   FROM (
    7.     SELECT `category_name` c_name, `category_id` cat_id
    8.     FROM `game_categories`
    9.     WHERE `parent_id` = 0 ) AS c
    10.   JOIN `game_categories` g
    11.   ON (`cat_id` = `parent_id`)
    12.   GROUP BY cat_id
    13. ) AS s
    14. JOIN `game_categories`
    15. ON (`category_id` = `cat_id`)
     
    _ne_scaju_ нравится это.
  12. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    сегодня покажу переделанный под себя вариант) который я нашел в инете, если сделаю)
    ответ я дал правильный, я типа спросил у себя и сам себе ответил, это была задумка такая :D
     
  13. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    обычно такие заявки не имеют продолжения — просто наблюдение )))
     
    _ne_scaju_ нравится это.
  14. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @_ne_scaju_
    Твоя таблица с одним уровнем категорий это вообще ни о чем, попробуй с пятью.
    Так чтобы готовый массив:
    PHP:
    1. SELECT category_name, CONCAT('["',games,']') games
    2. FROM (
    3. SELECT cat_id, GROUP_CONCAT(
    4.     CONCAT_WS('" => ',g.category_name,
    5.              g.category_status)
    6.   SEPARATOR ', "') games
    7.   FROM (
    8.     SELECT `category_name` c_name, `category_id` cat_id
    9.     FROM `game_categories`
    10.     WHERE `parent_id` = 0 ) AS c
    11.   JOIN `game_categories` g
    12.   ON (`cat_id` = `parent_id`)
    13.   GROUP BY cat_id
    14. ) AS s
    15. JOIN `game_categories`
    16. ON (`category_id` = `cat_id`)
     
  15. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    зачем, пока у меня не будет вложености на 5 подкатегории, думаю это не нужно.
    --- Добавлено ---
    учту это.
     
  16. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    А нафига тогда брался за это дерево? ;)
    Там left join чтобы все выбрать:
    PHP:
    1. SELECT category_name, CONCAT('[',games,']') games
    2. FROM (
    3. SELECT cat_id, GROUP_CONCAT(
    4.     CONCAT_WS(' => ',CONCAT('"', g.category_name, '"'),
    5.              g.category_status)) games
    6.   FROM (
    7.     SELECT `category_name` c_name, `category_id` cat_id
    8.     FROM `game_categories`
    9.     WHERE `parent_id` = 0 ) AS c
    10.   LEFT JOIN `game_categories` g
    11.   ON (`cat_id` = `parent_id`)
    12.   GROUP BY cat_id
    13. ) AS s
    14. JOIN `game_categories`
    15. ON (`category_id` = `cat_id`)
     
  17. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    мне предложили рекурсию вот я и ее пробую до сих пор сделать, почему-то не получилось под себя допилить(.
     
  18. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    _ne_scaju_ нравится это.
  19. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @_ne_scaju_, рекурсия не только вызывает саму себя, но и как любая нормальная функция возвращает управление тому кто её вызвал. В случае рекурсии возвращает самой себе, ровно на один раз меньше количества вызовов этой функции, плюс последний возврат в основную программу. В итоге количество возвратов, равно количеству вызовов.
     
    _ne_scaju_ нравится это.
  20. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    я до сих пор не могу обработать эту с у.. пер рекурсию( может кто поможет?
    PHP:
    1.    public $categories = []; # публик переменная для список всех категорий
    2.    public $categoriesTree = []; # публик переменная для список категорий в форме дерева
    3.    public function __construct() {
    4.        parent::__construct(); # вызываем родительский конструктор Model
    5.        $this -> categories = $this -> getCategories();
    6.         // $this -> categoriesTree = $this -> getFullTree();
    7.     }
    8.     /*
    9.      * Список всех категорий
    10.      */
    11.     private function getCategories(){
    12.         $arr_cat = [];
    13.         $result = $this -> db -> sel("SELECT * FROM `game_categories`");
    14.         foreach($result AS $category) {
    15.             $arr_cat[$category['category_id']] = $category;
    16.         }
    17.         return $arr_cat;
    18.     }
    19.     /*
    20.      * Список категорий, в форме дерева
    21.      */
    22.     public function getFullTree($categories) {
    23.         // $categories = $this -> categories;
    24.         $tree = [] ;
    25.         foreach($categories as $id => &$node) {
    26.             if(!$node['parent_id']){
    27.                 $tree[$id] = &$node ;
    28.             }else{
    29.                 $categories[$node['parent_id']]['children'][$id] = &$node ;
    30.             }
    31.         }
    32.         return $tree;
    33.     }
    34.  
    35.     public function showCat( $categories )
    36.     {
    37.         echo '<pre>';
    38.         var_dump($categories);
    39.         echo '</pre>';
    40.     }
    в первой функции получаю список всех категорий подкатегорий
    во второй функции получаю форму дерева из полученного массива
    и в третей функции по логике нужно сформировать сам вывод, этого дерева, но сколько не пытался у меня не чего не получилось(
    может кто подкинет идейку, спасибо, я уже много пересмотрел этих деревьев поверьте но так и не смог разобраться, сразу меня не пинайте ок?
     
    #70 _ne_scaju_, 26 апр 2019
    Последнее редактирование: 26 апр 2019
  21. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    долбанное дерево) иногда некогда решать эту задачу, как начинаю смотреть на нее так сразу хочется бросить программировать.
     
  22. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @_ne_scaju_, ты ещё даже не начинал программировать, а уже хочешь бросить :)
     
  23. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.989
    Симпатии:
    759
    просто же всё
    за два то с половиной года некоторые уже в офисе давно работают и пользу приносят миру
    и такими примитивными вопросами давно не задаются
    --- Добавлено ---
    коллеги, восхищаюсь вашим терпением
     
  24. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    да ну это же не обязательно, что я php каждый день учу, тем более 2 с половиной года, я максимум его 6 месяцев учу а может быть и меньше, разбираюсь пытаюсь понять этот язык. Да и практики у меня маловато. Да и так подумать, а может у меня свои дела работа учеба, что я не успеваю его даже учить, серьезно. Да возможно на форуме я уже 2 с половиной года, а толку? просто провожу время общаясь с форумом.
    Объясните мне логику что должно происходить в этом дереве, а я попробую его построить, спасибо.
     
  25. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.068
    Симпатии:
    1.231
    Адрес:
    там-сям
    @_ne_scaju_ что должно происходить - это ты нам скажи.

    Может заново сформулируешь что ты хочешь получить в итоге? В начальном посте ты описал задачу так, что в ней присутствует кусок структуры бд (как тебе это виделось в тот момент). И это было неправильно. Дай нам только цель. Что ты хочешь получить на выходе?