Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu. Zároveň využij akce až 80 % zdarma při nákupu kreditů. Více informací:
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Lekce 14 - Interface (rozhraní v PHP)

Zpět

 

 

Komentáře
Zobrazit starší komentáře (11)

Avatar
Vít Cigánek:15.10.2015 19:06
if ($obj instanceof IMovable) {
        // teď 100% víme, že objekt obsahuje metodu move()
}

Dobře tenhle kód ma smysl, ale ty dvě funkce se dají odpálit i když to není v rozhraní. Kromě toho podmínka platí

if ($obj instanceof IMovable) platí i když jsem zakomentoval fuknci v rozhraní

interface IMovable
{

    //    public function move();

}

navic IMovable je kličové slovo tak jsem to rozhrani musel přjemenovat na IMove

dále vůbec nevím jak by se zaházelo s atritbuty daného interface.

Abstraktní třídu chápu ale interface prostě ne, hlavně bych čekal že když zakomentuju fukci

public function move();

že mi podmínka

if ($obj instanceof IMovable)

vratí false a to se nestalo.

Nebo bych čekal že se

$obj->move();

neprovede. Ani jedno se nestalo. Interface mi připada pořád zbytečný.

 
Odpovědět
15.10.2015 19:06
Avatar
Odpovídá na Vít Cigánek
Martin Konečný (pavelco1998):15.10.2015 21:11

Tady jde o to, že ty nemusíš vůbec vědět, o jakou třídu jde, ale stačí ti, že implementuje dané rozhraní (které říká, že ta třída musí mít danou metodu/y).

Zkusim trochu jiný příklad. Představ si objekt, který bude někam ukládat data. Můžeš je ukládat např. do databáze MySQL, do textového souboru, do paměti atd. Pak to zjednodušeně může vypadat třeba takhle

interface IDataStorable
{

        public function save($key, $value);

        public function delete($key);

        public function load($key);

}

// jelikož třídy implemetují rozhraní, musí obsahovat všechny tři metody
class MySQLStorage implements IDataStorable
{

        public function save($key, $value)
        {
                mysql_query("INSERT INTO tabulka (...)");
        }

        public function delete($key)
        {
                mysql_query("DELETE FROM tabulka ...");
        }

        public function load($key)
        {
                mysql_query("SELECT data FROM tabulka WHERE $key ...");
        }

}


class FileStorage implements IDataStorable
{
        private $file;

        public function __construct()
        {
                $this->file = fopen("nějaký soubor");
        }

        public function save($key, $value)
        {
                fwrite($this->soubor, $value);
        }

        public function delete($key)
        {
                // něco na smazání ze souboru
        }

        public function load($key)
        {
                // něco na získání dat ze souboru
        }

}


class MemoryStorage implements IDataStorable
{

        private $data = array();

        public function save($key, $value)
        {
                $this->data[$key] = $value;
        }


        public function delete($key)
        {
                unset($this->data[$key]);
        }


        public function load($key)
        {
                return $this->data[$key];
        }

}

define("DEBUG", TRUE);
if (DEBUG) {
        // pro testovací účely
        $storage = new MemoryStorage();
        $storage->save("test", "nějaká hodnota");
} else {
        // ostrá DB
        $storage = new MySQLStorage();
}

// zde v kódu už vůbec nemusím řešit, jestli se jedná o nějaký debug nebo ne
// protože vím, že ať je to objekt pracující s databází MySQL nebo jen s pamětí,
// musí obsahovat tři výše uvedené metody
// takže nemusim dávat hromadu dalších podmínek a snadno použít
echo $storage->load("test");

Je to jen malý hloupý příklad, v reálu by to bylo trochu jinak, ale pro pochopení je to snad dostačující.

Odpovědět
15.10.2015 21:11
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Vít Cigánek:16.10.2015 12:59

V podstatě je to šablona pro třídy co musí obsahovat za metody. Co jsem se dočetl tak atributy rozhraní neobsahuje. V praxi to podle mě jde i bez rozhraní. Možná je to pro přehlednost ve třídách je lepší když ve třídě kde je více metod(abych na metodu rozhraní nezapomněl). Jde prostě o to aby se neopomněla nějaká metoda.

 
Odpovědět
16.10.2015 12:59
Avatar
Vít Cigánek:23.11.2015 20:25

Mám takový dotaz, jestli to chápu dobře, tak interface musí mit metody vždy public. Když jsem dal private tak mi to vyhubovalo.

 
Odpovědět
23.11.2015 20:25
Avatar
mv
Člen
Avatar
Odpovídá na Vít Cigánek
mv:23.11.2015 20:39

