Hlavní navigace

Zaostřeno na PHP (po roce) 2

Michal Burda 2. 9. 2003

Pokračuje exkurze po vlastnostech a změnách syntaxe připravovaného PHP 5.

Typová kontrola

Za revoluční počin považuji zavedení nepovinné kontroly typů objektů předávaných jako parametry metodám nebo funkcím. Vše funguje takto: před jméno argumentu v deklaraci metody či funkce lze uvést název třídy (tj. typ argumentu) a PHP potom při každém volání dané metody nebo funkce kontroluje, jestli typy předávaných parametrů odpovídají deklaraci.

<?php
function nejakaFunkce(Trida $t) {
  ...
}

...

$obj1 = new Trida();
$obj2 = new DalsiTrida();
nejakaFunkce($obj1); // V pořádku
nejakaFunkce($obj2); // Vyvolá chybu v případě, že DalsiTrida
                     // není potomkem třídy Trida
?>

Uvádění typu předávaného objektu je nepovinné – nic se tedy nestane, pokud tento mechanismus nebudete využívat. Okradete se pouze o výbornou pomůcku ladění.

Kontrolovat lze tímto způsobem pouze objektové parametry. Nelze tedy psát např. function f(string $s) a podobně. Testy typů se provádějí v čase běhu skriptu. Špatný typ parametru se tedy odhalí, až když na příslušný řádek s chybným kódem při vykonávání PHP narazí. Nelze tedy spoléhat jako u jiných jazyků na to, že jedno spuštění (zkompilování…) odhalí všechny nesrovnalosti s typy.

Operátor instanceof

Tvůrci PHP se nikdy netajili tím, že PHP 5 bude vypadat jako Java. Koneckonců, není nutné neustále vymýšlet objevené a stejné věci pojmenovávat různě. Důkazem mohutné inspirace Javou budiž i nový operátor instanceof. Můžete pomocí něj jednoduše(ji) zjišťovat, jestli je daný objekt instancí třídy, rodiče třídy, nebo implementací rozhraní.

<?php
class JakasiTrida {
  ...
}

$cosi = new JakasiTrida();
...
if ($cosi instanceof JakasiTrida) {
  echo 'nazdar chlapi (a holky)';
}
?>

Ano, čtete dobře, v poslední větě jsem skutečně psal rozhraní – to je další lahůdka OOP zavlečená z Javy. Nikam neodcházejte a čtěte dále…

Rozhraní (interface)

Používání rozhraní (interface) je jedním ze způsobů, jak objektově modelovat náš složitý svět. Při objektově orientovaném programování se občas dostaneme do situace, kdy nějaká třída vykazuje takové vlastnosti, že by bylo vhodné, aby jejím předkem byly současně dvě různé třídy. Přidržím-li se příkladu s ovládacími prvky z minulého dílu a vezmu-li v úvahu hypotetickou třídu Form (formulář), pak tato třída by mohla být potomkem třídyOvladaciPrvek. Pokud bychom ale chtěli třídu Form udělat velice chytře, mohli bychom požadovat, aby automaticky zobrazila a nabídla k editaci obsah nějakého záznamu v databázi. Přístup do databáze je umožněn řekněme pouze potomkům třídy NacitaniDat a my máme problém: Form logicky patří do podstromu ovládacích prvků, ale zároveň je třeba, aby zvládal i načítání dat. Co s tím?

V C++ se podobné situace daly řešit vícenásobnou dědičností, ale kolize názvů položek rodičovských tříd přinášela víc problémů než užitku. V Javě (a teď už i v PHP) se s tím poprali jinak: zavedli rozhraní.

Pojem rozhraní souvisí s rolemi objektu, jaké hraje vůči okolnímu světu. Náš objekt typu Form z předminulého odstavce vystupuje jednou v roli ovládacího prvku (tehdy, když po něm řekněme budeme chtít, aby se „zobrazil“ na stránce) a jindy zase v roli čtečky dat (když bude třeba, aby si data „natáhl“ sám z databáze).

Zamyslíme-li se nad skutečným světem, i zde najdeme řadu objektů, které vystupují v různých rolích: vy sami jako objekty se nyní nacházíte v roli čtenáře článku na Rootu. Až dočtete, přepnete se možná do role návštěvníka kina, člověka, který jde uhasit žízeň do blízké restaurace nebo hospodyně prahnoucí po umývání schodů.

Interface je jazyková konstrukce určená k deklaraci takové role. Neslouží k definici žádného kódu. Pouze vyjmenovává, jaké akce můžeme od objektu disponujícího danou rolí očekávat. Příklad:

<?php
interface KonzumentPiva {
  public function kupPivo();
  public function konzumuj(Pivo $p);
  public function jdiNaWC();
}
?>

Máme-li definováno rozhraní, potřebujeme také nějakou třídu, která by dané rozhraní implementovala:

<?php
class Student implements KonzumentPiva {
  public function kupPivo() {
    ...
  }

  public function konzumuj(Pivo $p) {
    ...
  }

  public function jdiNaWC() {
    ...
  }
}
?>

Vtip je v tom, že zatímco může být třída zděděna pouze z jednoho předka, implementovat může takřka libovolný počet rozhraní (ta se potom uvádějí čárkami oddělená za klíčovým slovem implements v deklaraci třídy).

Jak rozhraní řeší náš problém s třídou Form? Jednoduše. Podle povahy problému se třeba rozhodneme, že Form budeme dědit z abstraktní třídyOvladaciPrvek a navíc bude implementovat rozhraní NacitaniDat, které reprezentuje roli objektu načítajícího data z databáze.

Zatímco například v Javě jsou rozhraní přísně typově kontrolována, v případě PHP jde spíše o čistotu programování, která by nás měla vést k jejich používání. V PHP jakožto slabě typovém jazyce bychom se klidně bez rozhraní obešli. V malých prográmcích je to určitě pochopitelné, ale v rozsáhlejších projektech s desítkami tříd už trochu pořádku vneseného rozhraními neuškodí.

Dokončení příště.

Našli jste v článku chybu?

18. 11. 2007 10:54

Rejpal (neregistrovaný)
Nejrychlejší bude dobře napsaný framework nad Common Lispem, tam se dá dělat spousta černé magie s compiler makry a generováním nativního kódu... :-D

13. 8. 2006 1:16

dark lord of the sith (neregistrovaný)
nezapomels trochu na bytecode?
Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

DigiZone.cz: Ohrozí Freedom TV přechodové sítě?

Ohrozí Freedom TV přechodové sítě?

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

DigiZone.cz: Sat novinky: slovenská TV8 HD i ruský NTV Mir

Sat novinky: slovenská TV8 HD i ruský NTV Mir

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

DigiZone.cz: ČRa DVB-T2 ověřeno: Hisense a Sencor

ČRa DVB-T2 ověřeno: Hisense a Sencor

Lupa.cz: Seznam mění vedení. Pavel Zima v čele končí

Seznam mění vedení. Pavel Zima v čele končí

Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

120na80.cz: Jak oddálit Alzheimera?

Jak oddálit Alzheimera?