Pro lepší zapouzdření informací do tříd můžete nyní definovat některé atributy jako private, tj. soukromé. Přístup k takovým atributům třídy pak je možný jen z metod dané třídy – z vnějšku k nim přistupovat nelze. Definicí atributu jako private máte jistotu, že si žádnou vnitřní hodnotu, která by se nikdy neměla používat přímo, nikde omylem nepřepíšete.
<?php
class Test {
private $x = 'Ahoj';
function pozdrav() {
echo $this->x . '<br>';
}
}
class Testik extends Test {
function takyPozdrav() {
echo $this->x . '<br>';
}
}
$a = new Test();
$a->pozdrav();
printf('Tady nic není: (%s)<br>', $a->x);
$b = new Testik();
echo 'Tady taky nic nebude...';
$b->takyPozdrav();
?>
Tato malá ukázka dá na výstup následující text:
Ahoj Tady nic není: () Tady taky nic nebude...
V souvislosti s private atributy bych chtěl upozornit na jednu věc. Nevím jistě, jestli se jedná o vlastnost PHP, nebo spíše o chybu (a jestli to tak bude fungovat i ve finální verzi), ale zdá se, že každý druh atributů má svůj názvový prostor, takže klidně můžete mít tři různé (veřejné, soukromé a statické) atributy stejného jména. Zvažte následující příklad a jeho výsledek:
<?php
class Test {
var $x = "ahoj ";
static $x = "nazdar ";
private $x = "čau ";
function tisk() {
echo $this->x;
}
}
$a = new Test();
echo $a->x;
echo Test::$x;
$a->tisk();
?>
Výstup:
ahoj nazdar čau
V prvním echu přistupujeme k veřejné (var) proměnné objektu, druhým echem ke statickému (static) atributu třídy a voláním metody
tisk() k soukromému (private) atributu.
Klonování
Už když jsem se v minulém dílu zmínil o tom, že přiřazovacím operátorem se nyní nově objekty nekopírují, objevily se v diskusi dotazy, jak se tedy bude v případě potřeby kopírování provádět. Někteří další čtenáři už na dané téma odpovídali, ale já přesto vše zopakuji ještě jednou:
Klonování se provádí voláním metody __clone() klonovaného objektu. Po zavolání této metody se jádro PHP podívá, zda má daný objekt metodu __clone() definovánu, nebo ne. V záporném případě se spustí standardní klonovací metoda, která vytvoří identickou kopii objektu. Definováním vlastní metody __clone() získá programátor nad procesem klonování plnou kontrolu.
V metodě __clone() máte k dispozici speciální proměnnou $clone, která ukazuje na původní (klonovaný) objekt. Přitom platí, že standardní proměnná $this odkazuje na nově vytvářený klon.
<?
class Ovce {
var $jmeno;
function __construct($jmeno) {
$this->jmeno = $jmeno;
}
function __clone() {
$this->jmeno = 'Klon ' . $clone->jmeno;
}
function vystup() {
echo 'Já jsem ' . $this->jmeno . '<br>';
}
}
$dolly = new Ovce('Dolly');
$dolly->vystup();
$klon = $dolly->__clone();
$klon->vystup();
?>
Výstup:
Já jsem Dolly Já jsem Klon Dolly
Pokud definujete vlastní metodu __clone(), musíte ručně inicializovat všechny atributy objektu. Autoři PHP slibují, že implementují nějaký mechanismus (pravděpodobně funkci), který provede automatickou bitovou kopii objektu a na tvůrce skriptů pak zbyde jen přepsat podle potřeby ty atributy, u kterých kopírování bit po bitu není na místě.
Přímé odkazování na objekty vrácené z volání funkce
Dalším krůčkem dopředu (který ostatně už měl být udělaný dávno) je, že objekt vrácený jako výsledek volání funkce či metody může být ihned odkazován:
<?
class Vyrobek1 {
function vystup() {
echo 'Vyrobek 1<br>';
}
}
class Vyrobek2 {
function vystup() {
echo 'Vyrobek 2<br>';
}
}
class Tovarna {
function vytvorVyrobek($druh) {
if ($druh == 1)
return new Vyrobek1();
else
return new Vyrobek2();
}
}
$tovarna = new Tovarna();
$tovarna->vytvorVyrobek(1)->vystup();
$tovarna->vytvorVyrobek(2)->vystup();
?>
Výsledek:
Vyrobek 1 Vyrobek 2
Referenční parametry mohou mít defaultní hodnotu
Další novinkou v jazyku PHP je to, že argumenty funkcí, které přebírají odkaz na proměnnou, mohou mít nyní defaultní hodnotu. Příklad:
<?
function funkce(&$promenna = NULL) {
if ($promenna === NULL)
echo 'Funkce volaná bez parametru.<br>';
else
echo $promenna++ . '<br>';
}
$a = 1;
funkce($a);
funkce($a);
funkce();
?>
Výstup:
1 2 Funkce volaná bez parametru.
Statické atributy mohou být inicializovány
Další drobností ve vylepšeních PHP je fakt, že statické atributy tříd mohou být nyní inicializovány přímo ve svých definicích:
<?
class NejakaTrida {
static $promenna = 1;
}
echo NejakaTrida::$promenna;
?>
Co bude výsledkem takového příkladu, nemusím snad ani zveřejňovat…
Backtrackingem za snazší ladění
Pro snazší ladění budete moci v nové verzi PHP použít funkci debug_backtrace(), která vrací pole s informacemi o vnoření do volání funkcí. Prvky pole jsou asociativními poli s následujícími hodnotami:
- ‚class‘ – jméno třídy, ke které metoda patří (nebo prázdný řetězec, pokud se jedná o funkci),
- ‚function‘ – jméno volané funkce (metody),
- ‚file‘ – název zdrojového souboru, ve kterém došlo k volání,
- ‚line‘ – číslo řádku, ze kterého byla funkce volána.
Díky funkci debug_backtrace() získáte konkrétní představu o tom, jak funkce navzájem volají jedna druhou, a přehled, které funkce jsou rozpracovány. Možný způsob použití ukazuje následující příklad (čísla řádků jsou zde jen pro vaši informaci):
1 <?
2 function backtrace() {
3 $backtrace = debug_backtrace();
4
5 foreach ($backtrace as $krok) {
6 $class = isset($krok['class']) ? $krok['class'] . '::' : '';
7
8 echo $class . $krok['function'] . '() v souboru '
9 . $krok['file'] . ' na řádku ' . $krok['line'] . '<br>';
10 }
11 }
12
13 function nejaka_funkce() {
14 backtrace();
15 }
16
17 function dalsi_funkce() {
18 nejaka_funkce();
19 }
20
21 dalsi_funkce();
22 ?>
A zde je výsledek ukázky:
backtrace() v souboru /var/www/html/testPHP43.php na řádku 14 nejaka_funkce() v souboru /var/www/html/testPHP43.php na řádku 18 dalsi_funkce() v souboru /var/www/html/testPHP43.php na řádku 21
A to je vše, alespoň pro dnešek. Z novinek v PHP nám na příště zbyly názvové prostory, nová práce s konstantami a výjimky.