Gratis PHP-compilers. Volledige geheugenstatistieken

Alexey Romanenko: Mijn naam is Alexey Romanenko, ik werk bij RBC. Het onderwerp van dit rapport is enigszins controversieel. Het lijkt erop: waarom zou je PHP-scripts compileren als alles zo lijkt te werken?

Waarschijnlijk is de belangrijkste vraag: “Waarom?” In het algemeen is het doel van deze presentatie om te proberen te begrijpen of een dergelijke compilatie nodig is, zo ja, waarom, in welke vorm en voor wie.

Wat is een PHP-compiler?

Eerst een kort overzicht van wat een PHP-compiler is. Ik vertel je hoe het werkt, wat het is en hoe je het kunt versnellen.

De eerste functionele module is de zogenaamde SAPI (Server API), die een interface biedt voor toegang tot PHP vanaf verschillende clients (Apache, een soort CGI-server (Common Gateway Interface) en andere). Er is ook SAPI embedded, waarmee u PHP in elke applicatie kunt insluiten.

Het tweede hoofdonderdeel is PHP Core, dat verzoeken verwerkt, al het werk met het netwerk, het bestandssysteem implementeert en de scripts zelf parseert.

Het derde globale deel is de Zend Engine, die onze scripts in een bytecode compileert, deze op zijn virtuele machine uitvoert en het geheugenbeheer afhandelt (en uitgebreide allocators implementeert).

Een van de belangrijkste en grootste onderdelen is de Extensions-module, die 99% implementeert van wat we in PHP gebruiken. Dit zijn ofwel “wrappers” voor sommige bibliotheken, of functionaliteit, of klassen, ingebouwde bibliotheken, enz. We kunnen ook onze eigen extensies schrijven.

Hoe wordt het script zelf uitgevoerd?

Eerst. Er vindt lexicale analyse plaats - het bestand wordt gedownload, geparseerd, alle tekens uit de set van dit bestand worden vertaald in een bepaalde set tokens, waarmee we vervolgens werken.

De parseerfase parseert deze tokens. Op basis van deze analyse wordt een bepaalde grammaticale structuur samengesteld, op basis waarvan vervolgens de bytecode wordt gegenereerd.

Uiteindelijk voert Zend Engine het uit. Het resultaat wordt teruggestuurd naar de klant.

We hebben het over hoge belastingen. Als je dit actieschema elke keer herhaalt, zal alles heel langzaam werken. Wanneer onze tolk enkele honderden of duizenden verzoeken tegelijkertijd ontvangt, is de snelheid simpelweg onbestaande.

Maar er zijn oplossingen. Ze zijn al lang bekend.

Hoe versnelling bereiken?

De eenvoudigste, goedkoopste en goed geteste oplossing is bytecode-caching. In plaats van de parseerfase te doorlopen, cachen we eenvoudigweg onze bytecode. Hiervoor zijn speciale extensies - deze zijn bekend bij iedereen die met PHP heeft gewerkt - dit zijn APC, eAccelerator, Xcache enzovoort. Zend Engine voert eenvoudigweg de bytecode uit.

De tweede optie is codeprofilering, waarbij knelpunten worden geïdentificeerd. We kunnen iets herschrijven als PHP-extensies (dit zal een extensie in C/C++ zijn), het compileren en als modules gebruiken.

De derde optie is globaler: vergeet PHP en herschrijf alles. Over het algemeen heeft deze optie recht op leven, maar alleen als er niet genoeg PHP-code is. Bij grote, grote projecten (of die al een hele tijd bestaan) stapelt zich meestal veel ervan op, en het zal lang duren om alles te herschrijven. Zakelijke vereisten staan ​​u niet toe dit te doen. Over het algemeen duurt het schrijven van iets in PHP, bijvoorbeeld voor een front-end server, niet al te lang, omdat het een eenvoudige taal is. Hiermee kunt u snel dingen doen die langer duren in talen op een laag niveau.

Er is een alternatieve optie, die recentelijk wijdverbreid is geworden, en dat is om PHP ergens te compileren, naar iets snellers.

Laten we iets compileren?

Met het woord “compilatie” bedoel ik de vertaling van PHP-scriptcode naar iets anders, naar een andere code.

In dit geval kunnen er twee soorten zijn.

Native code is een soort binair bestand dat op een fysieke machine kan worden uitgevoerd.

Niet-native code. U kunt een bytecode compileren die op een andere virtuele machine kan worden uitgevoerd, bijvoorbeeld op de JVM.

Hoe kun je native code uit PHP compileren?

Roadsend-compiler. Het vervolg is Raven. Er is ook PHC (dit is een PHP Open Source-compiler). Sinds kort is ook HipHop (Facebook) verschenen.

Ik zal een kort overzicht geven van wat er kan worden gedaan voor niet-native code. Voor zover ik weet zijn er 3 werkopties. Dit is het genereren van bytecodes voor Java en het genereren van bytecodes voor .Net: Quercus, Project Zero, Phalanger. Ik zal compilatie in niet-native code niet overwegen, omdat we deze niet gebruiken. Laten we terugkeren naar het compileren in native code.

Naar mijn mening is Roadsend de oudste compiler. De ontwikkeling ervan begon lang geleden, in 2002. Het was oorspronkelijk een commerciële toepassing. Het was gesloten, pas in 2007 werd het vrijgegeven in Open Source. Er is een zeer complex compilatieschema: voor de Scheme-taal wordt een bepaalde Bigloo-compiler gebruikt, waarna native code wordt gegenereerd. Deze compiler maakt geen gebruik van de Zend Engine.

We kunnen een afzonderlijk uitvoerbaar binair bestand genereren of een module voor Apache genereren. Het is ook mogelijk om een ​​binair bestand te genereren dat als webserver zal werken. Maar het werkt niet. Ik weet niet waarom, maar bij mij werkt het helemaal niet.

Voor zover ik weet, wordt er momenteel niet aan Roadsend gewerkt. Het evolueerde naar het Raven-project, dat volledig werd herschreven in C++. Als compiler gebruikt het LLVM om code te genereren.

Op dit moment ziet alles er veelbelovend uit.

Maar het is nog in aanbouw. Zelfs in de documentatie zijn er aanwijzingen dat we geen binaire bestanden zullen genereren. Wachten.

