Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

PHP 4.4.0 krokem zpátky + skorotrik

Popisovat vadný OOP model v PHP4, který objekty místo předávání kopíruje, snad netřeba. Pokud nevíte, o čem hovořím, mrkněte do dokumentace. Tato nepříjemnost se řeší naužíváním znaku &. Ten je potřeba použít při:

  • vytváření objektu $object = &new MyClass()
  • přiřazení objektu $objectB = & $objectA
  • předávání objektu funkci function doIt(& $object)
  • vracení objektu funkcí function &getInstance()
  • a volání takové funkce $object = &getInstance()

Při předávání objektu funkci navíc přicházíme o možnost určit výchozí hodnotu – nelze psát function doIt(&$object = null) a komplikuje se vkládání přímých hodnot – doIt('ahoj') je třeba psát jako doIt($var = 'ahoj'). V některých případech ani & nepomůže (např. list() nebo foreach) a je třeba použít speciální konstrukce.

Programátor v PHP4 se s tím naučil žít. Jenže přišlo PHP 4.4.0 a to mu hodilo další klacek pod nohy. Následující konstrukce nově generuje chybu Notice: Only variable references should be returned by reference.

function &factory()
{
    return new MyClass();
}

A jako správné se považuje

function &factory()
{
    $php_4_sucks = &new MyClass();
    return $php_4_sucks;
}

Tedy jako běžné se stanou tyto konstrukce $false = false; return $false;. To je mazec, co?

Co to zkusit zcela jinak?

Docela dlouho jsem přemýšlel, jak celou tu ampersárdnu elegantně obejít. Jak psát PHP5-like skripty, aby jim čtverka rozuměla. Něco mě sice napadlo, ale je to stále řešení na půl cesty.

Aktualizováno 5. 8. 2005

Zde publikovaný způsob jsem nakonec zavrhl a vymyslel elegantnější řešení, viz spot PHP4: zbavme se ampersandů II.

napsáno 24. 7. 2005 | shlédnuto 8814x | nahoru


Komentáře RSS 2.0 komentářů » přidat

avatar

#1 rarous http://rarous.aspweb.cz nový

asi bych se na to vykašlal a odešel od PHP ;) Ale takový řešení asi nečekáte, že?

Posláno 24. 7. 2005 v 10.14 | Odpovědět
Na komentář reagoval [2] Mark
avatar

#2 Mark nový

#1 rarous: k MS Windows only ASP ? ne tak na takove rozhodnuti bych musel byt s PHP opravdu hodne nespokojeny (nechat si ufiknout kridla jen pro prislib cersvejsiho vzduchu:-) navic sve skripty v novych projektech uz takrka vyhradne nasazuji PHP5 preprocesor namisto ctyrkovych verzi, a to je uz trochu jine kafe ..

Posláno 24. 7. 2005 v 10.29 | Odpovědět
avatar

#3 rarous http://rarous.aspweb.cz nový

:)) o ASP nemluvim… .net je úplně něco jinýho a navíc neni Windows only, ale, komentář jsem nepsal kvůli flame ;) spíš jako pobavení.

Jinak jsem rád, že se někdo zajímá o OOP v PHP a Davidova práce se mi opravdu líbí, je vidět, že je to člověk, kterej tomu rozumí, takových by bylo potřeba mnohem víc ;)

Prosím, nereagujte na tento komentář ohledně .netu

Posláno 24. 7. 2005 v 10.38 | Odpovědět

#4 Arthur Dent nový

Je jistě spousta jiných řešení. Třeba Python. Nebo PERL – jediný jazyk, u kterého zdrojové kódy programů vypadají stejně, i když je zašifrujete algoritmem DES3.

Ale PHP je asi jediný „normální“ skriptovací jazyk, kde „normálním“ myslím „vypadající jako C nebo Pascal“.

S ASP jsem chvíli dělal. Asi rok. A po pravdě řečeno – ono vás brzy přestane bavit, když na každou kravinu potřebujete nějakou WIN komponentu a zjistíte, že ty WIN komponenty jsou v 90% případů „commercial“.

Po pravdě řečeno – proti výhodám ASP jsou ty nejhorší vlastnosti PHP ještě pořád skvělé.

Posláno 24. 7. 2005 v 10.39 | Odpovědět
Na komentář reagoval [6] David Bures

#5 Nai Dzet Quiv nový

Hmm, a to jsem včera „upgradoval“ na PHP 4.4.0 (s PHP5 jsem se ještě nestačil obeznámit :-) ).

Posláno 24. 7. 2005 v 11.38 | Odpovědět

#6 David Bures http://www.websky.cz nový

#4 Arthur Dent: on uz to psal rarous, ale rozdil mezi ASP a .NETem je asi takovy jako mezi programovanim a psanim skriptu ;)

Posláno 24. 7. 2005 v 18.15 | Odpovědět
Na komentář reagoval [7] Arthur Dent

#7 Arthur Dent nový

#6 David Bures: Ono to totiž není na první pohled vidět, ale já reagoval na 1 a 2. Když se podíváš na čas přidání příspěvku, tak zjistíš, že jsme s Rarousem reagovali nastejno… Takže teď už ti možná došlo, že nepíšu o .NET, ale o ASP. A to mi připadá blbé, ať už jej pohání JScript, VBScript, C#, J# nebo command.com…

Posláno 24. 7. 2005 v 18.57 | Odpovědět
avatar

#8 rarous http://rarous.aspweb.cz nový

Doporučuju přečíst něco o projektu MONO, nebo o projektu Phalanger, možná vám to pomůže rozšířit si obzory… Ostatně samo PHP5 se snaží ASP.NET nebo JSP dohnat nebo alespoň se jimi inspirovat… ;)

Posláno 24. 7. 2005 ve 21.15 | Odpovědět
avatar

#9 David Grudl http://davidgrudl.com nový

Prosím, ukončete debatu o jiných jazycích než je PHP.

Snažím se rozlousknout způsob, jak dnes psát v PHP4 skripty, které za cca půl roku snadno přehodím na PHP5 – tedy rád bych se zbavil ampersandů. Uvedený nástin v článku ukazuje, že to teoreticky lze. Pokud budete mít nějaký nápad k tématu, neváhejte jej napsat.

Posláno 24. 7. 2005 ve 21.43 | Odpovědět
Na komentář reagoval [13] rane

#10 markon http://blog.air4web.com/ nový

PHP4 i PHP5 má ještě jednu naprosto bezvadnou vlastnost, když si přečteš hodnotu hlavičky IF_MODIFIED_SINCE, tak po druhé ji nelze přečíst, třeba
echo $_SERVER[‚IF_MO­DIFIED_SINCE‘];
echo $_SERVER[‚IF_MO­DIFIED_SINCE‘];

vydává v PHP opravdu zajímavý výstup. Nebo ideální je

if(empty($class->$fce()))

taky nejde a navíc je to prý vpořádku

PHP má spoustu bugů, ale oproti jiným programovacím jazykům je znatelně lepší.

Posláno 24. 7. 2005 ve 23.58 | Odpovědět
Na komentář reagoval [11] Jakub Vrána

#11 Jakub Vrána http://php.vrana.cz/ nový

#10 markon: Asi jste měl na mysli spíš $_SERVER["HTTP_IF_MODIFIED_SINCE"]. Za jakých okolností se tahle chyba projevuje? Mě se ji nepodařilo zreprodukovat.

Mimochodem, lepší místo pro hlášení takovýchto chyb je http://bugs.php.net/.

Posláno 25. 7. 2005 v 11.21 | Odpovědět

#12 Ebo nový

Já bych radši zase čmáral omalovánky :-)

Posláno 25. 7. 2005 ve 13.09 | Odpovědět

#13 rane http://metatribe.org nový

#9 David Grudl: no ja mam napad: pol roka nerob nic, a potom mozes rovno pisat v php 5 :)

Posláno 25. 7. 2005 ve 13.15 | Odpovědět
Na komentář reagoval [14] David Grudl
avatar

#14 David Grudl http://davidgrudl.com nový

#13 rane: Ani nevíš, jak rád. Půl roku bych nedělal nic a pak bych si to zopakoval ;)

Posláno 25. 7. 2005 ve 13.41 | Odpovědět

#15 Michal nový

No neřekl bych, že je to chyba jako taková, když se to hlásí jako Notice: Only variable …

Sice jsem to nezkoušel, ale script se nezastaví a normálně se provede, ne?

Posláno 25. 7. 2005 ve 22.02 | Odpovědět
Na komentář reagoval [16] David Grudl
avatar

#16 David Grudl http://davidgrudl.com nový

#15 Michal: jde o chybovou hlášku úrovně E_NOTICE, tedy nepozastaví vykonávání skriptu.

Posláno 25. 7. 2005 ve 23.30 | Odpovědět
avatar

#17 lukas nový

A nevite, jak se zbavit toho $false = false; return $false? Mam treba funkci, ktera mi nacte parametr modulu v CMS (coz muze tahat ze spousty mist jako XML, databaze nebo HTTP query – zalezi to na situaci). Ten parametr se tedy musi vracet pres referenci (protoze je to nekdy velka promenna). Ale potrebuju mit taky moznost, aby ta funkce umela rict „smula kote, zadny parametr nebyl zadan“ a vratit false. Jedine me napadlo deklarovat promenou $false jako globalni, to bych sice pak uz mohl psat trosku hezci „return $false;“ jenze zase bych si ji musel ve funkci zavolat pres global $false;

Posláno 2. 8. 2005 ve 3.32 | Odpovědět
Na komentář reagoval [18] David Grudl
avatar

#18 David Grudl http://davidgrudl.com nový

#17 lukas: Ten parametr se tedy musi vracet pres referenci (protoze je to nekdy velka promenna).

PHP má kopírování proměnných celkem vychytané a fyzicky k němu nedojde, dokud se jedna z proměnných nezmění. Třeba tento příklad až do posledního kroku si vystačí s 10MB RAM:

function test($var) {
  return $var;
}

// alokuj 10MB
$s1 = str_repeat('a', 1e7);

$s2 = test($s1); // nějaká činnost

// stále je fyzicky alokováno jen 10MB!

$s2{1} = 'b';  // změníme proměnnou

// teprve nyní je zabráno 20MB

Zajímavé je také to, že předávání referencí je v podobných případech dokonce pomalejší! Pokud byste v uvedeném příkladě deklaroval funkci jako test(&$var), vykonávání by bylo 10.000× pomalejší. Ale to je samozřejmě extrém…

Posláno 2. 8. 2005 ve 3.55 | Odpovědět

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

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2012 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

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