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.
Dávám PHP4 rok, maximálně dva
To jsem si říkal v loni, když vyšlo PHP verze 5. Byl jsem
skeptický, neočekával jsem jeho brzké nasazení na placených hostinzích.
Dnes vidím, že jsem byl skeptický málo. Budou to spíš roky dva.
Proč má PHP5 stále tak malou podporu? Faktem je, že předělávat
existující a především fungující skripty jen kvůli tomu, že kdesi
vymysleli nové PHP, je nesmysl (stejně jako přepisovat hotové stránky
z HTML 4.01 do XHTML). A hostéři by k tomu neměli své klienty nutit.
Prostě do fungujících věcí se nešahá. Někdy je nebezpečné vymetat
i pavučiny, člověk neví, která co drží, která je ta nosná
Jenže stále se píše spousta nových skriptů, pro které by PHP5 představovalo zásadní přínos. Bohužel, bez masivní podpory hostingů si pětkový luxus nemůže spousta vývojářů dovolit. Myslím především vývojáře OpenSource aplikací. Z tohoto pohledu jsou to právě hostéři, kdo brzdí pokrok.
Je skutečně takový problém nabídnout klientům volbu mezi verzí 4 a 5?
p.s. jedno pozitivum to ale má: až většina hostingů začne pětku nabízet, nebude to už 5.0, ale 5.1 nebo 5.5.
Jak zabít procesor
Nedávno jsem uvažoval, jak pracuje takový překladač PHP. Napadlo mě napsat zdrojový kód, který by jej odstřelil. V případě PHP4 se mi to povedlo – stáhněte si a vyzkoušejte tento příklad. PHP5 už umí vstupní data ošetřit lépe a namísto smrti ohlásí Parse error: parser stack overflow (pro pětku použijte upravený příklad).
Na webové prohlížeče lze zaútočit i na další frontě. Například je nechat zobrazit extrémně velký obrázek. Pro experiment bude stačit bitmapa o velikosti např. 1024×768, ke zvětšení použijeme HTML:
<img width="9000000" height="9000000"
src="wallpaper.jpg" />
Jak si s tím poradí trojlístek IE, Firefox a Opera? První dva jmenovaní se pokusí vyhovět zadání a počítač vytíží natolik, že bude připomínat mrtvý stroj (zkuste zarolovat). Opera rozměry zdaleka nedodrží (má limit někde kolem 30.000 pixelů) a k přetížení nedojde. Co je důležité, žádný z prohlížečů nezačne bezhlavě alokovat kvanta paměti a vždy jen přepočítá zobrazovaný výřez.
Můžete si to sami vyzkoušet – ale klikejte jen s vědomím všech rizik!
Ještě dodávám, že testy jsem dělal na Windows 2000 SP4 s Apache 2.0.48, PHP 4.4.0 & 5.0.4, IE 6 SP1, Firefoxem 1.0.4 a Operou 8.01. Jinde se může chování lišit.
Když je spoluautorem automat
Nemám rád automaticky generované vysvětlivky. Tím myslím strojové podtržení určitých zkratek (např. HTML nebo CSS) a doplnění o vysvětlivku v title. Dopadá to asi takto:
Ta přednáška o prasatech je v HTML a najdeš ji na adrese http://www.la-trine.cz/HTML/kscm.php – tak se na to podívej.
Tato „feature“ nepřináší čtenáři žádnou přidanou hodnotu. Spíš naopak, odpoutává pozornost od textu. Autor by měl vědět, pro koho píše a sám se rozhodnout, jestli je třeba zkratku vysvětlit, kde tak učinit a jakým způsobem. Tohle automat nevymyslí.
Bohužel, spoustě uživatelů připadá jako skvělý nápad si do svého CMS automatický vysvětlovač nainstalovat. Vážně si myslíte, že člověka nechápavě hledícího na zkratku CSS, přivede title=Cascading Style Sheet k prozření? Nebo že v pojednání o plovoucích boxech je nutné čtenáři význam CSS připomenout?
p.s. Počítačoví odborníci, víte, co znamená PCI?
Jak zredukovat PHP skripty?
Občas je třeba zmenšit PHP skripty na minimum. Odstranit komentáře, zredukovat bílé místo. Zkrátí se doba nahrávání na server, mírně zrychlí provádění a program se stane hůře čitelný pro nepovolané osoby.
Existují sice nástroje, které tento úkol řeší téměř dokonale (Zend Encoder, SourceGuardian atd.), mají však svá „ale“. Buď v podobě závratné ceny, specifických nároků na hosting, nebo v prostém zatajení faktu, že existují i zpětné dekodéry.
Ukážu vám jeden směšně jednoduchý postup, jak vypustit ze skriptů
zbytečné znaky. Používám jej pro texy-compact.php, kde
dosahuji úspory cca 50% velikosti. A v žádném případě to neovlivní
jeho funkčnost.
// Dgx's PHP shrinker
// PHP 4 & 5 compatibility
if (!defined('T_DOC_COMMENT'))
define ('T_DOC_COMMENT', -1);
if (!defined('T_ML_COMMENT'))
define ('T_ML_COMMENT', -1);
// read input file
$input = file_get_contents('script.php');
$space = $output = '';
$set = '!"#$&\'()*+,-./:;<=>?@[\]^`{|}';
$set = array_flip(preg_split('//',$set));
foreach (token_get_all($input) as $token) {
if (!is_array($token))
$token = array(0, $token);
switch ($token[0]) {
case T_COMMENT:
case T_ML_COMMENT:
case T_DOC_COMMENT:
case T_WHITESPACE:
$space = ' ';
break;
default:
if (isset($set[substr($output, -1)]) ||
isset($set[$token[1]{0}])) $space = '';
$output .= $space . $token[1];
$space = '';
}
}
// write shrinked file
fwrite(
fopen('output.php', 'w'),
$output
);
Nevím, jestli to potřebuje podrobnější komentář, každopádně hlavní magie se skrývá ve funkci token_get_all, kterou doporučuji nastudovat.
novější články