Het zou triest zijn als we geen PHC hadden. Dit is een OpenSource-compiler. Het is ontwikkeld sinds 2005. Een van de nadelen: het maakt gebruik van ingebouwde SAPI. We laten de Java-machine, de Zend Engine, niet in de steek. In wezen vertaalt het PHP-code naar PHP-extensiemodulecode. Daarna compileert het, maar bij het uitvoeringsproces is opnieuw de Zend Engine betrokken.

Voorbeeld van het gebruik van PHC

Zeer vergelijkbaar met hoe we bijvoorbeeld werken met conventionele compilers, gcc. De eerste laat zien dat er één binair bestand is, we kunnen ook eenvoudig de C-code genereren. Omdat dezelfde gcc binnen wordt gebruikt na het genereren van deze code, kunnen we die vlaggen gebruiken die bedoeld zijn voor optimalisatie en andere dingen.

We hadden het over een applicatie die op de opdrachtregel draait.

Om een ​​webapplicatie te starten moet je verschillende stappen uitvoeren, het is behoorlijk complex. Eerst moet je een extensie genereren, vervolgens de code compileren en deze vervolgens op de een of andere manier (dynamisch of statisch) verbinden.

Belangrijkste voordelen van PHC

In wezen gebruiken we dezelfde PHP, we zijn volledig compatibel. Alle andere extensies worden ondersteund. We gebruiken alles wat we hebben samengesteld. Redelijk goede documentatie.

Een van de extra bonussen van PHC is trouwens dat je het XML-werk van ons script kunt genereren op basis van hoe XML is opgebouwd, soms kan dit handig zijn.

Nadelen

Naar mijn mening is dit een inferieur binair bestand, omdat het nog steeds afhankelijk is van Zend Engine. Er is ook enige complexiteit als het gaat om het verbinden van webprojecten.

Over het belangrijkste

Deze melding zou waarschijnlijk niet zijn gebeurd als HipHop, een oplossing van Facebook, niet was verschenen. De makers verzamelden ook een grote hoeveelheid PHP-code en dachten er lang over na wat ze ermee moesten doen.

Zoals ik het begrijp, werd, nadat de opties om alles te herschrijven waren afgewezen, besloten om een ​​soort vertaler te schrijven (in dit geval in C++-code). Het project is relatief jong; het werd pas in februari van dit jaar officieel uitgebracht. PHP-code wordt vertaald naar C++-code en vervolgens gegenereerd met behulp van standaardtools op uw besturingssysteem. Voorlopig wordt echter alleen het Linux-besturingssysteem ondersteund.

Gisteren vroeg ik een Facebook-vertegenwoordiger naar deze beslissing. Hij zei dat momenteel 100% van de PHP-code via HipHop wordt samengesteld. De code werkt niet in zijn pure vorm via de PHP-interpreter. Opnieuw kondigden de makers een aanzienlijke vermindering van de processorbelasting aan.

Basisfunctionaliteit van HipHop

Het genereert rechtstreeks het binaire bestand zelf, dat op de opdrachtregel kan worden uitgevoerd. Er is zo'n optie om het te lanceren als een streaming webserver. Er is ook een aparte ingebouwde debugger. Het kan scripts zowel lokaal als op afstand debuggen (het werkt als een server).

Het montageproces is vrij niet triviaal. Er is een beschrijving, maar deze wordt niet overal verzameld. Op dit moment is, zoals ik al zei, alles geassembleerd voor Linux, en aanvankelijk was alles “op maat gemaakt” voor 64 bits. Hoewel 32 bits nu experimenteel worden ondersteund. Maar het lukte me om het in elkaar te zetten en een beetje te patchen - over het algemeen deed het dit allemaal, omdat het niet standaard in elkaar wordt gezet.

Daarnaast hebben ze hun eigen versies van libcore en naar mijn mening zijn er een aantal bibliotheken die ook gepatcht moeten worden. Over het algemeen is het montageproces niet zo eenvoudig.

Bij de uitvoer na de montage ontvangen we een bepaald hphp-bestand, dat een vertaler is van onze PHP-code naar C++. Als we naar de vlaggen kijken, zijn het er behoorlijk veel. Ik heb hier een paar basisbehoeften benadrukt die je mogelijk nodig hebt.

We kunnen een bestand in HDF-formaat gebruiken als configuratiebestand (config), waarin verschillende richtlijnen worden gespecificeerd. Daar kunnen we het foutniveau en andere zaken instellen (HDF is alles wat in gestructureerde vorm beschikbaar is). We kunnen ook de configuratie zelf uit de database halen of deze rechtstreeks op de opdrachtregel gebruiken.

We stellen het logniveau in tijdens de compilatie: toon alle fouten of geef ook waarschuwingen en aanvullende informatie weer, of houd in het algemeen een volledig logboek bij van alles wat er gebeurt.

Een zeer nuttige richtlijn is input_list=FILE, waarmee we een lijst met scripts kunnen specificeren die we willen compileren. Het is ook de moeite waard om een ​​richtlijn als lazy-bind te noemen. We kunnen alle projectbestanden specificeren - de bestanden die zullen worden samengesteld.

Voorbeeld van het uitvoeren van PHP-scriptcompilatie

Het derde niveau van loggen is geïnstalleerd, er is vrij algemene informatie over de tijd, je kunt zien hoe lang het duurde. In feite is het script vrij eenvoudig. Dit is de gebruikelijke "Hallo wereld", ik heb zojuist een screenshot gemaakt.

Het zwaarste bestand is ons binaire “programma”, de grootte is 28 MB. In wezen weegt onze "Hallo, wereld" 28 MB. Ik wilde opmerken dat dit binaire bestand, naast de standaardregel "Echo "Hallo, Wereld!", nog veel meer bevat. Dit is een volwaardige webserver, een volwaardige server voor beheer.

Wat zijn we aan het doen?

We hebben "Hallo..." in C++, dat een functie uitvoert die bestaat uit één regel "echo" Hallo, wereld ". Bovendien worden er veel dingen van derden geladen. Zoals we kunnen zien, is dit een volwaardig bestand in C++.

Dit is het resulterende programma. Er zitten al heel wat verschillende sleutels in voor verschillende configuraties, maar ik zal er maar een paar noemen.

Dit is --mode, dit is de startmodus van ons programma. We kunnen het rechtstreeks uitvoeren (vanaf de opdrachtregel) of in een webserver of in een volwaardige daemon-modus. Er zijn nog een paar opties, maar deze zijn onbelangrijk.

config wordt in hetzelfde formaat gebruikt. Ik heb geen richtlijnen gegeven omdat er veel zijn. HipHop wordt geleverd met documentatie. Het staat niet op de wikisite, maar er wordt documentatie bij de distributie meegeleverd, waarin alles duidelijk wordt beschreven. Ik had niet eens verwacht dat de beschrijving zo gedetailleerd zou zijn. Hierdoor kun je de oplossing vrij flexibel configureren.

Om in de servermodus te werken, kunnen we de poort specificeren. Voor het beheer wordt een aparte poort gebruikt, waar u enkele verzoeken kunt verzenden waarmee u de server kunt beheren. Als we een foutopsporingsserver hebben, geven we de host en poort aan waar we zullen "binden" voor foutopsporing.

Voorbeeld van lancering

We hebben bijvoorbeeld poort 9999 gespecificeerd voor uitzending. Door eenvoudige http-verzoeken uit te voeren, kunnen we statistieken ontvangen, of op een of andere manier de server beheren, of wat aanvullende informatie verkrijgen. Over het algemeen is het erg handig.

Optie om statusinformatie te verkrijgen

Het is mogelijk om de serverstatusset in verschillende ingebouwde formaten (xml, json, html) te ontvangen. In wezen wordt informatie verstrekt over het servermasterproces zelf en de handlers - threads die verzoeken verwerken.

Aanvullende statistieken

Er worden zelfs veel statistieken verstrekt. Omdat HipHop native werkt met memcache en SQL in de vorm van MySQL, biedt het gedetailleerde informatie over alle bewerkingen die ermee worden uitgevoerd.

Volledige geheugenstatistieken

Er is hier een zeer nuttige functie: toepassingsstatistieken. Met behulp van de extra functies van HipHop zelf in PHP kunnen we statistieken in onze scripts schrijven, die we vervolgens ontvangen via reguliere toegang tot http.

Foutopsporing

Zoals ik al zei, is het mogelijk om de ingebouwde "debug" te gebruiken om scripts te debuggen. Dit is erg handig omdat de hphpi-interpreter op dezelfde manier werkt als wat we hebben gecompileerd. Er is een verschil in het “gedrag” van scripts wanneer ze worden uitgevoerd in standaard PHP en wanneer bepaalde gecompileerde gegevens worden gebruikt. Om te debuggen wat er is gecompileerd, heeft Facebook een aparte tolk geschreven.

In het eerste geval voeren we de code uit met de schakelaar “-f” en kijken we hoe het bestand zich gedraagt; alle uitvoer gaat naar stdout. Of we kunnen het in de debug-modus uitvoeren en naar de interactieve debugger gaan. Het lijkt erg op standaard GDB: u kunt ook breekpunten instellen, uitvoeren, variabele waarden invoeren, volgen en meer.

Eén van de extra functies

We hebben een programma dat bleek na compilatie. Het kan worden gebruikt als een RPC-server. We voeren verzoeken uit via http en door de params-functie aan te roepen, kunnen we een parameter doorgeven als een json-array of als een afzonderlijke parameter. We zullen json laten retourneren, die de resultaten van deze functies retourneert. Dit is erg handig: de benodigde functionaliteit is al vanaf het begin ingebouwd.

Nadelen van hiphop

Op dit moment ondersteunt HipHop geen taalconstructies en -functies zoals eval(), create_function() en preg_replace() met /e, hoewel deze allemaal analoog zijn aan eval(). Naar mijn mening kun je in de nieuwste releases echter nog steeds eval() inschakelen via config. Maar het wordt niet aanbevolen om dit te doen. Over het algemeen is het gebruik van eval() slecht.

De belangrijkste voordelen van HipHop

Het belangrijkste voordeel is natuurlijk de ondersteuning van Facebook. Het werkt en wordt behoorlijk actief ontwikkeld. Rond dit project ontstaat een gemeenschap van ontwikkelaars. Er is een compleet nieuwe PHP-implementatie geschreven.

Zoals ik al zei, is het voordeel dat er native code wordt gegenereerd. Er wordt een prestatieverbetering geclaimd door het verlagen van de belastingskosten van de processor (tests bevestigen dit).

Het is vrij flexibel qua configuratie. Ik was aangenaam verrast dat er nogal wat mogelijkheden zijn voor maatwerk. Ik denk dat dit komt doordat het project echt werkt. Alles wat gebruikt wordt, wordt verhoogd.

Zoals ik al zei, biedt HipHop behoorlijk wat extra functies. Deze omvatten het gebruik als RPC-server, administratie, diverse statistieken en nog veel meer. Er is trouwens ook een API om met andere talen te werken.

Er is behoorlijk goede documentatie geschreven voor deze oplossing. Nog een voordeel: dit is een oplossing die daadwerkelijk klaar is voor gebruik in de productie (bijvoorbeeld: Facebook).

Nadelen

Het grootste nadeel is dat er momenteel een vrij beperkt aantal modules wordt ondersteund. Als we bijvoorbeeld met een database werken, kunnen we alleen functies gebruiken voor het werken met MySQL. Er is hier geen PostgreSQL-ondersteuning.

Er bestaat ook zoiets als de complexiteit van de montage, die ik al noemde. Er zijn problemen met het bouwen op 32-bits systemen. Maar ik denk dat dit snel opgelost zal zijn. Voorlopig wordt alleen een compilatie uit PHP 5.2 gebruikt. Versie 5.3 wordt nog niet ondersteund, maar zal zoals beloofd worden ondersteund.

Wat mag je niet verwachten van de compilatie in het algemeen en van HipHop in het bijzonder?

Compileren zal op geen enkele manier uw langzame SQL-query's in de database versnellen. Als het knelpunt de database is, compileer het dan of compileer het niet, het zal geen enkel nut hebben.

Compilatie versnelt het statisch laden niet, alleen het dynamisch laden. Het maakt het debuggen een stuk lastiger. Veel mensen zijn er waarschijnlijk aan gewend dat alles vrij eenvoudig te debuggen is in PHP. Dit zal niet meer gebeuren tijdens het compileren. Hoewel, zoals ik al opmerkte, Facebook dit proces zo eenvoudig mogelijk heeft gemaakt, zou het zonder dit proces elke keer nog moeilijker zijn om te compileren.

