Objektově orientované programování (OOP) v PHP

1. Co přináší OOP

1.1 Zapouzdření

1.1.1 Uživatel se odstíní od vnitřního fungování prostřednictvím rozhraní.

1.2 Dědění

1.3 Polymorfismus

1.3.1 Schopnost OOP přeměnit chování nejaké třídy v závislosti na kontextu.

2. Pojmy

2.1 Třídy

2.1.1 class nazev { }

2.2 Objekty

2.2.1 Instance tříd, $objekt = new Trida();

2.3 Členské proměnné

2.3.1 např. class Trida { private $atribut; }

2.3.2 Atributy popisující charakteristiky třídy.

2.3.3 Odkazy: $objekt->atribut (uvnitř třídy $this->atribut)

2.4 Obor členských proměnných

2.4.1 public - lze k nim přistupovat přímo (např. $objekt->atribut = "neco";), nemělo by se používat

2.4.2 private - dostupné pouze uvnitř třídy, ve které jsou definované, ani v instanci a ani v podtřídách, musí se k nim přistupovat přes veřejné rozhraní

2.4.3 protected - určeny pouze pro interní potřebu třídy, dostupné pouze uvnitř tříd a v podtřídách

2.4.4 final - není možné ji překrýt v odvozené třídě

2.5 Vlastnosti

2.5.1 bohužel PHP 5 nenabízí "plně" vyhovující funkcionalitu, ale má něco co připomíná podporu vlastností

2.5.2 jde o přetěžování metod __set a __get (deklarujíc se jako metoda v třídě), které se volají, když se pokusíme odkázat na neexistující členskou proměnnou

2.5.3 využívají se k výpisu chybové zprávy nebo dokonce k rozšíření třídy za pochodu vytvářením nových proměnných

2.5.4 __set(promenna, hodnota)

2.5.4.1 mutátor (setter), skrývá implementaci a ověřuje data dříve, než se přiřadí

2.5.4.2 může rozšířit třídu o nové vlastnosti

2.5.5 __get(promenna)

2.5.5.1 accessor (getter), když chceme získat hodnotu proměnné z třídy

2.5.6 nejsou však postačující pro složitější objektové aplikace, v tom případě je na místě vytvořit pro každou privátní členskou proměnnou dvě veřejné metody napr. getJmeno(), setJmeno()

2.6 Konstanty

2.6.1 definují se uvnitř třídy, nezmění se po celou dobu života objektu vytvořeného z dané třídy (např. dobré pro PI)

2.6.2 const NAZEV = 'neco';

2.6.3 volá se echo trida::KONSTANTA;

2.7 Metody

2.7.1 Obdobné jako funkce, definují chování v nějaké konkrétní třídě.

2.7.2 volají se $objekt->metoda();

2.7.3 deklarace - obor function nazev() { ... }

2.7.4 pokud se neuvede obor, implicitně se bere public

2.8 Obory metod

2.8.1 public - jsou přístupné odkudkoliv

2.8.2 private - pouze pro interní potřebu původní třídy, nemohou je volat instance objektů ani původní, ani odvozených tříd, všechny metody určené jako pomůcky pro jiné metody mají být private

2.8.3 protected - dostupné pouze v původní třídě a v jejich podtřídách, mají sloužit jako pomůcky při interních výpočtech v původní třídě nebo v jejich podtřídách

2.8.4 abstract

2.8.4.1 deklarují se jen v rodičovské třídě, ale implementují v dceřiných

2.8.4.2 abstraktní metody mohou obsahovat pouze abstraktní třídy, používá se pro inavrhování API, které se později použije jako implementační model

2.8.4.3 abstract function nazev();, z dané abstraktní třídy se pak odvozují konkrétnější třídy

2.8.5 final - zabrání tomu, aby se mohla metoda překrývat v podtřídách

3. Type hinting (rada pro typ)

3.1 zajišťuje, že objekt, který se předává do metody, bude opravdu členem správné třídy

3.2 private function nazev(trida $objekt);

3.3 funguje pouze pro objekty

4. Konstruktory

4.1 Kód, který se vykonává automaticky v době, kdy se vytváří instance objektu.

4.2 Může přijímat parametry, které se v době vytváření instance přiřadí konkrétním členským proměnným objektu.

4.3 Může volat metody třídy a jiné fce.

4.4 Může volat jiné konstruktory včetně konstruktorů z rodičovské třídy.

4.5 function __construct (...) { }

4.6 PHP automaticky nevolá konstruktor rodičovské třídy, dělá se to explicitně pomocí parent::__construct() c konstruktoru odvozené třídy.

4.7 Můžeme volat i nespřízněný konstruktor pomocí trida::_construct();

5. Destruktory

5.1 function __destruct();

5.2 Když skript skončí, PHP zničí všechny objekty sídlící v paměti. Takže v tomto případě explicitní deklarování konstruktoru zbytečné.

5.3 Využijeme, když chceme například se zánikem objektu vymazat nějaká data z databáze nebo ze souboru apod.

6. Statické členy tříd

6.1 Členské proměnné a metody, které nebude volat žádný konkrétní objekt, ale budou patřit do všech instancí a všechny instance je budou sdílet.

6.2 Dobré např. když děláme třídu pro počítání návstěvníků stránky a počítáme jejich počet a nechceme, aby se tento počet vrátil na nulu pokaždé, když se vytvoří instance třídy.

6.3 private static $Nazev_tridy = neco;

6.4 Na statické členské proměnné a metody se odkazuje klíčovým slovem self a názvem třídy.

6.5 self::$Nazev;

7. instanceof

7.1 Zjišťuje, zda je nějaký objekt intancí dané třídy, podtřídou třídy nebo implemeentuje-li konkrétní rozhraní.

7.2 if ($osoba instanceof Clovek) echo "OK";

7.3 Jestliže se porovnání nezdaří, vykonávání skriptu skončí.

7.4 Vhodné, pokud voláme opakovaně nějakou konkrétní fci ale chceme její chování došít na míru podle typu objektu.

8. Pomocné funkce

8.1 class_exists(trida);

8.2 get_class(objekt);

8.2.1 vrátí název třídy do které patří objekt

8.3 get_class_methods(trida);

8.3.1 vrátí pole obsahující názvy všech metod

8.4 get_class_vars(trida);

8.4.1 vrátí asociativní pole názvů všech členských proměnných

8.5 get_declared_classes();

8.5.1 vrátí pole obsahující názvy všech tříd definovaných uvnitř aktuálně vykonávaného skriptu

8.6 get_object_vars(object);

8.6.1 vrátí asociativní pole členských proměnných a jejich hodnot, které jsou dostupné pro objekt, ty které nemají přidělenou žádnou hodnotu, v poli bude NULL

8.7 get_parent_class(objekt);

8.7.1 vrátí název rodičovské třídy té třídy, kam objekt patří, je-li objekt řetězec, předpokládá se, že je to název třídy a vrátí se název rodičovské třídy této třídy

8.8 is_a(objekt, trida);

8.8.1 vrátí TRUE jestliže objekt patří do třídy nebo do nějaké třídy, která je z ní odvozená

8.9 is_subclass_of(objekt, trida);

8.9.1 vrátí TRUE jestliže je objekt patří do třídy odvozené z třídy

8.10 method_exists(objekt, metoda);

8.10.1 vrátí TRUE jestliže je metoda dostupná objektu

9. Automatické načítání objektů

9.1 funkcí __autoload() se zbavíme nutnosti vkládat příkazy require_once() apod.

9.2 když se nějaké třída zavolá poprvé, zavolá se __autoload() a načte třídu podle příkazů v této fci

9.3 umístit ji do nějakého globálního konfiguračního souboru

9.4 function __autoload($trida) { require_once("tridy/$trida.class.php"); }