Autor Zpráva
Kubik
Profil *
Ahoj,

<?php

    class Registrace
    {
        var $login, $heslo;
        var $jmeno, $prijmeni;
    
        public function Osetreni($var)
        {
            $var = mysql_real_escape_string(htmlspecialchars($var));
        }
        public function PridatDoDatabaze($login="",$heslo="",$jmeno="",$prijmeni="") 
        {
            $login = $this::Osetreni($this->login);
            $heslo = $this::Osetreni($this->heslo);
            $jmeno = $this::Osetreni($this->jmeno);
            $prijmeni = $this::Osetreni($this->prijmeni);
            /* mysql_query(""); */
        
            echo $login . " " . $heslo;
            echo "Voláme původní funkci.";
        }
    }
    
    class PokrocilaRegistrace extends Registrace
    {
        var $ulice, $psc, $obec;
    
        public function PridatDoDatabaze($login = "", $heslo = "", $jmeno = "", $prijmeni = "", $ulice = "", $psc = "", $obec = "")
        {
            parent::PridatDoDatabaze();
            $ulice = parent::Osetreni($this->ulice);
            $psc = parent::Osetreni($this->psc);
            $obec = parent::Osetreni($this->obec);
            /* mysql_query(""); */
        
            echo $login . " " . $psc;
            echo "Voláme pokročilou funkci.";
        }
    }
    
    $registrace = new PokrocilaRegistrace("login","heslo","jmeno","prijmeni","ulice","psc","obec");
        $registrace->PridatDoDatabaze();

    
        
?>

Učím se OOP podle předloh nějakých knížek. U podobného případu byl použit __construct(), bohužel jsem si ještě
přesněji nepročetl jeho funkci a obsluhu. Proto se chci zeptat, zda-li mi můžete poradit, proč výsledkem
v $registrace->PridatDoDatabaze(); je vypsání obou ech, přičemž chci pracovat podle předposledního skriptového řadku
s druhou třídou.

Děkuji mockrát
Majkl578
Profil
Něco takového píší v knížkách? To doufám ne. Tohle nemá s OOP moc společného.

proč výsledkem
v $registrace->PridatDoDatabaze(); je vypsání obou ech
Protože voláš předka, tj. parent::PridatDoDatabaze()

V bodech vytknu i některé chyby:
- var je přežitek z PHP 4, nepoužívat, správně tam patří private/protected;
- funkce nevrací očekávanou hodnotu, nicméně ošetření s registrací stejně nesouvisí, nemá v takové třídě co dělat; mimochodem to ošetření htmlspecialchars je nežádoucí, takto bys měl ošetřovat až při výpisu;
- pokud potomek vyžaduje u metody více parametrů, než jeho předek, je něco špatně (ty je máš nepovinně zjevně jen aby to fungovalo);7
- $this::Osetreni, tohle je špatně a je to asi největší perla v tomto kódu;
- parent::Osetreni, proč ne $this->Osetreni?
- asi jedinou správnou myšlenkou je použití dědičnosti ve smyslu „potomek rozšiřuje předka“.
Marek88
Profil
Kubik:
Já osobně bych ti doporučil se dědičností zatím nezabývat a nepokoušet se jí za každou cenu někde použít. Jen si přečti k čemu se používá a až jí budeš potřebovat, tak to poznáš.

Jako první věc bys měl pochopit, jak se OOP používá. Bohužel nevím o vhodném článku na internetu, který by to jednoduše a jasně vysvětloval (neříkám, že neexistuje - jen o něm nevím). V podstatě jde o to dívat se na jeden logický celek jako na objekt. Takový logický celek není registrace, ale například uživatel. Uživatel má atributy (jméno, příjmení, email, atd.) a metody (funkce) (registrovat, přihlásit, uložit změny, smazat, atd.). Všechno, co logicky patří k uživatelskému účtu patří do třídy uživatel naopak tam nepatří nic, co s ním nic společného nemá.

Poté si přečti něco o tom konstruktoru - je to metoda, která se zavolá při vytvoření instance objektu - to je to když v kódu napíšeš $uzivatel = new Uzivatel();. Konstruktoru můžeš jako každé jiné metodě předat parametry (jméno, příjmení, email, atd.). Není to ale vždy vhodné. Někdy chceš totiž uživatele zaregistrovat a někdy vytáhnout z databáze - to bys chtěl radši předávat kontruktoru uživatelovo ID. Já to řeším tak, že konstruktor nedělá nic a poté volám buď metodu vytvorUzivatele nebo metodu nactiUzivatele. V kódu to pak může vypadat takto:

$uzivatel = new Uzivatel();
$uzivatel->vytvorUzivatele($jmeno, $prijmeni, $email);
// nebo
$uzivatel = new Uzivatel();
$uzivatel->nactiUzivatele($id);

Jak dané metody vypadají si budeš muset domyslet. V metodě vytvorUzivatele by nemělo být uložení do databáze. Na to si udělej další (třeba neveřejnou) metodu a tu pak jen zavolej (každá metoda by měla vykonávat jen jednu konkrétní činnost).

Je toho hodně a vydalo by to na několik stran textu. Víc se tady o tom rozepisovat nebudu, ale kdybys chtěl s něčím poradit, tak se klidně ptej.
pcmanik
Profil
Marek88:
Pani asi prve zrozumietelne vysvetlenie OOP co som doteraz nasiel. Mas pravdu na internete toho vela neni. Teda je, ale nie tak, aby som to jasne pochopil. Urcite vies ze sa pise PHP ucebnica, bolo by pre teba moc napisat sekciu OOP? Urcite by si tym pomohol mnozstvu uzivatelov a nielen mne. Hlavne ide o to to ukazat na jasnych prikladoch, ako tu s tym vytvaranim a nacitanim uzivatela.
Marek88
Profil
pcmanik:
Děkuji, potěšilo mě to. :)

Nicméně o učebnici vím, ale nemyslím si, že bych se na ní mohl s mými znalostmi podílet. Učebnice je totiž pojata (soudím podle obsahu) dost "profesionálně". Já bych to uměl vysvětlit takto laicky, ale to se do té učebnice nehodí - nedalo by se to nikam zařadit. Obsahově by to patřilo buď do první kapitoly (tam by ale nemohly být pojmy jako matoda, atribut, instance nebo ukázky kódu, protože to se probírá až později) nebo do "Základní principy objektově-orientovaného návrhu" (to už je ale náročnější a obsáhlejší téma a vyžaduje více té profesionality a na to si tak úplně netroufám). Navíc už má obě kapitoly zabrané Joker a myslím, že to zvládne vysvětlit dobře.
Majkl578
Profil
Marek88:
Tvoje vysvětlení OOP není zcela správné. Základní definice („V podstatě jde o to dívat se na jeden logický celek jako na objekt.“) je v pořádku, ale příklad už je špatný (přinejmenším porušuje SRP).
Jako příklad špatného návrhu můžeme vzít $uzivatel->nactiUzivatele($id) - dává smysl, aby uživatel načítal sám sebe? Nedává.

Pokud zůstaneme u příkladu s uživatelem, tak samotná třída User by byla v ideálním případě jen hloupá obálka nad daty (+ případné validace apod.). Metody jako vytvoření nebo smazání (nikoliv registrace nebo zrušení registrace, to už mluví o konkrétním záměru, o němž by ale objekt neměl vědět) a další, které uživatele nějak upravují, by spadaly do servisní třídy UserService. Metody pro vyhledávání a podobné čtecí operace by spadaly do repository UserRepository. Tento přístup využívá například známé ORM Doctrine 2, existují ale i další.
Kubik
Profil *
Prave kvuli dedicnosti a moznosti pristupovani k objektum a jejich funkcim znova a opakovane, bez psani dalsiho zbytecneho kodu, jsem na oop presel. Respektive se tim zacal zabyvat. Krom toho mi prijde oop jednodussi na zapis a prehlednost - rychlejsi prace. Bohuzel jsem nenasel zadny vhodny clanek a v knihach o PHP jsou oop metody popsány jen "hole". Například jsem také čerpal z učebnice, kde mi toho přišlo poměrně nejvíc, ale až před pár hodinami jsem se díval na verzi PHP, kde bylo . V další dokumentaci jsem pak pochopil narážku na var a ::

Každopádně díky.
Kubik
Profil *
Majkl578:
Rozumím, ale to potom budu mít na každý úkon, který se týká uživatele 1 metodu (funkci), několik atributů a hlavně to bude jako jedna třída. Takže registrace, přihlášení, změna dat, apod... nebude ve stejném objektu? Vždyť je to ve směs pořád to samé. Podle SRP to chápu, ale není potom zbytečné psát pro všechno 1 objekt? V procedurálním programování a především v PHP by to zastávala jedna (klidně nezávislá) funkce. Zde to musí být objekt, který bude mít další funkci... Pokud tomu tak rozumím...


<?php

    class Uzivatel
    {
        public $login, $heslo;
    }
    
    class UzivatelFunkce 
    {   
        public $uzivatelId;
        
        function prihlasitSe($login = "", $heslo = "")
        {
            if( isset ($this->login) && isset( $this->heslo) )
            {
                // ověření existence a správných údajů
                // vytvoření session a přesměrování
            }
        }
        function odhlasitSe($uzivatelId)
        {
            if( isset ($_SESSION['online']) && isset ($this->$uzivatelId))
            {
                session_destroy();
                // přesměrování 
            }
        }
    }
    
    /* prázdný obal dat */
    $uzivatel = new Uzivatel();
    
    /* přihlášení uživatele s př. jménem (login) a heslem (heslo) */
    $uzivatelskeFunkce = new UzivatelFunkce;
        $uzivatelskeFunkce->prihlasitSe("Martin","Novotný");
    
    /* odhlášení uživatel s ID 2 */
    $uzivatelskeFunkce = new UzivatelFunkce;
        $uzivatelskeFunkce->odhlasitSe('2');

?>


Pokus č. 2

rád uslyším názory všech :))
Ugo
Profil
Kubik:
to záleží na tom jak moc velkou míru odpovědnosti chceš použít. Striktní OOP včetně všech pouček je hrozná pakárna, má ale svoje výhody (i když je lepší to dělat bez pouček pomocí mozku), asi největší je univerzálnost (objekty můžeš měnit dle potřeby za podobné) a znovupoužitelnost. Pokud máš objekt kde tyhle 2 vlastnosti nejsou potřeba, neni důvod se jich držet. Kód pak budeš mít rychlejší, rychleji napsaný a přitom plně funkční. Musíš ale myslet na to že znova už z něj asi nic nepoužiješ a pokud to bude velký objekt, tak větší změny budou težké, přestože v rozdělení na OOP je to změna objektu a v rámci jednoho objektu většinou změna funkce - ale je to méně přehledné. Tady uvádíš uživatele, toho aspoň já mam vždy natolik odlišného že se nevyplatí ho nějak kouskovat, spíš ho nechám vycházet z automatizovaného db modelu a mam ho jako řádek v tabulce. Něco jinýho pak je třeba udržování přihlášení, to většinou postačí jedno na tisíc projektů.

K tomu co má být objekt, fce atp. -
předmět který k ničemu nepatří (hrnek, uživatel) bude objekt

předmět který k něčemu patří (uživatelův hrnek) bude nejspíš proměnná uživatele kterou někdy dostane jako dárek, případně pokud ví kam jít nakupovat, tak si jí sám koupí. Ale znalost kde nakoupit by mu někdo měl předat, ať už rodič a nebo kamarád.

činnost (registrace, přihlášení, pohyb) je metoda, dle toho jestli mu jí někdo přikazuje nebo ne má vnější nebo vnitřní parametry dle kterých jí provádí ($clovek->jdiSem('Praha'); $clovek->jdiNekam();)

vlastnost (barva, rychlost) je proměnná, některý má už na začátku, jiný získá časem a některý na něm změnit dokážeš, jiný ne (private, public). Některý pak jdou změnit jen procesem, třeba učením. (setter - $clovek->jdiSeUčit('matiku') - každý na to zareaguje jinak) stejně tak mu něco neukradnete - ($clovek->podejMiPenezenku()) čili getter

některý věci se názvově kryjou, barva je jak vlastnost tak objekt, registrace může být objekt taky - tam záleží na konkrétním kontextu, ale napovídá to, že vlastnost barva by mohla obsahovat objekt barva

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: