Na navigaci | Klávesové zkratky

Translate to English… Ins Deutsche übersetzen…

PHP hádanka IV.

Minule jsem sliboval, že dnes bude něco těžšího. A taky že jo! I když se to zdá na první pohled jasné, zdání může klamat. Tak tedy, jakou hodnotu bude mít na konci skriptu proměnná $foo?

function setFoo(&$value) {
  global $foo;
  $foo = & $value;
}

$foo = 123;
$bar = 777;

setFoo($bar);

echo $foo;

Komentáře

  1. Mormegil #1

    Sakra, já teda do PHP nevidím a vidět nechci, ale je nějaký rozumný důvod, proč by to nemělo vypsat 777?

    před 12 lety
  2. Thom #2

    No, rozumný dôvod …
    Vyskúšané: vypíše to `123 `.

    před 12 lety | reagoval [3] johno
  3. johno http://johno.jsmf.net/ #3

    avatar

    #2 Thome, Ja nechápem ľudí čo to spustia a napíšu sem výsledok. Odskúšať si to vie hádam každý sám nie?

    Ja som bol tiež presvedčený, že to bude 777.

    před 12 lety
  4. David Grudl http://davidgrudl.com #4

    avatar

    nápověda: je dobré vědět, že global $foo; je ekvivalentní s $foo = & $GLOBALS['foo'];

    před 12 lety | reagoval [6] Mormegil
  5. martinpav #5

    avatar

    No pokial to dobre chapem tak :
    global $foo; – obsahuje referenciu na premennu $foo
    $foo = & $value; – priradi sa referencia na premennu $value ⇒ akakolvek priradena hodnota sa priradi premennej $value

    Ale je mozno ze trepem bludy, tak to potom radsej zmaz :).

    před 12 lety
  6. Mormegil #6

    #4 Davide Grudle, Ano, to je důvod. Za rozumný bych ho ale rozhodně neoznačil, spíš za důkaz, že PHP je zbastlenina jaksepatří. ;-) (Ale faktem je, že ten ampersand v přiřazení tam poněkud smrdí.)

    před 12 lety | reagoval [7] David Grudl
  7. David Grudl http://davidgrudl.com #7

    avatar

    #6 Mormegile, je to spíš problém všeobecné neznalosti toho, co jsou reference. Za to PHP nemůže. Zrovna včera jsem něco hledal v manuálu a narazil na tuto stránku What References Are Not, kde je zlehka podobný příklad.

    před 12 lety | reagoval [8] Mormegil [18] johno
  8. Mormegil #8

    #7 Davide Grudle, Já se nehádám (už jsem konstatoval, že do PHP nevidím (a vidět nechci)); tou prasárnou jsem neměl na mysli chování referencí, ale fakt, že „globální proměnné“ jsou ve skutečnosti reference na globální proměnné. Howgh.

    před 12 lety | reagoval [9] David Grudl
  9. David Grudl http://davidgrudl.com #9

    avatar

    #8 Mormegile, taky se nehádám ;-)

    Ale kdy určité chování nazývat prasárnou, a kdy feature? V tomto případě jde o dobře zdokumentovanou záležitost, zkušeným péhápéčkařům jistě známou, tedy nic špatného v tom nevidím. global prostě tvoří reference, přímý přístup lze realizovat pomocí pole $GLOBALS

    Srovnejte:

    $a = 123;
    
    function foo() {
      $b = 777;
      global $a;
      $a = & $b;
    }
    
    foo(); // $a je stále 123
    $a = 123;
    
    function foo() {
      $b = 777;
      $GLOBALS['a'] = & $b;
    }
    
    foo(); // a nyní je $a 777
    před 12 lety | reagoval [19] Mormegil
  10. Prochaine http://blog.cernosice.cz/ #10

    Proč ve všech podobných hádankách hraje roli reference (&), bez kterých jsem se v PHP dobré 4 roky obešel?

    před 12 lety | reagoval [11] Adam Hošek [12] David Grudl
  11. Adam Hošek http://mamuf.bloguje.cz #11

    avatar

    #10 Prochaine, Možná proto, že v jiných oblastech není z čeho dělat hádanky :). I když na druhou stranu třeba na dagblogu vychází i jiné úkoly… vymyslet třeba algoritmus s nejmenším počtem příkazů… Sice je to zpravidla javovsky orientované, ale stejné problémy lze zpravidla řešit i v PHP.

    před 12 lety
  12. David Grudl http://davidgrudl.com #12

    avatar

    #10 Prochaine, Už jsem si to taky říkal :-) Snažím se postupovat „didakticky“, zatím se vyhýbám funkcím, v hlavní roli jen čistý jazyk. I ten skýtá dost tajemných zákoutí.

    Ale na příště už mám připravenou hádanku bez jakýchkoliv referencí!

    před 12 lety
  13. Petr #13

    A kdy bude rozřešení??? Docela by mě zajímalo, protože mě zde jaksi uniká smysl…

    před 12 lety
  14. Petr #14

    Mohl byste mi prosím někdo vysvětlit, proč mi nefunguje následující kód:

    $x=1;
    $vysledek.=eval("\\$cache$x");

    proměná $cache1 je cookies, takto jsem jich měl uložených 35 a potřeboval je naskládat do výsledku.

  15. Petr #15

    #14 Petře, mělo tam být jen jedno lomítko

    před 12 lety
  16. David Grudl http://davidgrudl.com #16

    avatar

    #14 Petře, vůbec nechápu, proč tam používáte to lomítko?

    jinak zkuste $vysledek .= ${"cache$x"};

    před 12 lety | reagoval [17] Adam Hošek
  17. Adam Hošek http://mamuf.bloguje.cz #17

    avatar

    #16 Davide Grudle, #14 Petr Nebylo by mnohem jednodušší to naskládat do pole a pak s ním pracovat? :))). Trošku mi to připomíná takové ty příklady použití vykonstruované na nějakou vlastnost jazyka, přičemž se takové úlohy řeší běžně zcela jinak :)).

    před 12 lety
  18. johno #18

    avatar

    #7 Davide Grudle, Tak mi to nedalo a pozrel som do manuálu. Konkrétne na pasáž v What References Do a v nej je ako prvý warning vysvetlené správanie presne tohto príkladu.

    Finta je presne v tom ako si písal. global $var; totiž nesprístupní globálnu premennú, ale vytvorí lokálnu premennú rovnakého názvu, ktorá obsahuje referenciu na danú globálnu premennú.

    Pokiaľ by sme chceli zapisovať do tejto premennej tak sa mení obsah globálnej premennej – to je jasné. Ak však priradíme tejto lokálnej premennej refenciu na inú premennú tak vlastne zrušíme väzbu na globálnu premennú.

    před 12 lety | reagoval [20] Squad_leader
  19. Mormegil #19

    #9 Davide Grudle, Jistěže to je feature, navíc dokumentovaná. Ale jakou výhodu mi ta konstrukce poskytuje? Možnost v druhé půlce funkce používat stejný název globální proměnné pro něco úplně jiného než v půlce první? A opravdu to je něco, co chci? TO je to, proč říkám, že to je prasárna, prostě se vymyslel nějaký obskurní způsob, jakým dosáhnout něčeho, co se po většinu času chová tak, jak očekávám po zkušenostech odjinud. Asi jako další způsoby, jak do jazyka dostat něco, co tam není.
    Ale nic ve zlém, PHP, na mých pár jednoduchých skriptů tě taky používám. :-)

    před 12 lety
  20. Squad_leader #20

    #18 johno, Přiznám se toto jsem nevěl. Už vím proč jsem u jednoho programu vybuchl a stahl se na ústup.

    před 10 lety
  21. Arthur Dent #21

    #14 Petře, Pro inspiraci:
    $x=1;
    $promenna='cache'.$x;
    $vysledek=$$promenna;

    před 10 lety

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