Autor Zpráva
Akali
Profil
Ahoj. K dokončení webu mi zbývá vytvoření poslední věci - strukturovaný výpis menu..
Výsledek by měl vypadat následovně

Kategorie1
-podkategorie1
-podkategorie1
-podkategorie1

Kategorie2
-podkategorie2
-podkategorie2

Co se práce s PHP týče, tak jsem amatér. Je mi jasné, že mě budete odkazovat na nějaké stránky, ale ty mi moc nepomůžou, protože to vůbec nechápu.
Jsou na to potřeba dvě tabulky? Nebo stačí jedna? Jak bude výpis vypadat?

Děkuji mnohokrát
Slark
Profil *
tabulka Ti stačí jedna.

Tabulka:
| id | name | parent_id |

V php:
function menu($parent_id = 0)
{
    $get_menu = $database->query("select * from menu where parent_id = ?", $parent_id);
    
    if($get_menu)
    {
      $build = '<ul>';
      
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= $this->menu($item["id"]);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}

Toto je na ukázku zjednodušený postup jak vytvořit menu kde každá položka může mít neomezeně dalších sub-položek. Psal jsem to rychle z hlavy tak snad tam nejsou chyby.
Akali
Profil
Tabulku jsem vytvořil a zkusil hodit php funkci na web..
Fatal error: Call to a member function query() on a non-object in /home/www/velkyberanov-fotbal.cz/subdomeny/jirka/index.php on line 3

Je potřeba v selectu zadávat do parent_id něco místo otazníku?
Tomášeek
Profil
Akali:
Je potřeba v selectu zadávat do parent_id něco místo otazníku?
Nikoliv, tam už hodnotu přiřazuješ, hned za čárkou.

Máš neexistující proměnnou (objekt) $database, ten je uvnitř funkce neviditelný. Přidej si ho jako parametr.
Akali
Profil
Teď mi to pro jistotu na stránce neukáže vůbec nic :-) Kód mám následující