Verwacht niet dat dit een soort wondermiddel is dat al je problemen zal oplossen. In feite lost compilatie een vrij beperkt aantal problemen op. Als dat zo is, kan dit helpen.

Welke problemen lost compilatie op?

Het vermindert de belasting van de CPU, omdat bij actief werken met PHP en een groot aantal verzoeken de belasting ervan aanzienlijk toeneemt. Natuurlijk wil ik graag een aantal tests uitvoeren.

Testen

De eerste test (de eenvoudigste) is een vrij dure operatie die behoorlijk wat tijd in beslag neemt. Bij de tests probeerde ik mezelf te abstraheren en geen verzoeken te doen met behulp van een externe bron.

De belasting valt volledig op de processor. Uit de test bleek dat HipHop van iedereen "gewonnen" heeft: het werkt bijna anderhalf keer sneller dan de standaard PHP-compiler. PHC slaagde heel langzaam voor deze test.

Voor de tweede prestatietest heb ik het officiële PHP-script gebruikt, dat kan worden gedownload van SVN. Het voert een aantal functies uit die sorteren, toewijzen en optellen uitvoeren - vrij dure bewerkingen vanuit wiskundig oogpunt.

HipHop stond opnieuw voorop. Bovendien is het tijdsverschil bij standaard PHP ongeveer 3 keer. PHC presteerde hier beter, maar was ongeveer half zo slecht als HipHop.

PHP wordt voornamelijk gebruikt voor threads die http-verzoeken afhandelen - dit is de moeite waard om in gedachten te houden.

Verschillende standaardconfiguraties (Apache met PHP, Nginx met fpm-php en plug-in APC voor codecaching). Als vijfde optie - HipHop.

Eerlijk gezegd heb ik de tests niet op de server uitgevoerd, maar op een laptop. De cijfers komen uiteraard niet volledig overeen met de werkelijkheid, maar in dit geval zijn de resultaten normaal. Het is vermeldenswaard dat naarmate de belasting toeneemt, het aantal verzoeken en het totale aantal verzoeken tegelijkertijd toeneemt. Het volgende is RPS. We hebben een standaardpagina getest die 10 eenvoudige insluitsels bevat. In wezen is dit het testen van PHP als tolk.

Vraag uit het publiek: Wat zijn de cijfers in de cel - seconden?

Alexey Romanenko: Dit is fps.

Hier kunnen we concluderen dat HipHop zich heel goed gedraagt ​​naarmate het aantal gelijktijdige verzoeken toeneemt.

Het is duidelijk dat het gebruik van APC een standaardpraktijk is. Daaruit blijkt dat het bijvoorbeeld als Apache een prestatieverbetering van ongeveer 2 keer toevoegt. Dit gebeurt ook met Nginx. Maar het feit dat Nginx traag is, betekent niet dat deze combinatie slechter is. Gewoon een specifieke test. Als we hier echt testen, zal Apache "sterven" bij langzame verzoeken.

We willen waarschijnlijk begrijpen of we dit nodig hebben of niet.

Wanneer moet je aan compilatie denken?

Hoogstwaarschijnlijk is dit nodig als we zien dat ons knelpunt de CPU is. Als we CPU-gebonden zijn en PHP als standaardinterpreter gebruiken, is het waarschijnlijk de moeite waard om te overwegen dat misschien een deel van het project kan worden gecompileerd.

In sommige gevallen waarin uw toepassing autonomie nodig heeft om te kunnen werken, is deze methode waarschijnlijk niet geschikt.

Het aantal servers verminderen. Als er veel servers zijn, verminderen we, door de productiviteit grofweg te verdubbelen, het aantal ook met de helft. Als het één server is, heeft het geen zin, maar als het er 100-200 zijn, dan is het waarschijnlijk wel logisch.

De belangrijkste reden waarom Facebook HipHop begon te gebruiken is de aanwezigheid van grote hoeveelheden PHP-code die niet kan worden herschreven (of die is er niet, of die is gewoon duur). De productiviteit twee keer verhogen is al goed.

Waarschijnlijk alles. Ik wacht op vragen.

Vragen en antwoorden

Vraag uit het publiek: Hallo. Vertel me alsjeblieft of je naast Facebook nog andere voorbeelden hebt van succesvolle Hiphop-implementaties. Wilt u de website van RBC bijvoorbeeld overzetten naar HipHop? Alexey Romanenko: Ik begin met de tweede. De RBC-website is moeilijk te vertalen. Over succesvolle implementatie. Ik heb PHP Unit zelf gecompileerd en het is met succes gecompileerd. Voor zover ik weet, compileert het PHP Bunty-bord ook met succes. Een aantal organisaties maakt zelfs al gebruik van compilatie. Verdere tests zullen uitwijzen hoe gerechtvaardigd het gebruik van dit project zal zijn. Vraag uit het publiek: Kun je een voorbeeld geven van een organisatie die het gebruikt? Alexey Romanenko: Eerlijk gezegd zal ik het je nu niet vertellen, maar dit is het Westen. Voor zover ik weet gebruikt niemand het hier. Vraag uit het publiek: Wat is het verschil tijdens runtime, behalve het gebrek aan ondersteuning voor sommige van de door u genoemde functies. Hoe gevaarlijk is het om een ​​‘live’ project te vertalen? Alexey Romanenko: Het verschil is dat elk gecompileerd programma kan mislukken. Misschien zullen er enkele problemen optreden die nog niet zijn geïdentificeerd. In feite zijn er een aantal verschillen in het "gedrag" van PHP zelf. Ik heb ze niet opgenomen omdat meer gedetailleerde informatie in de documentatie te vinden is. Het Facebook-team heeft zijn eigen tolk geschreven, die in feite voor 99,9% gelijk is aan de tolk die in gecompileerde vorm zal werken. Het is beter om je code niet te testen met een standaard PHP-interpreter, maar, zoals ik al zei, met hppi voor PHP.

