SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Member lubird's Avatar
    Join Date
    Apr 2003
    Location
    Vancouver, Canada
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Categories and subcategories difficulties

    After reading a bunch of the past threads on here about this topic, I managed to put together some code that (I thought) would allow me to display a bunch of categories and subcategories (to an unlimited level of subcategories) from a mysql database; however, I'm running into problems.

    My table is set up with the following columns:

    ID, Name, ParentCat, DepthNum

    After running the following code, the first "level" of categories displays properly, but then it gives me a bunch of errors stating that there are "Invalid argument supplied for foreach()..." for any levels underneath...

    PHP Code:
    $query mysql_query("SELECT * FROM Categories ORDER BY ParentCat, Name");
    while (
    $cat mysql_fetch_array($query)) {
        
    $Cats[$cat["ParentCat"]][$cat["ID"]] = array("Name" => $cat["Name"], "Depth" => $cat["DepthNum"]);
    }
    function 
    make_tree (&$var$arg 0$delim " ") {
        foreach(
    $var[$arg] as $catid => $cat) {
            
    $output .= str_repeat($delim,($cat["Depth"]-1)*2).$cat["Name"]."<br>\n";
            if (
    is_array($var[$catid])) {
                
    $output .= make_tree($Cats,$catid);
            }
        }
        return 
    $output;
    }
    echo (
    make_tree($Cats)); 
    Note: I've taken out some of the excess HTML coding that I had put into the $output variable (used for making output pretty) to make my posted code easier to follow.

    This thing SHOULD work... Any ideas?

    TIA

  2. #2
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ummm.... Not too sure about your script though what puzzles me is why do you need the depth at all ?

    You shouldn't need a counter in any case. For example, here is some script I wrote to do what your asking:

    PHP Code:
    function ShowCatolog($Id$Level$Str) {
            global 
    $Str;
            
            
    $db = new Dbase;
            
    $db -> SetDbase($_SESSION['OffManager']['App'][1], HOST_NAMEUSER_NAMEPASS_WORD);
            
            
    $sql $db -> QueryDbase("SELECT * FROM catolog WHERE cat_parent = '$Id'""error whilst querying database table 'catolog'");
            
    $Level++;
            
    $Space '---';
            
            while(
    $row mysql_fetch_array($sql)) {
                
    # find each record ID and NAME 
                
    $RecId $row['CAT_ID'];
                
    $RecName $row['CAT_NAME'];
                
                
    $Indent '';
                for(
    $a 0;$a $Level;$a++) {
                    
    $Indent .= $Space;
                }
                
    $Str .= $Indent .= ' ' $RecName '<br />';
                
                
    # loop again to see if sub-catogories exist
                
    ShowCatolog($RecId$Level$Str);
            } 
            return 
    $Str;
        } 
    You would use the following to call it:

    PHP Code:
    $fragment ShowCatolog(1, -1''); 
    This would return a delimited string holding the correct order of catogories found from the database.

    You only then need to explode the string.

    PHP Code:
    $LinkArray     explode('<br />'$fragment); 
    In this specific case I have some custom string handling within the function though you can remove this if you want - it simple appends --- to each catogory based on the depth countered so far.

    Here is the database structure by the way - almost forgot about it. 8)

    Code:
    mysql> select * from catolog;
    +--------+------------+---------------+----------------------------+
    | CAT_ID | CAT_PARENT | CAT_NAME      | CAT_DESCRIP                |
    +--------+------------+---------------+----------------------------+
    |      1 |          0 | Top           |                            |
    |      2 |          1 | Entertainment | Entertainment for the home |
    |      3 |          2 | PC Games      | The newest PC games titles |
    +--------+------------+---------------+----------------------------+
    3 rows in set (0.16 sec)

  3. #3
    SitePoint Member lubird's Avatar
    Join Date
    Apr 2003
    Location
    Vancouver, Canada
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I figured it out! Woke up this morning and BAM! it hit me... I was still using the $Cats variable in the function, but it's actually supposed to be $var (since $Cats isn't global and is just passed over to $var in the function)...

    So the working script is (if anybody's interested):

    PHP Code:
    $query mysql_query("SELECT * FROM Categories ORDER BY ParentCat, Name");
    while (
    $cat mysql_fetch_array($query)) {
        
    $Cats[$cat["ParentCat"]][$cat["ID"]] = array("Name" => $cat["Name"], "Depth" => $cat["DepthNum"]);
    }
    function 
    make_tree (&$var$arg 0$delim "&nbsp;") {
        foreach(
    $var[$arg] as $catid => $cat) {
            
    $output .= str_repeat($delim,($cat["Depth"]-1)*2).$cat["Name"]."<br>\n";
            if (
    is_array($var[$catid])) {
                
    $output .= make_tree($var,$catid);
            }
        }
        return 
    $output;
    }
    echo (
    make_tree($Cats)); 
    This is much simpler and cleaner than any of the other solutions I've found in here... so if you wanna use it, feel free.

    As for your suggestion Livingston, it's using multiple sql queries. That could get really slow when there are a lot of categories and subcategories present.

    But you're right, I probably don't need the depth there... maybe now that I've got it all figured out I can modify my code to do this without the depth...

    Thanks anyways!

  4. #4
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks - yes the script at the moment uses 2 queries though there is a way of using only 1 I believe ?

    I just need to read up on this article I read a while back that described how it could be done - alas I've lost the link. 8(


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •