Spartus interneto veržimasis į mūsų gyvenimus ne tik keičia kasdieninius įpročius, bet ir pasaulinio tinklo vystimosi tendencijas. Jeigu prieš dešimtmetį vienas kitas IT kompanijos ar švietimo įstaigos darbuotojas turėjo tinklalapį, suformuotą iš keleto HTML (angl. hypertext markup language) kalba aprašytų dokumentų, šiandien dažnas internautas turi nuosavą arba kokiame nors socialiniame tinkle pildomą tinklaraštį, kuriame kasdien arba dar dažniau įrašo naują tekstą. Jau nekalbant apie naujienų portalus, kuriuose po kelių akimirkų gali skaityti naują straipsnį. Akivaizdu, kad internetiniam turiniui pasiekus tokį dinamiškumo lygį, nebeužtenka į serverį įkelti iš anksto suformuotą dokumentą. Prireikia tinklalapį generuoti dinamiškai, o šioje srityje PHP – neabejotinas lyderis.

PHP – kas tai?

Pats pavadinimo „PHP“ sudarymo būdas byloja apie programavimą: „PHP Hypertext Preprocessor“ yra rekursinis akronimas. Rekursinė, arba pati save vykdanti funkcija, tokia kaip faktorialo skaičiavimas, retkarčiais sutinkama sprendžiant užduotis kompiuteriu. Taigi santrumpos „PHP“ pirmasis žodis ir yra jis pats. Kiti du aiškiau atskleidžia tikrąją paskirtį – „hiperteksto priešprocesorius“ arba kitaip tariant, tinklalapių pateikimo tarnybinėje stotyje pagal programuotojo scenarijų (angl. script) veikianti hipertekstinio dokumento formavimo priemonė. Jos veikimą nesunku suprasti pagal tokį pavyzdį: programuotojas nori, kad tinklalapyje būtų rodomas jo atvėrimo laikas. Tokią, atrodytų, paprastą užduotį įgyvendinti statiškai, kuomet pats kūrėjas suformuoja HTML dokumentą ir jį įkelia į serverį, būtų neįmanoma. Tuo tarpu dokumentą generuojant dinamiškai tarnybinėje stotyje, su įdiegtu PHP palaikymu, pakanka parašyti tokį kodą:

[code lang=”php”] <html>
<body>
<p><?php echo(date("H:i:s")) ?></p>
</body>
</html>[/code]

Jį įvykdęs serveris lankytojo naršyklei perduos hipertekstinį dokumentą su įrašytu generavimo metu buvusiu laiku, pvz:

[code lang=”html”] <html>
<body>
<p>9:15:25</p>
</body>
</html>[/code]

Nors PHP kalba kurta specialiai dinaminiams tinklalapiams programuoti, jos panaudojimo galimybės tuo neapsiriboja. Komandinės eilutės aplinkos palaikymas leidžia PHP naudoti nepriklausomose programose su grafine sąsaja. Vis dėlto, šiame straipsnyje akcentuosime tinklalapių programavimo galimybes. PHP scenarijus gali būti įterptas į HTML dokumentą arba jį formuoti pats. Tarnybinėje stotyje įdiegta PHP programa naudoja scenarijų kaip įvestį, o išveda tinklalapį – hipertekstinį dokumentą ar kitokį failą, priklausomai nuo paskirties. PHP galima įdiegti į daugumą interneto serverių, veikiančių beveik bet kokioje operacinėje sistemoje ir platformoje visiškai nemokamai. Tai neabejotinai sąlygojo faktą, kad šį atvirojo kodo produktą, 2007-ųjų balandžio mėnesio „Netcraft“ duomenimis, pasirinko 20917850 tinklalapių.

Istorija

Iš pradžių „PHP“ žymėjo „asmeninį tinklalapį“ (angl. personal home page). Istorija prasidėjo 1994-aisiais, kai iš Grenlandijos kilęs programuotojas Rasmusas Lerdorfas „C“ programavimo kalba parašė CGI (angl. Common Gateway Interface) aplinkoje vykdomų programų rinkinį.

