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

Translate to English… Ins Deutsche übersetzen…

PHAR - PHP v kompaktním balení

Je tomu právě tři a půl roku, kdy jsem distribuci Texy doplnil o tzv. kompaktní verzi. Zjednodušeně se dá říci, že jde o skript vzniklý spojením všech souborů tvořících knihovnu do jednoho jediného a vynecháním komentářů a nadbytečných mezer. Výsledkem je funkčně identický kód, jen s krapet hustší konzistencí. (Prostě je hustéééj. Jak Salko!)

Záměrem bylo zjednodušit nahrávání knihovny na server – uploadovat desítku malých souborů přes FTP bývá značně pomalejší, než nahrát soubor jeden. Jako vedlejší efekt se ukázalo, že jednosouborová knihovna znatelně zvyšuje výkon aplikace – klidně o 30 %. Používání kompaktních verzí se ujalo a od té doby většina bugreportů hlásila chybu na řádce 1 :-)

S příchodem jmenných prostoru v PHP 5.3 se generování kompaktních verzí poněkud zkomplikovalo – zatím totiž platí, že jeden soubor může obsahovat jen jeden jmenný prostor už to neplatí. To znamená, že „jednosouborová“ verze bude mít přinejmenším tolik souborů, kolik je v knihovně jmenných prostorů, plus případné další soubory řešící problémy se vzájemnou závislostí mezi prostory.

Zároveň však PHP 5.3 přichází s novinkou, která si klade za cíl vnést do kompaktních verzí nový svěží vítr: PHAR – PHP archive. Ostatně myslím, že promluvím za nás všechny, když řeknu: nemusí pršet, hlavně když kape!

Jak takový PHAR balíček vytvořit? Nejprve je nutné v PHP.INI zapnout extension=php_phar.dll a nastavit direktivu phar.readonly = Off. Následující kód zkonvertuje celý Nette Framework do souboru nette.phar

$phar = new Phar('nette.phar');

$phar->buildFromDirectory('libs/Nette'); // enter here path to Nette

$phar->setStub("<?php
Phar::mapPhar('nette.phar');
require 'phar://nette.phar/loader.php';
__HALT_COMPILER();");

$phar->compressFiles(Phar::GZ); // or Phar::BZ2

Nejprve se vytvoří nekomprimovaný archiv ze všech souborů v určeném adresáři a jeho podadresářích – jde o obdobu TAR archivu. Následně se definuje tzv. stub neboli zaváděcí program. Jeho úkolem bude načíst soubor loader.php, který je součástí Nette Frameworku a nalézá se vlastně uvnitř PHAR archivu. Stub musí být ukončen zvoláním __HALT_COMPILER(). Poté je možno archiv zkomprimovat.

Příklad použití:

require 'nette.phar';

echo Html::el('strong')->setText('It works!');

Vypadá to báječně, že? Ovšem podívejme se na věc podrobněji. PHP skripty nejsou v archivu nijak minimalizované, nejsou z nich odstraněny zbytečné komentáře ani mezery. To je potřeba udělat ručně. Takže zatímco komprimovaný nette.phar má nějakých 180 kB, stejný archiv vygenerovaný z kompaktní verze Nette (tj. místo adresáře libs/Nette použijeme libs/Nette.compact) váží pouhých 50 kB. Nicméně pokud si uvědomíme, že

  • minimalizace kódu vede k rychlejšímu parsování (závislost bude dost možná lineární)
  • dekomprimace naopak nutně zpomaluje

dojdeme k závěru, že ideální bude generovat PHAR rovnou z kompaktní verze a ukládat jej nekomprimovaný. Nojo – ale proč teda rovnou nezůstat u kompaktní verze? Bez PHAR režie navíc?

Důvod existuje. Kompaktní verze se vždy načte celá, zatímco PHAR lze parsovat a kompilovat po částech. Takže Zend Framework bude vhodnější zabalit do PHARu, u dibi nebo Texy si můžeme dovolit plný výkon kompaktní verze.

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

avatar

#1 Martin Malý http://www.misantrop.info nový

Nejpozději s uvedeném téhle novinky přijde kdosi s nápadem zPHARovat front controller i všechny další controllery a vytvořit vlastně jeden takový mohutný index.php, který bude obsahovat logiku pro celou aplikaci… bože… takovou novinku unesou programátoři maximálně třikrát za deset let!

Posláno 2. 9. 2008 ve 3.45 | Odpovědět
Na komentář reagoval [2] David Grudl
avatar

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

#1 Martin Malý: Myslíš tohle?

Posláno 2. 9. 2008 ve 3.50 | Odpovědět

#3 kukulich http://citaty.kukulich.net nový

„…zatím totiž platí, že jeden soubor může obsahovat jen jeden jmenný prostor…“

To není pravda, i v současné verzi jmenných prostorů bez složených závorek může být v jednom souboru více jmenných prostorů. Původně to opravdu bylo tak, jak je v článku uvedeno, ale kvůli různým frameworkům (myslím, že zmiňovali především Symfony) bylo povoleno více jmenných prostorů v jednom souboru. Ale právě proto se začalo znovu uvažovat o syntaxi se složenými závorkami.

Posláno 2. 9. 2008 v 9.39 | Odpovědět
Na komentář reagoval [5] David Grudl

#4 pmg nový

jde o obdobu TAR archivu

Mělo by smysl jednotlivé soubory před archivací předkompilovat?

Posláno 2. 9. 2008 ve 14.11 | Odpovědět
avatar

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

#3 kukulich: máš pravdu, v poslední verzi to skutečně jde. Ačkoliv stále nemůže být v jednom souboru kód bez jmenných prostorů a kód s nimi.

Posláno 2. 9. 2008 v 18.39 | Odpovědět
avatar

#6 OndroNR o_galbavy@atlas.sk nový

a co autoload? moc sa v tom nevyznam

Posláno 2. 9. 2008 ve 21.05 | Odpovědět
avatar

#7 A. http://www.adamh.cz nový

Vypadá to zajímavě, už se těším, až si do PHARu zabalím ZF. Díky :-)

Posláno 3. 9. 2008 v 7.02 | Odpovědět
avatar

#8 Jan Tvrdík jan.tvrdik@gmail.com nový

Jaká by byla rychlost např. Texy!, kdyby se „zkomprimovali“ jednotlivé soubory zvlášť a nebalily se všechny dohromady? Pokud jsou totiž sbaleny v jednom souboru, tak je tam obsažen i kód, který se nemusí využít. Pokud by byly zabaleny samostatně, tak by se nepotřebné moduly (předpokládám) vůbec nenačetly.

Posláno 4. 9. 2008 v 19.51 | Odpovědět
Na komentář reagoval [9] David Grudl [12] pmg
avatar

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

#8 Jan Tvrdík: V případě Texy se právě použíjí téměř všechny soubory. U dibi se sice obvykle použije jen jeden z ovladačů, nicméně i tak mi vychází rychlejší načíst vše v minimalizova­né formě.

Posláno 4. 9. 2008 ve 20.22 | Odpovědět

#10 Ondrej Ivanic nový

Používání kompaktních verzí se ujalo a od té doby většina bugreportů hlásila chybu na řádce 1

Tak toto musi byt peklo :)

Je jednosuborove Texy rychlejsie ako viac suborove Texy + op. cache (napr. APC)? Ak to tak nie je potom sa mi to zda ako zbytocna komplikacia urobit jeden subor (jednosuborove + op cache bude asi najrychlejsie, ale …)

Posláno 5. 9. 2008 v 9.47 | Odpovědět

#11 v6ak http://v6ak.profitux.cz/ nový

Bude fajn, až bude PhpMinAdmin distribuován jako index.phar :-D

Posláno 5. 9. 2008 v 10.56 | Odpovědět

#12 pmg nový

#8 Jan Tvrdík: PHP načte jen hlavičku archivu se seznamem souborů a vlastní kód čte, až když je potřeba. Důležité je, že má po celou dobu otevřený jen jeden soubor, ve kterém se přesouvá. Taková je má představa.

Přesná struktura archivu se dá vyčíst ze zdrojů PEAR pakáže PHP Archive. Letmo jsem na to kouknul a myslím, že je nejlepší jednotlivé soubory před archivací prohnat ještě PHP bytecode Compilerem.

Posláno 6. 9. 2008 v 9.59 | Odpovědět

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

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, 2010 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í.