Avatar billede sajbar Nybegynder
26. marts 2005 - 17:28 Der er 9 kommentarer og
1 løsning

Problemer med en rekursiv funktion.

Hej eksperter.

hjælp mig inden jeg hiver de sidste hår ud af hovedet på mig selv.

jeg har en rekursiv funktion som skal generere menu struktur ud fra min database
min database struktur ser således ud:
mysql> desc pages;
+-------------+----------+------+-----+---------+----------------+
| Field      | Type    | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| pid        | int(11)  |      | PRI | NULL    | auto_increment |
| parent      | int(11)  |      |    | 0      |                |
| page_name  | tinytext |      |    |        |                |
| titel      | text    |      |    |        |                |
| content    | text    |      |    |        |                |
| template_id | int(11)  |      |    | 0      |                |
| status      | int(1)  |      |    | 0      |                |
| position    | int(11)  |      |    | 0      |                |
+-------------+----------+------+-----+---------+----------------+

jeg kommenterer lige de attributer der er væssentlig for funktionerne

pid definere det unikke felt for siden.

parent indeholder information om hvilken side, siden hører til hvis det ikke er en hovedside

page_name er det navn der skal bruges når man skal udskrive linket.

funktionen der generer min array struktur, har prøvet lidt af hvert kan man se med de kommenterede linier

    function _getSubMenu($parent, $array) {
        //var_dump($array);

        $sql = "SELECT * FROM pages WHERE parent = '$parent'";
        $qh = fetch($sql);
        while ($row = mysql_fetch_assoc($qh))
        {
            //$array[] = array($row['pid'],$row['page_name'],$row['parent']);
            $array[][$row['pid']] = $row['page_name'];
            //$array[][$row['pid']][$row['page_name']] = $row['parent'];
            $array[] = $this->_getSubMenu($row['pid'], $array[]);
        }
        mysql_free_result($qh);
        return $array;

    }

funktionen der viser menuen

function showSubMenu($submenu, $parent, $ident="<li>") {
    //die(var_dump($submenu));
    foreach($submenu as $key=>$val) {
    if(!is_array($val)) {
            if($val != NULL) {
            //var_dump($val);
            echo($ident);
            ?>

            <a href="<?echo($phpself)?>?pid=<?echo($key);?>&amp;parent=<?echo($parent);?>"><?echo($val);?></a>
           
            <?
            }
       
    }
    else
        {
        showSubMenu($val, $parent, $ident);
        }
    }
}

mit problem er at jeg gerne vil have at rykker en plads ind hvis en af menu punkterne er et under menu punkt til det menu punkt der blev udskrevet før og rykker tilbage igen hvis det er et nyt menu punkt

altså ala
hvorfor
-fordi
--ok
tralala
-teste
woho
osv.
jeg er ikke en ørn til rekursive funktioner så det kan godt være at begge funktioner skal ændres

sig endlig til hvis der skal flere point til at løse problemet ! :)

mvh.
Daniel som er ved at være godt skaldet efter alle de hår han har revet ud af hovedet
Avatar billede coderdk Praktikant
26. marts 2005 - 18:36 #1
Ville denne ikke virke (gør det i en omgang i stedet for to):

function getMenu( $parent )
{
    $sql = "SELECT * FROM pages WHERE parent = '$parent'";
    $qh = fetch($sql);
    if ( @mysql_num_rows( $qh ) > 0 )
    {
        echo "<ul>";
        while ($row = mysql_fetch_assoc($qh))
        {
            echo "<li><a href='$_SERVER[PHP_SELF]?pid=$row[pid]'>$row[page_name]</a></li>";
            getMenu( $row['pid'] );
        }
        echo "</ul>";
        mysql_free_result($qh);
    }
}
Avatar billede sajbar Nybegynder
26. marts 2005 - 18:50 #2
min ide er/var at have en klasse der tog sig af at generere udtræk fra databasen og så sende dem videre til præsentationslaget, således at det blev gjort mere generelt, altså så klasserne kan bruges igen og igen uden at skulle ændres, så det kun var selve designet der skulle rettes til, derfor denne opdeling i 2 funktioner, den ene ligger på min klasse den anden ligger i min præsentation :)
Avatar billede coderdk Praktikant
26. marts 2005 - 19:04 #3
hehe ok, prøv at se om denne ikke virker:

