Hlavní navigace

Zaostřeno na PHP (2)

Michal Burda 24. 9. 2002

Dnešním dílem pokračuje prohlídka nových vlastností připravované verze PHP. Bude řeč o klonování objektů, soukromých atributech a dalších vylepšeních.

Soukromé atributy

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.

Našli jste v článku chybu?

22. 12. 2007 23:03

aribu (neregistrovaný)
Mno, přijde mi dost na prd. Když jsem ji použil, tak jsem automaticky očekával, že vznikne identická kopie objektu, akorát s jiným identifikátorem. Až když se to chovalo "divně", tak jsem začal hledat, co že to tedy dělá. Ten název mi tedy přijde poněkud zavádějící. Spíš by se to mělo jmenovat link nebo ref nebo tak nějak...

26. 9. 2002 20:53

SVAN (neregistrovaný)

Sorry za OT ale neviem si rady. Ako docielit v PHP toto. Mam obrazok modry kruh (transparentne PNG) a obrazok cerveny stvorec (PNG). Chcem skopirovat modry kruh na cerveny stvorec tak aby som dostal modry kruh na cervenom stvorci. Skusal som to cez imagecopymerge() ale dosiel som ktomu, ze sa transparentna farba nahradila bielou a dostal som modry kruh na bielom stvorci. Prosim o radu. Dakujem...

DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Vitalia.cz: Říká amoleta - a myslí palačinka

Říká amoleta - a myslí palačinka

Lupa.cz: Slevové šílenství je tu. Kde nakoupit na Black Friday?

Slevové šílenství je tu. Kde nakoupit na Black Friday?

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

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

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

Jsou čajové sáčky toxické?

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

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

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

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

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

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

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

Rakovina oka. Jak ji poznáte?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Podnikatel.cz: Na poslední chvíli šokuje vyjímkami v EET

Na poslední chvíli šokuje vyjímkami v EET

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

Jak vymáhat výživné zadarmo?

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

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

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

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

Lupa.cz: Avast po spojení s AVG propustí 700 lidí

Avast po spojení s AVG propustí 700 lidí

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá