Hlavní navigace

Zaostřeno na PHP

Michal Burda 10. 9. 2002

V pilotní části nového seriálu zaměřeného na PHP se podíváme do blízké budoucnosti této bezesporu populární technologie.

To, že PHP v dohledné době zaznamená výraznou změnu hlavně v oblasti týkající se objektů, je poměrně známá věc. Poprvé o tom padla na Rootu zmínka v rozhovoru Jirky Koska s jedním z autorů PHP, a že objektově orientované programování ve stávajícím PHP je řehole, jste se mohli přesvědčit při čtení seriálu PHP v objetí objektů.

Nová verze PHP s lepšími objekty je na spadnutí. Již delší dobu si ji můžete dokonce vyzkoušet v už druhé alfa verzi na www.php.net. V tomto článku bych se s vámi rád podělil o některé první dojmy.

Objekty se předávají odkazem

Změna v sémantice jazyka je opravdu radikální. Konečně můžete zapomenout na předávání odkazů na objekt (&=) a místo džungle zapomenutých ampersandů se věnovat skutečnému programování.

Dříve se s objektem zacházelo jako s obyčejnou proměnnou, takže když jste objekt přiřadili nějaké proměnné, ve skutečnosti se objekt zkopíroval a každá proměnná od toho okamžiku představovala jiný objekt. Přirozenější prací s objektem je předávání referencí (odkazem), ale to se ve „starém“ PHP muselo explicitně říct právě přiřazovacím příkazem s ampersandem (např. $b &= $a), což byl právě kámen úrazu. Na nutnost použití

& (a to nejen v přiřazovacích příkazech, ale i v definicích hlavičky funkcí, pokud jste chtěli objekty předávat jako parametry nebo je vracet jako výsledky funkcí) se často zapomínalo a vedlo to k mnoha záludným chybám. Od nynějška povinnost použití & odpadá a programování se tak stává mnohem intuitivnějším. Pokud chcete, aby dvě proměnné ukazovaly na jeden objekt, jednoduše napíšete $b = $a a hotovo.

Mějme následující kód:

<?php
class Test {

  var $hodn = 0;

  function zmen() {

    echo ++$this->a;
  }
}

$a = new Test();

$b = $a;
$a->zmen();
$b->zmen();

?>

Nové chování PHP ilustrují rozdílné výstupy. Zatímco dříve byste dostali 11, nyní to bude očekávaná dvanáctka.

Sjednocené konstruktory

Dříve se musely kontruktory (inicializační metody tříd, které se automaticky volají při vytvoření nového objektu) jmenovat stejně jako třída – podle toho se také v kódu rozpoznaly. Mělo to jednu nevýhodu. Je velmi časté a obvyklé, že se z konstruktorů tříd na některém místě volá i konstruktor nadřazené (rodičovské) třídy. Změna názvu třídy nebo výměna rodičovské třídy, ze které se dědí, ústila v nutnost opravy volání konstruktorů na různých místech kódu.

Nyní se konstruktory všech tříd označují stejně, a to identifikátorem __construct. Pokud chcete volat rodičovskou verzi konstruktoru, jednoduše napíšete parent::__con­struct(). Pokud u třídy konstruktor nespecifikujete, automaticky se použije konstruktor z nadřazené třídy (nebo prázdný konstruktor, pokud třída žádnou super-třídu nemá).

<?php
class Test {
  function __construct() {

    echo 'Test::__construct()<br>';
  }
}

class PodTest extends Test {

}

class PodPodTest extends PodTest {
  function __construct() {

    echo 'PodPodTest::__construct(), ';
    parent::__construct();
  }
}

$a = new Test();

$b = new PodTest();
$c = new PodPodTest();

?>

(Všimněte si volání konstruktoru nadřazené třídy pomocí identifikátoru parent::. Podobně se dají volat verze rodičovských metod z předefinovávané metody.)

Výstup:

Test::__construct()
Test::__construct()
PodPodTest::__construct(), Test::__construct()

Destruktory nově

Jestliže máme konstruktory sloužící k inicializaci objektu v době jeho vzniku, můžou se hodit i destruktory určené pro úklidové práce v čase zániku objektu. Ačkoliv nejsou destruktory v objektově orientovaných jazycích nic nového, v připravované verzi PHP se objevují poprvé.

Chcete-li třídě definovat destruktor, vytvořte novou metodu a pojmenujte ji __destruct. Destruktor se samočinně volá těsně před ukončením existence objektu. Objekt je automaticky zničen tehdy, když v programu neexistuje proměnná, která by na něj ukazovala. Tehdy není žádná možnost, jak s objektem pracovat a jádro PHP nemá důvod takový objekt dále držet v paměti.

Programátor má možnost uvolnit objekt z paměti i ručně. Slouží k tomu nový příkaz (a nové klíčové slovo) delete.

Jak a hlavně kdy se destruktory volají, je dobře vidět na následujícím příkladu:

<?php
class Test {
  var $nazev;

  function __construct($nazev) {

    $this->nazev = $nazev;
  }

  function __destruct() {

    echo 'Destrukce objektu ' . $this->nazev . '<br>';
  }

}


function bod() {
  static $n = 0;
  echo "Kontrolní bod $n<br>";
  $n++;

}


function delej() {
  $b = new Test('B');

}


bod();
$a = new Test('A');

bod();
delej();
bod();


$c = new Test('C');
bod();
delete $c;
bod();


$d = new Test('D');
bod();
$d = 'ahoj';
bod();

?>

Výstupem bude:

Kontrolní bod 0
Kontrolní bod 1
Destrukce objektu B
Kontrolní bod 2
Kontrolní bod 3
Destrukce objektu C
Kontrolní bod 4
Kontrolní bod 5
Destrukce objektu D
Kontrolní bod 6
Destrukce objektu A

…z čehož lze vypozorovat, že objekt A byl odstraněn až na konci skriptu, protože až tam končí oblast platnosti proměnné $a, která na něj udržuje odkaz. Objekt B byl uvolněn ihned po opuštění funkce

delej(), kdy se znepřístupnila držitelka reference na něj – lokální proměnná $b. Rovněž můžeme vidět, že destruktory objektů C a D se volaly ihned po vykonání příkazu delete $c v prvním případě a přiřazení textového řetězce do proměnné $d v případě druhém.

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

Našli jste v článku chybu?

9. 10. 2002 1:36

Kamil Sopko (neregistrovaný)

mno jeden duvod sem mel zrovna nedavno.
Pouzivam, sablony, ktere jsou zalozene na klicich vnorenych blocich a parsovani pres callbacky funkci, na nez je postavena nadstavba(conteiner), ktera se stara o formulare a ruzne dblisty a pod a vyuziva component a zde sem narazil na problem, jelikoz pri inicializaci projektu se nacitaji jazykove klice do parseru, a ty potrebuju pouzit v nekolika kontainerech na strance, ale kontainery by si navzajem menili klice, ktere pouzivaji jako promenne nebo…

Vitalia.cz: Pečete cukroví a zbyl vám bílek?

Pečete cukroví a zbyl vám bílek?

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: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

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

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

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

Horní cesty dýchací. Zkuste fytofarmaka

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

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

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

Jak vymáhat výživné zadarmo?

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

Vitalia.cz: Dáte si jahody s plísní?

Dáte si jahody s plísní?

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

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

Podnikatel.cz: Babiš: E-shopy z EET možná vyjmeme

Babiš: E-shopy z EET možná vyjmeme

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

Vitalia.cz: Baletky propagují zdravotní superpostel

Baletky propagují zdravotní superpostel

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

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