Ano musí :) Základní myšlenka rozhraní je, že se k němu bude přistupovat zvenčí, privátní metody nemají smysl.

 
Odpovědět
23.11.2015 20:39
Avatar
Petr Šauer
Člen
Avatar
Petr Šauer:27.1.2016 15:32

Tak tady jsme se fakt kousnul :-S , jak určím z jaké třídy je metoda "programuj" ?

interface Programator
{
    public function programuj();
}
 
Odpovědět
27.1.2016 15:32
Avatar
Patrik Valkovič
Člen IT Redactor Gang
Avatar
Odpovídá na Petr Šauer
Patrik Valkovič:27.1.2016 15:39

Jak z jaké třídy? Třída je nad rozhraním. První definuješ rozhraní, potom teprve třídu. Tebe nemusí zajímat, jakou třídu máš, pro tebe je důležité, že implementuje požadované rozhraní.

Odpovědět
27.1.2016 15:39
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Petr Šauer
Člen
Avatar
Odpovídá na Patrik Valkovič
Petr Šauer:28.1.2016 10:32

... impementací interface do třídy zajistím to že daná třída bude obsahovat metody přdepsané v interface ? Všechny třídy které implementují interface "IProgramator" budou mít (až je tam dopíšu) stejné metody (např. "pracuj" , "programuj"), je to tak?

 
Odpovědět
28.1.2016 10:32
Avatar
Jindřich Máca
Člen IT Redactor Gang
Avatar
Odpovídá na Petr Šauer
Jindřich Máca:28.1.2016 10:47

Ahoj, je to přesně tak. :-)

 
Odpovědět
28.1.2016 10:47
Avatar
Jan Štěch
Člen IT Redactor Gang
Avatar
Jan Štěch:23.8.2022 20:59

TL:DR:
Rozhraní má i v PHP své místo a může vám v reálných aplikacích dost pomoci. Bohužel ukázat takové použití bez předvádění složitějších projektů je celkem nemožné, a tak se k využívání rozhraní musíte dostat sami. Zkrátka si pamatujte, co rozhraní jsou a jak se používají a třeba ve správný okamžik odhalíte, že ho na daném místě máte použít. 😉

Plná verze:
Při programování webových aplikací v PHP se mi docela osvědčilo vytvořit si rozhraní DatabaseItem, které implementovaly všechny modely (viz MVC) reprezentující položky v databázi (Uzivatel, Komentar, Clanek) a předepisovalo metody jako:

  • save() - Vloží nebo aktualizuje danou položku v příslušné databázové tabulce podle vlastnosti $id
  • load() - Načte vlastnosti instance z příslušné databázové tabulky podle vlastnosti $id
  • delete() - Odstraní položku z databáze a unsetne všechny vlastnosti instance

Později se rozhraní změnilo na abstraktní třídu a všechny výše zmíněné metody již nepotřebovaly mít pro správnou funkci známé ID položky, avšak danou akci zkrátka provedly na jakémkoli řádku, u nějž se hodnoty ve sloupcích shodovali s hodnotami vyplněných vlastností instance. Šlo poté například vytvořit objekt Clanek jenom s vyplněnou vlastností URL a poté buďto načíst ostatní vlastnosti pomocí $clanek->load(), nebo článek smazat pomocí $clanek->delete(). URL sice v tomto případě byla unikátní hodnota, avšak při vyplnění většího množství vlastností, které nebyly pro každou položku unikátní to také fungovalo.

Jak jsem toto rozhraní a později abstraktní třídu vyvíjel se můžete podívat zde (rozklikněte si budoucí revize toho souboru). Nejnovější verze, která se rozrostla na 524 řádků dobře okomentovaného kódu máte tady: https://www.itnetwork.cz/…lighter/1498.

Jenom jsem poté narazil na problém, jak odlišovat hodnoty, které nejsou vyplněné/načtené z databáze od hodnot, které jsou v databázi uloženy jako NULL. Vyřešil jsem to tak, že jsem si udělal tuto třídu:

final class undefined {}

a její instance ukládal do vlastností, které nemám načtené. null jsem poté ponechal vlastnostem, které tak byly uložené i v databázi. Přišlo mi to jako docela elegantní řešení, i když odpověď na StackOverflow, která mi toto poradila dostala docela dost downvotů.

 
Odpovědět
23.8.2022 20:59
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 21. Zobrazit vše