Zápis některých aspektů objektově orientovaného programování v PHP má poměrně velký WTF faktor a nejednou jsem narazil na pokročilého programátora, jak tápal, proč jeho kód způsobuje parse error či nějakou jinou chybu. Rozhodl jsem se proto oprášit můj blog a přehledně na jednom místě shrnout OOP syntax v PHP.
U jednotlivých popisů budu velice stručný, článek si neklade za cíl vysvětlit OOP, zaměřuje se pouze na způsob zápisu.
K hezkému objektovému kódu patří i jeho jednotná podoba, doporučuji k nastudování Nette Coding Standard.
Třídy
Definice nové třídy
Konstruktor
Metoda, která se jmenuje __construct() a volá se při vytvoření instance nové třídy.
Vytvoření instance
Rozhraní (interfaces)
Viditelnost (zapouzdření)
U metod a statických/instančních členů (atributů třídy) lze nastavit viditelnost pro volání (u metod), resp. pro čtení a zápis (u atributů). PHP, stejně jako ostatní jazyky, podporuje tři typy viditelnosti:
public: volat metody a přistupovat k atributům může každý
protected: pouze samotná třída, její potomci (při překrývání - overriding - i předci) a sourozenci (dvě různé instance typu B či nadtypu A si navzájem mohou sahat na protected metody a atributy)
private: pouze samotná třída
Atributy
Definice atributů
Konvence říká, že všechny atributy by měly být definovány na začátku definice třídy.
Přistupování k atributům
Konstanty
PHP umožňuje definovat neměnitelné atributy třídy, např. pro všelijaká nastavení a podporu principu DRY.
Metody
Definice metod
Parametry metod
Volání metod
Překrývání
Pokud v potomkovi definuji atribut nebo metodu s názvem, který existuje už v předkovi, a jejich viditelnost je public či protected, dojde k překrytí (overriding).
Pokud se v třídním předkovi odkazuji na public/protected atribut či metodu, která je v potomkovi přepsána, volá se/přistupuje se k implementaci potomka.
Pozor! Tento způsob nefunguje u statických atributů a metod, tam se při přístupu pomocí self:: bude stále volat implementace v předkovi. Tento nedostatek řeší late static binding v PHP 5.3, viz níže.
Špatné návyky
Zdrojové kódy v této části doma, v práci, ani ve škole nezkoušejte! ;)
PHP kvůli své skriptovací povaze umožňuje v OOP opravdu nehezké věci.
Dynamické názvy
Pokud k tomu máme důvod, můžeme na základě nějaké proměnné či výpočtu rozhodovat, jaká třída se použije, k jakému atributu se přistoupí a jaká metoda se zavolá.
Musíme být samozřejmě připraveni na všechny hodnoty, kterých daná proměnná může nabýt.
Jmenné prostory (namespaces) (PHP 5.3)
Pokud se vám hodí mít dvě třídy stejného názvu, tak je stačí dát do dvou různých jmenných prostorů a nemáte problém. Ale pozor! Namespaces spíše přidělávají práci, než aby ji ulehčovali. Přesto se dá přijít na způsob, jak práci s namespaces minimalizovat na nejmenší možnou mez.
Late static binding (PHP 5.3)
Problém s překrýváním statických atributů a metod jsem zmínil už výše, zde uvedu jen praktický příklad: