Hlavní navigace

Zaostřeno na PHP (po roce)

Michal Burda

Rok se s rokem sešel, jak se říká, a objektů chtiví programátoři v PHP se dočkali beta-verze PHP 5 s novým jádrem Zend 2. Máte-li zájem se dozvědět, co PHP čeká a nemine, klikněte na odkaz tohoto článku; já naleštím křišťálovou kouli a nahlédnu do budoucnosti...

Rýpalové poznamenají, že mé „věštění“ o vlastnostech PHP 5 nepotřebují, že si raději sami stáhnou zmíněnou betu nebo se podívají na englicky psaný kmen (špalek, kládu) změn (a taky tohle). Mají pravdu. Sám jsem čerpal výhradně z těchto zdrojů v naději, že i tak bude můj článek přínosem; zejména těm, kteří si raději přečtou něco o PHP česky.

Čekání na PHP 5 by se dalo přirovnat k jedné divadelní hře, ve které nějací pánové neustále vyhlíželi jakéhosi Godota. Stále se o něm mluvilo, ale pořád nic. Nevím, jestli se v oné hře Godota nakonec dočkali, analogie s PHP je však o mnoho optimističtější. Beta-verze je venku; ještě vyjde možná nějaká další beta, jedna, dvě nebo tři pre-release a zbrusu nové PHP 5 bude na světě :-).

O objektech ve čtyřkové verzi se můžete dočíst ve starším seriálu PHP v objetí objektů. Dojmy z loňské alfa verze PHP 5 shrnuje seriál (předchůdce toho dnešního) Zaostřeno na PHP. Od té doby se ovšem mnoho změnilo. Podívejme se tedy, co další rok čekání přinesl. Nejprve ale krátký přehled vlastností, které byly zřejmé již loni:

  • objekty se předávají odkazem – aneb nejpalčivější problém „starého“ PHP vyřešen;
  • nová syntaxe konstruktorů – konstruktory (metody automaticky volané při vytváření objektů) se nyní pojmenovávají jednotným názvem __construct();
  • zavedení destruktorů – třídy mohou nyní obsahovat metodu __destruct(), která se automaticky zavolá před zánikem objektu;
  • klonování – řízení vytváření kopií objektů pomocí metody __clone();
  • soukromé atributy – zapouzdřování dat objektů;
  • přímé odkazování na objekty vrácené z volání funkce, inicializace statických atributů, defaultní hodnoty referenčních parametrů, konstanty uvnitř tříd (const) – drobnosti, které potěší;
  • výjimky – důležitý nástroj pro ošetřování chybových stavů.

O všech těchto vlastnostech se můžete dočíst v již zmíněném seriálu Zaostřeno na PHP 1, 2 a 3, proto se už o nich zde nebudu více rozkecávat. Za zmínku stojí pouze tzv. vnořené třídy, pomocí kterých se tvůrci snažili zavést do syntaxe jazyka něco jako názvové prostory. Od této vlastnosti bylo patrně upuštěno, protože současná betaverze PHP hlásí při pokusu o definici třídy v těle jiné třídy syntaktickou chybu.

Modifikátory přístupu

Potřebu nějak ukrývat soukromé atributy objektů před vnějším okolím si tvůrci uvědomili už před rokem. Do budoucna ale můžete v PHP počítat s plným repertoárem modifikátorů přístupu, jak jste zvyklí z jiných jazyků. Ke klíčovému slovu private přibudou ještě bratříčci protected a public, které bude možno použít nejenom před deklarací atributu, ale i před názvem metody.

Příklad:

<?php
class Trida {
  private $soukroma = 'ahoj';
  protected $chranena = 'nazdar';
  public $verejna = 'cau';
  ...

  protected function chranenaMetoda() {
    $o->soukroma = '...';    // v pořádku
    $o->chranena = '...';    // v pořádku
    $o->verejna = '...';     // v pořádku
    ...
  }
  ...
}

$o = new Trida();

// $o->soukroma = '...';    nelze
// $o->chranena = '...';    nelze
$o->verejna = '...';     // v pořádku

// $o->chranenaMetoda();    rovněž nelze
?>