Het compileren van PHP vanuit de broncode gebeurt vaak op Unix-achtige systemen. Degenen die in een Windows OS-omgeving werken, zullen hoogstwaarschijnlijk PHP downloaden en installeren vanuit binaire pakketten. En hoewel ik het er niet mee eens ben dat het een gemakkelijker te gebruiken, voorgecompileerde oplossing is, zijn er zelfs op Unix-systemen enkele voordelen verbonden aan het compileren van een binair bestand vanaf de broncode. Al met al:

  • Tijdens het samenstellen heb je de mogelijkheid om het eindproduct te verfijnen. Misschien wilt u een bepaalde extensie die rechtstreeks naar het binaire bestand compileert in plaats van deze als een externe bibliotheek te laden. Of misschien wilt u iets uitschakelen dat normaal gesproken standaard beschikbaar is.
  • U kunt, indien nodig, tijdens het compilatieproces een truc uitvoeren die de prestaties voor een specifieke omgeving kan verbeteren (hierbij wordt er uiteraard van uitgegaan dat u al weet wat u doet je zou dit artikel niet lezen !).
  • Compileren kan de enige manier zijn om alles werkend te krijgen als de gecompileerde binaire bestanden zijn gebouwd op oudere versies van ondersteunende software en bibliotheken, en u nu op een nieuw systeem draait.

Waarschuwing: compilatie kan frustrerend zijn, vooral op Windows! U moet ervoor zorgen dat de bouwomgeving correct is ingesteld, leert hoe u de compiler en andere bouwtools op de juiste manier gebruikt en aan eventuele bibliotheekafhankelijkheden voldoet. We hopen dat dit artikel je eerste stap is in het overwinnen van veel van deze obstakels.

Het opzetten van de bouwomgeving

PHP is geschreven in C en daarom is een C-compiler vereist als je PHP vanuit broncode gaat bouwen. C++ is een supersuite van C, dus een goede C++-compiler zou C-code moeten kunnen compileren, hoewel dit niet altijd het geval is. Voor Windows is Visual Microsoft, C++ Express (later VC++ genoemd) gratis beschikbaar op de website van Microsoft. Er werd gebruik gemaakt van de editie van 2010.

Wanneer u een compilerversie kiest, moet u er rekening mee houden hoe u PHP gaat gebruiken. Als je moet werken met mod_php van de officieel gecompileerde Apache-binaire bestanden, en je wilt dat, compileer dan PHP met Visual Studio 6, aangezien dit de Apache-compilatieversie is. De module moet zich richten op dezelfde runtimebibliotheek als Apache, in dit geval msvcrt.dll. Als je Apache ook vanuit de broncode bouwt, of als je PHP als FastCGI of CLI gaat draaien, dan is dit geen probleem en zal 2010 prima werken.

U moet ook de Windows Development Kit (SDK)-software installeren. De SDK geeft ons de belangrijke headerbestanden voor het Windows-platform die we nodig hebben om succesvol te compileren. Ook hiervoor werd versie 7.1 gebruikt.

Installeer de compiler en vervolgens de SDK. Ik zal de installatie niet bespreken, aangezien beide een grafische installatiewizard hebben die je door het hele proces leidt.

Als je een werkende compiler hebt, download dan de binaire tools en bekende pakketten van windows.php.net. Het pakket met binaire tools (ik gebruik het archief 20110915) bevat ontwikkeltools zoals re2c, bison en enkele extra opdrachten die je nodig hebt om PHP te bouwen. Het bekende pakket (ik gebruik het 5.4-archief omdat het overeenkomt met de PHP-versie die ik ga compileren) bevat de minimale benodigde headers en afhankelijkheidsbibliotheken, bijvoorbeeld zlib.h.

Het spreekt waarschijnlijk voor zich dat u de PHP-broncode ook wilt downloaden van windows.php.net. Op het moment dat we dit schrijven is de huidige versie van PHP 5.4.6, dus dat is het versienummer dat je in de voorbeelden ziet.

Het is een goed idee om een ​​werkruimte te creëren waarin u de broncode kunt extraheren en zo kunt compileren dat deze de rest van uw systeem niet beïnvloedt. Maak een map C:\PHP-Dev die als uw werkmap zal dienen en pak vervolgens het binaire archief en de tools daarin uit.

Pak vervolgens de inhoud van het archief uit, PHP-bron in C:\PHP-Dev, nu heb je php5.4 in de bronmap, en pak vervolgens het deps-archief uit in de deps-zusmap. De mapstructuur zou er ongeveer zo uit moeten zien:

Open de Windows SDK-opdrachtprompt die met de SDK is geïnstalleerd (Start => Microsoft Windows SDK => Windows SDK-opdrachtprompt) en voer de volgende opdrachten uit:

Setenv /release /xp /x86 cd C:\PHP-Dev bin\phpsdk_setvars.bat

Het gebruik van de opdrachtregel van de SDK-console verdient de voorkeur boven de gewone cmd.exe-console, omdat hiermee veel omgevingsvariabelen worden ingesteld die specifiek zijn voor het compileren van de broncode. Compilaties van opdrachten later moeten ook in deze console worden gedaan.

setenv stelt enkele build-eigenschappen voor de omgeving in, in dit geval is de doelomgeving de Windows XP 32-bits versie van de build. Je kunt proberen te bouwen met /x64 als je op zoek bent naar avontuur. Het definiëren van verschillende versies van Windows, zoals /Vista, zal hoogstwaarschijnlijk uitvoerproblemen opleveren vanwege een aantal vreemde definities in de scripts (PHP wil nog steeds XP-compatibel zijn). Tenzij je echt weet wat je doet, is het waarschijnlijk het veiligst om je aan de aanbevolen waarden te houden die ik hierboven heb gebruikt.

Het script phpsdk_setvars.bat heeft toegang tot enkele aanvullende omgevingsvariabelen, het bouwproces kon de binaire tools vinden.

Houd er rekening mee dat al deze variabele-instellingen slechts tijdelijke sessies in de console zijn. Als u snel alles sluit om later terug te komen om te compileren, moet u de opdracht opnieuw uitvoeren. Als u dat niet doet, krijgt u fouten zoals de volgende. Als u later configure uitvoert, kunt u niet doorgaan:

Controleren op bison.exe ... FOUT: bizons zijn vereist

Ervoor zorgen dat u over de juiste bouwomgeving, de benodigde bronnen en eventuele afhankelijkheden beschikt, is het moeilijkste deel van het proces. Dus nu uw omgeving is ingericht met broncode en afhankelijkheden, is het tijd om te compileren!

PHP compileren

Ga op de SDK-opdrachtregel naar de PHP-bronmap en voer buildconf uit. De opdracht is verantwoordelijk voor het genereren van configuratiebestanden die door Makefile worden gemaakt om het compilatieproces te besturen.

Nadat buildconf klaar is (dit duurt maar een seconde), voer je configure --help - uit en onderzoek je de help voor welke functies je wilt in-/uitschakelen. Voer vervolgens configure opnieuw uit met welke optie je maar wilt. Het is een goed idee om de uitvoer te controleren voordat u deze verplaatst, omdat deze u waarschuwt als een van de vereiste afhankelijkheden niet beschikbaar is. Als dit gebeurt, kunt u de afhankelijkheden installeren en de installatie opnieuw uitvoeren, of de aanroepen aanpassen om extensies uit te schakelen die deze nodig hebben.

Voer ten slotte NMAKE uit om te beginnen met compileren.

Cd C:\PHP-Dev\php5.4 buildconf configureer nmake nmake test

Als een configuratie of NMAKE mislukt, zijn er twee problemen: ten eerste is de omgeving niet correct geconfigureerd, ten tweede heb je een functie ingeschakeld die afhankelijk is van externe bibliotheken en zijn de bibliotheken niet op je systeem geïnstalleerd. Controleer nogmaals of u de omgeving hebt gemaakt volgens de bovenstaande instructies en of eventuele aanvullende bibliotheken die mogelijk vereist zijn in de onderliggende configuratie-instellingen, zijn geconfigureerd.

Wanneer de eerste NMAKE van het compilatieproces is voltooid, vindt u uw gloednieuwe PHP-bestanden in de map Release_TS. De NMAKE-test voert nieuwe dubbele capaciteitsfouttests uit om ervoor te zorgen dat alles naar behoren werkt. NMAKE-testresultaten worden naar het QA-team gestuurd dat ervan afhankelijk is om PHP te verbeteren, dus het kan een paar minuten duren om eraan te werken, het is een groot probleem.

Op dit punt kunt u ook profiteren van de extra stap van het uitvoeren van de NMAKE-module, waarmee ZIP-archieven en binaire bestanden worden gemaakt die u kunt kopiëren.

Compilatie-extensies

Er zijn twee manieren om PHP-extensies te compileren: statisch en dynamisch. Een statisch gecompileerde extensie wordt gecompileerd in een binair PHP-bestand, terwijl een dynamisch gecompileerde extensie één afzonderlijke DLL is die later kan worden geladen via een php.ini-bestand. Extensies worden over het algemeen gecompileerd als DLL's, hoewel er enkele voordelen zijn verbonden aan statische compilatie, en uiteindelijk hangt dit af van uw behoeften.

Om PHP-extensies op Windows te compileren, extraheert u de broncode-extensiemap in de ext-map van uw PHP-bronmap. Configureer vervolgens het script opnieuw door buildconf --force uit te voeren en PHP opnieuw te compileren met de juiste opties om de extensie in te schakelen.

Laten we als voorbeeld de AOP-extensie statisch compileren. Download de broncode van PECL en pak deze uit in een map ext. Volg dan deze stappen:

Cd C:\PHP-Dev\php5.4 buildconf --force configure --enable-aop nmake

De --force, buildconf optie dwingt het om het configuratiescript te herstellen. Voer vervolgens configure --help uit en u zou de optie moeten zien om de nieuwe extensie in de uitvoer in te schakelen. In dit geval is het --enable-AOP.

Wanneer nmake klaar is, heb je een nieuw gebouwd PHP-binair bestand met AOP.

De extensies zullen beschikbaar zijn als een DLL in plaats van in PHP gebakken. U kunt dezelfde stappen volgen als hierboven, maar door "gedeeld" op te geven als de waarde voor de configuratie staat deze optie toe.

Buildconf --force configureren --enable-aop=gedeeld

Als gevolg hiervan bevindt de DLL zich in de map Release_TS samen met het binaire PHP-bestand wanneer de compilatie eindigt. In dit geval is de naam php_aop.dll.

P.S.

Compileren op Windows is nog steeds een beetje lastig, vooral als het om extensies gaat. Het kunnen compileren van de broncode is een goede vaardigheid, vooral als je later PHP wilt wijzigen.

Het artikel is voor u voorbereid door het siteteam
Origineel artikel:
Vertaald door: Victor Klim

Bijna alle ontwikkelaars worden vroeg of laat geconfronteerd met de noodzaak om code uit te voeren of snel te controleren, maar niet iedereen weet dat het voor zo'n eenvoudige taak helemaal niet nodig is om zware desktop-IDE's of applicatiecompilers te draaien. Het is voldoende om online tools te gebruiken waarmee je alles veel sneller kunt doen: Ctrl+C, Ctrl+V, Uitvoeren, meppen - en de uitvoer van het programma is al voor je roodachtige ogen te zien.

We hebben de beste online compilers geselecteerd: sommige zijn vrij universeel, andere zijn op maat gemaakt voor strikt gedefinieerde taken. Ze zullen in ieder geval niet overbodig zijn.

Koding

Koding.com is geen online compiler in de traditionele zin van het woord. Elke gebruiker van de dienst kan in de cloud meerdere volwaardige virtuele machines met Ubuntu 14.04 creëren, waarop hij kan doen wat hij wil, inclusief het compileren van code. Alle populaire talen worden standaard ondersteund, maar u kunt eenvoudig uw eigen talen toevoegen.

Naast het controlepaneel voor uw server zijn in de interface een handige IDE en een terminalvenster beschikbaar. Koding is het meest universele hulpmiddel; hierna zullen we kijken naar eenvoudigere en meer gespecialiseerde opties.

IdeeEen

IdeOne is een online compiler- en debuggingtool waarmee u code in meer dan 60 programmeertalen en hun specifieke versies rechtstreeks in de browser kunt uitvoeren.

Voor degenen die geen vriendin hebben, hebben de makers een codecompilatie in de Brainfuck-taal verzorgd.

JDoodle

Nog een online compiler die vele talen ondersteunt, waaronder enkele die je in veel andere online compilers niet zult vinden. Een leuke functie van JDoodle is de mogelijkheid om samen te werken: stuur gewoon een link naar je huidige sessie en genereer bugs met dubbele snelheid!

jsFiddle

Laat je niet misleiden door de naam: jsFiddle is niet alleen gebouwd voor JavaScript. Met deze online front-end editor kunt u elke combinatie van JavaScript, HTML en CSS testen. Uiteraard is er ondersteuning voor verschillende frameworks, bijvoorbeeld jQuery, Vue, React, TypeScript, maar ook CSS-preprocessors zoals SCSS. Voor uw gemak kunt u een sneltoets uit uw favoriete editor selecteren. Toegegeven, alleen als je favoriete editor Vim, Emacs of Sublime Text is.

CodePad

CodePad is een minimalistische service waarin u code kunt opslaan, delen en uitvoeren, met daaropvolgende uitvoer van de resultaten van de uitvoering ervan. Er zijn verschillende van de meest voorkomende talen om uit te kiezen, maar helaas is er geen keuze uit specifieke versies van tolken of compilers.

Het belangrijkste voordeel is de eenvoud en het gemak: de site werkt snel, zelfs met een trage internetverbinding. Automatische verbinding van standaard headers is mogelijk, evenals integratie met Vim of Emacs.

Een van de nadelen is het volledige gebrek aan syntaxisaccentuering bij het invoeren van code in het formulier. Bij het bekijken van een reeds opgeslagen opname is de achtergrondverlichting echter aanwezig.

GCC GodBolt

GCC GodBolt is een interactieve C++-compiler. Ik ben in deze collectie terechtgekomen omdat het een eenvoudige interface heeft, evenals een groot aantal instellingen, inclusief opties die met toetsen kunnen worden aangepast.

Er zijn veel compilerversies waaruit u kunt kiezen, inclusief de nieuwste. Een van de interessante kenmerken is de onmiddellijke vertaling van de programmacode in assembleertaal.

PHP is een geïnterpreteerde programmeertaal; bij elke aanvraag wordt de broncode geanalyseerd en “uitgevoerd”. Deze aanpak is uiteraard erg handig in de projectontwikkelingsfase, maar introduceert een extra stap in het proces van het uitvoeren van productiecode. Interpretatie, wat op het eerste gezicht het sterke punt van PHP is, kost dus extra CPU-tijd en middelen.

Hieronder zullen we het hebben over compilers waarmee u PHP-code in C++ en in uitvoerbare code kunt compileren. PHP-applicaties worden dus rechtstreeks door de processor uitgevoerd, waarbij de tolk wordt omzeild.

Laten we eens kijken of alles in de praktijk zo goed is.

Hoe de tolk werkt

De interpretatie van PHP-code vindt plaats in twee fasen:

  1. Codeparsing en genereren van opcodes (Zend-opcodes) - instructies die begrijpelijk zijn voor de tolk.
  2. Uitvoering van opcodes.

Terwijl de eerste fase zich goed leent voor optimalisatie (met behulp van een opcode-cache), is de tweede tamelijk gesloten: de tolk is altijd een tussenpersoon tussen de reeks instructies en de processor die deze uitvoert. Zonder tolk kan de processor niet begrijpen wat hij met opcodes moet doen.

Om van de tolklink af te komen, zijn er compilers uitgevonden, waarvan HipHop van Facebook de meest populaire en recente is. Laten we het dichterbij voelen.

Hiphop PHP

HipHop is geschreven door Facebook-ontwikkelaars en is een applicatie die:
  1. optimaliseert PHP-code
  2. converteert naar C++
  3. genereert vanuit uw applicatie een multi-threaded webserver die deze uitvoert
  4. compileert naar uitvoerbare code met behulp van g++

De invoer is dus PHP-code, de uitvoer is een server, waarvan een deel de geschreven functionaliteit is.

Laten we eens kijken hoe HipHop om kan gaan met het compileren van een applicatie die is geschreven met behulp van een framework, zoals Wordpress.

Het samenstellen van Wordpress

Na het installeren van HipHop krijgen we in de map src/hphp/ het hphp-bestand, dat de compiler is. Voordat de compilatie begint, stelt u de omgevingsvariabelen in:

Cd .. # ga naar de map met hiphop export HPHP_HOME=`pwd` export HPHP_LIB=`pwd`/bin export CMAKE_PREFIX_PATH=`/bin/pwd`/../

en ga je gang!

Download Wordpress en pak het archief uit:

Wget http://wordpress.org/latest.tar.gz tar zxvf nieuwste.tar.gz

Kopieer wp-config-sample.php naar wp-config.php en specificeer de instellingen voor verbinding met de database (in de hostinstellingen specificeren we 127.0.0.1, niet localhost).

Voor een succesvolle compilatie moet je Wordpress een beetje patchen:

  1. Open wp-includes/js/tinymce/plugins/spellchecker/classes/SpellChecker.php en vervang: function &loopback(/* args.. */) ( return func_get_args(); ) met functie &loopback(/* args.. */ ) ( $ret = func_get_args(); retourneer $ret; )
  2. In wp-includes/query.php, in plaats van if (!isset($q["suppress_filters"])) $q["suppress_filters"] = false; voeg $q["suppress_filters"] = waar in;

Wordpress is klaar.

Hiphop moet de lijst met bestanden specificeren die we zullen compileren - we zullen deze ophalen en opslaan in files.list:

Vinden. -naam "*.php" > bestanden.lijst

Alles is klaar voor compilatie, laten we verder gaan:

$HPHP_HOME/src/hphp/hphp --input-list=files.list -k 1 --log=3 --force=1 --cluster-count=50

Na het voltooien van de opdracht ontvangen we in de tijdelijke map (aan het begin van de compilatie het pad ervan, zoiets als "/tmp/hphp_ptRgV1") een gecompileerde webserver. Laten we het starten (als er iets op poort 80 blijft hangen, bijvoorbeeld apache of nginx, moet je het eerst stoppen om de poort vrij te maken):

Sudo /tmp/hphp_6s0pzd/program -m server -v "Server.SourceRoot=`pwd`" -v "Server.DefaultDocument=index.php" -c $HPHP_HOME/bin/mime.hdf

Voila! Als we naar http://localost gaan, zien we een werkend Wordpress-blog.

Prestatie

Laten we eens kijken of er een prestatieverbetering zal zijn vergeleken met de niet-gecompileerde versie van WordPress die op apache2 draait. Hieronder vindt u grafieken van de afhankelijkheid van de snelheid van het genereren van pagina's van het aantal parallelle gebruikers.

Zoals je kunt zien waren de resultaten schokkend: de samengestelde blog draait gemiddeld 6 keer sneller! Het gemiddelde aantal verzoeken dat per seconde wordt verwerkt in de niet-gecompileerde versie is 9, en in de gecompileerde versie 50! Ik weet niet hoe het met jou zit, maar deze resultaten verbaasden mij; ik had niet zo’n sterke prestatieverbetering verwacht.

Laten we het samenvatten

Na zulke verbluffende resultaten kan er maar één ding gezegd worden: de jongens van Facebook hebben geweldig werk geleverd. De compiler maakt echt een raket van een applicatie, en hoewel de applicatie moet worden voorbereid voordat deze wordt gecompileerd, is het resultaat de moeite waard.

On-topic:

Als je het bericht leuk vond, klik dan op Google +1 - het geeft me meer motivatie om te schrijven en het zal gewoon een plezier zijn.

Er zijn twee soorten programmeertalen: geïnterpreteerd en gecompileerd. Welke taal is PHP? Om deze vraag te kunnen beantwoorden, moeten we de terminologie begrijpen.

Een programma dat code die in de ene programmeertaal is geschreven, in een andere vertaalt, wordt een vertaler genoemd. Een compiler is ook een vertaler. Het vertaalt code die in een taal op hoog niveau is geschreven, naar machinecode. Het compilatieproces creëert een binair uitvoerbaar bestand dat zonder compiler kan worden uitgevoerd.

Een tolk is een heel andere categorie. De tolk vertaalt de code niet, maar voert deze uit. De tolk analyseert de programmacode en voert elke regel ervan uit. Elke keer dat u dergelijke code uitvoert, moet u een tolk gebruiken.

In termen van prestaties zijn tolken aanzienlijk inferieur aan compilers, omdat binaire code veel sneller wordt uitgevoerd. Maar met tolken kunt u het programma volledig controleren tijdens de uitvoering ervan.

Wat PHP betreft, het is noch een compiler, noch een tolk. PHP is een kruising tussen een compiler en een tolk. Laten we proberen dit te begrijpen en kijken hoe PHP code verwerkt.

Laten we naar de foto kijken:

We zien dat PHP uit twee vrijwel onafhankelijke blokken bestaat: een vertaler en een tolk. Waarom moest je dit doen? Uiteraard vanwege de snelheid.

De PHP-invoer is een script. Het vertaalt het (vertaalt het), waarbij de syntaxis wordt gecontroleerd, in een speciale bytecode (interne representatie). PHP voert vervolgens de bytecode uit (niet de programmacode zelf), maar maakt geen uitvoerbaar bestand aan.

Bytecode is veel compacter dan gewone programmacode, dus gemakkelijker (en sneller) te interpreteren (uit te voeren). Oordeel zelf: het parseren wordt slechts één keer uitgevoerd in de vertaalfase en er wordt een "halffabrikaat" uitgevoerd - bytecode, wat veel handiger is voor deze doeleinden. Daarom is PHP meer een tolk dan een compiler. Dit “dubbele werk” was nodig voor de volgende doeleinden.

Beschouw de lus:

Voor (i=0;i<10; i++) { Operator_1; Operator_2; Operator_3; ............ Operator_99; Operator_100; }

Deze cyclus zal 10 keer “draaien”. Voor elk van deze tien passen moet de tolk dat doen 100 regels code. En het moet 10*100 = 1000 regels code analyseren en uitvoeren! Als je de hele lus één keer omzet in bytecode, dan hoeft hij 10 keer minder te analyseren! Dit betekent dat scripts 10 keer sneller draaien!

Het blijkt dat PHP dat is.

De belangrijkste fase van PHP's werk is de interpretatie van de interne representatie van het programma en de uitvoering ervan. Het is deze fase die in ernstige scenario’s de meeste tijd in beslag neemt. De vertraging is echter niet zo groot.

Het is de moeite waard om te onthouden dat PHP-versie 3 een “pure” tolk was, en dat PHP 4-scripts veel sneller begonnen te werken, aangezien PHP-versie 4 (en PHP5) een interpretatieve vertaler is.

De Perl-taal, die bijna altijd een compiler wordt genoemd, werkt op precies dezelfde manier: het vertaalt programmatekst naar een interne representatie en gebruikt vervolgens de resulterende code tijdens de uitvoering. Je zou dus kunnen zeggen dat PHP versie 4 net zo goed een compiler is als Perl.

We zijn dus genoodzaakt te concluderen dat PHP een tolk is met een ingebouwd vertaalblok dat de interpretatiestroom optimaliseert.

Het gebruik van een tolk (en dus PHP) heeft onmiskenbare voordelen:

  • U hoeft zich geen zorgen te maken over het vrijmaken van toegewezen geheugen, het is niet nodig om bestanden te sluiten als u klaar bent met werken - de tolk zal al het routinewerk doen, aangezien het programma onder waakzame controle draait;
  • Het is niet nodig om na te denken over typen variabelen, en het is ook niet nodig om een ​​variabele te declareren vóór het eerste gebruik ervan;
  • Het debuggen van programma's en het opsporen van fouten wordt aanzienlijk vereenvoudigd - de tolk heeft volledige controle over dit proces;
  • In de context van webapplicaties heeft de tolk ook een heel belangrijk voordeel: er bestaat geen gevaar dat de server “bevriest” als het programma niet correct werkt.

Er zijn ook andere voordelen. Over het algemeen kan het gebruik van een tolk scripts de kracht geven die internetgebruikers van hen verwachten.

De prestatievermindering van PHP is merkbaar in het geval van grote en complexe lussen, bij het verwerken van een groot aantal regels, enz. Houd er echter rekening mee dat dit het enige nadeel van PHP is, dat steeds minder zal verschijnen naarmate er krachtigere processors worden uitgebracht. , zodat ze uiteindelijk helemaal verdwijnen.

<<< Назад
(Wat is er nieuw in PHP5?)
Inhoud Vooruit >>>
(Overgang naar PHP 5.3)

Als u nog andere vragen heeft of iets niet duidelijk is, welkom bij ons