Čia reikia paminėti, kad CGI yra standartinis protokolas, įgalinantis internetiniame serveryje vykdyti išorines (neįeinančias į HTTP serverio programinį kodą) programas, kurios atsako į komandas, HTTP serveriui perduodamos išvesties turinį. Lerdorfas programų rinkiniu, pavadintu „asmeninio tinklalapio įrankiai“ (angl. personal home page tools), pakeitė „Perl“ programavimo kalba parašytus scenarijus, kuriuos jis naudojo savo asmeniniam tinklalapiui atvaizduoti. Šio rinkinio paskirtis buvo atvaizduoti Lerdorfo biografiją ir rinkti tinklalapio lankomumo statistiką. Programas jis sujungė kartu su kitu kūriniu – formų interpretatoriumi (angl. Form Interpreter) ir pavadino „PHP/FI“, į kurį taip pat įtraukė geresnį „C“ kalbos palaikymą ir darbo su duomenų bazėmis priemonę. To pakako paprastoms dinaminėms interneto aplikacijoms.

Siekdamas sparčiau aptikti klaidas kode ir jį tobulinti, Lerdorfas 1995-aisiais PHP išplatino viešai. 1996-aisiais šiai laidai suteiktas antros versijos numeris ir ji turėjo pradinį PHP kalbos funkcionalumą, į kurį įėjo „Perl“ stiliaus kintamieji, formų apdorojimas, galimybė įterpti HTML. Sintaksė buvo panaši į „Perl“ tačiau gerokai ribotesnė, paprastesnė ir nuoseklesnė.

1997-aisiais du programuotojai iš Izraelio Zeev Suraski ir Andi Gutmans perrašė programinio kodo sintaksės analizatorių (angl. parser) ir pavadino „PHP 3“, kalbos pavadinimą keisdami į tokį rekursinį akronimą, kokiu jis yra dabar.

Bandomosios versijos statuso „PHP 3“ „atsikratė“ 1998-aisiais, kai buvo išleista galutinė versija. Dėl interpretuojamos PHP prigimties, scenarijų nereikėjo kompiliuoti – programuotojo parašyti sakiniai buvo vykdomi sužadinus scenarijų. Kadangi „PHP 3“ scenarijus buvo galima įterpti į HTML dokumentus, šią programavimo kalbą labai pamėgo tinklalapių kūrėjai, išvarginti nuolatinio statiškų dokumentų atnaujinimo ciklo. 10 procentų visų interneto serverių buvo įdiegta trečioji PHP versija. Tais pačiais metais Suraski ir Gutmans pradėjo iš naujo perrašyti PHP branduolį, 1999-aisiais jį pavadinę „Zend Engine“. Šie programuotojai įkūrė kompaniją „Zend Technologies“ Izraelyje.

2000-ųjų gegužę išleista ketvirtoji PHP versija, pagrįsta „Zend Engine 1.0“. Pagrindinis kūrėjų tikslas buvo optimizuoti pagrindinį kodą, kad sudėtingi, didelės apimties scenarijai galėtų veikti našiau. Šioje versijoje pristatytos ribotos objektiškai orientuoto programavimo galimybės.

2002 pabaigoje, į versiją 4.2.0 įtraukta eksperimentinė CLI (angl. command line interface) versija, kaip alternatyva CGI. Pradedant 4.3.0 versija, CLI sąsaja yra numatytoji diegiant PHP. PHP vykdymo CLI ir CGI sąsajomis skirtumus aptarsime kiek vėliau.

2004-ųjų liepą išleista penktoji PHP versija, pagrįsta „Zend Engine II“, kurios pagrindinė naujovė buvo objektiškai orientuoto programavimo palaikymas. Versijoje taip pat įdiegtas „PHP Data Objects“ papildymas, užtikrinantis sparčią sąsają su duomenų bazėmis, stipriai pagerinta bendra programos sparta. Kurį laiką penktoji ir ketvirtoji versijos buvo vystomos lygiagrečiai, tačiau 2008-ųjų rugpjūtį „PHP Group“, dabar prižiūrinti PHP projektą, nusprendė nutraukti tolesnį ketvirtosios versijos palaikymą, palikdama versiją 4.4.9 paskutiniu šios šakos leidimu.

Žurnalo rengimo metu naujausia stabili ir palaikoma PHP versija buvo 5.2.8. Tiesa, šioje versijoje nėra palaikomas tarpinis variantas tarp statinio ir dinaminio reikšmių susiejimo su identifikatoriais (angl. late static binding), tačiau jį kūrėjai žada šių metų pirmąjį ketvirtį turinčioje pasirodyti PHP 5.3.0 versijoje. Joje taip pat planuojamas grupavimo konteinerių (angl. namespace) palaikymas, nuolatinio ryšio su MySQLi biblioteka galimybė, patobulintas XML apdorojimas (ir „XMLReader“, ir „XMLWriter“ įtraukti į branduolį) bei kitos naujovės.

Reikia paminėti, kad PHP bendruomenėje netyla diskusijos apie šeštąją versiją. Jos išleidimo data kol kas nenustatyta, tačiau jau žinomi kai kurios savybės. „PHP 6“ nebeturės register_globals, magic_quotes ir safe_mode direktyvų, bus pašalinta POSIX (angl. Portable Operating System Interface) reguliarių išraiškų funkcijos ereg ir kitos, vietoje kurių programuotojai bus įpareigoti naudoti spartesnes ir daugiau galimybių siūlančias PCRE (angl. Perl compatible Regular Expressions) funkcijas preg_match ir kt.

Prognozuojama, kad pastarasis pakeitimas sukels nemažai problemų, todėl nuspręsta reguliarių išraiškų palaikymą pašalinti iš branduolio, tačiau siūlyti kaip papildomą priedą (angl. extension). Šioje versijoje nebebus galima naudoti ASP stiliaus žymų <% ir %> – jas teks keisti į <?php ir ?>, nebebus palaikomos pirmosios „FreeType“ ir „GD“ versijos, taip skatinant naudoti naujausias. Šeštojoje versijoje numatomas pilnas unikodo palaikymas.

Kol kas nežinoma esminių pakeitimų, trukdančių „PHP 5“ pritaikytiems scenarijams sėkmingai veikti „PHP 6“ aplinkoje, todėl tikimasi, jog perėjimas prie šeštosios versijos bus lengvesnis nei iš ketvirtosios prie penktosios. Pastarajam skatinti net buvo suburta iniciatyvinė grupė GoPHP5, jungianti talpinimo paslaugų tiekėjus ir PHP aplikacijų kūrėjus, palaikančius penktąją versiją. Nepaisant perėjimo prie „PHP 5“, didesni talpinimo paslaugų tiekėjai vis dar siūlo galimybę specialios nuostatos pagalba tame pačiame serveryje naudoti ir ketvirtąją versiją.

Sparta

Kaip ir visų scenarijų programavimo kalbų, PHP scenarijai saugomi kaip žmogui lengvai skaitomas tekstas net ir vykdomosiose sistemose. Tai reiškia, kad PHP programa turi sukompiliuoti scenarijų jo aktyvavimo metu ir tai atlikti kiekvieną kartą. Akivaizdu, kad tai pailgina scenarijaus vykdymo trukmę nes, lyginant su jau sukompiliuotu scenarijumi, kaskart reikia atlikti viena vykdymo operacija daugiau – prieš vykdant kompiliuoti.

Kaip ir kitoms programavimo kalboms, PHP scenarijams yra sukurti kompiliatoriai. Juos naudojant kartu su PHP akceleratoriais, kurie patalpina sukompiliuotus scenarijus savo saugyklose, galima ženkliai paspartinti scenarijų vykdymą ir sutaupyti sistemos resursų, nes kiekvieną kartą aktyvavus scenarijų nebereikės kompiliuoti iš naujo.

Spartai įtakos turi ir kodo dydis. Todėl yra sukurti kodo optimizatoriai, gebantys sumažinti sukompiliuoto kodo apimtį bei atlikdami kitus veiksmus, mažinančius vykdymo laiką. Vienas iš tokių – PHP praplėtimas „Zend Optimizer“.

CLI prieš CGI arba sparta prieš saugumą

CLI ir CGI yra serverio aplikacijų programavimo sąsajos (angl. SAPI – Server Application Programming Interface). Kaip jau minėta, PHP veikia CLI sąsaja įdiegus pagal nutylėjimą. Ji yra spartesnė, leidžia kurti taikomąsias programas, nes PHP scenarijų gali vykdyti komandinėje eilutėje. Tiesa, pastaroji funkcija tinklalapių kūrėjams neaktuali, nes jų scenarijai dažniausiai vykdomi interneto serverio programos, pvz.: „Apache HTTP Server“, modulyje, o ne komandiniu rėžimu (angl. shell). Taigi pagrindinis argumentas rinktis diegti PHP CLI versiją tinklalapių tarnybinė stotyje būtų sparta.

Reikia nepamiršti, kad teisės, kurias sistemoje vykdymo metu turės PHP scenarijus, bus tokios pačios kaip vartotojo, kurio paskyra naudojama HTTP serveriui veikti. T. y. jeigu „Linux“ operacinėje sistemoje „Apache“ nustatytas veikti vartotojo nobody teisėmis, jam bus pasiekiami visi failai ir katalogai, kurios sistema leidžia šiam vartotojui. Jeigu tinklalapius tame pačiame serveryje turi keli vartotojai, CLI versiją naudoti nesaugu.

