Autor Zpráva
Martin02
Profil
Ahoj,

jsem více méně začátečník v OOP. Mám například třídu NavItem (položka v menu), jejíž data se berou z databáze. Chci se zeptat, jak se tohle řeší, když chci najednou získat všechny položky do menu - tzn. inicializovat několik objektů? Můj kód vypadá takto:
<?php


class NavItem
{

    /** @var integer */
    public $id_nav_item;
    
    /** @var integer */
    public $id_parent;
    
    /** @var string */
    public $name;
    
    /** @var string */
    public $url_name;
    
    /** @var integer */
    public $position;
    
    /** @var bool */
    public $active;
    
    
    function __construct($id_nav_item)
    {
        global $db;
        
        $stm = $db->prepare('SELECT id_parent, name, url_name, position, active FROM cz_nav_item WHERE id_nav_item = ? LIMIT 1');
        $stm->execute(array(intval($id_nav_item)));
        $row = $stm->fetch(PDO::FETCH_ASSOC);
        
        $this->id_nav_item = intval($id_nav_item);
        $this->id_parent = intval($row['id_parent']);
        $this->name = $row['name'];
        $this->url_name = $row['url_name'];
        $this->position = intval($row['position']);
        $this->active = (bool)$row['active'];
    }
    
    
    static function getNavItems()
    {
        global $db;
        
        $navItems = array();
        $res = $db->query('SELECT id_nav_item FROM cz_nav_item ORDER BY position ASC');
        
        while ($row = $res->fetch(PDO::FETCH_ASSOC))
            $navItems[] = new NavItem(intval($row['id_nav_item']));
        
        return $navItems;
    }
    
}

?>

A funguje. Metoda getNavItems() vrací pole objektů třídy NavItem, což je správně. Ale nejsem si jistý, jestli je správné, když se vlastně provede jeden dotaz na IDčka a pak pro každý jednotlivý objekt další SQL dotaz. Dřív jsem to měl ta, že tahle metoda vybrala jedním dotazem úplně všechno a sama vytvářela objekty a sama jim přiřazovala hodnoty. To mi ale nepřijde úplně správné, aby aby se vlastnosti třídy přiřazovali odněkud zvenku. Navíc pak budu chtít něco změnit (přidat sloupec atd.) a musím to předělávat na více místech.

Jak se to řeší?


Díky za odpovědi
Slark
Profil *
Ve view(template) si pole s položkama menu projedete přes foreach.
Joker
Profil
Martin02:
Podle mě na tom není správně ten databázový dotaz v konstruktoru. Třída NavItem je pak zbytečně svázaná s konkrétní databází, kdybych chtěl jinou strukturu dat, nebo třeba je ukládat v XML, musel bych udělat jinou třídu.
Kdyby konstruktor místo id přebíral rovnou to pole s hodnotami, bude třída poměrně nezávislá na zdroji dat a zároveň plnění může obstarat metoda getNavItems jedním SQL dotazem.
Martin02
Profil
Joker:
Děkuji, to jsem potřeboval.

Možná jste si všimli v tom kódu, že se používám databázi pomocí global $db; (v konfiguračním souboru je připojení do mysql uloženo do tého proměnné), je to správné řešení?
Joker
Profil
Martin02:
Lepší by bylo předávat hodnoty přes parametry metod.

Jinak s tím vybíráním položek, spíš než to dávat na třídu položky by asi bylo lepší udělat nějakou repository třídu, která bude dělat tyhle operace.
(tj. spíš než mít u každé entity ty databázové věci je výhodnější mít repository třídu, která se o tyhle věci postará)

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: