accessing array inside object inside array

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

Post June 25th, 2004, 5:03 pm

ok, is there any way i can get rid of the '$temp' variable in the following code?
im trying to create a new menuItem inside the array in the menuItem inside of $masterMenu[1]...
PHP Code: [ Select ]
$masterMenu[1] = new menuItem();
 
      $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
 
      $temp = $masterMenu[1]->getArray();
 
      $temp[0] = new menuItem();
  1. $masterMenu[1] = new menuItem();
  2.  
  3.       $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
  4.  
  5.       $temp = $masterMenu[1]->getArray();
  6.  
  7.       $temp[0] = new menuItem();

any ideas?
  • Anonymous
  • Bot
  • No Avatar
  • Joined: 25 Feb 2008
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post June 25th, 2004, 5:03 pm

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

Post June 25th, 2004, 10:29 pm

sry for the double post... but ive been working on it, and i think ive made soem improvement but its still throwing an error at me...

Quote:
Parse error: parse error, unexpected T_OBJECT_OPERATOR in menus2.php on line 7


PHP Code: [ Select ]
<?php
 
   $masterMenu[0] = new menuItem();
 
      $masterMenu[0]->setItem('<a href = "/" class = "nav level1">Home</a>', array());
 
   $masterMenu[1] = new menuItem();
 
      $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
 
         $masterMenu[1]->createItem(0);
 
/*line 7*/  $masterMenu[1]->getMenu(0)->setItem('test1', array());
 
     
 
   class menuItem{         
 
      function setItem($alpha, $beta){
 
         $this->menuItem = $alpha;
 
         $this->subMenu = $beta;
 
      }
 
      function createItem($location){
 
         $this->subMenu[$location] = new menuItem();
 
      }
 
      function getEntry(){
 
         return $this->menuItem;
 
      }
 
      function getMenu($location){
 
         return $this->subMenu[$location];
 
      }
 
   }
 
?>
  1. <?php
  2.  
  3.    $masterMenu[0] = new menuItem();
  4.  
  5.       $masterMenu[0]->setItem('<a href = "/" class = "nav level1">Home</a>', array());
  6.  
  7.    $masterMenu[1] = new menuItem();
  8.  
  9.       $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
  10.  
  11.          $masterMenu[1]->createItem(0);
  12.  
  13. /*line 7*/  $masterMenu[1]->getMenu(0)->setItem('test1', array());
  14.  
  15.      
  16.  
  17.    class menuItem{         
  18.  
  19.       function setItem($alpha, $beta){
  20.  
  21.          $this->menuItem = $alpha;
  22.  
  23.          $this->subMenu = $beta;
  24.  
  25.       }
  26.  
  27.       function createItem($location){
  28.  
  29.          $this->subMenu[$location] = new menuItem();
  30.  
  31.       }
  32.  
  33.       function getEntry(){
  34.  
  35.          return $this->menuItem;
  36.  
  37.       }
  38.  
  39.       function getMenu($location){
  40.  
  41.          return $this->subMenu[$location];
  42.  
  43.       }
  44.  
  45.    }
  46.  
  47. ?>


what am i doing wrong?
  • this213
  • Guru
  • Guru
  • User avatar
  • Joined: Mar 01, 2004
  • Posts: 1242
  • Loc: ./
  • Status: Offline

Post June 25th, 2004, 11:03 pm

This is just a guess, so don't hang me if it's wrong, but:
PHP Code: [ Select ]
<?php
 
    $masterMenu[0] = new menuItem();
 
        $masterMenu[0]->setItem('<a href = "/" class = "nav level1">Home</a>', array());
 
    $masterMenu[1] = new menuItem();
 
        $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
 
            $masterMenu[1]->createItem(0);
 
      $masterMenu[1]->setItem('test1', array());
 
                $masterMenu[1]->getMenu(0);
 
 
 
    class menuItem{            
 
        function setItem($alpha, $beta){
 
            $this->menuItem = $alpha;
 
            $this->subMenu = $beta;
 
        }
 
        function createItem($location){
 
            $this->subMenu[$location] = new menuItem();
 
        }
 
        function getEntry(){
 
            return $this->menuItem;
 
        }
 
        function getMenu($location){
 
            return $this->subMenu[$location];
 
        }
 
    }
 
