Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

PHP v objetí objektů (5)

V předposledním pokračování seriálu o objektově orientovaném programování v PHP si ukážeme jednu záludnost, která na programátory číhá v nevinně vyhlížejícím operátoru přiřazení (=).

Tweetni to Twitter Jaggni to! Jagg Del.icio.us Delicious
Objekty a operátor přiřazení

Objekty vystupující jako argument operátoru přiřazení ( =) jsou podle mě další velkou nepříjemností, která vás v PHP čeká. Narozdíl od jiných programovacích jazyků v PHP příkazem

$promenna = $objekt; 

přiřadíte do proměnné $promenna kopii (!) objektu uloženého pod proměnnou $objekt. Tento fakt se musí obcházet použitím odkazů (operátoru &). Dlouho jsem si na tuto skutečnost nemohl zvyknout a byla příčinou mnoha nechutných chyb. Pro lepší pochopení problému uvedu příklad:

class NejakaTrida {
  var $hodnota;

  function NejakaTrida($h) {
    $this->hodnota = $h;
  }
}


function zobraz() {
  global $a, $b, $c;
  print '<p>';
  print 'Hodnota $a je ' . $a->hodnota . '<BR>';
  print 'Hodnota $b je ' . $b->hodnota . '<BR>';
  print 'Hodnota $c je ' . $c->hodnota . '<BR>';
}


$a = new NejakaTrida('AAA');
$b = $a;
$c =& $a;
zobraz();

$b->hodnota = 'BBB';
zobraz();

$c->hodnota = 'CCC';
zobraz(); 

Výsledkem kódu bude:

Hodnota $a je AAA
Hodnota $b je AAA
Hodnota $c je AAA

Hodnota $a je AAA
Hodnota $b je BBB
Hodnota $c je AAA

Hodnota $a je CCC
Hodnota $b je BBB
Hodnota $c je CCC 

Pokud k přiřazení objektu do proměnné použijeme příkaz typu

$b = $a; 

uloží se do $b kopie objektu $a. Vznikne tak další samostatný objekt, který nemá s prvním nic společného (až na třídu, ke které oba patří).

K tomu, abyste do nové proměnné ( $c) uložili odkaz na tentýž objekt ( $a), musíte použít konstrukci

$c =& $a; 

Od této chvíle je $c jen jiné jméno pro objekt uložený v $a  – obě proměnné odkazují na tentýž objekt.

Často můžete potřebovat metodu, která jako argument požaduje odkaz na objekt. Potom před název argumentu v hlavičce musíte umístit znak  &:

function ptakovina(&$odkaz_na_objekt) {
  # ...
} 

Malá ukázka použití v praxi:

/*
Kontejnerová třída, která ukládá do pole různé objekty
a na požádání volá jejich metody zobraz()
*/
class Kontejner {
  var $polozky;

  # vlož odkaz na objekt do kontejneru
  function vloz(&$obj) {
    $this->polozky[] =& $obj;
  }

  # zobraz všechny objekty v kontejneru
  function zobraz() {
    for ($x = 0; $x < count($this->polozky); $x++) {
      $this->polozky[$x]->zobraz();
    }
  }
}


/*
Jednoduchá třída implementovaná proto, abychom
měli do kontejneru co vkládat
*/
class Odstavec {
  var $text;

  # konstruktor
  function Odstavec($t = '') {
    $this->text = $t;
  }

  # zobrazovací metoda
  function zobraz() {
    print '<P>Text odstavce: ' . $this->text . '</P>';
  }
}


$stranka = new Kontejner();

$a = new Odstavec('Odstavec 1');
$b = new Odstavec('Odstavec 2');
$c = new Odstavec();

$stranka->vloz($a);
$stranka->vloz($b);
$stranka->vloz($c);

$c->text = 'Odstavec 3';

$stranka->zobraz(); 

Vynecháním všech & v metodě vloz() třídy Kontejner byste si zadělali na nepříjemnou chybu. Místo očekávaného výstupu:

Text odstavce: Odstavec 1
Text odstavce: Odstavec 2
Text odstavce: Odstavec 3 

byste se dočkali pouze tohoto:

Text odstavce: Odstavec 1
Text odstavce: Odstavec 2
Text odstavce: 

Je to proto, že objekt $c jsme kontejneru $stranka předali dříve, než nabyl textu 'Odstavec 3'. Bez použití odkazů bychom v kontejneru uchovávali pouze kopie objektů $a, $b, $c, a tedy příkaz $c->text = 'Odstavec 3' by se objektu uloženého v kontejneru vůbec netýkal.

Potřebujete-li vyrobit funkci či metodu, která vrací odkaz na objekt, musí její hlavička vypadat takto:

function &ziskej($parametr) {
  # ...
  return $objekt;
} 

Bez & před názvem funkce bychom příkazem return $objekt vrátili pouze kopii objektu $objekt.

davame_internetu_obsah
       

Poznámka: Machrování s odkazy se dá obecně použít na proměnnou jakéhokoliv typu. Podrobněji o odkazech viz manuál k PHP.

Dokončení příště…

Michal Burda

Michal Burda

Michal Burda vystudoval informatiku a aplikovanou matematiku a nyní pracuje na Ostravské univerzitě jako odborný asistent. Zajímá se o data mining, Javu a Linux.

Školení: Návrh a používání MySQL databáze

 

Naučte se používat jednu z nejrozšířenějších databází. Dozvíte se vše potřebné od návrhu až po samotné využití MySQL v projektech.

Školení pro všechny, kteří se chtějí naučit efektivně pracovat s MySQL nebo se v práci s touto databází zlepšit.

Přihláška a podrobné informace

Ohodnoťte jako ve škole:
Průměrná známka 2,83

Přehled názorů

Svítání na lepší časy
Jirka Kosek 13. 8. 2001 11:14
Nový
└ 
Re: Svítání na lepší časy
Petr 15. 8. 2001 11:24
Nový
 
└ 
Re: Svítání na lepší časy
Jirka Kosek 15. 8. 2001 17:22
Nový
Dotaz: předání objektu referencí v PHP3
Vladislav Švadlenka 23. 8. 2001 15:52
Nový
Dotaz: předání objektu referencí v PHP3
Vladislav Švadlenka 23. 8. 2001 15:52
Nový
└ 
Frájo, máš starou verzi
NOVEJ MODEL 4. 3. 2008 14:57
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem