Acest material este produs sub licență CC BY 3.0 de către membrii echipei ITSpark.ro,
cu susținerea Microsoft România (Todi, Zoli, Sebi, Petru, @OpenAtMicrosoft și alții).

Subiectul utilizării PHP pe Windows/IIS este unul de care m-am lovit deseori de-a lungul timpului, însă în ultima perioadă am observat că multe dintre percepții se bazează în continuare pe informații vechi sau incorecte. De aceea, aș dori să încerc să lămuresc exact care e punctul în care s-a ajuns și să demontez câteva din miturile ce țin de suportul și performanța aplicațiilor web scrise în PHP sub server-ul web din Windows - IIS (Internet Information Services).

Scurt istoric

Răspândirea soluțiilor gen Wordpress, Drupal, Joomla, phpBB, MediaWiki, SugarCRM etc.  precum și utilizarea PHP de către entități precum Yahoo!, Flickr, Digg, Facebook, YouTube sau Wikipedia sunt doar o parte din motivele evidente care fac din PHP un limbaj de scripting greu de ignorat în domeniul web, și implicit și în zona Windows/IIS. Din acest punct de vedere, relația dintre Microsoft și comunitatea PHP a fost una plină de elemente interesante de-a lungul timpului...

Să ne întoarcem puțin în timp, și să vedem care era situația PHP/Windows la începuturi?

  • Nu exista nici măcar un programator dedicat care să se ocupe de dezvoltarea suportului PHP sub Windows
  • Windows era considerată o platformă secundară pentru PHP
  • Variantele binare (pentru Windows) erau publicate la zile sau chiar săptămâni de la publicarea surselor originale
  • Nu exista nici un fel de QA (quality assurance) pentru Windows
  • Documentația și comunicarea lipseau parțial sau complet

Uitându-ne la lista de mai sus, putem spune că situația nu era foarte încurajatoare. Ce s-a întâmplat între timp, și unde s-a ajuns?

  • S-a creat o echipă de dezvoltatori dedicată suportului pentru Windows
    • 2 programatori dedicați
    • 7 persoane care ajută, contribuie sau testează periodic codul (numărul lor e în creștere)
  • Windows a devenit acum o platformă primară pentru PHP
  • Publicarea noilor versiuni s-a realizat sincronizat, începând de la PHP 5.2.6 încoace
  • Există QA pentru Windows
    • Mai mult decât atât, peste 95% din testele de bază ale PHP trec din prima pe Windows
  • Au apărut canale de comunicare dedicate 

Pe lângă toate aceste schimbări, versiunea PHP 5.3 e de departe cel mai important update pentru PHP pe Windows de până acum. De ce spun asta? În principal deoarece:

  • Toate librăriile au fost actualizate la ultimele versiuni
    • În unele cazuri se folosesc versiuni chiar mai noi decât cele de pe Linux
  • S-a rescris întregul build system de la zero
  • Unul dintre programatorii cei mai importanți ai comunității PHP Windows (Pierre Joye) a ajuns să lucreze pentru Microsoft
  • Build-urile de PHP sunt acum compilate folosind VS 2008
  • PHP e acum disponibil atât pe 32 cât și pe 64 de biți
  • 99% din call-urile POSIX au fost transformate în call-uri native Windows

O soluție reală, disponibilă astăzi

În ceea ce privește utilizarea PHP sub Windows, în trecut alegerea se făcea clar între două extreme: stabilitatea oferită de IIS și performanța oferită de Apache. Astfel, chiar dacă Apache funcționează foarte bine și pe Windows (oferind performanță cu prețul stabilității), suportul PHP pentru IIS a existat și el de foarte mult timp, însă chiar dacă era mult mai stabil, îi lipsea performanța.

De unde acele probleme de performanță în IIS? Inițial, aveam două metode de a rula PHP sub IIS, fie folosind CGI (Common Gateway Interface), fie prin ISAPI (Internet Server Application Programming Interface), ambele cu avantaje și dezavantaje. Însă această barieră a dispărut odată cu apariția suportului pentru FastCGI în IIS, situația putând fi sintetizată astfel:

Datorită arhitecturii sale, handler-ul FastCGI se integrează în pipeline-ul de execuție al IIS. Ceea ce înseamă că acum aplicațiile PHP devin parte a acestui pipeline și deci pot fi tratate ca orice altă aplicație:

Ținând cont de îmbunătățirile aduse codului PHP în privința suportului pentru Windows, precum și de prezența FastCGI și integrarea PHP în pipeline-ul din IIS7+, putem afirma fără rețineri că Windows/IIS devine o platformă de prim rang pentru aplicațiile scrise în PHP din punct de vedere al performanței și stabilității.

Însă asta nu e totul. Chiar dacă PHP va funcționa foarte bine doar ținând cont de aspectele de mai sus, haideți să vedem ce alte soluții avem la dispoziție pentru a transforma acel ”foarte bine” în ”excelent”.

De la ”foarte bine” la ”excelent”

Una din principalele metode de a obține performanțe crescute în cazul tehnologiilor web este utilizarea soluțiilor de caching. Însă este foarte important să putem identifica varianta potrivită pentru fiecare caz în parte, deoarece utilizarea unor soluții neadecvate poate fi mai degrabă nocivă. Vom vedea în continuare de ce...

IIS Output Caching

Conținutul web se poate împărți în două mari categorii: conținut static și conținut dinamic. Conținutul static nu se modifică de la un request la altul, ci este întotdeauna la fel. Exemple de astfel de conținut îl reprezintă paginile HTML sau fișierele JPG/GIF/PNG. Pe de altă parte, conținutul dinamic se poate modifica la fiecare request – exemple aici ar fi paginile ASP.NET sau PHP.

Între aceste două categorii se situează conținutul ”semi-dinamic”. Imaginați-vă o pagină ASP.NET care execută un query pe o bază de date. Este evident că nu e necesar ca acel query să fie executat de fiecare dată când pagina este accesată dacă baza de date din spate nu se modifică decât foarte rar, în restul timpului putându-se servi conținutul static rezultat în urma acelui query, fără a se mai accesa baza de date.

Mai mult decât atât, IIS face cache automat pentru conținutul static (pagini HTML, imagini și fișiere CSS), deoarece aceste tipuri de conținut nu se modifică de la un request la altul. De asemenea, IIS detectează când acele fișiere au fost modificate, și le elimină din cache.

Prin soluția de Output Caching, IIS acoperă în plus și partea de conținut semi-dinamic, permițând ca server-ul web să ofere răspunsuri statice pentru pagini dinamice, crescând astfel scalabilitatea aplicațiilor.

Este foarte important de reținut însă că nu toate paginile dinamice ar beneficia de acest tip de caching. Paginile care sunt extrem de personalizate (cum ar fi de exemplu o soluție de e-commerce sau un forum) nu sunt buni candidați, deoarece conținutul dinamic se modifică foarte des.

Concluzionăm astfel că utilizarea Output Caching e relevantă doar în anumite cazuri, și că utilizarea sa pentru site-uri ASP.NET sau PHP existente, fără a avea o analiză clară, efecutată în prealabil, ar putea cauza probleme.

WinCache for PHP

Dacă Output Caching se ocupă de partea de conținut semi-dinamic, WinCache for PHP este un accelerator PHP destinat special creșterii vitezei aplicațiilor PHP care rulează pe IIS. Odată ce extensia WinCache este activată și încărcată de engine-ul PHP, aplicațiile vor beneficia de avantajele de funcționalitate fără să fie nevoie de modificări de cod suplimentare.

WinCache include 5 tipuri diferite de cache:

  • PHP Opcode Cache – PHP este un limbaj de scripting care citește un șir de date ce conțin text și/sau instrucțiuni PHP și produce un alt șir de date, de obicei în format HTML; aceasta înseamnă că pe un server web engine-ul PHP citește, parsează, compilează și execută un script PHP de fiecare dată când server-ul web primește un request. Acest proces de citire, compilare și execuție generează încărcare suplimentară pe CPU și pe sistemul de fișiere, afectând implicit și performanța aplicației PHP. Codul PHP astfel obținut (numit și opcode, sau operation code) este păstrat în memorie pentru execuții ulterioare ale aceluiași script, fără să mai fine nevoie de întreg procesul de citire/parsare/compilare.
  • File Cache – chiar și cu PHP opcode cache activat, motorul PHP trebuie să acceseze fișiere de tip script pe disc. Atunci când aceste script-uri sunt într-un file share, operațiile respective aduc cu ele un impact de performanță; WinCache include un file cache care va ține conținutul acelor fișiere PHP în memorie, reducând astfel accesul la disc al engine-ului PHP
  • Resolve File Path Cache – scripturile PHP includ deseori referințe către alte fișiere prin ceea ce se numesc ”relative file paths” (spre exemplu ”css/style.css”). Fiecare astfel de path este normalizat la un path absolut (spre exemplu ”d:\sites\itspark\css\style.css”) care indică locația exactă pe disc a fișierului. În momentul în care o aplicație PHP utilizează un număr mare de fișiere pe care le accesează pe baza unor astfel de ”relative paths”. Operațiile prin care acele path-uri sunt echivalate cu locațiile exacte (”absolute paths”) pot avea și ele un impact semnificativ asupra performanței. WinCache aduce și un Resolve File Patch cache, care va păstra acea echivalență între ”relative paths” și ”absolute paths”, contribuind astfel la creșterea performanței generale a aplicației.
  • User Cache (v1.1) – scripturile PHP se pot folosi de shared memory cache prin intermediul API-urilor de user cache. Astfel, obiecte și variabile PHP pot fi stocate în acest user cache și mai apoi reutilizate în requesturi ulterioare. Acest tip de cache poate fi folosit pentru a îmbunătăți performanța script-urilor PHP și pentru a partaja date între mai multe procese PHP
  • Session Handler (v1.1) – WinCache vine și cu un session handler, care va păstra datele sesiunilor PHP în shared memory cache. Această abordare evită operațiunile pe disc destinate scrierii și citirii datelor ce țin de sesiune, iar efectul este foarte vizibil atunci când o cantitate mare de date este stocată la nivelul sesiunii PHP