function getMenu( $parent, &$array, $level = 0 )
{
    $sql = "SELECT * FROM pages WHERE parent = '$parent'";
    $qh = fetch($sql);
    if ( @mysql_num_rows( $qh ) > 0 )
    {
        while ($row = mysql_fetch_assoc($qh))
        {
            $row['level'] = $level;
            $array[] = $row;
            getMenu( $row['pid'], $array, $level + 1 );
        }
        mysql_free_result($qh);
    }
}

Du kalder den sådan:

$array = array();
getMenu( 0, $array );

Så skulle $array indeholde menuen, du kan så checke om de ligger i samme niveau, eller højre eller mindre med $array[$i]['level']... Altså du kan hive den ud med noget i stil med:

function dispMenu( $array )
{
    $oldlevel = -1;
    foreach ( $array as $item )
    {
        if ( $oldlevel != $item['level'] )
        {
            if ( $oldlevel < $item['level'] )
            {
                echo "<ul>";
            }
            elseif ( $oldlevel > $item['level'] )
            {
                echo "</ul>";
            }
            $oldlevel = $item['level'];
        }
        echo "<li><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a></li>";
    }
}

Bemærk at intet af det er testet ;)
Avatar billede coderdk Praktikant
26. marts 2005 - 19:05 #4
Det er muligt at der vil mangle en </ul> til sidst ;P
Avatar billede sajbar Nybegynder
26. marts 2005 - 19:07 #5
jeg prøver at kigge på det senere skal snart spise :)
Avatar billede sajbar Nybegynder
07. april 2005 - 15:15 #6
havde helt glemt den her.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>test</title>
</head>
<body>
<?
include("./inc/database/dbfunctions.inc.php");
connect();
function getMenu( $parent, &$array, $level = 0 )
{
    $sql = "SELECT pid, parent, page_name FROM pages WHERE parent = '$parent'";
    $qh = fetch($sql);
    if ( @mysql_num_rows( $qh ) > 0 )
    {
        while ($row = mysql_fetch_assoc($qh))
        {
            $row['level'] = $level;
            $array[] = $row;
           
            $array[] = getMenu( $row['pid'], $array, $level + 1 );
        }
        Return $array;
        mysql_free_result($qh);
    }
}
$array = array();
$array1  = getMenu( 0, $array );
//var_dump($array1);

function dispMenu( $array )
{
    $oldlevel = -1;
    foreach ( $array as $item )
    {
        if($item !=NULL) {
               
        if ( $oldlevel != $item['level'] )
        {
            if ( $oldlevel < $item['level'] )
            {
                echo "<ul>\n";
            }
            elseif ( $oldlevel > $item['level'] )
            {
                echo "</ul>\n";
            }
            $oldlevel = $item['level'];
        }

        echo "<li><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a></li>\n";
        }
    }
    echo("</ul>\n");
}
dispMenu($array1);
?>
</body>
</html>
der manglede en </ul> ja men får også en fejl om at der mangler en <li> hvis jeg kører den, output kan ses på:
http://home.sajbar.dk/mediaoptik.dk/test.php
Avatar billede sajbar Nybegynder
07. april 2005 - 16:27 #7
jeg ved ikke helt hvad der går galt, men har lige forsøgt at tilføje et element på 3. niv. og så går den helt amok, håber at du kan greje hvad der er galt...

jeg paster lige det seneste, sidder og arbejder på en måde så jeg kan få samlet det med en tree menu

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>test</title>
</head>
<body>
<?
include("./inc/database/dbfunctions.inc.php");
connect();
function getMenu( $parent, &$array, $level = 0, $submenu = 0 )
{
//    if($submenu > 1) {
//        $submenu = 1;
//    }
    $sql = "SELECT pid, parent, page_name FROM pages WHERE status = '1' and parent = '$parent'";
    $qh = fetch($sql);
    if ( @mysql_num_rows( $qh ) > 0 )
    {
        while ($row = mysql_fetch_assoc($qh))
        {
            $row['level'] = $level;
            $row['submenu'] = $submenu;
            //$submenu = 0;
            $array[] = $row;
           
            $array[] = getMenu( $row['pid'], $array, $level + 1, $submenu + 1 );
        }
        Return $array;
        $submenu = 0;
        mysql_free_result($qh);
    }
}
$array = array();
$array1  = getMenu( 0, $array );
//var_dump($array1);

function dispMenu( $array )
{
    $oldlevel = -1;
    foreach ( $array as $item )
    {
        if($item !=NULL) {
               
        if ( $oldlevel != $item['level'] )
        {
            if ( $oldlevel < $item['level'] )
            {
                echo "<ul>\n";
            }
            elseif ( $oldlevel > $item['level'] )
            {
                echo "</ul>\n";
            }
            $oldlevel = $item['level'];
           

        }
        if($item['submenu'] == 1) {

           
        echo "<li class=\"under\"><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a></li>\n";
        }
        else {
                    echo "<li class=\"over\"><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a></li>\n";
        }

        }

    }
    echo("</ul>\n");
}
dispMenu($array1);
//var_dump($array1);
?>
</body>
</html>
Avatar billede sajbar Nybegynder
07. april 2005 - 17:00 #8
blev så fixet, hjalp at skrive en funktion der ryddede op i indholdet af det array getMenu lavede.

funktionen ser således ud.
function cleanup($array, $array2) {
foreach($array as $key=>$val) {

    if(!$val == NULL && count($val) == 5) {
        $array2[] = $val;
    }


}
Return $array2;
}
Avatar billede sajbar Nybegynder
07. april 2005 - 17:04 #9
efter en lille oprydning ser det således ud:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>test</title>
</head>
<body>
<?
include("./inc/database/dbfunctions.inc.php");
connect();
function getMenu( $parent, &$array, $level = 0, $submenu = 0 )
{
    $sql = "SELECT pid, parent, page_name FROM pages WHERE status = '1' and parent = '$parent'";
    $qh = fetch($sql);
    if ( @mysql_num_rows( $qh ) > 0 )
    {
        while ($row = mysql_fetch_assoc($qh))
        {
            $row['level'] = $level;
            $row['submenu'] = $submenu;
            //$submenu = 0;
            $array[] = $row;
           
            $array[] = getMenu( $row['pid'], $array, $level + 1, $submenu + 1 );
        }
        Return $array;
        $submenu = 0;
        mysql_free_result($qh);
    }
}

function dispMenu( $array )
{
 
    $oldlevel = -1;
    foreach ( $array as $item )
    {
        if($item !=NULL) {
               
        if ( $oldlevel != $item['level'] )
        {
            if ( $oldlevel < $item['level'] )
            {
                echo "<ul>\n";
            }
            elseif ( $oldlevel > $item['level'] )
            {
                echo "</ul>\n";
            }
            $oldlevel = $item['level'];
           

        }
        if($item['submenu'] > 0) {

           
        echo "<li class=\"under\"><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a>\n";
        }
        else {
                    echo "<li class=\"over\"><a href='$_SERVER[PHP_SELF]?pid=$item[pid]'>$item[page_name]</a>\n";
        }

        }

    }
    echo("</ul>\n");
}
function cleanup($array) {

    foreach($array as $key=>$val) {
        if(!$val == NULL && count($val) == 5) {
            $array2[] = $val;
        }
    }
    Return $array2;
}

$array  = getMenu( 0, $array );
$array2 = cleanup($array);
dispMenu($array2);

?>
</body>
</html>

jeg har forsøgt at finde frem til en måde jeg kan checke om et item har en submenu, hvis den har det skal den være af class'en over, ellers skal det bare være en under kan ikke helt greje det, det er derfor jeg har indført submenu tingen, jeg håber du kan hjælpe mig, eller i det mindste vil kaste et svar så jeg kan få givet dig point :)
Avatar billede sajbar Nybegynder
12. juni 2006 - 11:30 #10
jeg lukker og slukker dette gamle spørgsmål
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester