Három kiterjesztés a Zend motor működésének megismeréséhez
Három olyan modulról szeretnék írni, amik segítségével jobban megismerhetjük a PHP nyelvet, betekintést kaphatunk a Zend motor működésébe, és elrejthetjük a forráskódunkat a kíváncsi szemek elől. A cikk szerzője egy összefogott leírást szeretne adni a modulokról, de ez az írás nem helyettesítheti a kiterjesztések kézikönyvét, csupán bevezető lehet a használatukhoz.
Ez a három modul a Vulcan Logic Disassembler, az Advanced PHP Debugger és az eAccelerator. A cikk írását az indította el, hogy mindhárom modulnál átírtam egy-egy részt, amik összességében jelentősebb módosítások lettek, amit esetleg érdemes lehet közzétenni. A kiterjesztések szabadon használhatóak, a licencelésükre vonatkozó feltételek nem változtak.
Ennek az egyik megoldása az, hogy az általunk készített, még le nem fordított programot nem közvetlenül a processzor hajtja végre, hanem közbeiktatunk egy programot, ami azt értelmezi és végrehajtja. Ezt a programot nevezzük virtuális gépnek, azért mert ugyanúgy saját, alacsony színtű utasításokkal és végrehajtási móddal rendelkezik, mint a valódi számítógép.
Ha telepítve van a programunknak megfelelő virtuális gép az adott számítógépen, a programunk végrehajtható azon a számítógépen is. Ilyen virtuális gép például a Java Virtual Machine és a Zend Engine is.
A Java Virtual Machine olyan kódot hajt végre, amit már a Java Development Kit-tel lefordítottunk Java bájtkódra. Ellentétben a Zend Engine-nel, aminél a végrehajtható fájl maga a forrásprogram. Az ilyen szöveges, végrehajtható állományt hívjuk szkriptnek.
Ezzel, hogy közbeiktattunk a gép és a programunk közé egy virtuális gépet, a kód hordozható lett, és lehetővé vált, hogy a forrásprogramunkon végrehajtott változtatásokat azonnal ellenőrizzük. Mindezért ellenben azzal kell fizetnünk, hogy a szkriptünk feldolgozása és értelmezése futásidőben történik.
Az értelmező rész végén előáll a szkriptünkből egy, a Zend Engine végrehajtó része által futtatható, háromcímes utasításokat tartalmazó bájtkód. A Zend terminológiában ezeket az utasításokat hívják opcode-nak, mely az operation code (műveleti kód) rövidítése. A Zend motor végrehajtó része ezt a bájtkódot hajtja végre.
A Vulcan Logic Disassembler-rel megnézhetjük, hogy a Zend motor feldolgozó része milyen bájtkódot állít elő. Most már, hogy van némi képünk az interpreter működéséről, rácsodálkozhatunk arra, hogy mit is látunk a VLD futtatásakor.
Másoljuk be aEgy kicsit átírtam a VLD forráskódját, így már nem csak parancssorból, hanem böngészőből is használható, és olvashatóbb kimenetet hoz létre. A
Megjegyzendő, hogy a parancssoros használathoz érdemes a Path környezeti változóba a
Mivel a cikkben szereplő modulok mindegyike használható parancssorból, érdemes készíteni egy parancsikont az Asztalra. Majd állítsuk be a parancsikon tulajdonságainál, az Elrendezés lapon a nekünk megfelelő képernyőpuffert. A képernyőpuffer magassága azt adja meg, hogy mennyi sort tudunk visszalapozni, nyugodtan adjunk meg elég nagy számot. A sorhossz pedig azt határozza meg, hogy hanyadik karakter után fog sort törni a konzol.
A disassembler használata parancssorból:A
A böngészőből való használatnál, Apache webkiszolgáló esetén, abban a könyvtárban, ahol a szkript helyett a VLD kimenetet szeretnénk látni, aA három ellenőrzés bizonyos esetekben ugyanazt az eredményt hozza, és természetesen a helyzettől függően ezek az ellenőrzések felcserélhetők. Megjegyzem, az A
AzAz Az Egy kis magyarázat a kódhoz: a Egy kis meglepetést okoz a két függvény - a belső A saját és a belső függvény hívásának ugyanaz a bájtkódja, a Zend motor nem tesz különbséget a két függvényhívás között. Mindez addig igaz, míg a függvény deklarálása a függvényhívás előtt szerepel, és nem utána. Ha a függvénydeklaráció a hívás után szerepel, a Zend Engine egy kicsit összetettebb kódot hoz létre.A három sor bájtkódja:Az
Érdemes lehet kisebb kódok, kódrészletek nézegetése csak a kíváncsiság kedvéért is. De nagyobb kódok megnézése pont annyira érdekes, mint például egy bináris, futtatható állomány megtekintése disassemblerben. A modul készítője, Derick Rethans egy encodert akart létrehozni, végül a disassembler elkészítéséig jutott.
A VLD modulról további információkat találhatunk még a következő helyeken: Derick Rethans honlapja, VLD a PECL webhelyen.
Ezen kívül a PHP nyelvvel való ismerkedésünk bizonyos fokán eljutunk arra a pontra, mikor elkezd érdekelni bennünket, hogy ez vagy az a megoldás a gyorsabb. Ez azért is van így, mert a PHP nyelv rengeteg függvénye miatt egy feladatra számos megoldás adódik. Az összehasonlításhoz nem kell bajlódnunk például a
Másoljuk be a bővítményeket tartalmazó mappába aAz APD egy Zend kiterjesztés. Előfordulhat, hogy nem működik együtt egyéb Zend kiterjesztéssel, például a Zend Optimizer-rel. Fontos, hogy az APD modul betöltéséhez teljes elérési úttal kell megadnunk a dll-t, és az APD használatához meg kell adni egy munkakönyvtárat is, amit nem árt, ha létre is hozunk. A példában ez a
Az APD által előállított fájlra sok minden mondható, csak az nem, hogy ember által olvasható formátumban tartalmazza a mérési adatokat. Az adatok megjelenítéséhez használjuk parancssorból aA megadott kapcsolók szerint összesíthetjük, és jeleníthetjük meg az elkészített profile adatait. A
A
Megjelenítési kapcsolók:
A program futtatásakor az APD elkészíti a szkript futási információit tartalmazó fájlt a munkakönyvtárába. Az eredmény megtekintéséhez futtassuk parancssorból a Az R kapcsoló használatával a függvények a gyermekhívások idejét is tartalmazzák, ezért került a legelső helyre a main függvény. Az
Még meg kell említenem, hogy jelen mérés lehet, hogy téves eredményt ad, mert a preg függvények gyorsítótárazást használnak. Lehet, hogy pontosabb eredményt kapnánk, ha a méréshez előállítanánk egy tömböt. De jelen esetben csak a példa kedvéért szerepel a szkript, amin jól látszik, hogy mennyire megkönnyíti az APD a különböző futási eredmények összehasonlítását, ennek csak az a feltétele, hogy a mérendő dolgokat külön-külön függvénybe tegyük.
Érdemes odafigyelni arra, hogy ne adjunk meg túl nagy ismétlési értéket, különben ennek az lehet az eredménye, hogy a szkript futása közben az operációs rendszer elkezd swap-elni, amivel teljesen téves eredményeket kaphatunk. A Windows operációs rendszereket néha kifejezetten nehéz rávenni arra, hogy időlegesen hagyják abba ezirányú tevékenységüket. Remélhetőleg, azt meg sem kell említenem, hogy mérés közben nem internetezünk, nem játszunk, és lehetőleg semmi olyat nem teszünk, ami téves mérési eredményt okozhat.
Az Advanced Php Debugger modulról további információkat kaphatunk még a következő helyeken: APD honlapja, APD a PECL webhelyen.
Ilyen modulok a következők:
Ezek a betöltő modulok ingyenesen letölthető és használható Zend Engine kiegészítések. A Zend Optimizer, az ionCube Loader és az eAccelerator Loader olyan modulok, amik segítik a szkriptek végrehajtását. Ha még emlékszünk a Vulcan Logic Disassembler résznél leírtakra, a szkript végrehajtási menete: forrásszöveg beolvasása, forrásszöveg feldolgozása (a bájtkód elkészítése), bájtkód végrehajtása.
A felsorolt betöltők gyorsítótárazzák az elkészített bájtkódot, így a szkriptek feldolgozása összességében kevesebb időt vesz igénybe. Az ilyen betöltő modulok használatával a Zend Engine feldolgozó része azzal bővül, hogy a modul ellenőrzi, hogy a gyorsítótárában szerepel-e a szkript bájtkódja, és az megfelelő-e, ha igen, akkor az adott bájtkód azonnal végrehajtható.
Nem kell a Zend Engine értelmező részének feldolgoznia a programunkat, ha a modul gyorsítótárában rendelkezésre áll a szkript lefordított változata, akkor ennek betöltésével elkezdődhet a bájtkód végrehajtása. Így ezek a gyorsítók önmagukban is, anélkül, hogy hozzányúlnánk a PHP programokhoz, gyorsítják a végrehajtás menetét. Ha nincs meg, vagy nem megfelelő a rendelkezésre álló bájtkód, akkor a Zend Engine feldolgozó része előállítja azt, majd a betöltő modul elmenti az elkészített kódot, és továbbadja a Zend motor végrehajtó részének.
Biztos feltűnt, hogy ezen a folyamaton tovább gyorsíthatnánk, ha már eleve lefordított PHP szkripteket tudnánk betölteni. Így a Zend Engine feldolgozó részét nem kellene meghívni. Szerencsénk van, mert mind a három betöltőhöz létezik bájtkódot előállító program.
A Zend SafeGuard, a Zend Encoder és az ionCube PHP Encoder fizetős alkalmazások, míg az eAccelerator nyílt forrású és ingyenesen használható program. Ezekkel a programokkal további gyorsítást érhetünk el, mivel a betöltő modulnak nem kell meghívnia a Zend motor feldolgozó részét, ráadásul többféle kódoptimalizációt is tartalmaznak. Sajnos a probléma az, hogy a fönt felsorolt betöltők csak a nekik megfelelő bájtkóddal képesek dolgozni.
Mi lehet a probléma? Hisz a Zend Engine által feldolgozható bájtkód egy és ugyanaz. Nos, ezeket a programokat főleg pont e miatt a problémát jelentő dolog miatt használják. Mindegyik valamiféle védelmet is alkalmaz az előállított kódon, ezért csak a saját betöltője tudja kicsomagolni a védett bájtkódot.
A Zend SafeGuard, a Zend Encoder és az ionCube PHP Encoder esetén a titkosítási algoritmus nem nyilvános. Az eAccelerator esetén nem igazán beszélhetünk titkosításról, nyílt forrású programról van szó. Néhány utasítás után megkaphatjuk a bájtkódot, igaz a bájtkód még ember által nem olvasható formátum. Az eAccelerator által a bájtkódon alkalmazott módosítások inkább azt célozzák, hogy a betöltő modul minél gyorsabban és biztosan azt a kódot kapja vissza, amit az eAccelerator létrehozott.
Ezért a Zend Optimizer és ionCube Loader képes lehetne kezelni az eAccelerator által előállított kódot, de valószínűleg üzleti megfontolásokból ezt nem teszik.
Mindenesetre az itt felsorolt betöltők és bájtkód előállítók a szerverüzemeltetők nagy barátai. A hosztingcégeknek mindenképpen ki kellene választaniuk egyet, és azt a lehető legjobban támogatniuk kellene. Használatukkal komoly terheket vehetnek le a szervereikről, kis ráfordítással jelentős teljesítménynövekedést érhetnek el. Mivel ezek a betöltők a Zend Engine feldolgozó részét próbálják kiváltani, ezért nem szükséges mindegyik betöltő használata, halmozásukkal nem lesz gyorsabb a PHP szkriptek végrehajtása.
Ha olyan szerveren van a weblapunk ahol elérhető az eAccelerator, készítsük el az általa feldolgozható bájtkódot. Ne azért, mert ezzel a szerverüzemeltetőnknek segítünk, hanem azért, mert a weblapunk kódja gyorsabban fog végrehajtódni. Ezen kívül nem elhanyagolható tény, hogy ha nem is bombabiztos, de legalább minimális védelmet tudunk alkalmazni a PHP programunkon.
Másoljuk be azFontos, hogy a kiterjesztés megadásakor teljes elérési utat adjunk meg, és hozzuk létre a
Az eAcceleratornak két dll-je van, az egyik az
Az
A parancssoros használathoz szükséges, hogy telepítve legyen a PEAR Console\Getop csomag. Webes felület használatához ez a csomag nem kell, de böngészőből való használathoz másoljuk a mappába a
A PHP programjaink kódolásához elegendő a forrás és a célfájl megadása. A forrásfájl az a PHP szkript amit kódolni szeretnénk, a forrásnak megadhatunk könyvtárat is. Az előállított, kódolt szkript a megadott célfájl nevén kerül elmentésre. Ha a forrásnak könyvtárat adunk meg, akkor a célnak is könyvtárat kell megadnunk, a célfájlnak vagy könyvtárnak nem szükséges léteznie. A kiterjesztéshez adjuk meg azokat a fájlkiterjesztéseket, amiket kódolni szeretnénk. Ha nem adunk meg kiterjesztést, minden fájl kódolásra kerül.Az
Kezdetnek esetleg próbáljuk ki az encodert a PEAR csomagokon. Nálam a telepített csomagok a következők voltak: Archive_Tar, Auth_SASL, Console_Getopt, DB, Mail, Mail_Mime, Mail_Queue, Net_SMTP, Net_Socket, PEAR, PHPUnit, PHP_Compat, XML_RPC. Ezt nem mint referenciát soroltam fel, csak viszonyítási alapul szolgálhat egyéb forrásfájlok kódolásához. Az encoder futtatása böngészőből:
A kódolás alatt néhány szkriptben az
A
A
A
Láthattuk, hogy az encoder használatával néhány rejtett hibára is rálelhetünk. Ezen kívül az előállított szkriptek sokkal kevesebb helyet foglalnak, a példában a kódolt fájlok mérete kevesebb, mint a forrásfájlok negyede. Mondhatnánk azt, hogy ez mindegy, hisz elég tárhelyünk van, de a programok végrehajtásakor ezek a memóriából vesznek el helyet, ebből pedig mindig kevés szokott lenni. A programok beolvasása is ezzel arányosan kevesebb időt fog igénybe venni, és a lemezműveleteknél csak egyetlen egy költségesebb művelet van, a távoli lemezműveletek. Ezért, ha a szerveren telepítve van az eAccelerator, érdemes kódolnunk a szkriptjeinket.
■ Ez a három modul a Vulcan Logic Disassembler, az Advanced PHP Debugger és az eAccelerator. A cikk írását az indította el, hogy mindhárom modulnál átírtam egy-egy részt, amik összességében jelentősebb módosítások lettek, amit esetleg érdemes lehet közzétenni. A kiterjesztések szabadon használhatóak, a licencelésükre vonatkozó feltételek nem változtak.
Vulcan Logic Disassembler v0.8
Minden processzor bizonyos utasításkészlettel rendelkezik, ezek alacsony színtű utasítások. Például egy C compiler az adott gépnek megfelelő utasításkészletre fordítja le a forráskódunkat, amit a processzor az operációs rendszeren keresztül közvetlenül végre tud hajtani. A weblapok programozásakor az egyik problémát az jelentheti, hogy nem tudjuk, milyen gépen fog futni a programunk. Hiába készítenénk otthon futtatható állományt, ha az otthoni gépünkön elkészített program nem működhetne a szerveren.Ennek az egyik megoldása az, hogy az általunk készített, még le nem fordított programot nem közvetlenül a processzor hajtja végre, hanem közbeiktatunk egy programot, ami azt értelmezi és végrehajtja. Ezt a programot nevezzük virtuális gépnek, azért mert ugyanúgy saját, alacsony színtű utasításokkal és végrehajtási móddal rendelkezik, mint a valódi számítógép.
Ha telepítve van a programunknak megfelelő virtuális gép az adott számítógépen, a programunk végrehajtható azon a számítógépen is. Ilyen virtuális gép például a Java Virtual Machine és a Zend Engine is.
A Java Virtual Machine olyan kódot hajt végre, amit már a Java Development Kit-tel lefordítottunk Java bájtkódra. Ellentétben a Zend Engine-nel, aminél a végrehajtható fájl maga a forrásprogram. Az ilyen szöveges, végrehajtható állományt hívjuk szkriptnek.
Ezzel, hogy közbeiktattunk a gép és a programunk közé egy virtuális gépet, a kód hordozható lett, és lehetővé vált, hogy a forrásprogramunkon végrehajtott változtatásokat azonnal ellenőrizzük. Mindezért ellenben azzal kell fizetnünk, hogy a szkriptünk feldolgozása és értelmezése futásidőben történik.
A PHP értelmező
A PHP elnevezés egy programozási nyelvet jelöl, a PHP utasításokat a PHP-hez készített virtuális gép, a Zend Engine hajtja végre. A Zend Engine és PHP nevek összeforrottak, de nem egyenlők egymással. Amikor futtatunk egy PHP kódot, a Zend motor értelmezi és hajtja végre az általunk alkotott kódot. A programunk betöltése után, első lépésben a kód értelmezése történik. Az értelmező rész többféle dolgot is elvégez.- Az értelmező program a számára felesleges részeket eltávolítja a kódból (pl. megjegyzések, plusz határoló jelek stb.). Ténylegesen nem távolítja el, inkább figyelmen kívül hagyja ezeket a részeket.
- A kifejezéseket a végrehajtó rész által értelmezhető formára hozza.
- És még számos lexikai elemzést elvégez, aminek eredményeképp, ha a szkript nem tartalmaz szintaktikai hibát, a műveletsor végére az utasításokat átalakítja a virtuális gép által végrehajtható kódsorrá.
Az értelmező rész végén előáll a szkriptünkből egy, a Zend Engine végrehajtó része által futtatható, háromcímes utasításokat tartalmazó bájtkód. A Zend terminológiában ezeket az utasításokat hívják opcode-nak, mely az operation code (műveleti kód) rövidítése. A Zend motor végrehajtó része ezt a bájtkódot hajtja végre.
A Vulcan Logic Disassembler-rel megnézhetjük, hogy a Zend motor feldolgozó része milyen bájtkódot állít elő. Most már, hogy van némi képünk az interpreter működéséről, rácsodálkozhatunk arra, hogy mit is látunk a VLD futtatásakor.
Telepítés
A telepítéshez szükséges fájlok a cikk mellékleteként letölthetőek. A csomag tartalmazza a Windows rendszeren való telepítéséhez szükséges dll-t is.
Másoljuk be a
php_vld.dll
fájlt a kiterjesztéseket (extensions) tartalmazó mappába, és a php.ini
fájlt egészítsük ki a következővel.[VLD]
extension = php_vld.dll
php.ini
beállítása után, parancssorból azonnal tudjuk használni a kiterjesztést, böngészőből való használathoz újra kell indítani a webkiszolgálót.Megjegyzendő, hogy a parancssoros használathoz érdemes a Path környezeti változóba a
C:\Program Files\PHP\cli;C:\Program Files\PHP
könyvtárakat ebben a sorrendben felvenni. Ha nem tudjuk, hogyan kell, keressünk rá a súgóban a környezeti változók kifejezésre, vagy nézzük meg a Weblabor PHP telepítésről szóló cikkét.Mivel a cikkben szereplő modulok mindegyike használható parancssorból, érdemes készíteni egy parancsikont az Asztalra. Majd állítsuk be a parancsikon tulajdonságainál, az Elrendezés lapon a nekünk megfelelő képernyőpuffert. A képernyőpuffer magassága azt adja meg, hogy mennyi sort tudunk visszalapozni, nyugodtan adjunk meg elég nagy számot. A sorhossz pedig azt határozza meg, hogy hanyadik karakter után fog sort törni a konzol.
A disassembler használata parancssorból:
php -d vld.active=1 -d vld.execute=0 <phpszkript>
-d
kapcsolóval módosíthatunk vagy állíthatunk be egy php.ini
direktívát. A -d vld.execute=0
beállítást elhagyhatjuk, ekkor a szkript kimenete is meg fog jelenni. Ha nem abban a könyvtárban vagyunk, ahol az ellenőrizendő szkript van, akkor a szkript nevét az elérési úttal együtt kell megadnunk.A böngészőből való használatnál, Apache webkiszolgáló esetén, abban a könyvtárban, ahol a szkript helyett a VLD kimenetet szeretnénk látni, a
.htaccess
fájlt ki kell egészítenünk a következővel.php_value vld.active 1 #Aktívvá teszi a VLD modult.
php_value vld.execute 0 #Ha be van kapcsolva, a szkript kimenete is látszik.
Néhány példa
A VLD használatával beleshetünk egy kicsit a Zend motor bugyraiba. Nézzünk meg néhány PHP program bájtkódját.Feltételek
<?php
$e = 5;
if ($e == true) ;
if ($e == 5) ;
if ($e) ;
?>
($e == true)
és az ($e)
ellenőrzések teljesen ekvivalensek. Érdemes a kisebb bájtkódot eredményező megoldást használni, feltéve, ha az nem gátolja a forráskódunk későbbi megértését. A szkript futtatása után a következő kimenetet fogjuk kapni.C:\www\vld>php -d vld.active=1 -d vld.execute=0 info.php
filename: C:\www\vld\info.php
function name: (null)
number of ops: 15
line # opcode fetch ext res operands
-----------------------------------------------------------------------------
2 0 FETCH_W |local | |$0 |string:'e'
1 ASSIGN | | |$1 |$0, int:5
3 2 FETCH_R |local | |$2 |string:'e'
3 FETCH_CONSTANT | | |$3 |string:'true'
4 IS_EQUAL | | |$4 |$2, ~3
5 JMPZ | | | |~4, ->7
6 JMP | | | |->7
4 7 FETCH_R |local | |$5 |string:'e'
8 IS_EQUAL | | |$6 |$5, int:5
9 JMPZ | | | |~6, ->11
10 JMP | | | |->11
5 11 FETCH_R |local | |$7 |string:'e'
12 JMPZ | | | |$7, ->14
13 JMP | | | |->14
6 14 RETURN | | | |int:1
line
a forráskódunk sorszámait adja meg. Láthatjuk, hogy az értelmező egy-egy utasítást több műveleti kódra fordít le. A fetch
oszlop az adott változó hatóköréről és élettartamáról ad információt. Az ext
oszlop jelöli függvényhívás esetén, hogy az adott függvény hány paramétert igényel. A res
oszlop azt adja meg, hogy ha az adott műveleti kód visszatérési értékkel rendelkezik, akkor az a verem melyik részére kerül. Az operands
oszlop az adott műveleti kód operandusait, paramétereit tartalmazza, maximum kettő lehet. Elsőre elég zavarosnak tűnhet ez a Zend Engine opkód, de hámozzuk ki belőle azt, ami minket érdekel.Az
($e == true)
kifejezés bájtkódja:$2 FETCH_R string:'e'
$3 FETCH_CONSTANT string:'true'
$4 IS_EQUAL $2, ~3
($e == 5)
kifejezés bájtkódja:$5 FETCH_R string:'e'
$6 IS_EQUAL $5, int:5
($e)
kifejezés bájtkódja:$7 FETCH_R string:'e'
fetch_r
a jobb oldali értéket a verembe másolja, fetch_constant
az adott konstanst a verembe másolja, az is_equal
összehasonlít két verembeli értéket, és az eredményt a verembe teszi. Láthatjuk, hogy a fönti, hasonló ellenőrzést végző kódok, más-más bájtkódot eredményeztek, nem meglepő módon, a tömörebb fogalmazás tömörebb bájtkóddal, és gyorsabb végrehajtással jár.Függvényhívás
<?php
function isInt($str){
return $str == (string)(int)$str;
}
is_int("10");
isInt ("10");
?>
is_int
és a saját isInt
függvény - hívásának bájtkódja:
SEND_VAL string:'10'
$0 DO_FCALL string:'is_int', int:0
SEND_VAL string:'10'
$1 DO_FCALL string:'isint', int:0
Nyelvi elemek
A PHP kézikönyvben többek között azecho
leírásánál azt olvashatjuk, hogy az tulajdonképpen nyelvi elem. De mit jelenthet ez a rejtélyes kifejezés? Próbáljuk ki, hogy milyen bájtkódot eredményez a következő forráskód.<?php
echo ("1.sor");
print ("2.sor");
printf("3.sor");
?>
ECHO string:'1.sor'
$0 PRINT string:'2.sor'
FREE ~0
SEND_VAL string:'3.sor'
$1 DO_FCALL string:'printf', int:0
echo
és print
PHP utasításokhoz létezik nekik megfelelő műveleti kód. A program feldolgozásakor nem kell az utasítást tovább bontani, mint pl. a printf
függvénynél, ezért ezek az utasítások gyorsabban végrehajthatók. Bár a print
együtt jár legalább egy free
opkóddal is, mivel a print
által visszaadott értékkel kell kezdeni valamit.Érdemes lehet kisebb kódok, kódrészletek nézegetése csak a kíváncsiság kedvéért is. De nagyobb kódok megnézése pont annyira érdekes, mint például egy bináris, futtatható állomány megtekintése disassemblerben. A modul készítője, Derick Rethans egy encodert akart létrehozni, végül a disassembler elkészítéséig jutott.
A VLD modulról további információkat találhatunk még a következő helyeken: Derick Rethans honlapja, VLD a PECL webhelyen.
Advanced Php Debugger v0.9.2
Az ADP modullal a PHP szkriptünkről készíthetünk profile-t. Azaz információt kaphatunk arról, hogy a programunk utasításai mennyi erőforrást használnak, melyik függvényt hányszor hívjuk meg. Igazán hasznos lehet, ha javítani szeretnénk egy-egy programunk futásán. Nem kell találgatnunk, hogy hol is kezdjük a fejlesztést. A profile elkészítése után azonosíthatjuk a lassan működő részeket.Ezen kívül a PHP nyelvvel való ismerkedésünk bizonyos fokán eljutunk arra a pontra, mikor elkezd érdekelni bennünket, hogy ez vagy az a megoldás a gyorsabb. Ez azért is van így, mert a PHP nyelv rengeteg függvénye miatt egy feladatra számos megoldás adódik. Az összehasonlításhoz nem kell bajlódnunk például a
microtime
függvénnyel vagy PEAR csomagokkal, egyszerűen használjuk az APD lehetőségeit. Arról nem is beszélve, hogy pontosabb eredményt is kapunk.Telepítés
A telepítéshez szükséges fájlok a cikk mellékleteként letölthetőek. A csomag tartalmazza a Windows rendszeren való telepítéséhez szükséges dll-t is.
Másoljuk be a bővítményeket tartalmazó mappába a
php_apd.dll
fájlt, és egészítsük ki a következővel a php.ini
fájlt:[APD]
zend_extension_ts = "C:\Program Files\PHP\extensions\php_apd.dll"
apd.dumpdir = "C:\apd"
C:\apd
mappa. Ezután másoljuk ebbe a mappába a pprofp.php
fájlt is.Az APD használata
Amelyik szkriptnél használni akarjuk a profilekészítést, meg kell hívnunk azapd_set_pprof_trace
függvényt. Ezután az APD egy fájlt hoz létre a munkakönyvtárába, ami tartalmazza az apd_set_pprof_trace
függvény utáni futási információkat. A fájl neve pprof.xxxxx.yy
lesz, ahol xxxxx
a php.exe
vagy a webkiszolgáló folyamatazonosítója, az yy
pedig egy sorszám.Az APD által előállított fájlra sok minden mondható, csak az nem, hogy ember által olvasható formátumban tartalmazza a mérési adatokat. Az adatok megjelenítéséhez használjuk parancssorból a
pprofp.php
szkriptet. Telepítéskor azért másoltuk az APD munkakönyvtárába, hogy ne kelljen külön keresni. A használat módja:
php pprofp.php [kapcsolók] pprof.xxxxx.yy
pprofp.php
használja a PEAR Console\Getop csomagot, ezért a futtatása előtt ezt is telepítenünk kell. A PEAR telepítéséhez futassuk parancssorból a PHP mappában lévő go-pear.bat
fájlt, a telepítéshez internetkapcsolat kell.A
ppprofp.php
szkriptet átírtam, így olvashatóbb eredményt szolgáltat Windows parancssorban is. Néhány kapcsoló nem, vagy hibásan működött, ezeket kijavítottam, ezen kívül jelentősen gyorsabban dolgozza fel az APD által készített fájlt.A pprofp szkript kapcsolói:
Adatok rendezése:- a - Rendezés az eljárások neve szerint
- l - Rendezés az eljárások hívásszáma szerint
- m - Rendezés a memóriahasználat szerint. (A memóriaadatok megjelenítéséhez az APD-t és a PHP-t is az
--enable-memory-limit
kapcsolóval kellene lefordítani.)
- r - Rendezés a valós idő szerint.
- R - Rendezés a valós idő szerint (tartalmazza a gyermekhívásokat)
- s - Rendezés a rendszeridő szerint
- S - Rendezés a rendszeridő szerint (tartalmazza a gyermekhívásokat)
- u - Rendezés a felhasználói idő szerint.
- U - Rendezés a felhasználói idő szerint. (tartalmazza a gyermekhívásokat)
- v - Rendezés az eljárásokban töltött átlagos idő szerint.
- z - Rendezés a felhasználói + rendszeridő szerint. (alapértelmezett)
- Z - Rendezés a felhasználói + rendszeridő szerint (tartalmazza a gyermekhívásokat)
Megjelenítési kapcsolók:
- t - Tömörített hívási fát jelenít meg.
- T - Tömörítetlen hívási fát jelenít meg.
- c - A hívási fánál megjeleníti a valós időt is.
- i - A beépített függvényeket nem jeleníti meg.
- m - A hívási fában megjeleníti a fájl, sor és memóriahasználati információkat. Ha más szerint szeretnénk rendezni az eljárásokat, a rendezési kapcsolót ezután adjuk meg.
- O <szám> - Megjelenített eljárások legnagyobb száma (alapértelmezett: 20)
Példa
A profile készítéséről a PHP fejlesztés felsőfokon című könyv 18. fejezetében részletesen olvashatunk. A példában azt szeretném bemutatni, hogyan használhatjuk az APD-t különböző programozási megoldások összehasonlítására. Nemrég a PHP levelezési listán volt szó arról, hogy mennyire gyorsak a preg függvények. A listán előkerült függvények összehasonlítására a következő szkriptet használtam.<?php
$iteration = 10000;
$str = 'mr akarki (AB)';
$pattern = '!\((.*)\)$!';
function _preg_str($str){
for ($i = 0; $i < $GLOBALS['iteration']; ++$i){
preg_match($GLOBALS['pattern'], $str);
}
}
function _simple_substr($str){
for ($i = 0; $i < $GLOBALS['iteration']; ++$i){
substr($str, -3, 2);
}
}
function _complex_substr($str){
for ($i = 0; $i < $GLOBALS['iteration']; ++$i){
$start = strpos($str, "(") + 1;
substr($str, $start, strpos($str, ")") - $start);
}
}
apd_set_pprof_trace();
_complex_substr($str);
_simple_substr($str);
_preg_str($str);
?>
pprofp.php
szkriptet. A következő ábra, a példa kedvéért, a saját mérési eredményeimet mutatja be.
C:\apd>php \www\apd\test.php
C:\apd>php pprofp.php -iR pprof.03028.0
Trace for C:\www\apd\test.php
Total Elapsed Time = 0.50s
Total System Time = 0.09s
Total User Time = 0.41s
Real User System secs/ cumm
Time% (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name
-------------------------------------------------------------------------------------------
100.0 0.00 0.50 0.00 0.41 0.00 0.09 1 0.0000 0.5010 0 main
56.5 0.28 0.28 0.25 0.25 0.03 0.03 1 0.2831 0.2831 0 _complex_substr
23.0 0.12 0.12 0.10 0.10 0.02 0.02 1 0.1153 0.1153 0 _preg_str
20.3 0.10 0.10 0.06 0.06 0.04 0.04 1 0.1016 0.1016 0 _simple_substr
0.2 0.00 0.00 0.00 0.00 0.00 0.00 1 0.0010 0.0010 0 apd_set_pprof_trace
i
kapcsolóval pedig kizártuk a listából a beépített függvényeket. Láthatjuk, hogy mennyire részletes listát kapunk arról, hogy melyik függvény végrehajtása mennyi időt vett igénybe. Az oszlopok a következők:Time
- A felhasznált idő százalékban az egész program futási idejére levetítve.
Real
- A valós idő, azexcl
oszlop a végrehajtás ideje, acumm
oszlop a végrehajtás ideje a gyermekhívásokkal együtt.
Calls
- Az adott függvényt hányszor került meghívásra.
secs/call
- Egy hívás átlagos végrehajtási ideje.
cumm s/call
- Egy hívás átlagos végrehajtási ideje gyermekhívásokkal együtt.
Memory Usage
- Az adott függvény által felhasznált memória. Ez a lehetőség az APD készítői szerint sem ad megbízható mérési eredményt, és csak bizonyos esetekben működik.
Még meg kell említenem, hogy jelen mérés lehet, hogy téves eredményt ad, mert a preg függvények gyorsítótárazást használnak. Lehet, hogy pontosabb eredményt kapnánk, ha a méréshez előállítanánk egy tömböt. De jelen esetben csak a példa kedvéért szerepel a szkript, amin jól látszik, hogy mennyire megkönnyíti az APD a különböző futási eredmények összehasonlítását, ennek csak az a feltétele, hogy a mérendő dolgokat külön-külön függvénybe tegyük.
Érdemes odafigyelni arra, hogy ne adjunk meg túl nagy ismétlési értéket, különben ennek az lehet az eredménye, hogy a szkript futása közben az operációs rendszer elkezd swap-elni, amivel teljesen téves eredményeket kaphatunk. A Windows operációs rendszereket néha kifejezetten nehéz rávenni arra, hogy időlegesen hagyják abba ezirányú tevékenységüket. Remélhetőleg, azt meg sem kell említenem, hogy mérés közben nem internetezünk, nem játszunk, és lehetőleg semmi olyat nem teszünk, ami téves mérési eredményt okozhat.
Az Advanced Php Debugger modulról további információkat kaphatunk még a következő helyeken: APD honlapja, APD a PECL webhelyen.
eAccelerator v0.9.3
Mivel a PHP egy szkriptnyelv, időről-időre előkerül az az igény, hogy hogyan védhetnénk le szkriptjeinket. Alapállapotban sem maga a PHP nyelv, sem a Zend Engine nem ad megoldást erre. Kulcsot a Zend Engine annyiban nyújt, hogy készíthető hozzá olyan modul, ami a belső végrehajtási sorba ékelődik.Ilyen modulok a következők:
Ezek a betöltő modulok ingyenesen letölthető és használható Zend Engine kiegészítések. A Zend Optimizer, az ionCube Loader és az eAccelerator Loader olyan modulok, amik segítik a szkriptek végrehajtását. Ha még emlékszünk a Vulcan Logic Disassembler résznél leírtakra, a szkript végrehajtási menete: forrásszöveg beolvasása, forrásszöveg feldolgozása (a bájtkód elkészítése), bájtkód végrehajtása.
A felsorolt betöltők gyorsítótárazzák az elkészített bájtkódot, így a szkriptek feldolgozása összességében kevesebb időt vesz igénybe. Az ilyen betöltő modulok használatával a Zend Engine feldolgozó része azzal bővül, hogy a modul ellenőrzi, hogy a gyorsítótárában szerepel-e a szkript bájtkódja, és az megfelelő-e, ha igen, akkor az adott bájtkód azonnal végrehajtható.
Nem kell a Zend Engine értelmező részének feldolgoznia a programunkat, ha a modul gyorsítótárában rendelkezésre áll a szkript lefordított változata, akkor ennek betöltésével elkezdődhet a bájtkód végrehajtása. Így ezek a gyorsítók önmagukban is, anélkül, hogy hozzányúlnánk a PHP programokhoz, gyorsítják a végrehajtás menetét. Ha nincs meg, vagy nem megfelelő a rendelkezésre álló bájtkód, akkor a Zend Engine feldolgozó része előállítja azt, majd a betöltő modul elmenti az elkészített kódot, és továbbadja a Zend motor végrehajtó részének.
Biztos feltűnt, hogy ezen a folyamaton tovább gyorsíthatnánk, ha már eleve lefordított PHP szkripteket tudnánk betölteni. Így a Zend Engine feldolgozó részét nem kellene meghívni. Szerencsénk van, mert mind a három betöltőhöz létezik bájtkódot előállító program.
A Zend SafeGuard, a Zend Encoder és az ionCube PHP Encoder fizetős alkalmazások, míg az eAccelerator nyílt forrású és ingyenesen használható program. Ezekkel a programokkal további gyorsítást érhetünk el, mivel a betöltő modulnak nem kell meghívnia a Zend motor feldolgozó részét, ráadásul többféle kódoptimalizációt is tartalmaznak. Sajnos a probléma az, hogy a fönt felsorolt betöltők csak a nekik megfelelő bájtkóddal képesek dolgozni.
Mi lehet a probléma? Hisz a Zend Engine által feldolgozható bájtkód egy és ugyanaz. Nos, ezeket a programokat főleg pont e miatt a problémát jelentő dolog miatt használják. Mindegyik valamiféle védelmet is alkalmaz az előállított kódon, ezért csak a saját betöltője tudja kicsomagolni a védett bájtkódot.
A Zend SafeGuard, a Zend Encoder és az ionCube PHP Encoder esetén a titkosítási algoritmus nem nyilvános. Az eAccelerator esetén nem igazán beszélhetünk titkosításról, nyílt forrású programról van szó. Néhány utasítás után megkaphatjuk a bájtkódot, igaz a bájtkód még ember által nem olvasható formátum. Az eAccelerator által a bájtkódon alkalmazott módosítások inkább azt célozzák, hogy a betöltő modul minél gyorsabban és biztosan azt a kódot kapja vissza, amit az eAccelerator létrehozott.
Ezért a Zend Optimizer és ionCube Loader képes lehetne kezelni az eAccelerator által előállított kódot, de valószínűleg üzleti megfontolásokból ezt nem teszik.
Mindenesetre az itt felsorolt betöltők és bájtkód előállítók a szerverüzemeltetők nagy barátai. A hosztingcégeknek mindenképpen ki kellene választaniuk egyet, és azt a lehető legjobban támogatniuk kellene. Használatukkal komoly terheket vehetnek le a szervereikről, kis ráfordítással jelentős teljesítménynövekedést érhetnek el. Mivel ezek a betöltők a Zend Engine feldolgozó részét próbálják kiváltani, ezért nem szükséges mindegyik betöltő használata, halmozásukkal nem lesz gyorsabb a PHP szkriptek végrehajtása.
Ha olyan szerveren van a weblapunk ahol elérhető az eAccelerator, készítsük el az általa feldolgozható bájtkódot. Ne azért, mert ezzel a szerverüzemeltetőnknek segítünk, hanem azért, mert a weblapunk kódja gyorsabban fog végrehajtódni. Ezen kívül nem elhanyagolható tény, hogy ha nem is bombabiztos, de legalább minimális védelmet tudunk alkalmazni a PHP programunkon.
Telepítés
A telepítéshez szükséges fájlok a cikk mellékleteként letölthetőek. A csomag tartalmazza a Windows rendszeren való telepítéséhez szükséges dll-t is.
Másoljuk be az
eAccelerator.dll
fájlt a PHP modulokat tartalmazó mappába, és egészítsük ki a php.ini
fájlt a következő sorokkal.[eAccelerator]
zend_extension_ts = "C:\Program Files\PHP\extensions\eAccelerator.dll"
eaccelerator.cache_dir = "C:\php_eaccelerator"
eaccelerator.shm_size = "2"
eaccelerator.enable = "1"
eaccelerator.optimizer = "1"
eaccelerator.filter = ""
cache_dir
direktívánál megadott könyvtárat.Az előbbi beállítási direktívák:
eaccelerator.cache_dir
- Annak a könyvtárnak a helye, amit az eAccelerator lemezes gyorsítótárként használhat. Ez a példában aC:\php_eaccelerator
mappa, de megadhatunk más könyvtárat is.
eaccelerator.shm_size
- A megosztott memória gyorsítótár mérete megabájtban. Fejlesztői gépen ennek nem kell nagy értéknek lennie.
eaccelerator.enabled
- 1 esetén engedélyezzük az eAccelerator működését, 0 esetén tiltva van.
eaccelerator.optimizer
- 1 esetén az eAccelerator belső kódoptimalizációt is használ, 0 esetén tiltva van az optimalizálás.
eaccelerator.filter
- Azokat a PHP fájlkiterjesztéseket adhatjuk meg, amiket az eAccelerator gyorsítótárazzon. Üres sztring esetén minden PHP szkriptet gyorsítótáraz. Fontos, hogy kettős idézőjelet használjunk, az eAccelerator fórumán olvasottak szerint, egyszeres idézőjel használatakor probléma léphet fel a modul működésében.
Az eAcceleratornak két dll-je van, az egyik az
eLoader.dll
, a másik az eAccelerator.dll
. Az eLoader.dll
csak a betöltési funkciókat tartalmazza, használatának csak szerveren van jelentősége. Az eAccelerator.dll
modul tartalmazza a loader funkcióit is, de lehet vele bájtkódot is előállítani. Nekünk most az eAccelerator.dll
lehetőségeire is szükségünk van, ezért ezt telepítsük.A PHP programjaink kódolása
A bájtkódot az eAccelerator moduleaccelerator_encode
függvényével tudjuk előállítani. Ez így elég nehézkes lenne, ezért a függvény használatához nyújt segítséget az encoder.php
szkript, ami egy felületet ad az eaccelerator_encode
függvényhez. Az encoder.php
használható mind böngészőből, mind parancssorból is.Az
encoder.php
szkriptben volt egy hiba, a kódolt szkript végére beszúrt egy felesleges sortörés karaktert. Először csak ezt módosítottam, majd elkezdtem átnézni a szkriptet, aminek az lett az eredménye, hogy az egészet újraírtam. Osztály alapú kódot használ, amivel esetleges továbbfejlesztése remélhetőleg könnyebb lesz, és Windows rendszer alatt jobban kezeli a fájlneveket. A szkript jelenleg magyar nyelvű, de könnyen fordítható más nyelvre is.A parancssoros használathoz szükséges, hogy telepítve legyen a PEAR Console\Getop csomag. Webes felület használatához ez a csomag nem kell, de böngészőből való használathoz másoljuk a mappába a
main.css
fájlt is. A stíluslap olyan beállításokat is tartalmaz, amit az Internet Explorer nem vagy nem jól értelmez, ezért a webes felület használatához más böngésző ajánlott.A PHP programjaink kódolásához elegendő a forrás és a célfájl megadása. A forrásfájl az a PHP szkript amit kódolni szeretnénk, a forrásnak megadhatunk könyvtárat is. Az előállított, kódolt szkript a megadott célfájl nevén kerül elmentésre. Ha a forrásnak könyvtárat adunk meg, akkor a célnak is könyvtárat kell megadnunk, a célfájlnak vagy könyvtárnak nem szükséges léteznie. A kiterjesztéshez adjuk meg azokat a fájlkiterjesztéseket, amiket kódolni szeretnénk. Ha nem adunk meg kiterjesztést, minden fájl kódolásra kerül.
Az encoder.php
szkript kapcsolói
- Alkönyvtárak kódolása - Ha forrásnak könyvtárat adunk meg, a kapcsoló bejelölésével az alkönyvtárakat is kódolni tudjuk.
- A nem kódolható fájlok átmásolása - Ha bejelöljük, akkor a nem kódolt fájlokat (pl. képeket, stílusfájlokat, stb.) is a célmappába másolhatjuk.
- Létező fájlok felülírása - Ha bejelöljük, akkor a célmappában a már létező fájlokat felül fogja írni. A kapcsoló csak a fájlokra van hatással, a mappákra nem.
- eAccelerator ellenőrzésének mellőzése - Ha nem jelöljük be, akkor a kódolt szkript tartalmazni fog egy ellenőrzést, hogy telepítve van-e a szerveren az eAccelerator. Ha nincs telepítve, akkor a szkript futtatásakor egy figyelmeztető üzenet fog megjelenni arról, hogy a szükséges modul hiányzik. Szerintem ez az ellenőrzés egy jól beállított szerveren felesleges.
- Minden üzenet kiírása - Ha bejelöljük, akkor konvertálás alatt minden üzenet meg fog jelenni, ellenkező esetben csak a hibaüzeneteket fogjuk látni. Néha zavaró lehet, ha az összes üzenetet látjuk, de követhetjük vele a konvertálás menetét.
Kezdetnek esetleg próbáljuk ki az encodert a PEAR csomagokon. Nálam a telepített csomagok a következők voltak: Archive_Tar, Auth_SASL, Console_Getopt, DB, Mail, Mail_Mime, Mail_Queue, Net_SMTP, Net_Socket, PEAR, PHPUnit, PHP_Compat, XML_RPC. Ezt nem mint referenciát soroltam fel, csak viszonyítási alapul szolgálhat egyéb forrásfájlok kódolásához. Az encoder futtatása böngészőből:
eAccelerator használata böngészőben (35.41 KB)
A kódolás alatt néhány szkriptben az
eaccelerator_encode
függvény hibát fedezett fel. A hibás szkripteket az encoder nem menti el, ezért nézzük meg, hogy miért jelzett hibát ezeknél a fájloknál!A
Mail\Queue.php
fájlban a hibát az okozza, hogy a Mail_Queue_Error
metódus deklarálásánál a paraméterlistában a következő szerepel: $file=__FILE__, $line=__LINE__
. Ezt ki tudjuk javítani, ha a $file
és $line
paraméterek alapértelmezetten NULL
értéket kapnak, és a metóduson belül írjuk át az értéküket, ha szükséges.A
PEAR\Exception.php
fájl fordítása azért nem sikerült, mert a szkript a PHP 5 verziójától elérhető, új objektum orientált programozási lehetőségeket használja. A szkript kódolásához PHP 5 és a hozzá lefordított eAccelerator modul szükséges.A
PHP\Compat\Function\version_compare.php
fájlban a következő sor okozza a hibát: elseif (is_numeric($i2]))
. Ami egyértelműen szintaktikai hiba, de a csomag készítője nem vette észre. A szkript meggyógyításához egyszerűen töröljük a felesleges ]
karaktert, a kódolás ezután hiba nélkül végrehajtódik.Láthattuk, hogy az encoder használatával néhány rejtett hibára is rálelhetünk. Ezen kívül az előállított szkriptek sokkal kevesebb helyet foglalnak, a példában a kódolt fájlok mérete kevesebb, mint a forrásfájlok negyede. Mondhatnánk azt, hogy ez mindegy, hisz elég tárhelyünk van, de a programok végrehajtásakor ezek a memóriából vesznek el helyet, ebből pedig mindig kevés szokott lenni. A programok beolvasása is ezzel arányosan kevesebb időt fog igénybe venni, és a lemezműveleteknél csak egyetlen egy költségesebb művelet van, a távoli lemezműveletek. Ezért, ha a szerveren telepítve van az eAccelerator, érdemes kódolnunk a szkriptjeinket.
Szép munka
Csak megjegyzés, a feltételek rész alatt található táblázat szét van csúszva kicsit.
Üdv:
mefi
http://mefi.be
elcsúszva?
Már nincsen
üdv:
mefi
http://mefi.be
mefi!
A három modul közül kipróbáltad valamelyiket? A cikk melyik része tetszett?
Szépséghiba
Egy kissé zavaró szépséghiba, hogy a ,,kimenetek'' esetén az egyszerű megjelenítés (nyomtatási nézet) esetén a háttér fehérre vált, viszont a betűk is fehérek maradnak. ;)
FARKAS Máté
Cikk
-boogie-
hmm
--
connor
Nagyon jó kérdés!
Lehet, hogy rosszul csináltam, mert a VLD az Optimizer előtt volt regisztrálva a php.ini-ben. De én úgy csinálnám a helyükben, és valószínűleg így is teszik, hogy a végrehajtó részbe is beépüljön a betöltő modul. Ha sikerül a visszafejtés, akkor is egy obfuszkált program bájtkódját kapnád vissza.
Ha esetleg valakit Java bináris visszafejtése érdekel: DJ Java Decompiler
Fantasztikus
Gondolom vannak még ilyen "meglepetések" az egész nyelvben. Várom őket.
Bízzál Istenben és tartsd szárazon a puskaport!" -Cromwell
compile
How can I compile VLD to windows binary php_vld.dll? I want to make some changes in source code. Thank you!
compiling under windows
- Read the part titled "Building from source code" in the chapter "Installation on Windows system" from the php manual.(php manual) Get the all the source files required and follow the manual. The manual contains all information that you need for compiling.
- Extract vld source to /php-x.z.y/ext/vld directory. (vld source from weblabor)
- Open the vld project file. Run the MSVC++ and choose Open workspace menu item from File menu and select the vld.dsp file from vld's directory. Rebuild All project after modifications.
<Nincs cím>
Néhány javítás
Nem lehetett beállítani, hogy a kiterjesztés nélküli fájlokat is kódolja. Ekkor a kiterjesztéshez pontot (.) kell megadni. Szükség lehet rá a rövid webcímekhez. Hiba jelentkezett akkor is, ha a megadott forráskönyvtár nem volt része a célkönyvtárnak, csak a neve részben azonos volt azzal, vagy vice-versa. Néhány metódust szétbontottam, hogy átláthatóbb legyen.
Miért lett lassabb?
Lefuttatom egyik scriptemen. A script elején ez van:
$time_start = microtime(true);
A végén meg ez:
$time_end = microtime(true);
$time = $time_end - $time_start;
És mi ad vissza?
Optimizált: 0.0421240329742
Eredeti: 0.00737500190735
Aki tudja, hogy ezt hogy sikerült összehoznom, annak várom a válaszát.
Miért lett lasabb?
1. Az eAcceleratornak még nincs stabil változata az 5.x PHP változatokhoz. A 0.9.4 eAccelerator kisebb hibajavításokat tartalmaz, nem működik jól együtt az 5.x PHP verziókkal.
2. Az hogy önnön magában mérted a szkript futását, nem befolyásolhatta igazán, hogy milyen szkript volt. Mivel amikor fut, már a bájtkód hajtódik végre, és annak a futását mérted.
[beolvasás]=>[fordítás]=>[végrehajtás]
A [végrehajtás] egy részét mérted. A különböző betöltés gyorsítók az első két műveletre vannak hatással. Ettől függetlenül természetesen előfordulhat, amit írsz. Hogy miért, ahhoz teljes egészében ismerni kellene az eAccelerator működését.
Próbáld meg esetleg mérni a szkript futását az APD modullal is. Azt nem írtad, hogy rendszeresen ez az eredmény jött ki, vagy csak egyszeri eset volt. Hibás méréshez, éppen elég, ha megmozdítod az egeret, vagy az oprendszer úgy "gondolja", hogy a szkript futása alatt még csinál valamit. Méréshez készíts egy batch-fájlt, ami parancssorból futtatja a mérni kívánt szkripteket.
Mondj nemet a Zend Optimizerre
Miért is?
András írja néha, hogy milyen gyorsan jelennek meg új dolgok a webfejlesztés területen. No, de ennyire? Leírod a hozzászólás címét, és mire a szövegnél tartasz, máris érvénytelen az egész? :) Mégis, ha már elvetetted a kétséget, legalább megindokolhatnád!
Uninstall
Kérdés az okosokhoz: a sebességnövekedésnek mikor (melyik fázisban) kéne megjelennie? Én azt tapasztalom, hogy a RINIT és RSHUDOWN (request init, ~ shutdown) az optimizerrel több idő telik el, mint nélküle. Azt el tudom képzelni, hogy normál esetben a fordítás a RINIT előtt történik, és a mostani cache-elés viszont a RINIT után, és eztért látszik hosszabbnak a futásidő, ami valójában rövidebb.
Tud erről valaki valamit?
ZendOptimizer
- Mivel a betöltők a lefordított szkriptet gyorstárazzák ezért elsősorban a betöltés, értelmezés részt gyorsítják. De ha végeznek kódoptimalizációt is, akkor a végrehajtási részt is gyorsíthatják. Nem felejtkezve meg arról, hogy magának a gyorsítótárazásnak is van erőforrásigénye.
Egyébként a cikknek nem volt célja, hogy a Zend Engine C-forráskód szintjéig menjen. Egy általános rátekintés akart lenni a PHP belső működésére.
A többieknek: A PHP_RINIT és a PHP_RSHUTDOWN: makrók a Zend Engine forráskódjában szabványos felület kialakításához. Zend kiterjesztések készítésekor lehet rájuk szükség.
Hogy pontosan hogyan működik a Zend Optimizer?
Fejtsd meg! Ha megvan, már csak egy bájtkód-forráskód konvertálót kell megírnod, és kezdheted is a kódolt szkriptek visszafejtését.
Nem annyira az optimizer
A cache-elés eredményét nem is vártam, hogy ebben a fázisban megjelenik, de lassulásra (bár kis mértékű), még ennyire sem számítottam.
Help plz!!!
Who does nibud' know English? Can you help with the translation of this article?
Or whether there are services of translation by which it is possible to translate this article into English.
PS: I am very interested by the question of decoding of zend, but I found this article and does
not even know on what she language :(