Astfel, utilizând WinCache putem obține un nivel de performanță mult peste cel implicit, fără să fie nevoie de vreo modificare în codul aplicației PHP, și fără să avem vreun impact negativ așa cum s-ar întâmpla spre exemplu în cazul utilizării neadecvate a funcției de Output Caching disponibilă în IIS.

Extensia WinCache este suportată pe următoarele configurații și versiuni:

  • Windows:
    • Windows XP SP3 cu IIS 5.1 și extensia FastCGI
    • Windows Server 2003 cu IIS 6.0 și extensia FastCGI
    • Windows Vista SP1 cu IIS 7.0 și modulul FastCGI
    • Windows Server 2008 cu IIS 7.0 și modulul FastCGI
    • Windows 7 cu IIS 7.5 și modulul FastCGI
    • Windows Server 2008 R2 cu IIS 7.5 și modulul FastCGI
  • PHP:
    • PHP 5.2.X, Non-thread-safe build
    • PHP 5.3 X86, Non-thread-safe VC9 build

Soluții de URL Rewrite

O altă funcție extrem de utilizată în cadrul aplicațiilor web este cea de URL Rewriting. În cazul utilizării PHP sub Apache, regulile de URL rewrite sunt stocate în fișierele .htaccess. Cum IIS nu suportă aceste fișiere, avem și aici câteva alternative:

SQL Server Driver for PHP

SQL Server driver for PHP e o extensie PHP 5 pentru Windows care permite integrarea scalabilă și rapidă cu Microsoft SQL Server direct din PHP, bazându-se pe driver-ul ODBC din Microsoft SQL Server 2008 R2 Native Client pentru comunicarea cu SQL Server.

Extensia SQL Server driver for PHP conține două drivere: SQLSRV și PDO_SQLSRV. SQLSRV oferă o interfață procedurală, pe când PDO_SQLSRV vine cu suport îmbunătățit pentru UTF-8 și implementează PHP Data Objects pentru accesul la date din toate edițiile de SQL Server pornind de la 2005 în sus (inclusiv SQL Azure).

Documentația oficială este disponibilă pe MSDN, aici.

SQL Server Reporting Services SDK for PHP

SQL Server Reporting Services SDK for PHP este o librărie care folosește API-urile SOAP din SQL Server Reporting Services pentru a permite dezvoltatorilor PHP să utilizeze funcțiile de Business Intelligence și Reporting din SRSS în aplicațiile lor.

Mai multe detalii pe pagina proiectului.

Microsoft Web Platform Installer

Despre Web Platform Installer a scris deja Cosmin în articolul său legat de Microsoft Web Platform. Pe scurt, folosindu-ne de WPI putem instala foarte ușor atât server-ul web IIS sau IIS Express, cât și toate elementele descrise de mai sus (PHP 5.2 sau 5.3, WinCache, URL Rewrite, SQL Server driver, etc) cu un efort minim.

Recomand călduros lectura articolului pentru mai multe detalii.

Concluzie

Prin articolul de mai sus am încercat să schimb eventualele percepții greșite și să arăt că suportul PHP sub Windows/IIS a evoluat enorm de-a lungul timpului, transformându-se astfel într-o soluție viabilă cel puțin echivalentă (ca performanțe/facilități) cu alternativele disponibile pe piață.

Link-uri utile

Aș dori să-i mulțumesc de asemenea lui Maarten Balliauw (ASP.NET MVP), cu acordul căruia am reutilizat mai sus o parte din ideile sintetizate într-una din prezentările sale.

Feedback