Na navigaci | Klávesové zkratky

První PHP hádanka

Inspirován programátorskými hádankami Reného Steina bych rád podobnou kratochvíli dopřál i znalcům PHP. Pro začátek takový chyták: Co vypíše příkaz echo?

class Foo {
  var $self;
  var $bar = 11;

  // constructor
  function Foo() {
	$this->self = & $this;
  }
}

$foo = new Foo();
$foo->bar = 22;
echo $foo->self->bar;

před 20 lety v rubrice PHP | blog píše David Grudl | nahoru

Mohlo by vás zajímat

Komentáře

  1. Dero #1

    avatar

    Dvaadvacet?

    před 20 lety | reagoval [2] formanet
  2. formanet #2

    #1 Dero, 11

    před 20 lety
  3. Prochaine #3

    $bar je přeci konstanta, takže 11. Vyzkoušeno na PHP4.

    před 20 lety | reagoval [4] David Grudl
  4. David Grudl #4

    avatar

    #3 Prochaine, $bar není konstanta, ale před-inicializovaná proměnná, kterou je možné měnit.

    Jsou nějaké nápady, PROČ je to 11 nebo 22 ?

    před 20 lety
  5. Martin Kopta #5

    Protože hodnota $bar se přiřadí do $foo->self->bar až ve chvíli, kdy je echovaná?

    před 20 lety
  6. Havran #6

    avatar

    Preto lebo & pred priradenim $this sposobi ze sa neurobi kopia $this ale sa len odkaze nan – cize vlastne $self === $foo (take volaco :D)

    před 20 lety | reagoval [8] David Grudl
  7. Havran #7

    avatar

    Ale je zaujimave co urobi toto $foo->self->self->bar = 22; :D Btw. print_r($foo) toho vela ukaze…

    před 20 lety
  8. David Grudl #8

    avatar

    Tak tedy: v čem je chyták? V tom, že PHP verze 4 vrací 11 a verze 5 vrací 22.

    Jak správně píše Havran #6 Havran, přiřazení $this->self = &$this; nevytvoří kopii objektu, ale referenci (něco jako odkaz). Tedy logicky by po nastavení $foo->bar=22; mělo mít hodnotu 22 i $foo->self->bar, neboť $foo a $foo->self je totéž.

    Proč tedy PHP verze 4 vypíše 11? Zrada se skrývá v $foo=new Foo(). Tady přiřazením vznikne kopie objektu! To je místo, ve kterém duplikování objektu ani španělskou inkvizici nikdo nečeká. Takže $foo obsahuje jinou instanci objektu, než na jakou referuje $foo->self.

    Aby k nevhodnému duplikování nedošlo a kód vypsal očekávatelných 22, je třeba před new přidat &. Tedy: $foo = &new Foo().

    Závěr: v PHP4 před klíčovým slovem new VŽDYCKY pište &.

    před 20 lety | reagoval [14] Havran
  9. Petr #9

    Na rozdíl od Reného hádanek u této nějak postrádám smysl.

    před 20 lety | reagoval [10] bear
  10. bear #10

    avatar

    #9 Petře, hlavně že tys odpověď hned věděl, že?

    Programátor nemůže hádat, co tak krátký a jasný kód udělá, musí to vědět! A jak vidíš, nevěděl to nikdo. A raděj se takovou věc naučím hádanlou, než tím, že budu tři hodiny hledat chybu v tisíci řádkách programu.

    před 20 lety | reagoval [11] Petr
  11. Petr #11

    #10 beare, Odpověď jsem hned nevěděl a ani mě nezajímá. Je to teoretický konstrukt, který kdyby použil nějaký člen mého programátorského týmu, tak to bude mít nepříznivý vliv na jeho výplatu (tím chci říct, že by se v praxi nemělo stát, že tisíce řádek kódu nebudou fungovat kvůli exhibici nějakého potrhlého programátora).

    před 20 lety | reagoval [12] David Grudl
  12. David Grudl #12

    avatar

    #11 Petře, Petře, je mi líto, že Vás hádanka nezaujala, příště bude třeba lepší 🙂

    Určitě ale nesouhlasím s tím, že jde o teoretický konstrukt. Vždyť v příkladu jde jen o užití objektu a reference. Tedy dvou nejčastěji používaných prostředků OOP programátora. A je dobré znát jejich limity.

    před 20 lety
  13. martinpav #13

    avatar

    Ja som odpoved vedel (vinimocne :) ), len som sa sem dostavil trosku neskoro. Nejake dalsie info sa da najst tu: https://web.archive.org/…/developers/…

    před 20 lety
  14. Havran #14

    avatar

    #8 Davide Grudle, Ahaaa :) Ze mi to hned nedoslo… Nevadi aspon som sa poucil.

    před 20 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.


phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.