accessing array inside object inside array

  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 27th, 2004, 5:24 pm

well, assuming that what i said above is true... this is what i have so far...

PHP Code: [ Select ]
<?php
 
   include('sqlQuery.php');
 
   
 
   $level = '0';
 
   $menuStr = NULL;
 
   $nodes = NULL;
 
   $index = 0;
 
   
 
   $menu = generateMenu('0.2');
 
   echo($menu);
 
 
 
   function generateMenu($address){
 
      global $nodes;
 
      $nodes = explode('.', $address);
 
      $menu = menuCrawler();
 
      return $menu;
 
   }
 
   function menuCrawler(){
 
      global $level, $menuStr, $nodes, $index;
 
     
 
      $level += '.' . $nodes[$index];
 
      $result = queryDB("SELECT address FROM menus WHERE address = '" . $level . "'", true);
 
     
 
      for($i = 0; $i < count($result) - 1; $i++){
 
         $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $level . "'", true);
 
         foreach($result as $key => $item){
 
            $menuStr += "<li>" . $item[1];
 
            if($item[0] == $nodes[$index + 1]){
 
               $index += 1;
 
               $menuStr += "<ul>" . menuCrawler($level) . "</ul>";
 
            }
 
         }    
 
         $menuStr += "</li>";
 
      }
 
      return $menuStr;
 
   }
 
?>
  1. <?php
  2.  
  3.    include('sqlQuery.php');
  4.  
  5.    
  6.  
  7.    $level = '0';
  8.  
  9.    $menuStr = NULL;
  10.  
  11.    $nodes = NULL;
  12.  
  13.    $index = 0;
  14.  
  15.    
  16.  
  17.    $menu = generateMenu('0.2');
  18.  
  19.    echo($menu);
  20.  
  21.  
  22.  
  23.    function generateMenu($address){
  24.  
  25.       global $nodes;
  26.  
  27.       $nodes = explode('.', $address);
  28.  
  29.       $menu = menuCrawler();
  30.  
  31.       return $menu;
  32.  
  33.    }
  34.  
  35.    function menuCrawler(){
  36.  
  37.       global $level, $menuStr, $nodes, $index;
  38.  
  39.      
  40.  
  41.       $level += '.' . $nodes[$index];
  42.  
  43.       $result = queryDB("SELECT address FROM menus WHERE address = '" . $level . "'", true);
  44.  
  45.      
  46.  
  47.       for($i = 0; $i < count($result) - 1; $i++){
  48.  
  49.          $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $level . "'", true);
  50.  
  51.          foreach($result as $key => $item){
  52.  
  53.             $menuStr += "<li>" . $item[1];
  54.  
  55.             if($item[0] == $nodes[$index + 1]){
  56.  
  57.                $index += 1;
  58.  
  59.                $menuStr += "<ul>" . menuCrawler($level) . "</ul>";
  60.  
  61.             }
  62.  
  63.          }    
  64.  
  65.          $menuStr += "</li>";
  66.  
  67.       }
  68.  
  69.       return $menuStr;
  70.  
  71.    }
  72.  
  73. ?>


however, it is outputing a 0...
  • Anonymous
  • Bot
  • No Avatar
  • Joined: 25 Feb 2008
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post June 27th, 2004, 5:24 pm

  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 28th, 2004, 4:29 am

Calendae wrote:
Quote:
parentID - ID - link
0 - 0 - <a href = "/" class = "nav level1"...
0 - 1 - <a href ="/main.php?page=e2004" class ="nav level1...
0 - 2 - <a href ="/main.php?page=wow" class ="nav level1"...
0 - 3 - <a href ="/main.php?page=stargate" class ="nav lev...
2 - 0 - <a href =" /main.php?page=wow&sub=races" class =" ...
2 - 1 - <a href =" /main.php?page=wow&sub=classes" class ="...


Id=0 parentid=0. That will cause you problems, you will continually loop through that one node, placing it inside itself.

Quote:
and if i want to specify which menu i want wouldnt i have to specify something like '0.2.1.3' and then have it split it, and the determine the node by which level its at???

ie:
level0: node = 0
level1: node = 2 (for parentID = 0)
level2: node = 1 (for parentID = 2, super-parentID = 0)
level3: node = 3 (for parentID = 1, super-parentID = 2, super-super-parentID = 0)

I'm not entirely sure why you would need to know what level you are at at any one point? The idea of a tree i that you don't need the entire address. If you have the full address then you will start to get inconsistancies. #

Hang on I see what you have done, the Id's should be unique. For example
Quote:
parentID - ID - link
0 - 0 - <a href = "/" class = "nav level1"...
0 - 1 - <a href ="/main.php?page=e2004" class ="nav level1...
0 - 2 - <a href ="/main.php?page=wow" class ="nav level1"...
0 - 3 - <a href ="/main.php?page=stargate" class ="nav lev...
2 - 4 - <a href =" /main.php?page=wow&sub=races" class =" ...
2 - 5 - <a href =" /main.php?page=wow&sub=classes" class ="...

Because each node is an individual item. If you have lots of nodes with id=1, and a node with parentID=1, how can you know <B>which</B> node with ID 1 is the parent. If you have unique ID's you can get the full address by traversing the tree in to other way. Also check out the original example I showed you. The arrayindex is the same as the database ID. See how it is used in both cases.

having looked through your code and your menu, I can see a few other problems.

I now see that you need to know how many levels down you are to know which sections to have open. This makes things complicated but not as complicated as you have made them.

You are using both returns and global variables to build the $menuStr . Either method is viable, but you cannot use both at the same time. I chose the returns because it felt "neater" to me.

At the moment I think you are going to have to start with the node that you are at. Then work back up the tree to the very root node to get the address (as an array of Id's, call it $openId[] for eg). Then you modify the menu crawler to open the base menu, and any subsection node that is specified in the openId[] array.

I'll mock up an example, but I have no way of testing it because I am at work at the moment. Give me a bit and I'll edit it onto this post


PHP Code: [ Select ]
//Assume we know the current Node Id and it is held in the variable $thisPageId
 
 
 
$openId = array();
 
$openId[-1] = "";
 
 
 
 
 
getAddress($ThisPageId);
 
/*
 
This will giv us an array like:
 
-1 -> ""
 
2 -> ""
 
7 -> ""
 
 
 
which is the node Id=7 which has parentId=2, and 2 is a top level.
 
I've done it this way round, using keys instead of values so
 
that you can use isset().
 
*/
 
menu=makeMenu(-1);
 
 
 
function getAddress($currentNode){
 
    global $openId;
 
    $openId[$currentNode]="";    //Done this was so we can use isset later on
 
    //Get parent node for this node from the database
 
    if ($parentNode!=-1){
 
        getAddress($parentNode);
 
    }
 
}
 
 
 
 
 
function getMenu($parentId){
 
    //Get all nodes with parentId=$parentId
 
    global $openId;
 
    $menuStr='';
 
    foreach(/*results*/){
 
        $menuStr+="<li>"./*link from DB*/;
 
        if(isset($openId[/*currentIdfromDB*/])){
 
            $menuStr+="<ul>";
 
            $menuStr+=getMenu(/*currentIdfromDB*/);
 
            $menuStr+="</ul>";
 
        }
 
   menuStr+="</li>"
 
    }
 
}
  1. //Assume we know the current Node Id and it is held in the variable $thisPageId
  2.  
  3.  
  4.  
  5. $openId = array();
  6.  
  7. $openId[-1] = "";
  8.  
  9.  
  10.  
  11.  
  12.  
  13. getAddress($ThisPageId);
  14.  
  15. /*
  16.  
  17. This will giv us an array like:
  18.  
  19. -1 -> ""
  20.  
  21. 2 -> ""
  22.  
  23. 7 -> ""
  24.  
  25.  
  26.  
  27. which is the node Id=7 which has parentId=2, and 2 is a top level.
  28.  
  29. I've done it this way round, using keys instead of values so
  30.  
  31. that you can use isset().
  32.  
  33. */
  34.  
  35. menu=makeMenu(-1);
  36.  
  37.  
  38.  
  39. function getAddress($currentNode){
  40.  
  41.     global $openId;
  42.  
  43.     $openId[$currentNode]="";    //Done this was so we can use isset later on
  44.  
  45.     //Get parent node for this node from the database
  46.  
  47.     if ($parentNode!=-1){
  48.  
  49.         getAddress($parentNode);
  50.  
  51.     }
  52.  
  53. }
  54.  
  55.  
  56.  
  57.  
  58.  
  59. function getMenu($parentId){
  60.  
  61.     //Get all nodes with parentId=$parentId
  62.  
  63.     global $openId;
  64.  
  65.     $menuStr='';
  66.  
  67.     foreach(/*results*/){
  68.  
  69.         $menuStr+="<li>"./*link from DB*/;
  70.  
  71.         if(isset($openId[/*currentIdfromDB*/])){
  72.  
  73.             $menuStr+="<ul>";
  74.  
  75.             $menuStr+=getMenu(/*currentIdfromDB*/);
  76.  
  77.             $menuStr+="</ul>";
  78.  
  79.         }
  80.  
  81.    menuStr+="</li>"
  82.  
  83.     }
  84.  
  85. }


As you can see we create an array of the nodes we wish to open and then make the menu, opening nodes that are specified in the array.
This is not necessarilly accurate, I've just knocked it together again, and I have left all the database bits out. Note that any top-level node needs to have parentId = -1 for this to work. Then each node has a <b>completely unique</b> id, starting at 0.
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 28th, 2004, 3:06 pm

ok, i think i see what youre getting at... but im thinking that that would be extreamly hard to maintain... is there any whay i could do it wiht the addresses i mentioned before?
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 29th, 2004, 1:32 am

not that hard to maintain. When you add a new page, you find the parent and you add the correct parent Id to it, which is basically how a normal filesystem works. Just think of the parents as directories.

Anyway the way your method falls down is if you want to alter your categorisation at a later date. think about moving a node in your system, you would have to manually edit the address of EVERY descendant node. My method, all of the descendants move automagically.

However, it is perfectly feasable to set up your method. First step would be to decide whether the string would be a global or a returned value. The best thing I can suggest is to do run through it manually, writing down exactly what is going on. Recursion can be a little bit difficult to understand, so it might be worth looking up some tutorials on it.
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 29th, 2004, 7:12 am

ok, i guess i didnt mean maintain... your way would be easier to maintain... but i think my way would be easier to use because you wouldnt have to remeber which ID goes with which menu... using my way, you just have to work your way down the chain... *shrug* that is what is easier to me anyway...

back to the code now... :P using returns would make everything easier... so thats what im going to do... however, it is saying that there is an 'Invalid Argument' in my foreach loop, and im not sure why...

PHP Code: [ Select ]
<?php
 
   include('sqlQuery.php');
 
   
 
   $nodes = NULL;
 
   $level = '';
 
   $index = NULL;
 
   
 
   $menu = generateMenu('0.3');
 
   echo($menu);
 
 
 
   function generateMenu($address){
 
      global $nodes;
 
      $nodes = explode('.', $address);
 
      $menu = menuCrawler();
 
      return $menu;
 
   }
 
   function menuCrawler(){
 
      global $level, $nodes, $index;
 
     
 
      $level += '.' . $nodes[$index];
 
     
 
      $current = $level;
 
     
 
      $result = queryDB("SELECT address FROM menus WHERE address = '" . $current . "'", true);
 
     
 
      for($i = 0; $i <= count($result) - 1; $i++){
 
         $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $current . "'", true);
 
         foreach($result as $key => $item){
 
            $menuStr += "<li>" . $item[1];
 
            if($item[0] == $nodes[$index + 1]){
 
               $index++;
 
               $menuStr += "<ul>" . menuCrawler($current) . "</ul>";
 
            }
 
         }    
 
         $menuStr += "</li>";
 
      }
 
      return $menuStr;
 
   }
 
?>
  1. <?php
  2.  
  3.    include('sqlQuery.php');
  4.  
  5.    
  6.  
  7.    $nodes = NULL;
  8.  
  9.    $level = '';
  10.  
  11.    $index = NULL;
  12.  
  13.    
  14.  
  15.    $menu = generateMenu('0.3');
  16.  
  17.    echo($menu);
  18.  
  19.  
  20.  
  21.    function generateMenu($address){
  22.  
  23.       global $nodes;
  24.  
  25.       $nodes = explode('.', $address);
  26.  
  27.       $menu = menuCrawler();
  28.  
  29.       return $menu;
  30.  
  31.    }
  32.  
  33.    function menuCrawler(){
  34.  
  35.       global $level, $nodes, $index;
  36.  
  37.      
  38.  
  39.       $level += '.' . $nodes[$index];
  40.  
  41.      
  42.  
  43.       $current = $level;
  44.  
  45.      
  46.  
  47.       $result = queryDB("SELECT address FROM menus WHERE address = '" . $current . "'", true);
  48.  
  49.      
  50.  
  51.       for($i = 0; $i <= count($result) - 1; $i++){
  52.  
  53.          $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $current . "'", true);
  54.  
  55.          foreach($result as $key => $item){
  56.  
  57.             $menuStr += "<li>" . $item[1];
  58.  
  59.             if($item[0] == $nodes[$index + 1]){
  60.  
  61.                $index++;
  62.  
  63.                $menuStr += "<ul>" . menuCrawler($current) . "</ul>";
  64.  
  65.             }
  66.  
  67.          }    
  68.  
  69.          $menuStr += "</li>";
  70.  
  71.       }
  72.  
  73.       return $menuStr;
  74.  
  75.    }
  76.  
  77. ?>
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 29th, 2004, 2:54 pm