Pokud vám význam modifikátorů přístupu není moc jasný, pak vězte, že metoda nebo atribut s klíčovým slovem private před svým názvem jsou přístupné pouze z třídy, ve které jsou definovány, protected položka je přístupná navíc i ve zděděných třídách a public znamená neomezený přístup (tj. i z vnějšku třídy).

Modifikátory na rozdíl od jiných jazyků nelze použít v záhlaví definice třídy (před klíčovým slovem class) a vytvářet tak soukromé nebo chráněné třídy (v PHP jsou všechny třídy automaticky public).

Abstraktní třídy a metody

Co by to bylo za objektově orientovaný jazyk bez možnosti definovat abstraktní třídy a metody? Od verze 5 si mohou i programátoři v PHP užít klíčového slova abstract:

<?php
abstract class AbstraktniTrida {
  abstract protected function abstraktniMetoda();
}
?>

Jak je dobrým zvykem, abstraktní metoda nemůže obsahovat tělo – místo {…} se jednoduše dává středník. Pokud třída obsahuje nějakou abstraktní metodu, musí být sama pomocí abstract před klíčovým slovem class deklarována jako abstraktní.

Abstraktní třídy a metody jsou jedním z nástrojů polymorfismu (viz třeba PHP v objetí objektů 4/6 – ale pozor, v seriálu je řeč o PHP verze 4!). Jejich smyslem je deklarovat nějakou funkcionalitu na takovém stupni hierarchického stromu tříd, na jakém ještě není důležitá žádná konkrétní implementace.

Trochu lidštěji vyjádřeno: jako abstraktní definujeme ty třídy, které slouží pouze jako jistý obecný logický článek ve stromu dědičnosti a nepředpokládáme, že bychom je někdy instanciovali (vytvářeli objekty tohoto typu). Abstraktní třídy mohou mít abstraktní metody, které neobsahují žádný kód. Teprve potomci abstraktní třídy musí všechny abstraktní metody překrýt a nějaký kód definovat.

Příklad: předpokládejme, že chceme vytvořit nějakou knihovnu ovládacích prvků. Vytvoříme si proto abstraktní třídu OvladaciPrvek, ze které budeme dědit všechny konkrétní ovládací prvky. Třída může mít mnoho metod, které něco dělají, navíc však deklarujeme abstraktní metoduzobrazSe(), která bude sloužit k výstupu ovládacího prvku na stránku. Metodu zobrazSe() musíme deklarovat jako abstraktní, protože na úrovni třídy OvladaciPrvek ještě nelze rozhodnout, jakým způsobem se má zobrazit! Teprve konkrétní ovládací prvky (potomci třídy OvladaciPrvek) metodu zobrazSe() nějak konkrétně implementují…

Používání klíčového slova abstract je důležité zejména z hlediska čistoty kódu. Explicitně si pomocí něj ujasníme, které třídy jsou obecné (abstraktní), a interpret PHP nás upozorní na případné chyby typu: zapomenutí předefinování abstraktní metody v neabstraktním potomkovi. Z hlediska ryzí funkčnosti je ale v PHP rozdělování metod na abstraktní a neabstraktní zcela zbytečné. PHP dopředu nekontroluje (ani nemůže!), jestli daný objekt má definovánu určitou metodu (na to přijde až v době běhu programu), a tak by se vůbec nic nestalo, kdybychom abstraktní metody v třídách vůbec neuváděli a definovali jen ty konkrétní…

Klíčové slovo final

…je dalším obohacením slovníku vývojářů v PHP. Jeho význam je podobný jako v Javě. Lze jej psát před definice metod a tím znemožnit jejich předefinování v případných potomcích třídy. Klíčové slovo final lze používat jen v souvislosti s metodami. Pokud chcete „read-only“ atribut, máte smůlu; tehdy je dobré se porozhlédnout po klíčovém slově const (viz Zaostřeno na PHP 3).

Příklad:

<?php
class NejakaTrida {
  final public function nebezpecnaMetoda() {
    ...
  }
}

class PotomekTridy extends NejakaTrida {
  // pokus o předefinování vyvolá chybu:
  public function nebezpecnaMetoda() {
    ...
  }
}
?>

Pokračování příště…

Našli jste v článku chybu?