Tarkime, kad du vartotojai saugo savo puslapius atitinkamuose kataloguose: /home/gerietis/public_html ir /home/blogietis/public_html. Abiejų vartotojų public_html katalogai (ir failai juose) turi būti pasiekiami „Apache“ vartotojui (šiuo atveju nobody). Tai reiškia, kad vykdomas scenarijus /home/blogietis/public_html/skaityti_failus.php galės nuskaityti ir parodyti turinį failų, kurie saugomi /home/gerietis/public_html. Nesunku suprasti, kad taip vartotojas blogietis galės sužinoti pvz.: prisijungimo prie vartotojo gerietis forumo duomenų bazės duomenis, nes galės matyti konfigūracijos su tokiais duomenimis failą.

Dar didesnių problemų kiltų, jeigu gerietis kuriam nors vidiniam public_html katalogui, nurodytų leidimo rašyti teises (paprastai žymimas 777) – to paprastai reikia, jeigu norima, kad PHP scenarijus į serverį nusiųstų failą (nuotrauką ar pan.) arba rašytų į tekstinį failą. Tuomet blogietis galėtų įvykdyti scenarijų savo kataloge, kuris atvertų minėtą vartotojo gerietis katalogą ir taip pat galėtų jį keisti – rašyti, trinti, koreguoti.

Aprašytos situacijos galima išvengi naudojant PHP direktyvą open_basedir, kuri neleidžia išeiti iš tam tikro katalogo ribų su, pvz.: failų atvėrimo funkcija fopen().

Vis dėlto, saugiausia „Linux“ aplinkoje, kuria naudojasi daugiau nei vienas vartotojas, naudoti PHP CGI versiją ir papildomą priemonę-modulį „suPHP“. Ši kombinacija užtikrins, kad scenarijus bus vykdomas to vartotojo, kuriam priklauso failas, teisėmis. Praktiškai tai reiškia, kad scenarijus, kurį vartotojas gerietis sukūrė savo public_html kataloge, bus vykdomas ne nobody, o gerietis vartotojo teisėmis. Todėl šio failo prieigos atributus galima nustatyti taip, kad jį galėtų pasiekti tik jo šeimininkas (žymima 600). Tai užkirs galimybę vartotojui blogietis pasiekti ar daryti bet kokią įtaką šiam failui.

Dar vieną naudingą „suPHP“ galimybę iliustruosime pavyzdžiu. Sakykime, kad „Apache“ serveris sukonfigūruotas taip, kad anksčiau minėti vartotojų katalogai /home/gerietis/public_html ir /home/blogietis/public_html atitinkamai susieti su domenais www.gerietis.tld ir www.blogietis.tld. Įdiegus „suPHP“, „Apache“ konfigūracijoje, ties kiekvienu domenu (<VirtualHost> direktyvoje) reikia nurodyti vartotojų, kuriems priklauso susieti katalogai, vardus. Jeigu vardas, nurodytas konkretaus domeno <VirtualHost> direktyvoje, nesutampa su norimo įvykdyti scenarijaus failo savininko vardu, „suPHP“ išveda „Internal Server Error“ ir scenarijaus nevykdo.

Įsivaizduokime, kad vartotojas gerietis pamiršo uždrausti kitiems vartotojams rašyti į kurį nors katalogą, pvz.: /home/gerietis/public_html/failai paliko prieigos teises 777. Tuomet vartotojas blogietis įrašė į jį scenarijų viska_trinti.php. Kadangi failo šeimininkas yra blogietis, o „suPHP“ leidžia domeno www.gerietis.tld lankytojams vykdyti tik vartotojo gerietis scenarijus, atvėrus www.gerietis.tld/failai/trinti_viska.php scenarijus vykdomas nebus – „suPHP“ išves klaidą.

PHP CGI ir „suPHP“ naudojimas smarkiai kilsteli serverio saugumo lygį, tačiau turi savo kainą – stipriau apkrauna sistemą nei PHP CLI. Todėl reikia rinktis kas svarbiau – sparta ar saugumas. Jeigu tarnybinė stotis išimtinai skirta vienam tinklalapiui (t. y. tik vienam vartotojui) arba visus tinklalapius sukūrė ir prižiūri tas pats vartotojas (pvz.: tinklalapių kūrimo bendrovė talpina savo klientų, kuriems pati sukūrė svetaines, tinklalapius), tuomet naudoti PHP CGI ir „suPHP“ nėra būtinybės.

Šis straipsnis spausdintas žurnale „Naujoji komunikacija“ 2009 m. Nr. 2. (230), psl. 18-20. ISSN 1392-3927.