well, i did it, it works! w00t! :D

i just though id share the final scripts incase anyone wants to use it... subsequently, i realized after the fact, that i made this using strings, not integers, or doubles... :) so you dont have to have '00.03.00' menu codes and so forth... you can also use menu codes such as 'root.WoW.races' which is cool... :)

heres the final script:
PHP Code: [ Select ]
function generateMenu($address){
 
      global $nodes, $index, $level;
 
      $index = 0;
 
      $level = '';
 
      $nodes = explode('.', $address);
 
     
 
      $menu = menuCrawler();
 
      return $menu;
 
   }
 
   function menuCrawler(){
 
      global $level, $nodes, $index;
 
      $menuStr = '';
 
     
 
      if($index == 0){
 
         $level = $nodes[0];
 
      }
 
      else{
 
         $level = $level . '.' . $nodes[$index];
 
      }
 
      $current = $level;
 
      $indent = $index;
 
     
 
      $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $current . "' ORDER BY ID", 'menu');
 
      for($i = 0; $i <= count($result) - 1; $i++){
 
         $menuStr = $menuStr . str_replace("%level%", ('level' . $indent), $result[$i][1]) . chr(13) . chr(10);
 
         if($result[$i][0] == $nodes[$index + 1]){
 
            $index++;
 
            $menuStr = $menuStr . menuCrawler($current);
 
         }
 
      };
 
      return $menuStr;
 
   }
  1. function generateMenu($address){
  2.  
  3.       global $nodes, $index, $level;
  4.  
  5.       $index = 0;
  6.  
  7.       $level = '';
  8.  
  9.       $nodes = explode('.', $address);
  10.  
  11.      
  12.  
  13.       $menu = menuCrawler();
  14.  
  15.       return $menu;
  16.  
  17.    }
  18.  
  19.    function menuCrawler(){
  20.  
  21.       global $level, $nodes, $index;
  22.  
  23.       $menuStr = '';
  24.  
  25.      
  26.  
  27.       if($index == 0){
  28.  
  29.          $level = $nodes[0];
  30.  
  31.       }
  32.  
  33.       else{
  34.  
  35.          $level = $level . '.' . $nodes[$index];
  36.  
  37.       }
  38.  
  39.       $current = $level;
  40.  
  41.       $indent = $index;
  42.  
  43.      
  44.  
  45.       $result = queryDB("SELECT ID, link FROM menus WHERE address = '" . $current . "' ORDER BY ID", 'menu');
  46.  
  47.       for($i = 0; $i <= count($result) - 1; $i++){
  48.  
  49.          $menuStr = $menuStr . str_replace("%level%", ('level' . $indent), $result[$i][1]) . chr(13) . chr(10);
  50.  
  51.          if($result[$i][0] == $nodes[$index + 1]){
  52.  
  53.             $index++;
  54.  
  55.             $menuStr = $menuStr . menuCrawler($current);
  56.  
  57.          }
  58.  
  59.       };
  60.  
  61.       return $menuStr;
  62.  
  63.    }


and heres an example of the database (dashes denote next colom):
Quote:
address - ID - link
00 - 03 - <a href ="/main.php?page=wow" class ="nav %level%"...
00.03 - 04 - <a href = "/main.php?page=wow&sub=basics" class = ...
00.03.00 - 00 - <a href = "/main.php?page=wow&sub=races&side=allia...
00.03.00 - 01 - <a href = "/main.php?page=wow&sub=races&side=horde...
00.03.00.00 - 00 - <a href = "main.php?page=wow&sub=races&side=allian...
00.03.00.00 - 01 - <a href = "main.php?page=wow&sub=races&side=allian...


enjoy!

//yay! and thanks rtm223 :)

Post Information

  • Total Posts in this topic: 21 posts
  • Users browsing this forum: No registered users and 125 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
cron
 

© 2011 Unmelted, LLC. Ozzu® is a registered trademark of Unmelted, LLC.