Klonování, PHP4 a jeden hack
Kvůli převaze hostingů podporujících PHP jen do verze 4,
programuji zatím stále v této překonané verzi. A je to občas utrpení,
cpát všude & a přitom vědět, že v PHP 5 už
nemusím.
Nicméně programovat v PHP 4 se dá s vědomím dopředné kompatibility, už jsem o tom jednou psal. Dnes jsem však narazil na zajímavý oříšek.
Potřeboval jsem naklonovat objekt, říkejme mu třeba $dolly.
PHP4 má tendenci klonovat jakýkoliv objekt, který mu přijde pod ruku. Tedy
stačí napsat $klon = $dolly a je hotovo. Protože však
klonování není přesně to, co programátor v naprosté většině
případů očekává (a navíc je to v Evropské unii zakázané), je třeba
v přiřazení použít symbol reference: $klon = & $dolly.
PHP5 tuto nutnost eliminuje a zápis $reference = $dolly vytvoří
automaticky referenci. Ale to už určitě dávno víte.
Kompatibilní klonování
Dobrá, a co když skutečně chci v PHP5 $dolly naklonovat?
K tomuto účelu slouží zcela nová konstrukce:
$klon = clone $dolly;
Bohužel, PHP4 si na tomto zápisu vyláme zuby, ohlásí Parse error a odporoučí se do věčných lovišť. A teď babo raď, jak napsat kód, který by fungoval v obou verzích?
První myšlenka byla příkaz do zdrojového kódu vložit jako řetězec
(vyhnout se parseru) a pak jej spustit přes eval(). Ale nakonec mě napadlo, že přece
zápis $dolly a ($dolly) je ekvivalentní.
Ozávorkováním nic nezkazím. Takže v PHP5 lze klidně napsat také:
$klon = clone ($dolly);
A co na to PHP4? Ve své dětinské naivitě myslí, že tímto zápisem volám funkci clone(). Takže parse error je zažehnán a stačí jen deklarovat funkci clone(). Samozřejmě jen pro PHP verze 4:
if (PHP_VERSION < 5) eval('
function clone($obj)
{
return $obj;
}
');
That's all folks…
PHP hádanka VI.: zjištění názvu třídy
V těchto věcech si nejsem nikdy jist a občas si musím napsat modelový
miniprográmek, abych věděl, jak se PHP zachová. V uvedeném příkladu
vypisuji název aktuální třídy pomocí funkce get_class($this)
a „magické“ konstanty __CLASS__. Konstanta má tu výhodu, že
ji lze užít i ve statické metodě (tam není definováno
$this). Otázka je, jestli i ve zděděné třídě vypíší
totéž. Tak co, programátoři?
class A {
function showClassName() {
echo get_class($this) . ' ' . __CLASS__;
}
}
class B extends A {
}
$foo = &new B();
$foo->showClassName();
PHP hádanka V.
Dnešní pondělní hádanka se týká bitových operací. Následující skript zjišťuje
pomocí logického součinu přítomnost druhého nejnižšího bitu
v proměnné $foo. Jenže vrací opačné výsledky, než by se
očekávalo. Kde je chyba?
// pro 1
$foo = 1;
// čekám false, ale vrací true!
$isSet = ($foo & 2 == 2);
// pro 2
$foo = 2;
// čekám true, ale vrací false!
$isSet = ($foo & 2 == 2);
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;
PHP hádanka III.
Je pondělí a s ním „pravidelná“ hádanka pro PHP kódéry. Chtěl jsem původně přijít s něčím složitějším, ale nechám si to na čtvrtek, přece jen po víkendu hlava ještě tak nepracuje.
Dnešní otázka tedy zní: jakou hodnotu bude mít $a?
$a = 123;
$b = & $a;
$a = & $b;
echo $a;
novější články