<? 
function menu($parent_id = 0)
{    
$database = mysqli_connect
          ('údaje k databázi');   
                  
    $get_menu = $database->query("select * from menu where parent_id = ?", $parent_id);
    
    if($get_menu)
    {
      $build = '<ul>';
      
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= $this->menu($item["id"]);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}   

menu();
 ?> 

Tabulka v DB vypadá takto
id name parent_id
1 Malba1 1
2 Malba2 1
3 kresleni1 2
Keeehi
Profil
echo menu();
Akali
Profil
To samé, s tímto kódem se na webu nic nevypíše

<? 
function menu($parent_id = 0)
{    
$database = mysqli_connect
          ('údaje k DB');   
                  
    $get_menu = $database->query("select * from menu where parent_id = ?", $parent_id);
    
    if($get_menu)
    {
      $build = '<ul>';
      
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= $this->menu($item["id"]);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}   

echo menu();
 ?> 
Tomášeek
Profil
Akali:
Psal jsem p5idat jako parametr, ale budiž...

Každopádně, tohle nic vypsat nemůže, protože v $get_menu nemáš sadu výsledků, nýbrž použe mysql result.
Keeehi
Profil
Akali:
To samé, s tímto kódem se na webu nic nevypíše
Ani prázdné <ul></ul>?
Akali
Profil
Keeehi
Ne, ani prázdné <ul>.. Zdrojový kód stránky je prázdný :-/
Keeehi
Profil
To znamená, že buď je tam někde chyba a ty máš vypnuté vypisování chyb, nebo se ten kód nedostane dovnitř podmínky. => špatné připojení k databázi nebo špatný dotaz
Akali
Profil
Sám to do kupy nedám.. Když se kouknu na sedmý řádek. SQL dotaz z něj vypadá následovně
select * from menu where parent_id = ?0

Není chyba tady?
Lonanek
Profil
Při prvním zavolání funkce zadejte jako parametr první existující parent_id, tedy např. menu(1);.
Připojení k databázi není vhodně umístěno uvnitř funkce. Funkce je volána rekurzivně a tedy pokaždé dochází k opětovnému připojování.
Pokud Tomášeek [#4]: psal o přidání jako parametr, měl na mysli:

<?php
$database = mysqli_connect
          ('údaje k DB');   

function menu($parent_id = 0, $database)
{
...
}

echo menu(1, $database);
Akali
Profil
Pochopil jsem vše správně? Pořád prázdná stránka

<?
$database = mysqli_connect
          (); 
          
           
function menu($parent_id = 0, $database)
{     
                  
    $get_menu = $database->query("select * from menu where parent_id = ?", $parent_id);
        
    if($get_menu)
    {
      $build = '<ul>';
      
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= $this->menu($item["id"]);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}   

echo menu(1, $database);

 ?> 
Lonanek
Profil
$database = new mysqli(host, user, pass, db);  // doplnit dle skutecnosti
Co obsahuje proměnná $get_menu? Určitě to je pole hodnot?
Nechte si ji ve funkci vypsat a uvidíte. Jsou zapnuty chybové hlášky?

Jaké je první parent_id?
Slark
Profil
Jaké by mělo být první parent_id ? Vždy bude parent_id minimálně 0. Není teď podstatné co má do parametru volání funkce menu dosazovat. Pokud má v DB pouze položky kde je parent_id > 1 tak to má chybně. Vložte si do db pouze pár testovacích řádků kde všude budete mít parent_id 0. Jinak ten parametr $database si přenáštejte pouze pokud to budete chtít volat jako funkci. V mém příkladu nejde o volání funkce spíše jsem to bral tak že to budete mít jako metodu v nějakém objektu třeba -> MenuControl a proto se také sub-položky volají přes $this->menu($item["id"]).

Takže pokud funkci nemáte jako metodu objektu změňte řádek $build .= $this->menu($item["id"]); na $build .= menu($item["id"]); a bude to fungovat.

funkci volejte pouze jako menu(); popř. menu(0) nikoliv menu(1). Voláním menu(1) by jste získal všechny "děti" rodiče s id 1.

Dále pak při sestavování menu do databáze zařiďte, aby položky postavené nejvýše v celém stromu menu (tzn. Kategorie1, Kategorie2 jak uvádíte ve vašem příkladu) měli parent_id 0 nikoliv 1.
Akali
Profil
Lonanek
$get_menu jsem si nechal vypsat ve funkci a na stránce se nic neobjevilo.

Slark
Tabulka je v databázi nyní takto
id name parent_id
1 Malba1 0
2 Malba2 0
3 kresleni1 1

Kód nyní vypadá takto, ale stránka je pořád prázdná :-/
<?
$database = new mysqli
          (???); 
          
           
function menu($parent_id = 0, $database)
{     
                  
    $get_menu = $database->query("select * from menu where parent_id = ?", $parent_id);
       echo $get_menu;
    if($get_menu)
    {
      $build = '<ul>';
        
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= menu($item["id"]);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}   

echo menu(0, $database);

 ?> 
Slark
Profil
$database = new mysqli
          (???); 

to nevíte jak se připojit k db? Jako první zařiďte aby Vám připojení k db fungovalo na 100%. Psal jste že pracujete na dokončení webu, takže bych předpokládal že db již máte dávno funkční, nebo ne?

moje ukázka selectu z db vám nebude fungovat přes čisté mysqli, resp. to bindování parametrů se řeší jinak. Psal jsem to zjednodušeně a volání dotazu je nutné upravit podle toho jaký používáte db wrapper. Upravte to takto:

function menu($parent_id = 0, $database)
{                       
    $get_menu = $database->query("select * from menu where parent_id = ".(int)$parent_id." ");
    
    if($get_menu)
    {
      $build = '<ul>';
        
        foreach($get_menu as $item)
        {
            $build .= '<li><a href="#">'.$item["name"].'</a>';
            $build .= menu($item["id"] $database);
            $build .= '</li>';
        }
        
        $build .= '</ul>';
        
        return $build;
     
    }
}   
 
echo menu(0, $database);

Podle vaší ukázky struktury db a dat by to mělo vypsat menu dle očekávání.
Lonanek
Profil
Žádná chybová hláška?
Minimálně by měla zařvat na ř.18:
            $build .= menu($item["id"]);
mělo by být
            $build .= menu($item["id"], $database);

Tak trochu postrádám načtení řádků databáze do pole.
Upravený kód:

<?
$database = new mysqli
          (???); 

function menu($parent_id = 0, $database)
{     
                  
    $result = $database->query("SELECT * FROM menu WHERE parent_id = " . (int)$parent_id);

    $build = '<ul>';
    while ($item = $result->fetch_assoc())
    {
        $build .= '<li><a href="#">'.$item["name"].'</a>';
        $build .= menu($item["id"], $database);
        $build .= '</li>';
    }
    $build .= '</ul>';
    return $build;
}

echo menu(0, $database);
Akali
Profil
Lonanek, Slark...
Díky mockrát! Nyní už to funguje.

Jenom bych ještě potřeboval, aby rodič (kategorie) nebyl jako odkaz, ale jako obyčejný text.. Jak script upravit?
Tomášeek
Profil
Akali:
Co ti brání si tam dát do toho kódu podmínku a odkaz vypsat pouze pro potomky (vnitřní volání funkce)? Zkus se zamyslet nad tím, jak by ta podmínka mohla vypadat.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: