2009-12-11 3 views
0

Я пытаюсь создать массив массивов, чтобы создать динамическое меню, но я теряюсь среди кода. Мой результат выглядит следующим образом:Создание php-массивов из sql-запросов

$menu = Array ( 
     [0] => Array ( 
      [text] => Home 
      [class] => 875 
      [link] => //Home 
      [show_condition] => TRUE 
      [parent] => 0 
      ) 
     [1] => Array ( 
      [text] => About 
      [class] => 326 
      [link] => //About 
      [show_condition] => TRUE 
      [parent] => 0 
      ) 
     etc 
     etc 
     etc  
     [339] => Array ( 
      [text] => Planner 
      [class] => 921 
      [link] => //Planner 
      [show_condition] => TRUE 
      [parent] => 45 
      ) 
    ) 

И эти две функции, которые должны строить меню являются:

function build_menu ($menu) { 
      $out = '<div class="container4">' . "\n"; 
      $out .= ' <div class="menu4">' . "\n"; 
      $out .= "\n".'<ul>' . "\n"; 

      for ($i = 1; $i <= count ($menu)-1; $i++) 
      { 

if (is_array ($menu [ $i ])) {//must be by construction but let's keep the errors home 
        if ($menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == 0) {//are we allowed to see this menu? 
         $out .= '<li class="' . $menu [ $i ] [ 'class' ] . '"><a href="' . $menu [ $i ] [ 'link' ] . '">'; 
         $out .= $menu [ $i ] [ 'text' ]; 
         $out .= '</a>'; 
         $out .= get_childs ($menu, $i); 
         $out .= '</li>' . "\n"; 
        } 
       } 
       else { 
        die (sprintf ('menu nr %s must be an array', $i)); 
       } 
      } 

      $out .= '</ul>'."\n"; 
      $out .= "\n\t" . '</div>'; 
      return $out . "\n\t" . '</div>'; 
     } 

    function get_childs ($menu, $el_id) { 
      $has_subcats = FALSE; 
      $out = ''; 
      $out .= "\n".' <ul>' . "\n"; 
      for ($i = 1; $i <= count ($menu)-1; $i++) 
      { 

       if ($menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == $el_id) {//are we allowed to see this menu? 
        $has_subcats = TRUE; 
        $add_class = (get_childs ($menu, $i) != FALSE) ? ' subsubl' : ''; 
        $out .= '  <li class="' . $menu [ $i ] [ 'class' ] . $add_class . '"><a href="' . $menu [ $i ] [ 'link' ] . '">'; 
        $out .= $menu [ $i ] [ 'text' ]; 
        $out .= '</a>'; 
        $out .= get_childs ($menu, $i); 
        $out .= '</li>' . "\n"; 
       } 
      } 
      $out .= ' </ul>'."\n"; 
      return ($has_subcats) ? $out : FALSE; 
     } 

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

Спасибо!

ответ

1

Ваш код почти нет - вы можете захотеть изменить mysql_fetch_array к mysql_fetch_assoc, и вы можете конвертировать значения, возвращаемый в соответствующие типы, используя такие функции, как: intval

$menu = array(); 
$sql = "SELECT TabName as text, TabID as class, TabPath as link, IsVisible as show_condition, ParentId as parent FROM dnn_SMA_Tabs WHERE PortalID = 3 AND IsVisible = 'True' ORDER BY TabOrder ASC"; 
$result = mysql_query($sql); 
$index = 1; 
while($row = mysql_fetch_assoc($result)) { 
    $row['parent'] = intval($row['parent']); 
    $menu[$index] = $row; 
    $index++; 
} 

Вам нужно преобразовать show_condition в соответствующий тип - как это сделать, вероятно, зависит от типа столбца IsVisible.

+0

Я думаю, что это действительно близко к работе, но теперь я получаю это сообщение об ошибке Примечание: Неопределенное смещение: 373 в sitemap2.php on line 24 menu nr 373 должен быть массивом Запрос возвращает 373 строки, поэтому последний делает что-то смешное. Есть идеи? – MrFidge

+0

Что такое строка 24 'sitemap2.php'? –

+0

отредактировал все это в мой ответ – MrFidge

0

я вижу ваш массив имеет индексы от [0] до [399]

Array (

[0] => Array ( 
    [text] => Home 
    [class] => 875 
    [link] => //Home 
    [show_condition] => TRUE 
    [parent] => 0 
    ) 
[1] => Array ( 
    [text] => About 
    [class] => 326 
    [link] => //About 
    [show_condition] => TRUE 
    [parent] => 0 
    ) 
etc 
etc 
etc  
[339] => Array ( 
    [text] => Planner 
    [class] => 921 
    [link] => //Planner 
    [show_condition] => TRUE 
    [parent] => 45 
    ) ) 

но вы пытаетесь показать детали от [1] до [340]

для ($ = 1; $ я < = Count ($) меню; $ я ++)

Количество ($ меню) возвращает 340 ([0] -> [399])

Решение: для ($ I = 0; $ i < count ($ menu); $ Я ++)

начало от 0 и идти до 399 (строго < 340)

+0

Привет, мой массив только до 340, не совсем уверен, откуда вы получаете 399! Проблема с графом также была указана в приведенном выше ответе, но это не совсем исправленные вещи. – MrFidge

0

Я хотел бы сделать это в другой способ: объектно-ориентированный.

class Menu { 
    private $children = array(); 
    private $name = ''; 
    private $link = ''; 
    private $class = ''; 
    private $show = TRUE; 

    function __construct($name, $class, $link, $show = TRUE, $parent = null) { 
    $this->name = $name; 
    $this->link = $link; 
    $this->class = $class; 
    $this->show = $show; 
    if(!is_null($parent)) { 
     $parent->addChild($this); 
    } 
    } 

    function addChild(Menu $child) { 
     $this->children[] = $child; 
    } 

    // ... remaining getters (and probably setters) 
} 

Затем вы можете создать меню, как это:

$home = new Menu('Home', '875', '//Home'); 
$about = new Menu('About', '326', '//About'); 

//... 

$planner = new Menu('Planner', '921', '//Planner', true, $home); 

$menu = array($home, $about,...); 

Это только один пример. Я знаю, что это будет означать, что вы создадите 340 переменных для хранения вашего меню. С помощью других методов setter и getter вы можете сделать это лучше, это просто быстрый «эскиз».

Вы можете создать меню, как это:

function build_menu ($menu, $showContainer = false) { 
    $out = ''; 
    if($showContainer) { 
     $out = '<div class="container4">' . "\n"; 
     $out .= '  <div class="menu4">' . "\n";    
    } 

    if(!empty($menu)) { 
     $out .= '<ul>' . "\n"; 

     for ($entry in $menu) { 
      if($entry->getShow()) {//are we allowed to see this menu? 
       $out .= '<li class="' . $entry->getClass() . '"><a href="' . $entry->getLink() . '">'; 
       $out .= $entry->getText(); 
       $out .= '</a>'; 
       $out .= "\n" . build_menu($entry->getChildren()); 
       $out .= '</li>' . "\n"; 
      } 
     } 
     $out .= '</ul>'."\n"; 
    } 
    if($showContainer) { 
     $out .= "\n\t" . '</div>'; 
     $out .= "\n\t" . '</div>';     
    } 
    return $out; 
} 

Я не проверял код, но это идея позади него. Если у вас нет опыта работы с ООП и php, посмотрите на official documentation.

А также обратите внимание, что для этого требуется PHP5.

Смежные вопросы