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.
Komentáře
Adam Hošek #1
Nešlo by odstranit whitespace úplně? Totiž, jestli by to nevadilo tomu sešrinkovanýmu skriptu. Ještě více by se ušetřilo na velikosti a bylo by to snad ještě méně čitelnější.
Leo #2
No nevim, neni to uz trochu uchylarna? 🙂 Nepovolane osoby nemaji co zdrojaku koukat, jak se k nemu dostanou tak je pozde. Komentare a bila mista ve zdrojaku podle me nejsou pro rychlost zpravovani vubec rozhodujici, a nahravani na server… bez komentare, Leo
votok #3
Podle me je to pekna blbina. Daleko lepsi je prehlednejsi zdrojak nez nejaka milimili uspora mista nebo casu.
David Grudl #4
#1 Adame Hošku, úplně ne, ale algoritmus jsem lehce upravil a je o něco účinnější
#2 Leo, #3 votok tak to prostě nepoužívejte! Pokud tě Votoku nenapadá uplatnění, proč hned označuješ nástroj za blbinu? To sis mohl v dětství klidně ustřihnout koule ;)
llook #5
Když nastane chyba v redukovaném zdroji, tak se dost blbě hledá – všechno je na jedné řádce.
Ideál bych viděl takový:
Kdysi jsem něco podobného zkoušel implementovat, redukovalo to i názvy proměnných a funkcí, ale tehdy jsem o PHP věděl tak strašně málo, že je z toho použitelný už jen ten nápad.
rony #6
hm a Ctrl-A, Del nepomaha?
Llaik #7
Spis VGd, ne? :)
David Grudl #8
#5 llooku, vůbec nepředpokládám, že by ten redukovaný soubor ještě někdo editoval. Já to používám u kompaktní varianty Texy, protože nahrát na web 160kB ve 25 souborech je něco jiného, než jeden 75kB soubor. Během uploadu je totiž chování webu nedefinovatelné, jde o kritické místo. Měřením jsem si ověřil, že mírně naroste i výkon, což bylo pro mě překvapením a považuji to spíš za perličku.
Jako prostředek utajení bych spíš použil Zend Encoder (legálně i za cenu hostingu). Tento nástroj jen čtení ztíží, ale natolik, že bez nějakého ‚source beautifuleru‘ je nemožné. Nicméně komentáře už nevrátí nic.
Tímto skriptem jsem chtěl spíš ukázat, že úkol lze efektně řešit i bez napsání složitého parseru.
#6 rony, Zkusil jsem, je to velmi efektivní, ale nezachovalo mi to původní funčnost 🙂
hvge #9
Pekne, predpokladam, ze tam uz staci len dopisat case pre T_REQUIRE_ONCE a rekurzivne dosadit obsah toho file (pokial nie je zrovna variabilny)…
hvge #10
David Grudl #11
#9 hvge, přesně tak 🙂
votok #12
#8 Davide Grudle, dgx: No to bych nerad! Takze jestli to chapu, zdrojaky mas porad velky, akorat pred nahranim na ostrou to prozenes timhle filtrem. To se muze hodit. Ja chtel jen zachranit mlade vyvojare pred odstranovanim svych komentaru :)
martinpav #13
No niekde som videl obfuscator pre PHP v php. Myslim ze ho mam aj odlozeny ale nemal by byt problem najst ho znova. Mal nejake chybicky (nezvladal HEREDOC) ale pouzit sa dal.
Inak pred casom som tiez skusal aky vlyv ma velkost scriptu na jeho beh a dospel som k podobnemu vysledku ako dgx. Da sa tam trosicka usetrit na case ale jedna zla query to v pohode dozene.
Nai Dzet Quiv #14
Hmm. Možná se to pro Texy! a podobné nástroje hodí, ale pro „normální“ (;-) ) skripty ASI ne. Musím souhlasit s Leem. Editace bude problematická. A do skriptů mi nebude (snad) nikdo čumět.
benny #15
#14 Nai Dzete Quive, ach jo, to nechápeš, že už to editovat nepůjde? A zajímalo by mě, jak víš, že ti nikdo (třeba správce hostingu) do skriptů nekouká. hehe 🙂
OttY #16
Mne sa páči riešenie menom TruckMM cache, ktorý ma na hostingu na starosti to, ze drží v RAM server posledne spustené PHP skripty. Keď som posledne pozeral server kde hostujem, tak v cache boli 195 skriptov. Zrýchlenie je zjavné, keď sú skripty v RAM 🙂
gregor #17
ja to dobra vec, hlavne ak to znizy rychlost skriptov…Ale ked php suborov mam co ja viem 50 tak osobitne robit kazdy subor, je dost o drzku…
Mozno by som tam pridal moznost urcit nieco ako document root (napr. /) a spustit skript.
Ten by prehladal vsetky podzlozky a kazdy subor s koncovkov php by upravil a ulozil do urcenej zlozky pricom by zachoval stromove poradie suborov… mozno velmi zlozite ale dobre…
lukas #18
Je to hezky, diky za tip na tu funkci (a vubec cely tokenizer), ale IMHO je to k nicemu.
>> Zrychlí se nahrávání na server
Nahravani na server trva nejakou dobu? Osobne krome zdrojaku posilam na server i graficke navrhy ve Photoshopu a Corelu (tak 10MB) a to jen proto, ze jsem liny v Total Commanderu odoznacit slozku „podklady“.
>> mírně i provádění
To velmi pochybuji. Nedela to PHP tak, ze vezme zdrojak preparsuje si ho a ulozi nekam v citelnejsi podobne (kde uz treba mezery roli nehraji)? Krk bych za to nedal, ale proc by mi jinak prvni vykonani skriptu vzdycky trvalo o neco dele nez vsechny nasledujici?
>> a program se stane hůře čitelný pro nepovolané osoby.
Automaticke zformatovani snad maji vsechny editory.
LLaik #19
No porovnej si rychlost Smarty a nasledne Smarty orezane o komentare.
Zalezi na konfiguraci PHP, ale v nejake „ciste“ podobe to vliv jednoznacne ma.
PHP neni cecko :)
lukas #20
Ja se ptal na PHP, ne na sablony. I kdyby to nejaky vliv melo (jako ze nevim), tak by to bylo porad jen linearni zrychleni s mizivym koeficientem.
David Grudl #21
#18 lukasi, nahrávání na server je velmi kritická záležitost. Už jsem to tu psal jednou – pokud aktualizuji knihovnu, který má třeba 20 souborů, při nahrání části z nich je chování aplikace nepředvídatelné. A co když v tuto chvíli spojení klekne a třeba hodinu nepojede?
Proto jsem u Texy přišel s jednosouborovou „zminimalizovanou“ verzí. A jak správně vytušil #9 hvge, ke generování používam upravený algoritmus ze článku. Nebudu jej tu uvádět, ať si každý naprogramuje sám, nemám zájem o další spršku komentářů jako „je to k ničemu“, „je to blbost“ a podobně.
llook #22
#21 Davide Grudle, Tohle ale musím potvrdit. Taky už jsem se dostal do situace, kdy jsem měl připojení jen z počítače se špatně nastaveným firewallem, takže FTP nefungovalo.
Nahrávat 20 souborů přes formulář je fakt na sebevraždu. Přemýšlel jsem o napsání něčeho na způsob shar archívů, ale v PHP. Jenže mezitím se moje konektivitní problémy vyřešily.
Gagarin #23
… „(velmi, velmi) mírně zrychlí provádění“…
U PHP skriptu dejme tomu o sto řádcích se provádění nezrychlí více než o jednu stotisícinu vteřiny, to jen aby nějaká lama nezačla takto komprimovat skripty jen a pouze za účelem zrychlení.
von Banhoff #24
vždycky když si dovolím smáznout nějakou prázdnou řádku našemu coderovi, tak se může – to nevidí rád – prohnat mu to tou tvojí fcí, tak ho asi na místě :)
Llaik #25
Ja mluvim o PHP. Nemluvil jsem o parsovani sablony, ale o parsovani ktere dela PHP interpret s php skriptem. Smarty jsem jako priklad pouzil proto, ze je to vcelku velky skript a jeho opravdu nezanedbatelnou casti jsou komentare – tj. pokud je odstranis, vyrazne tim snizis velikost skriptu.
Ted jsem si na lokalni masine profil jednoduchy php skript pouzivajici jako priklad Smarty – naparsovani skriptu trvalo 75%, zbylych 25% celkoveho casu pak trvalo uz samotne provadeni skriptu.
Tj. cas vynalozeny interpretem PHP na pouhe naparsovani vasich php skriptu (aby mohly byt provedeny) neni v zadnem pripadne zanedbatelny.
LLaik #26
Jinak vtipna praxe – mel jsem nejaky pomaly skript, trval cca 0.2s vteriny. Kdyz jsem zrusil odsazeni cca 200 radku, trval 0.002s. Vratil jsem odsazeni, trval 0.2s…
vzal jsem jiny skript a odsadil kazdy z 200 radku o 1000 mezer doprava – zadna zmena.
Doted je to pro me hezka zahada, kde asi co preteklo (?), ze to trvalo tak dlouho? Kazdopadne muj instalacni skriptik rusi vsechny prebytecne blank znaky, at ma duse klid :)
Ladis #27
#16 OttY, TruckMM cache umí nejen to. Umí taky spouštět (vlastním algoritmem) zakódované PHP soubory jako Zend Safeguard, ale navic je ZDARMA!
BTW. uz to neni TruckMM cache ale EAccelerator.
spaze #28
#22 llooku, nejaky arxivz pro PHP jsou.. bud v PEAR, bo v PECL se neco najde.
medden #29
Mimochodom, akurát som si v php manuáli všimol funkcie php_strip_whitespace, ktorá fakticky robí to, čo uvedený zdroj, aj keď si niečo myslím o tom takýto balast dávať do php…
David Grudl #30
#29 meddene, ano, od PHP5 na to existuje funkce. Kupodivu však neredukuje tak účinně, jako tento skript.
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.