?>
  1. <?php
  2.  
  3.     $masterMenu[0] = new menuItem();
  4.  
  5.         $masterMenu[0]->setItem('<a href = "/" class = "nav level1">Home</a>', array());
  6.  
  7.     $masterMenu[1] = new menuItem();
  8.  
  9.         $masterMenu[1]->setItem('<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>', array());
  10.  
  11.             $masterMenu[1]->createItem(0);
  12.  
  13.       $masterMenu[1]->setItem('test1', array());
  14.  
  15.                 $masterMenu[1]->getMenu(0);
  16.  
  17.  
  18.  
  19.     class menuItem{            
  20.  
  21.         function setItem($alpha, $beta){
  22.  
  23.             $this->menuItem = $alpha;
  24.  
  25.             $this->subMenu = $beta;
  26.  
  27.         }
  28.  
  29.         function createItem($location){
  30.  
  31.             $this->subMenu[$location] = new menuItem();
  32.  
  33.         }
  34.  
  35.         function getEntry(){
  36.  
  37.             return $this->menuItem;
  38.  
  39.         }
  40.  
  41.         function getMenu($location){
  42.  
  43.             return $this->subMenu[$location];
  44.  
  45.         }
  46.  
  47.     }
  48.  
  49. ?>


At least - it doesn't throw out any errors
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 25th, 2004, 11:09 pm

the reason its not throwing out errors is because you reset $masterMenu[1], its set on line 5, and the you set it again on line 7, you then called getMenu() and did nothing with it...

what i wouldnt give to be able to do this in Java right now... :P
  • this213
  • Guru
  • Guru
  • User avatar
  • Joined: Mar 01, 2004
  • Posts: 1242
  • Loc: ./
  • Status: Offline

Post June 25th, 2004, 11:31 pm

Don't know how I missed that one, I'll attribute it to my PHP newbie status.

Does this need to be object oriented? Forgive me if I'm wrong, but it just seems like you're trying to build something like this:
PHP Code: [ Select ]
<?php
 
   $masterMenu = array(
 
      '<a href = "/" class = "nav level1">Home</a>' => array('test1' => array()),
 
      '<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>' => array()
 
   );
 
?>
  1. <?php
  2.  
  3.    $masterMenu = array(
  4.  
  5.       '<a href = "/" class = "nav level1">Home</a>' => array('test1' => array()),
  6.  
  7.       '<a href = "/main.php?page=wow" class = "nav level1">World of Warcraft</a>' => array()
  8.  
  9.    );
  10.  
  11. ?>


or am I not reading it right?
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 26th, 2004, 5:24 am

Calendae, I have only just skimmed through this post, but are you trying to create a navigation with multiple levels? If you are, the words "binary tree" springs to mind.

If you are trying to do this and you don't know what a binary tree is then post back and I'll explain (I don't wanna explain the whole thing now in case I have the wrong end of the stick or if you already know about them!)
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 26th, 2004, 11:38 am

yes, it needs to be object oriented...
im not trying to use associated values...
the 'test1' was a string stored in an object i created, as was the array...
what i need to figure out how to do is how to access the functions of that object, which is inside an array, inside an object, which is inside '$masterMenu'...
no i have no idea what a binary tree is...
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 26th, 2004, 1:08 pm

Ok, a word of warning: the binary tree method will be slightly harder to maintain, but will be a hell of a lot easier to code and probably easier to understand.

A Binary Tree is a list of items (in this case an array of objects) has two parts to it, information and pointers. For this we will use a single pointer, which will point to the <i>parent</i>. So you would define your navigational elements as having:

Id
ParentId
information - which is anything you might want.

In fact the Id could very well be the index of the object in the array.

So if we start off with the first level, which will all have the ParentId=-1, and then add levels as you go:

Code: [ Select ]
Array index | What is it | ParentId
-------------|--------------|-----------
0      | Node 1   |  -1
1      | Node 2   |  -1
2      | Node 3   |  -1
3      | Node 1.1  |   0
4      | Node 1.2  |   0
5      | Node 3.1  |   2  
6      | Node 1.2.1 |   4
  1. Array index | What is it | ParentId
  2. -------------|--------------|-----------
  3. 0      | Node 1   |  -1
  4. 1      | Node 2   |  -1
  5. 2      | Node 3   |  -1
  6. 3      | Node 1.1  |   0
  7. 4      | Node 1.2  |   0
  8. 5      | Node 3.1  |   2  
  9. 6      | Node 1.2.1 |   4


The example above will come out like:

Code: [ Select ]

Node 1
 Node 1.1
 Node 1.2
  Node 1.2.1
Node 2
Node 3
 Node 3.1
  1. Node 1
  2.  Node 1.1
  3.  Node 1.2
  4.   Node 1.2.1
  5. Node 2
  6. Node 3
  7.  Node 3.1


As you can see the method is handy because you only need the one array, it is a really easy structure to build and work with because you can just add new nodes onto the bottom, have as many elements as you like, and as many levels as you like.

You can also move a node (by changing it's parent) and all of it's descendents will move acordingly. Just like a normal directory tree.

Whats the problem? You have to use filtering (ie array_filter() ) , and recursion to build the navigational elements.

check out <a href="http://www.ozzu.com/programming-forum/asp-recursion-issue-t26453.html&highlight=asp+recursion" target="_blank">this thread</a> where Rabid Dog was doing the same thing with ASP and a database, instead of an array of objects. If you decide to go this way and need a hand, just ask :wink:
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 26th, 2004, 3:55 pm

yes, this is exactly what im trying to do, and it does look a hell of a lot easier...

the end result i want is to be able to stick a menu colom in my content database, and heve the entry in it go something like '1.1.2.3' which would bring up this page: http://www.aysaedara.net/main.php?page= ... ace=undead
(not that i have the menus hard coded into the page right now...)

i would then have a routine that would go and make the menu based on that code...

i looked at the other topic, and well, im not really sure what is going on over there... :oops: so any help would be greatly appreciated...
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 26th, 2004, 4:34 pm

Well this is perfect for a databases simply because it uses a simple list, obviously you can't nest stuff in a database well.

Well, after doing that with rabid dog, I built a shell of a php version, but it has never been tested and has none of the database code in it - I couldn't be bothered to build a database of pretend links lol.

Anyway, it's nearly half past midnight and I was planning on getting up early so I'll get back to you on this one tomorrow :wink:
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 26th, 2004, 5:56 pm

mmmkay, sure, thanks alot :)
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 27th, 2004, 5:06 am

Well, so much for getting up early :roll:


Anyway I dug out my function, and now I remember it is a lot more complicated that what you need, it allows starting at any node and will allow you to specify maximum number of levels and stuff.


PHP Code: [ Select ]
 
function fullMenu(){
 
   return ("<ul id='fullmenu'>".menuCrawler(0)."</ul>");
 
}
 
function menuCrawler($parentId, $maxLevels){
 
   if(!isset($maxLevels)){$maxLevels=1000};                                //saves faffing later on in the recursion bit
 
   $sqlStr = "SELECT * FROM tblContents WHERE parent_Id='$parentId';";       
 
   $menuStr='';                                                      //initialise menuStr.  Local version.
 
   foreach(/*record returned*/){
 
         $menuStr+="<li>linky bit";                                     //start the list item
 
         if(/*has_children*/ && $maxLevels > 1){                              //if it has kiddies, go get them
 
            $menuStr+="<ul>".fullMenu(/*returned_Id*/,($maxLevels-1))."</ul>";      //recursive function call
 
         } 
 
         $menuStr+="</li>";                                             //end the list item.
 
      }
 
   }
 
   return $menuStr;
 
}
 
 
 
 
  1.  
  2. function fullMenu(){
  3.  
  4.    return ("<ul id='fullmenu'>".menuCrawler(0)."</ul>");
  5.  
  6. }
  7.  
  8. function menuCrawler($parentId, $maxLevels){
  9.  
  10.    if(!isset($maxLevels)){$maxLevels=1000};                                //saves faffing later on in the recursion bit
  11.  
  12.    $sqlStr = "SELECT * FROM tblContents WHERE parent_Id='$parentId';";       
  13.  
  14.    $menuStr='';                                                      //initialise menuStr.  Local version.
  15.  
  16.    foreach(/*record returned*/){
  17.  
  18.          $menuStr+="<li>linky bit";                                     //start the list item
  19.  
  20.          if(/*has_children*/ && $maxLevels > 1){                              //if it has kiddies, go get them
  21.  
  22.             $menuStr+="<ul>".fullMenu(/*returned_Id*/,($maxLevels-1))."</ul>";      //recursive function call
  23.  
  24.          } 
  25.  
  26.          $menuStr+="</li>";                                             //end the list item.
  27.  
  28.       }
  29.  
  30.    }
  31.  
  32.    return $menuStr;
  33.  
  34. }
  35.  
  36.  
  37.  
  38.  

As you can see it's just a mockup - half php and half pseudocode in notes - also bear in mind I've never done any php database work yet. It also includes support for a hasChildren field which will greatly reduce the number of queries.


from that other topic, this is the nested list we are going to be creating (lists are good for links - always put your links in lists!)
Code: [ Select ]
<ul>
  <li>Item Text here</li>
  <li>Parent Item Text here
    <ul>
      <li>Item Text here</li>
      <li>Item Text here</li>
      <li>Item Text here</li>
      <li>Item Text here</li>
    </ul>
  </li>
  <li>Item Text here</li>
  <li>Item Text here</li>
</ul>
  1. <ul>
  2.   <li>Item Text here</li>
  3.   <li>Parent Item Text here
  4.     <ul>
  5.       <li>Item Text here</li>
  6.       <li>Item Text here</li>
  7.       <li>Item Text here</li>
  8.       <li>Item Text here</li>
  9.     </ul>
  10.   </li>
  11.   <li>Item Text here</li>
  12.   <li>Item Text here</li>
  13. </ul>


I can't really think how to explain that function well. It uses recursion so that there can be any number of levels. Recursion is when a function calls itself. So, the function itself ONLY gets a single level, and then if any of the nodes has a child, it will call itself. When the second function call is completed the first then resumes from where it left off. So first function to be called is the last one to be completed.

I am struggling to explain this, it might be worth do a dry run (on paper) through this function with the eample I gave earlier. Bear in mind the version I showed you started with parent at -1, this requires the initial parent to be 0.
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 27th, 2004, 1:35 pm

ok, this is what i have so far... and something is going terribly wrong...

PHP Code: [ Select ]
<?php
 
   include('sqlQuery.php');
 
   menuCrawler(2);
 
   
 
   function menuCrawler($parentID, $maxLevels = 15){
 
      $result = queryDB("SELECT ID, link FROM menus WHERE parentID = '" . $parentID. "'", true);
 
     
 
      $menuStr='';
 
      foreach($result as $node){
 
         $menuStr += "<li>" . $node[1];
 
         if(hasChildren($node[0]) && ($maxLevels > 1)){
 
            $menuStr += "<ul>" . menuCrawler($node[0] , ($maxLevels - 1)) . "</ul>";
 
         }    
 
         $menuStr += "</li>";
 
      }
 
      return $menuStr;
 
   }
 
   function hasChildren($nodeID){
 
      $result = queryDB("SELECT * FROM menus WHERE parentID = '" . $nodeID . "'", true);
 
      if(count($result) > 0){
 
         return true;
 
      }
 
      else{
 
         return false;
 
      }
 
   } 
 
?>
  1. <?php
  2.  
  3.    include('sqlQuery.php');
  4.  
  5.    menuCrawler(2);
  6.  
  7.    
  8.  
  9.    function menuCrawler($parentID, $maxLevels = 15){
  10.  
  11.       $result = queryDB("SELECT ID, link FROM menus WHERE parentID = '" . $parentID. "'", true);
  12.  
  13.      
  14.  
  15.       $menuStr='';
  16.  
  17.       foreach($result as $node){
  18.  
  19.          $menuStr += "<li>" . $node[1];
  20.  
  21.          if(hasChildren($node[0]) && ($maxLevels > 1)){
  22.  
  23.             $menuStr += "<ul>" . menuCrawler($node[0] , ($maxLevels - 1)) . "</ul>";
  24.  
  25.          }    
  26.  
  27.          $menuStr += "</li>";
  28.  
  29.       }
  30.  
  31.       return $menuStr;
  32.  
  33.    }
  34.  
  35.    function hasChildren($nodeID){
  36.  
  37.       $result = queryDB("SELECT * FROM menus WHERE parentID = '" . $nodeID . "'", true);
  38.  
  39.       if(count($result) > 0){
  40.  
  41.          return true;
  42.  
  43.       }
  44.  
  45.       else{
  46.  
  47.          return false;
  48.  
  49.       }
  50.  
  51.    } 
  52.  
  53. ?>


im getting an infinite error....
Quote:
Warning: Invalid argument supplied for foreach() in menus2.php on line 9
  • rtm223
  • Mastermind
  • Mastermind
  • User avatar
  • Joined: Mar 24, 2004
  • Posts: 1855
  • Loc: Uk
  • Status: Offline

Post June 27th, 2004, 1:45 pm

Well first off, why are you starting at 2?

Code: [ Select ]
menuCrawler(2);


I'm not sure why it is saying invalid argument? Can you use a foreach with a database (like I said, I've not got round to doing any database work yet). Alternatively you have started with parent ID = 2, and there may not be any nodes with parent ID=2. If it's returning no records it could be the foreach doesn't like that?

Any chance you can post the sample data you are working with?

Also bear in mind I never tested any of the code I posted, it was all theoretical.
CSS website design tutorials
  • Cae
  • Expert
  • Expert
  • User avatar
  • Joined: Feb 25, 2004
  • Posts: 734
  • Status: Offline

Post June 27th, 2004, 2:44 pm

ok, i wasnt thinking... my database starts with parentID 0... i wanted it to output this menu: http://www.aysaedara.net/main.php?page=wow i realize now that thats not how im susposed to do it, but i cant think of how to do it...
here is what is in the table 'menus' in my database...
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 ="...


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)

or something along those lines??

and then i would have to revamp the database entries so that the parentIDs would read '0.2.1' and so forth...
  • Anonymous
  • Bot
  • No Avatar
  • Joined: 25 Feb 2008
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post June 27th, 2004, 2:44 pm

Post Information

  • Total Posts in this topic: 21 posts
  • Users browsing this forum: No registered users and 182 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.