Můj ročníkový projekt na téma jak co nejvíce urychlit běh aplikací v
Transkript
Můj ročníkový projekt na téma jak co nejvíce urychlit běh aplikací v
Vysoké učenítechnické v Brně Fakulta informač ních technologií Roč níkovýprojekt Petr Soukup, 2003 Prohlaš uji, že jsem tuto diplomovou práci vypracoval samostatně pod vedením Ing. Jaromíra Maruš ince. Uvedl jsem vš echny podstatné literární prameny a publikace, ze který ch jsem č erpal. V Brně dne ................................... … … … … … … … … … … … … … Petr Soukup Abstrakt a klíčová slova Abstrakt Tato práce se zabývá problematikou vytváření interaktivního webové ho rozhraní s využitím PHP skriptů a databáze Oracle. Důraz je kladen především na vysokou efektivnost a rychlost tohoto řešení tak, aby systé m co nejlé pe zvládal ně kolik tisíc souč asně pracujících uživatelů. Kromě základních znalostí potřebných k vytváření takových aplikací jsou zde té ž shrnuty jednotlivé možnosti a techniky zvyšování výkonu webové ho serveru využívajícího PHP skripty. Klíčová slova PHP, Oracle, Apache, SQL, sqlplus, HTML cache, PHP cache, proxy server, komprese Abstract and keywords Abstract This paper is oriented on making interactive web interface using PHP scripts and database Oracle. The emphasis of this work is high efficiency and performance of this solution in order to manage few thousand users possibly working at the some time. Except the basic knowledge required for this implementation there are also summarized possibilities and methods how to increase performance of web server running PHP scripts. Keywords PHP, Oracle, Apache, SQL, sqlplus, HTML cache, PHP cache, proxy server, compression Obsah 1.Ú vod................................................................................................................................................11 2.Souč asnýstav..................................................................................................................................12 3.Jazyk PHP........................................................................................................................................13 3.1 Instalace PHP...........................................................................................................................13 3.2 Vkládání PHP do HTML ........................................................................................................13 3.3 Rozdíly mezi PHP a C++........................................................................................................13 3.4 Vkládání souborů do PHP skriptů...........................................................................................14 3.5 Zpracování dat z odeslaných formulářů..................................................................................14 3.6 Přístup PHP k databázím.........................................................................................................15 3.7 Optimalizace PHP kódu..........................................................................................................15 HTML caching.........................................................................................................................15 Využití cache pamě ti proxy serverů.........................................................................................16 Obcode cache...........................................................................................................................16 Komprese..................................................................................................................................17 4. Databáze........................................................................................................................................18 4.1 Jazyk SQL...............................................................................................................................18 4.2 Sqlplus.....................................................................................................................................18 5.Vzdálené spravování unixové ho poč ítač e.......................................................................................20 5.1 Š ifrované protokoly.................................................................................................................20 5.2 Nešifrované protokoly.............................................................................................................20 6.Implementace...................................................................................................................................22 6.1 Návrh tabulek relač ní databáze...............................................................................................22 6.2 Knihovna č asto využívaných funkcí......................................................................................23 Pomocné funkce - modul.php...................................................................................................24 Implementace HTML cache.....................................................................................................25 6.3 Práce s databází.......................................................................................................................27 Zobrazování tabulek.................................................................................................................28 Zapsání studenta.......................................................................................................................29 6.4 Testování rychlosti..................................................................................................................30 7.Závě r................................................................................................................................................34 -9- - 10 - 1. Ú vod Vývoj v oblasti informač ních systé mů kráč í nezadržitelně kupředu. Za necelých osm let rozvoje internetu i mimo akademickou obec v České republice se práce s internetem stává bě žnou záležitostí každodenního života stále vě tšího poč tu lidí. S poč tem lidí s přístupem na internet přímo úmě rně rostou i možnosti využití internetu. Nutno však podotknout, že vě tšina souč asných uživatelů využívá internet především k prohlížení zajímavých webových stránek –č asto internetových č asopisů a psaní elektronické pošty. Tato č innost však nepředstavuje nic revoluč ně nové ho, protože prohlížet č asopisy si můžeme např. v knihovně a poslat dopis na poště . To co je na internetu nové , je především možnost interaktivní komunikace se systé mem. Potenciál možností internetu v té to oblasti zůstává stále z vě tší č ásti nevyužit. Přestože je vše již technologicky zvládnuto, barié ra zůstává především v lidech. Ně které úřady již zahájily pilotní projekty v té to oblasti. Je to však teprve zač átek. Vě tšina bank již poskytuje službu tzv. přímé bankovnictví. Zvláštní je ale fakt, že poplatky za vedení té to služby se nastavují tak, aby se naprosté vě tšině lidí komunikace s bankou přes internet vůbec nevyplatila. Jisté je, že komunikace s klienty přes internet může být řádově mnohonásobně levně jší a pohodlně jší jak pro úředníky, tak pro klienty. Jelikož se soukromýsektor ani úřady do plné ho využívání možností internetu nijak zvlášť nehrnou, je především na vysokých školách, aby byly průkopníky v té to oblasti. Mají k tomu totiž dva zásadní předpoklady. Jak zamě stnanci, tak studenti nemají problé m s přístupem na internet a nemají také odpor k uč ení se ně č emu nové mu. Např. na Masarykově univerzitě v Brně již ně kolik let úspě šně funguje osobní administrativa studenta, ve které mohou na jednom místě na webu provádě t té mě ř všechny administrativní úkony spojené se studiem. VUT je v té to oblasti stále trochu pozadu. Jedním z takovýchto projektů je i projekt zapisování studentů do sportů CESA. V té to práci nejdříve uvedu č tenáře do problematiky zapisování sportů, poté jej krátce seznámím s principy a slabými místy jazyka PHP s ohledem na rychlost a možné obcházení tě chto slabých míst. V následujících kapitolách se krátce vě nuji popsání různých způsobů správy webové ho serveru na dálku, a té ž základní prací s databází. V poslední, nejrozsáhlejší kapitole, se vě nuji konkré tní implementaci, v níž na příkladech vysvě tluji použité techniky. - 11 - 2. Současný stav Jednotlivé kurzy sportovních aktivit jsou pořádány společ ně pro všechny studenty VUT všech fakult. Vyuč ující vypisují jednotlivé termíny různých sportů vě tšinou s omezeným poč tem studentů, kteří se mohou do kurzu zapsat. Zapisování probíhá tradič ně v prvním týdnu výuky, kdy je studentům již znám rozvrh. Zapisování sportů má i další specifič nost v tom, že není vyžadováno vysoké zabezpeč ení proti zneužití. Sporty jsou vě tšinou nepovinné bez vlivu na celkovýprospě ch studenta. Studenty je možné jednoznač ně identifikovat a zapsat jen se znalostí rodné ho č ísla. Stránka se zapisováním je přístupna komukoliv s přístupem na internet. Zneužití třetí osobou brání jen fakt, že pro tuto osobu není jednoduché si zjistit potřebná rodná č ísla studentů. Třetí osoba takté ž nemá k nežádané mu zapsání konkré tního studenta žádnou motivaci č i prospě ch. Proto se jeví tohle zabezpeč ení jako dostateč né . Tímto konstatováním nám odpadá celá problematika autentizace studentů, č ímž můžeme docílit znač né zjednodušení a zefektivně ní a tím i z rychlení přihlašování. V souč asné době již dva semestry elektronické zapisování do sportů funguje na technologii Oracle Portal. Jeho tvůrce a správce je pan Aleš Hrnč árek. Oracle Portal je aplikace spravovaná i používaná výhradně z webu. Je to velká všestranná aplikace a jako taková se stává nároč nou na hardware a obtížná pro optimalizaci. Na VUT studuje řádově deset tisíc studentů a proto naše aplikace musí být schopná odolávat tisícům studentů pokoušejících se o práci se systé mem souč asně . Je to tedy zátě ž, blížící se zátě ži velkých internetových serverů, jako například email.cz, které jsou na to patřič ně vybaveny. V minulých dvou semestrech se ukázalo, že použitá implementace na platformě Oracle Portal nedovedla spolehlivě odolávat tomuto náporu. V prvních hodinách se velké č ásti studentů nepodařilo ani do systé mu dostat, natož se přihlásit. Trávili tak v systé mu nedobrovolně celé hodiny č asto bez úspě chu. Tohle způsobovalo negativní zpě tnou vazbu v podobě mnohonásobně vě tšího poč tu lidí v systé mu. Po dohodě s panem Hrnč árkem jsme se rozhodli pro jeden z nejbě žně jších nástrojů pro tvorbu WWW stránek - PHP skripty využívající OCI funkce pro komunikaci s databází. OCI je zkratka „Oracle Call Interface”. Je to množina funkcí s rozhraním implementovaná pro vě tšinu bě žných programovacích jazyků tedy i PHP. - 12 - 3. Jazyk PHP PHP je skriptovací jazyk urč enýpro tvorbu WWW stránek. Psaní WWW rozhraní s užitím PHP skriptů je v souč asné době druhá možná nejrychlejší varianta hned po psaní kódu přímo v C++, což by ovšem bylo velice nepraktické . Podle literatury [7] jsou PHP skripty ně kolikanásobně rychlejší než konkurenč ní ASP skripty firmy Microsoft. PHP je volně k dispozici pod Open source licencí a používá se převážně pod spolehlivými linuxovými webovými servery, což je nesporně další velkou výhodou. PHP skript je uložen na serveru v jednom souboru společ ně se svým html kódem. Při požadavku na zobrazení souboru s příponou PHP je soubor nejdříve předán interpretu jazyka PHP. Interpret jazyka PHP nahradí č ásti souborů s PHP skripty jejich výstupem a teprve tento soubor odešle WWW prohlížeč i. Je také samozřejmě možné , že soubor na serveru s koncovkou PHP neobsahuje vůbec žádnýHTML kód jen samotnýPHP skript, nebo obsahuje jen HTML kód. Jelikož je PHP kód vždy nahrazen jeho výstupem, č lově k prohlížející si webové stránky tak nikdy nemá možnost podívat se na zdrojový kód skriptů, což je velkýpřínos pro bezpeč nost. V té to kapitole se pokusím struč ně popsat charakteristické rysy jazyka PHP. Často bývá více možností řešení č i zapsání. Já se ale převážně zmiňuji jen o tě ch základních, vě tšinou doporuč ených způsobech pro PHP verze 4 a výše. 3.1 Instalace PHP Aby jsme mohli využívat poč ítač jako webovýserver s podporou PHP, je nutné mít nainstalovanýjak webovýserver tak i PHP interpret. Nejč astě ji se používá webovýserver Apache, kterýmá implementaci na všech platformách. PHP interpret stejně jako webovýserver bývá obvykle souč ástí distribuce Linuxu, tudíž stač í jen při instalaci zvolit přidání tě chto balíč ků. Webovýserver Apache musí být nastaven pro spouště ní PHP interpretu v případě požadavku na soubory s koncovkou .php. Pokud chceme, aby naše PHP využívalo databázi je nutné mít nainstalovánu na stejné m poč ítač i i databázi nebo alespoňklientskýsoftware té to databáze. 3.2 Vklá dá níPHP do HTML Pro označ ení zač átku kódu PHP se používá řetě zec <?php, pro ukonč ení ?>. Vše uvnitř tě chto oddě lovač ů je považováno za PHP skript, kterýje proveden při každé m nač tení stránky. Tento PHP skript je nahrazen jeho výstupem. Naopak uvnitř PHP skriptu mohu vložit HTML kód generovat výstup např. použitím speciální funkce echo. echo ”<b>ahoj</b>”; Po nainstalování ově říme funkč nost vytvořením souboru test.php, kterýobsahuje jedinýřádek: <?php phpinfo() ?> . Funkce phpinfo vygeneruje tabulku informující o nastavení PHP. 3.3 Rozdíly mezi PHP a C++ Syntaxe Jazyka PHP je na první pohled podobná jazyku C++. Z hlediska programátora se liší především typovou volností bez nutnosti deklarovat promě nné před jejich použitím. To znamená, že promě nné nemají přiřazen typ a je na ně vždy možné nahlížet jako na řetě zec. Odpadá - 13 - tak nutnost konverze promě nné na řetě zec před vypsáním hodnoty promě nné . Pokud je řetě zcem zapsáno platné č íslo, lze na tento řetě zec pohlížet i jako na č íslo. Z té to vlastnosti vyplývají i další nutné změ ny o proti jazyku C++. Identifikátory promě nných vždy zač ínají znakem $. Pro spojování řetě zců se používá znak „.”, místo v C++ obvyklé ho znaku „+”. Z použité ho operátoru je tak zřejmé , jestli se má na promě nné nahlížet jako na řetě zce nebo na č ísla. Rozdílně se pracuje také s poli, které se stejně jako jiné promě nné nemusí deklarovat. Jako index může sloužit libovolnýřetě zec. Další rozdíly obou jazyků vyplývají z toho, že se jedná o interpretovanýjazyk. Například zavolání echo $$a; je platnýzápis a zobrazí obsah promě nné , jejíž jmé no je uloženo v promě nné $a. Práce se soubory je podobná, ovšem je zde i možnost celýsoubor nač íst do pole a pak se souborem pracovat po jednotlivých řádcích v libovolné m pořadí. Rozdíl je také s přístupem k globálním promě nným. V PHP není přístup ke globálním promě nným uvnitř funkcí automatický. Musí se buď deklarovat klíč ovým slovem global na zač átku funkce a nebo k nim přistupovat přes pole GLOBALS. PHP stejně jako C++ podporuje objektově orientované programování. Na rozdíl od C++ však je dobré mít na pamě ti, že k překládání zdrojové ho kódu za normálních okolností dochází vždy před nač tením stránky. Proto využívání rozsáhlejších knihoven a objektových konstrukcí může být na škodu v případech s velkou zátě ží serveru. Celkově je používání jazyka PHP oproti C++ mnohem jednodušší a snadně ji se pracuje především s řetě zci. 3.4 Vklá dá nísouborůdo PHP skriptů I vkládání souborů funguje obdobně jako v jazyce C++. Za klíč ovým slovem include následuje řetě zec se jmé nem souboru, kterýse má vložit. Soubor může být obyč ejnýHTML soubor, nebo další PHP skript. Tento PHP skript musí být stejně jako v jaké mkoli jiné m souboru uzavřen mezi řetě zci <?php a ?>. Často se tento způsob používá k deklaraci funkcí, které jsou společ né pro více skriptů. Tímto způsobem se tedy vkládají použité knihovny. V mé m projektu takto vládám do vě tšiny skriptů dva soubory: modul.php a cache.php. Soubory mají z bezpeč nostního důvodu také koncovku php, aby nebylo možné zobrazit jejich zdrojovýkód při přímé m zavolání webovým prohlížeč em. 3.5 Zpracová nídat z odeslaný ch formulá řů V PHP se velice snadno pracuje s daty, které byly aplikaci zaslány uživatelem pomocí formulářů. Existují dva druhy způsobů jak přené st data vyplně né uživatelem na server. Metoda get předává data přímo v hlavič ce URL. Metoda post zašle data na jiné m místě v souboru dat posílaných prohlížeč em WWW serveru. Výhoda i nevýhoda get je v tom, že v adrese URL jsou všechny vyplně né údaje viditelné . Také je možné si tuto adresu uložit např. mezi oblíbené a poté se vrátit zpě t na stejné místo stránek. Pro úč ely přihlašování sportů je tohle spíše výhodou, protože si tak může ně kdo uložit adresu informací o různých termínech například fotbalu. Také je snadně jší ladě ní, protože je krásně vidě t, co předchozí skript předal tomu souč asné mu. Naproti tomu post se může hodit, pokud ně kdo zadává heslo a my nechceme, aby pak bylo zobrazeno v URL, které je mimo jiné možné dohledat v historii prohlížených stránek. V PHP jsou hodnoty předány metodou post k dispozici v poli $_POST[] a hodnoty předány - 14 - metodou get v poli $_GET[]. Jako index pole slouží jmé no promě nné . 3.6 Přístup PHP k databá zím Jednou z možností komunikace PHP a databáze je pomocí OCI funkcí. Všechny OCI funkce zač ínají písmeny OCI a je možné najít jejich podrobnýpopis ve standardním PHP manuálu.[1] Obdobné funkce jsou i pro přístup k jiným databázím, které zač ínají vždy písmeny identifikující databázi. Funkce pro přístup k databázi MySQL zač ínají vždy MySQL_. K databázi Oracle by bylo také možné přistupovat přes funkce ODBC, které jsou společ ným rozhraním pro vě tší množství databází. Lze ovšem oč ekávat, že by programování bylo zdlouhavě jší a přístup by nebyl tak efektivní, jako užitím originálních funkcí. Možností přístupu k oraclovým databázím je té ž skupina starších, údajně lehce mé ně výkonných, funkcí zač ínající řetě zcem ora_. O přistupování k databázi se podrobně ji zmíním až při objasňování konkré tní implementace. 3.7 Optimalizace PHP kó du. Samotnýfakt, že se jedná o interpretovanýjazyk naznač uje, že rychlost PHP skriptů by mohlo být slabým místem při užívání PHP. Navíc jsou PHP skripty standardně volány vždy, když dojde k požadavku na zobrazení stránky, přestože se stránka celé dny nemě ní a stač ilo by ji vygenerovat jen po změ ně ně kterých dat. Tato vlastnost při bě žné m použití vede evidentně k velké mu plýtvání strojové ho č asu serveru. Navzdory tě mto zkuteč nostem kapitoly zabývající se redukcí tohoto plýtvání v literatuře o PHP té mě ř vždy chybí. Naště stí je možné nalé zt ně kolik velice dobrých č lánků na internetu na toto té ma. HTML caching Při požadavku na zobrazení stránky se vygenerovanýHTML kód uloží do vyrovnávací pamě ti cache, aby tak v následujícím volání před uplynutím platnosti té to stránky se nemusela znovu generovat. Ukládá se vě tšinou rovnou do textové ho souboru, nebo bývá také implementována varianta ukládání tě chto dat do databází. Při ukládání tě chto dat do databází je však sporné , jestli se dosáhne vůbec ně jaké ho zrychlení. Dalším zajímavým faktem je, že veškeré řešení, na které jsem na internetu narazil, kešování řeší na úrovni PHP skriptů. Vždy se jedná o ně jakou knihovnu, která se pak vkládá do hlavního skriptu, kterýmá HTML caching podporovat. Je zřejmé , že nejlepší by bylo mít uloženou pamě ťcache v pamě ti RAM, č ili v promě nných nebo nejlé pe poli, ke které mu by mě ly přístup všechny PHP skripty na dané m serveru. Každýskript by si tak na zač átku zjistil, jestli není platnýHTML výstup uložen v tomto poli a pokud by byl, použil by jej místo generování. Bohužel však souč asná verze PHP tuto možnost (narozdíl od konkurenč ních ASP skriptů) zatím nepodporuje, přestože může být velice užiteč ná. Je tedy nutné ukládat takto vygenerovanýHTML kód do souborů. Na druhé straně operač ní systé m Linux disponuje natolik výkoným souborovým systé m, že č asové zpoždě ní při č tení z č asto přistupovaných souborů je naprosto zanedbatelné . Další informace je možné nalé zt v implementač ní č ásti mojí práce nebo v literatuře [9]. - 15 - Využ ití cache pamě ti proxy serverů To, jestli a na jak dlouho je možné data uložit do cache pamě ti proxy serverů, č i vyrovnávací pamě ti klientské ho poč ítač e, urč uje obsah HTTP hlavič ky. Je nutné si uvě domit, že HTTP hlavič ka není uvnitř HTML kódu, ale samotné mu HTML kódu předchází a generuje ji web server. Obsah tě chto hlavič ek je v PHP možné ovlivnit voláním funkce header(). Různých kombinací nastavení je spousta a nastavení není triviální. Co může fungovat s jedním proxy serverem a WWW prohlížeč em nemusí fungovat s jiným. Ú spory v podobě snížení zatě žování sítě a zrychlení odezvy mohou však být naprosto zásadní. Pro naše potřeby se jeví možné použití především přidání do hlavič ky HTTP následně popsaných dvou řádků. První z nich je uvozen řetě zcem „Expires:”a urč uje přesnýokamžik konce platnosti stránky. Např. Expires: Fri, 30 Oct 1998 14:19:41 GMT. Je nutné si uvě domit, že se jedná o č as v Londýně , kterýje považován za svě tovýč as. Pokud naše stránka má platnost jen řádově desítky sekund, uvádě ní absolutního č asu zjevně není možné , protože systé movýč as poč ítač ů bývá nastaven s menší přesností. Lepší je nastavit č as vypršení stránky relativně v sekundách. Tohle nastavení je v hlavič ce uvozováno řetě zcem „CacheControl:”. Udává poč et sekund platnosti dat. Příklad: Cache-Control: max-age=3600, public. Přesnýpopis všech možností lze nalé zt např. v [6]. Ošetření zasílání správných hlavič ek je možné vložit do knihovny obstarávající HTML cache na úrovni PHP, která má k dispozici informace o dé lce platnosti souborů. Obcode cache Pro PHP od verze 4 se před spuště ním nejprve PHP skript přeloží do mezikódu, v anglič tině nazývané ho Zend Opcode. V dalším kroku je tento mezikód proveden a vygenerován HTML kód a poslán klientovi. Zrychlení oproti starším verzím PHP bylo především v případě smyč ek, kdy opakované procházení uložené ho mezikódu je podstatně rychlejší než sledování příkazů v textové m souboru. Tímto vylepšením se PHP zač íná řadit spíše mezi jazyky jako je java. Znač nou nedokonalostí ovšem je, že překládání na mezikód probíhá vždy před spuště ním skriptu. Předpokládám, že tahle zjevná nedokonalost je zde zámě rně , aby autoři PHP mohli nadstavbu řešící tento problé m komerč ně prodávat. Existují zde i jiné alternativní volně šiřitelné implementace, i když více č i mé ně za originálním řešení pokulhávají. Jedním z doporuč ovaných freewarových řešení je PHP Accelerátor. [13] Míra zrychlení záleží především na dé lce kódu, kterýby jinak bylo nutné vždy překládat před spuště ním. Za dobrých podmínek se může průchodnost systé mu zvýšit až trojnásobně . Moje aplikace by se ale mohla řadit spíše k aplikacím s kratším kódem, tudíž nepředpokládal bych tak podstatné zrychlení. - 16 - PHP Script compilation Zend Opcode optimization Optimized obcode caching Opcode Cache Cached html execution html compression Compressed html sending Web Browser Obrázek 3.1Diagram toku dat. Šedé obdé lníky jsou nepovinné a přidávajíse pro zvý š ení vý konu. Obrázek převzat z literatury [8]. Komprese Další č asto velice úč innou možností jak zvýšit rychlost zobrazování stránek je používání komprese. Do HTTP hlavič ky je nutné přidat řádek s obsahem Accept-Encoding: gzip , aby tak WWW prohlížeč vě dě l, že obsah zprávy musí před použitím dekomprimovat. Kompresi podporují jen nově jší prohlížeč e jako Internet Explorer 4.0 a Netscape 4, proto je nutné vždy zjišťovat, zdali je možné pro dané ho uživatele kompresi použít. Nevýhodou je, že komprimace vyžaduje jistýstrojovýč as serveru, kterýmusí každou zprávu komprimovat předtím, než ji odešle. Kompresi zatím nelze kombinovat s využíváním proxy serverů, ale lze ji s výhodou zahrnout do implementace HTML cache. Vygenerovanou stránku můžeme do pamě ti cache ukládat jak ve zkomprimované tak i v nezkomprimované verzi. Další informace o používání komprese lze nalé zt například v literatuře [11]. Využívat kompresi je výhodné především u delších HTML nebo textových souborů zvláště v případě , pokud je slabým místem průchodnost sítě např. v případě připojování na internet přes telefonní linku. Za tě chto okolností je možné dosáhnout ně kolikanásobné ho zrychlení. Pro přihlašování do sportů s využitím mé implementace by nebyla č asová úspora tak výrazná, protože velikost přenášených souborů obvykle nepřesahuje 5kB a přihlašování se odehrává především uvnitř sítě VUT. - 17 - 4. Databáze Databáze je soubor dat organizovanýtak, aby k datům bylo lehké přistupovat, data mohla být lehce spravována a aktualizována. Obvykle se k tomuto úč elu užívají speciální aplikace. V našem případě využíváme produkt firmy Oracle. Existují ovšem i případy, kdy je dobré se zamyslet nad tím, zda-li pro webovou aplikaci má smysl využívat databázovou aplikaci, nebo data ukládat v podobě souborů a adresářů rovnou na disku serveru. Pokud máme menší množství dat snadno uchovatelných v tě chto souborech, nemusíme služeb databáze č asto využít. Pokud je navíc k tě mto datům č asto přistupováno můžeme tak docílit znač né ho zrychlení. Příkladem je č ítač poč tů přístupů na stránky č i ukládání statistických údajů o zatě žování serveru. Naproti tomu při velké m množství dat, ke kterým je navíc možné přistupovat různými způsoby je využití databázové aplikace přínosem. 4.1 Jazyk SQL Standardem pro přístup k datům v relač ních databázových systé mech je jazyk SQL. Příkazy jazyka SQL umožňují přidávat a modifikovat tabulky a té ž přidávat, modifikovat, vypisovat a mazat jednotlivé záznamy v tabulce. Přestože je jazyk SQL standardizovanýnormou ISO i ANSI, mnohé implementace mají své odlišnosti a rozšíření oproti standardu. Často je také možné kromě příkazů jazyka SQL databázi spravovat užíváním administrač ních nástrojů příslušné ho databázové ho systé mu. Mohou však mít své více č i mé ně skryté vady a např. i z důvodu snadně jšího přechodu na jiné verze a platformy systé mu č i dokonce na úplně jiné databázové systé my osobně preferuji administraci v podobě SQL skriptů. Mohu tak mít jeden skript na vytvoření všech tabulek a trigerů mé ho projektu a další skript pak na naplně ní tě chto tabulek daty č i opě tovné zrušení tě chto tabulek apod. Navíc pokud máme databázi nebo jejího klienta nainstalovány na unixové m poč ítač i, podstatně se tak zjednoduší vzdálená údržba databáze. Bude ji pak možné provádě t bezpeč ným způsobem z které hokoli poč ítač e připojené ho na internet bez nároků na speciální software. 4.2 Sqlplus Ke spouště ní sql skriptů č i interaktivních SQL příkazů slouží u produktů Oracle program s názvem sqlplus. Ostatní databázové systé my mají vždy k dispozici ně jakou obdobu tohoto programu. Jedná se o textovýprogram, kterýmůže bě žet a chovat se úplně stejně v dosovské m okně i v konzole operač ního systé mu Linux. Po spuště ní vyzve k zadání uživatelské ho jmé na a hesla. Uživatelské jmé no je možné zadat v podobě uživatel@hoststring. Sqlplus se připojí k databázi, která je definována řetě zcem hoststring. Význam řetě zce hoststring je definován v souboru tnsnames.ora, kterýje možné nalé zt v podadresáři network/admin. Je v ně m uvedena IP adresa, port a způsob připojení k databázové mu serveru. Je také možné , že pro řetě zec hoststring bude přítomná třetí výzva promptu. V případě instalace pro Windows, je možné spustit více uživatelsky přátelskou verzi s názvem sqlplusw, která využívá prostředí Windows. Ovšem ani tato verze se zásadně od své textové verze pro primitivní terminály neliší. Po spuště ní je možné napsat - 18 - libovolnýSQL příkaz ukonč enýstředníkem a zmáč knout Enter. Příkaz bude okamžitě proveden. Bližší návod pro práci s sqlplus lze nalé zt např. v [5]. Pro složitě jší příkazy nebo skupiny příkazů bych doporuč il používat ně jakýtextovýeditor a hotové příkazy vkládat do sqlplus pomocí schránky. Rozsáhlejší skupiny sql příkazů je také možné uložit do souboru a ten potom spustit napsáním např. @./install.sql , kde za znakem @ následuje soubor se skriptem. Skript je také možné spustit rovnou z příkazové řádky dosu nebo unixové ho shellu napsáním : sqlplus login/passwd@hoststring @./install.sql - 19 - 5. Vzdálené spravování unixového počítače Poč ítač , na které m bě ží WWW server, obvykle bývá vyhrazen výhradně k té to č innosti z bezpeč nostních, ale i praktických důvodů. Proto je nutné řešit vzdálenou administraci serveru. Pro samotné vyvíjení HTML stránek a PHP skriptů je možné si nainstalovat server i databáze na svůj pracovní poč ítač a systé m vyvíjet lokálně na ně m. Není tak vyžadováno konstantní rychlé připojení k internetu a programátor má na své poč ítač i rootovská práva a všechny soubory s kterými pracuje vždy k dispozici. Je možné tímto způsobem předbě žně i testovat rychlost skriptů. Pokud je však již systé m používán, č i se chcete vyhnout nutnosti dvojí instalace veškeré ho software, je potřeba zpravovat systé m na dálku. 5.1 Š ifrované protokoly Tradič ně se pro vzdálené připojování na unixové systé my používá textová konzole s šifrovaným protokolem ssh1, nebo ssh2. Je dostateč ně bezpeč ná, rychlá a praktická. Na té to konzoli je možné na dálku spouště t unixové programy, které jsou zobrazovány na klientské m poč ítač i. Nevýhodou je, že se dají spouště t pouze terminálové aplikace (č ili textové ). S konzolových programů bych doporuč il MC (Midnight Commander), kterýpodobnýznámé mu Nortonu Commanderu. Může být užiteč nýi jako ftp klient a má také zabudovanývýbornýeditor. Nejnově jší verze MC podporuje i zvýrazňování syntaxe PHP skriptů. Osobně považuji zpravování PHP skriptů s využitím editoru MC za dostateč ně pohodlnýzpůsob. Nejnově jší verzi MC je možné přeložit a nainstalovat i bez rootovských práv- samozřejmě do jiné ho než standardního adresáře. Pomocí tě chto šifrovaných protokolů je možné přenášet i soubory. Mezi unixovými systé my je možné použít program scp, kterýfunguje podobně jako obyč ejnýcp. (viz. man scp). Pro přenášení souborů na a z operač ního systé mu Windows existuje uživatelsky velice příjemnýklient od č eské ho autora s názvem winscp. 5.2 Nešifrované protokoly V souč asné době nejpoužívaně jším nešifrovaným protokolem, přes kterýse posílá nešifrované heslo po síti je protokol ftp. Pokud je použit jen pro lokální přenos a nejedná se o možné prozrazení strategicky důležitých a zneužitelných dat je tento způsob akceptovatelný. Nicmé ně je dobré omezit IP adresy, z kterých je možné se k serveru přihlašovat, protože připojovat se na ftp zvenč í je znač né bezpeč nostní riziko zvláště v případě , že použité heslo je shodné s heslem pro přihlašování do systé mu. Tomuto se mohu vyhnout tím že ftp server spustím na poč ítač i, na které m pracuji a k ně mu se pak připojím z webové ho serveru. Heslo si tímto způsobem mohu zvolit libovolné a IP adresu si omezit na adresu našeho serveru. I tento způsob však není 100% bezpeč ný, protože ně kdo na cestě si mohl č íst posílané soubory. Používat ftp po každé - 20 - změ ně skriptů může být také velice nepohodlné , zvláště když k tomu nemáme podporu rovnou v editoru PHP nebo HTML souborů. Jiné řešení pro přenos souborů, je spustit na webové m serveru Sambu. Samba je program, kterýumožňuje sdílení disku na unixové m poč ítač i s operač ních systé mu Windows. Je té ž nutné omezit přístup jen na lokální nebo přímo vybrané IP adresy. Práce se soubory by tak byla velice pohodlná pro uživatele Windows. Další možné řešení jak pohodlně pracovat se soubory na serveru je spouště ní X-Window aplikací přímo na serveru, ale zobrazování a ovládání tě chto aplikací z jiné ho poč ítač e. Je možné využít i šifrovaných protokolů. Nevýhoda je v tom, že pokud je server ve stejnou dobu i používán, může spouště ní tě chto rozsáhlejších aplikací server výrazně zpomalovat. Obecně se ani pro webové servery nedoporuč uje systé m X-Windows instalovat. Pokud ovšem netrápí doč asné snížení výkonu serveru je tento způsob také velice pohodlný. Pro spuště ní aplikace se stač í přihlásit na WWW server pomocí ssh a přesmě rovat zobrazování nastavením promě nné display takto: export DISPLAY=moje.ip.vutbr.cz:0 . Po nastavení promě nné display mohu spustit libovolnou aplikaci pro x-window systé m např. editor kate. Pokud pracuji na poč ítač i s Windows, musím na ně m mít nainstalovanýtaké X-server. Nalezení kvalitního freewarové ho X-serveru pro Windows může být znač nýproblé m. Pokud však pracuji na poč ítač i se systé mem Linux, stač í jen povolit zobrazování z IP adresy klienta příkazem xhost +ip.serveru.vutbr.cz . Pro Linux jsou k dispozici kvalitní HTML editory se zvýrazňováním syntaxe PHP, které je možné tímto způsobem využít. - 21 - 6. Implementace Jak již bylo zmíně no v úvodu, pro implementaci přihlašování do sportů byla vybrána kombinace Apache, PHP a Oracle databáze. Databáze bě ží na jiné m poč ítač i než webovýserver, což potencionálně znamená další možné zvýšení výkonu. Je ale nutné , aby na webové m serveru byl nainstalovanýOracle klient kvůli potřebným knihovnám pro komunikaci s databázovým serverem. Sché ma komunikace je možné vidě t na obrázku 6.1. Ze stránky firmy Oracle je možné stáhnout verzi Oracle client jak s variantou pro Windows tak i pro Linux. WWW server (Apache) Oracle server Oracle klient WWW klient (Netscape) Obrázek 6.1:Sché ma komunikace poč ítač ů při zapisovánísportů 6.1 Ná vrh tabulek relačnídatabá ze Existuje jisté množství sportů jako badminton, basketbal, fotbal atd. Dále existuje přes dvacet různých sportovišťv Brně využívaných VUT k vyuč ování tě chto sportů. Každýze sportů má své termíny (od do) na různých sportovištích. Každýtermín obsahuje informaci o maximálním poč tu studentů a poznámku, v které může vyuč ující sdě lovat různé speciální požadavky. RE diagram použitých tabulek je na obrázku 6.2. Z obrázku je zřejmé , že zde může vznikat jistá redundance (více termínů může mít shodné poznámky případně i další informace). Nabízí se tedy možnost vytvoření další tabulky - tabulky kurzů. Každýkurz by mě l jeden nebo více termínů. Z hlediska zásad vytváření relač ních databází je tabulka kurzů jistě na místě . Ovšem v naší aplikaci je kladen důraz především na rychlost. Jelikož požadavek na tabulku termínů vč etně doplňujících informací je jeden z nejč astě jších složitě jších SQL dotazů bě hem samotné ho procesu zapisování studentů, může být ušetření jedné tabulky znač nou č asovou úsporou. Je také dána vě tší volnost uč itelům, kteří tak mohou pro každýtermín volit jiná specifika podle potřeby. Tato redundance té ž umožňuje mírné zjednodušení administrace. Další nutnou tabulkou je kopie tabulky studentů. Tato tabulka musí obsahovat především - 22 - rodná č ísla studentů, aby bylo možné rozpoznat, zda-li zadané rodné č íslo je rodným č íslem ně které ho ze studentů, nebo se jedná o překlep. Může také obsahovat pro kontrolu i údaje jako jmé no, příjmení a fakultu. Poslední je tabulka, s názvem registrace. Každýřádek té to tabulky obsahuje rodné č íslo ukazující na konkré tního studenta, ale také identifikač ní č íslo termínu, ukazující na jeden konkré tní termín. Každýstudent smí mít jeden termín registrovanýmaximálně jedenkrát, proto jsem obě tyto položky označ il jako primární klíč e. Jeden z nových požadavků pana Zelinky z CESY bylo umožnit při zápisu vložení emailové adresy, na kterou by bylo možné zasílat studentovi informace. Jednou z možností by bylo aktualizovat tabulku studentů, nebo vkládat záznamy do úplně nové tabulky, pokud by tabulka studentů byla jen pro č tení. Z hlediska rychlosti a jednoduchosti implementace samotné ho zápisu je však dostateč né vkládat email, případně i další Registrace * - datum reg. - email * Student Termín - jmé no - login - rodné č íslo - fakulta - den - od - do - volných míst * Místo - adresa * Sport - název Obrázek 6.2:RE-diagram použitý ch databázový ch tabulek informace jako fakulta č i roč ník přímo do tabulky registrace. Jelikož tabulky jednotlivých sportů a termínů nejsou příliš rozsáhlé , bylo možné je vytvořit a naplnit v jednom skriptu. Tento SQL skript jsem nazval instal.sql. Aby skript mohl prob ě hnout za všech okolností, tedy i pokud již tabulky existují, nejdříve se všechny tabulky pokusím zrušit. Po zrušení tabulek zač ne skript vytvářet a naplňovat jednu tabulku pod druhé v takové m pořadí, aby nedošlo k porušení ně jaké ho integritního omezení. Jinýskript, kterýjsem nazval student, vytváří tabulku studentů a naplní ji postupně údaji o přibližně 1700 studentech. Z důvodu ochrany osobních údajů nejsou rodná č ísla skuteč ná, ale jsou přidě lována postupně od jednič ky do 1700. 6.2 Knihovna často využívaný ch funkcí K usnadně ní práce jsem napsal ně kolik funkcí, které jsou opakovaně využívány v různých PHP skriptech. Tyto funkce jsem rozdě lil do dvou souborů s názvy modul.php a cache.php. Ostatní skripty pak vkládají jejich kód do své ho tě la pomocí klíč ové ho slova include podobně jako v jazyce C. První soubor je vkládán úplně do všech PHP souborů a obsahuje funkce generující společ né - 23 - záhlaví a zápatí HTML kódu a také funkce pro usnadně ní práce s databází. Druhýsoubor je vkládán jen do tě ch skriptů pro které má význam využívat HTML cache, tedy stránky u nichž lze předpokládat, že v brzké době bude vyžadováno jejich další zobrazení v nezmě ně né podobě . Po přímé m zavolání jednoho z tě chto dvou souborů by se zobrazila na webové m prohlížeč i prázdná stránka, protože přímo negenerují žádnývýstup, ale jen definují funkce. Pomocné funkce - modul.php Nejč astě ji vkládanýskript jsem pojmenoval modul.php. První dvě jeho funkce myHeader() a myFooter()usnadňují generování HTML kódu na zač átku a na konci každé ho HTML souoboru. V hlavič ce HTML souboru jsou informace o kódování písma (ISO— 8859-2), používané m souboru stylů a titulku stránky, kterýje funkci předán jako parametr. Funkce myFooter generuje kromě ukonč ovacích tagů také menu pod č arou, které je společ né pro všechny stránky zápisu. modul.php – skript definující společné funkce 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?php function myHeader($titulek) { ?> <!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html> <head> <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html;charset=ISO-8859-2"> <title> <?=$titulek ?> </title> <LINK href="./styl.css" rel="stylesheet" type="text/css"> </head> <body> <center>Stránka vygenerování v<? echo date ("H:i:s"); } function myFooter() {?><hr><?if (substr($_SERVER["PHP_SELF"],-8)!="menu.php") { ?><P> <A href="menu.php">[menu]</A> </P> <?} ?> </center> </body> </html><?ob_end_flush(); } function pripojDB() {$db="(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = pc-dbvyvoj.ro.vutbr.cz)(PORT = 1521)) (CONNECT_DATA = (SID = CIS)) )"; $GLOBALS["con"] = OCILogon("jmeno","heslo",$db); } function proved($SQLprikaz) {// echo $SQLprikaz; // pro potřeby ladění .... $naparsovano =OCIParse($GLOBALS["con"],$SQLprikaz); - 24 - 39 40 41 42 43 OCIExecute($naparsovano,OCI_DEFAULT); $arrError = OCIError($naparsovano); return $naparsovano; } ?> Další dvě funkce usnadňují práci s databází. Funkce pripojDB() naváže spojení s databází a identifikátor spojení uloží do globální promě nné con. Druhou funkcí je funkce proved(), která provede sql příkaz v předané m parametru na databázi s identifikátorem spojení uloženým v globální promě nné con. Využívá při tom standardní OCI funkce OCIParse() a OCIExecute(). V případě potíží je zde možné také vložit řádek vypisující sql příkaz před samotným provedením, protože je možné , že chyba vznikla právě kvůli chybně sestavené mu sql dotazu. Implementace HTML cache Obecně byla již probrána problematika HTML cache v kapitole o optimalizaci PHP. Knihoven poskytujících funkci HTML cache existuje celá řada. (jpcache[12], phpcache ...) Část z nich je souč ástí ještě rozsáhlejších knihoven (PEAR cache, Smarty template engine ). Podrobně jší a lé pe popsanýseznam je možné nalé zt v literatuře [7], v níž je možné nalé zt i spousty jiných zajímavých č lánků týkajících se PHP, č asto s ohledem na výkonnost. Pro naše potřeby je však dobré , aby byl kód struč ný, krátký, ale přitom dostateč ný. Všechny z výše zmíně ných knihoven obsahují z našeho pohledu zbyteč ně rozsáhlýkód, což spolu z faktem, že při každé m nač ítání stránky musí být PHP program vždy znovu a znovu překládán, č iní výše zmíně né knihovny málo efektivní. Napsal jsem tedy vlastní knihovnu, která tyto parametry splňuje. Mnou napsaná knihovna je celá obsažena v souboru cache.php, kterýdefinuje dvě funkce. Jedinou zvenč í používanou funkcí té to knihovny je funkce s názvem my_cache(). Algoritmus, kterýtato funkce používá je v principu velice jednoduchýa je zobrazen na vývojové m diagramu obrázku 6.3. Tato funkce provádí test, zdali je možné využít souboru uložené ho na disku a nebo je nutné stránku znovu vygenerovat. Pokud je možné využít již hotové ho souboru, tento soubor nač te a pošle na výstup. Tím probíhání funkce, ale i celé ho skriptu skonč í. V opač né m případě se vygeneruje novýHTML výstup, kterýse také uloží pro případné pozdě jší využití. Při psaní HTML cache knihovny musíme mít na pamě ti, že je možné , že ve stejnýokamžik pobě ží desítky nebo snad i stovky stejných PHP skriptů souč asně , které budou mít zájem č íst, nebo zapisovat do stejné ho souboru. V okamžiku, kdy vyprší platnost ně jaké ho souboru, by se mohlo také stát, že HTML soubor zač ne generovat např. 10 PHP skriptů souč asně ještě předtím, než je k dispozici nově jší verze. Tento jev jsem zjistil při testování své ho modulu cache.php. Všem tě mto neduhům je možné zabránit zamykáním souborů s využitím PHP funkce flock(), která je obdobou podobné funkce v jazyce C. Před zahájením generování souboru tento soubor uzamknu jak pro č tení tak i pro zápis jiným procesům. Jiné procesy, které mají zájem o tentýž soubor tedy vyč kají, až bude vygenerovaná jeho aktuálně jší verze. Před uzamknutím souboru k výhradnímu přístupu je nutné poč kat, až dokonč í ostatní procesy práci s tímto souborem... - 25 - start existuje cache soubor a je aktuální? ano ne nač ti soubor a pošli ho na výstup vygeneruj html ulož html do souboru a pošli jej na výstup konec konec Obrázek 6.3Vý vojový diagram použité ho algoritmu HTML cache. cache.php – skript obstarávající HTML cache 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <? function callback($data) { global $fpt,$CacheFile; if (!connection_aborted()) { // pokud je spojení zrušeno, dotyčný to už vzdal, vygenerovaný výstup // memusí být kompletní a proto jej neuložíme $return = FALSE; $fp=@fopen($CacheFile, "wb+"); if (!$fp) { $data.="Failed to open for write of $CacheFile <br>"; } else { fwrite($fp, $data, strlen($data)); fclose($fp);} } @flock($fpt, LOCK_UN); @fclose($fpt); return $data; } function my_Cache($file,$timeout) {global $fpt,$CacheFile; $CacheFile=$file; $fpt = @fopen($CacheFile, "rb"); @flock($fpt, LOCK_SH); // V případě, že se nějaký jiný thread pokouší právě zapsat, počkáme ... if (file_exists($CacheFile)&&(($howOld=(time()-filemtime($CacheFile)))<=$timeout)) { // echo "<p>Z důvodu snížení množství přístupů k databázi jsou zobrazené údaje staré ".$howOld." sekund </P> "; $buff=""; while (($tmp=fread($fpt, 4096))) { $buff.=$tmp; } flock($fpt, LOCK_UN); // Release lock fclose($fpt); echo $buff; exit; - 26 - 35 } 36 else 37 { 38 @flock($fpt, LOCK_EX); 39 // echo "<p>Zobrazené údaje jsou aktuální.</P> "; 40 ob_start("callback"); // vystup zpracuji 41 ob_implicit_flush(0); 42 } 43 } 44 ?> Funkce callback() má za úkol uložit výstup skriptu do pamě ti cache a je automaticky volána samotným PHP interpretem, po skonč ení veškeré ho výstupu. Má jeden vstupní parametr, kterým je promě nná v níž je uloženýdosavadní výstup skriptu. Tento výstup může jakýmkoli způsobem zpracovat č i dokonce změ nit, ale v našem případě jej pouze uloží do souboru. To, co je nakonec opravdu posláno uživateli, je hodnota vrácená touto funkcí. (viz řádek č . 16) To, že bude volána právě funkce callback(), se nastaví voláním ob_start() na řádku 40. Hned za voláním funkce ob_start() je také volána funkce ob_implicit_flush(0) , která zaruč í, že naše funkce bude volána jen jednou a to s celým výstupem k dispozici. Implicitně by totiž byla volána po menších blocích dat. Následující příklad demonstruje využití knihovny cache. Obyč ejnýPHP skript přemě níme na PHP skript využívající vyrovnávací pamě t pouhým přidáním tří řádků - v příkladu řádků 1,2 a 6. Příklad použ ití HTML cache 1 2 3 4 5 6 include ”cache.php”; my_cache("./cache/VypisSport".$_GET[’SPORT_ID’].".html",5); .. echo ”<h1>Nyní generuji html kód </h1>”; .. ob_end_flush(); // další výstup už nebude následovat Na prvním řádku vložíme knihovnu cache.php. Následně voláme funkci my_cache(), které předáme dva parametry. První je název souboru a druhý poč et sekund, po kterýje možné považovat obsah tohoto souboru za platnýod okamžiku jeho vygenerování. Název souboru volíme tak, aby byl rozdílnýpro každou možnou variantu stránky. Poslední řádek, kterýmusíme do skriptu přidat, je volání standardní funkce ob_end_flush() , aby jsme tím interpretu PHP sdě lili, že již skonč il výstup a může dojít k zapsání do souboru. Interpret PHP pak automaticky zavolá naši první funkci s názvem callback(), č ímž dojde k fyzické mu uložení výstupu do pamě ti cache. Stránka obvykle generuje jinývýstup v závislosti na předaných promě nných za adresou url.(způsob předání formulářů GET) Ošetření tě chto variant je velice jednoduché viz. řádek č . 2, kde v názvu požadované ho souboru jsou obsažena i důležitá předaná data. 6.3 Prá ce s databá zí Při psaní PHP skriptů bylo mou prioritní snahou, aby byl kód snadno udržovatelnýv případě razantních změ n jak vzhledu aplikace, tak i využívaných databázových tabulek. Je totiž zřejmé , že jak tabulky tak i detaily přihlašování se budou rok od roku znatelně mě nit. - 27 - Zobrazování tabulek Tabulky zobrazující výsledek sql dotazu SELECT se v mé aplikaci generují č etně hlavič ek automaticky. Při změ ně tabulek je tak zásah do programu minimální. Jako příklad, na které m se snažím vše objasnit uvádím skript s názvem VypisSport.php, kterýmá za úkol vypsat všechny termíny vybrané ho sportu. Identifikač ní č íslo tohoto sportu, stejně tak jako jeho slovní název jsou předány skriptu v url- tedy metodou get. Příklad vypisování tabulek z databáze – soubor VypisSport.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <? include "cache.php"; include "modul.php"; my_cache("./cache/VypisSport".$_GET[’SPORT_ID’].".html",5); myHeader("Výběr termínu"); echo "<H1> Výběr termínu pro sport:{$_GET[’SPORT_NAZEV’]}</H1>"; pripojDB(); $pom="SELECT TERMIN.DEN , TERMIN.ZACATEK od, TERMIN.KONEC do, TERMIN_ID, MISTO.SPORTOVISTE, MISTO.ADRESA, TERMIN.VOLNA_MISTA POCET_VOLNYCH_MIST FROM TERMIN, MISTO WHERE ((TERMIN.REF_SPORT_ID={$_GET[’SPORT_ID’]})AND (MISTO.MISTO_ID=TERMIN.REF_MISTO_ID)) order by den, od "; $naparsovano =proved($pom); echo "\n<table border=1 align=center>\n"; $poprve=true; $dny=array(1 =>"PO","ÚT","ST", "ČT", "PÁ", "SO","NE"); while(OCIFetchInto($naparsovano, $MyArr, OCI_ASSOC+OCI_RETURN_NULLS)) { if ($poprve) { echo "<tr>"; foreach($MyArr as $index => $hodnota) { if ($index!="TERMIN_ID") echo "<th> $index </th> \n";} $poprve=false; echo "</tr>"; }; echo"\n<tr>\n"; // řádek začíná $reference="registrace.php?SPORT_NAZEV={$_GET[’SPORT_NAZEV’]}&"; $MyArr["DEN"]=$dny[$MyArr["DEN"]]; // převedu den z kódování 1..7 na Po..Ne foreach($MyArr as $index => $hodnota) { $reference.="$index=$hodnota&"; // všechny hodnoty z databáze budou předány dál pomocí GET if ($index!="TERMIN_ID") echo "<td> $hodnota </td> \n"; } if ($MyArr[’POCET_VOLNYCH_MIST’]>0) { echo "<td> <A href=\"$reference\"> přihlásit </A> </td> \n"; } echo"</tr>\n"; // řádek končí } echo "</table>\n\n"; if ($poprve) { echo "<p> Vybraný sport nemá v databázi žádné termíny ...</p>";} myFooter(); ?> - 28 - Obecně vypisování tabulky s užitím příkazu SELECT je provádě no ve dvou krocích. V prvním kroku necháme prové st vlastní SQL příkaz. V mé m příkladu je to na řádku 16, voláním funkce proved(). Tímto krokem jsme stále ještě nezískali žádná data. Ty jsou získávány v druhé m kroku. Druhým krokem je cyklus while, zač ínajícího na řádku 20, kterýopakovaně volá funkci OCIFetchInto() . Každým zavoláním té to funkce získáme další řádek tabulky, kterýnám funkce vrátí v poli $MyArr . Indexy tohoto pole jsou názvy jednotlivých sloupců tabulky, hodnoty tě chto sloupců jsou hodnoty pod nimi uloženy. Z tohoto pole je tedy možné získat jak hodnoty, tak i jednotlivá jmé na sloupců tabulky pro aktuální řádek. Jmé na sloupců mohou být buď opravdová jmé na sloupců tabulky urč ené při vytváření tabulky a nebo jmé na, která jednotlivým sloupcům byla přiřazena v příkazu select. Přiřadit sloupcům vlastní jmé na uvnitř příkazu select je v našem případě velice užiteč né , protože naše aplikace přestává být závislá na tom, jak si pojmenoval sloupce správce databáze i na tom, z jaké tabulky jsou tyto sloupce nakonec vypsány. Díky speciální smyč kové konstrukci foreach jazyka PHP je možné z pole $MyArr vygenerovat i záhlaví vypisované tabulky. Vygenerovat záhlaví tabulky je nutné jen při prvním průchodu smyč kou while, což zabezpeč uje podmínka testující hodnotu promě nné s názvem $poprve na řádku 22. Od řádku 29 již následuje generování řádku tabulky. Každýřádek tabulky s kterým je možné dále pracovat obsahuje také minimálně jeden odkaz na jiný PHP skript. V tomto konkré tním případě každýřádek tabulky představuje termín a odkaz na konci každé ho řádku umožňuje přihlášení na tento termín. Skriptu zabezpeč ujícímu přihlášení je nutné předat minimálně identifikač ní č íslo (primární klíč ) termínu o kterýmá uchazeč zájem. Z úsporných důvodů předávám nejen toto identifikač ní č íslo, ale i všechny zjiště né údaje o tomto termínu. Volanýskript pak nemusí tyto údaje znovu zjišťovat z databáze, č ímž docílím jisté úspory. Generování tohoto odkazu probíhá rovně ž automaticky společ ně s generováním řádku tabulky v tě le cyklu zač ínajícího na řádku 33. Pro generování odkazu je využita pomocná promě nná s názvem $reference. Popsanýpříklad je v podstatě univerzální kostra, která lze lehkými úpravami změ nit na vypisování libovolné tabulky. Obecně lze říci, že v PHP by bylo možné napsání takové knihovny PHP , která by umožňovala univerzálním způsobem přes web zpravovat obsah celé libovolně rozsáhlé databáze podobně jak to umožňuje Oracle Portal. Pokud se vám výše uvedenýpříklad zdá pro zač átek příliš komplikovaný, je možné se nejprve podívat na příklady uvedené v literatuře [4]. Zapsání studenta Samotnýzápis provádí skript s názvem registruj.php. Tomuto skriptu je předáno v url platné rodné č íslo studenta a také identifikač ní č íslo termínu, na kterýse tento student pokouší zapsat. Tento příklad zde uvádím proto, abych na ně m demonstroval ošetření pokusu o porušení integritního omezení, kterývznikne v případě , kdy se student pokouší zapsat na jeden termín více než jedenkrát, nebo je termín již obsazen. Příklad ošetřeníporušeníintegritních omezenív databá zi – soubor registruj.php: 1 2 3 <? include "modul.php"; include "VypisZapsane.inc.php"; - 29 - 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 myHeader("Registrace"); pripojDB(); $pom1="INSERT INTO REGISTRACE (REF_RODCIS_ID, REF_TERMIN_ID,EMAIL, DATUM) VALUES({$_GET[’RODCIS’]},{$_GET[’TERMIN_ID’]},’{$_GET[’EMAIL’]}’,SYSDATE)"; $pom2="UPDATE TERMIN SET VOLNA_MISTA=VOLNA_MISTA-1 WHERE TERMIN_ID={$_GET[’TERMIN_ID’]}"; // echo "$pom1 \n \n $pom2 \n"; // pro potřeby ladění $stmt = @ociparse($con,$pom1, OCI_DEFAULT); if (!@ociexecute($stmt,OCI_DEFAULT)) { // $error = ocierror($stmt); // printf("OCIEXECUTE error:%s", $error["message"]); // pro ladění echo "<h1> Zdá se, že daný termín, máte již jednou zapsaný. ? </h1>"; ocirollback($con); } else { $stmt = @ociparse($con,$pom2, OCI_DEFAULT); if (!@ociexecute($stmt,OCI_DEFAULT)) { // $error = ocierror($stmt); // printf("OCIEXECUTE error:%s", $error["message"]); // pro ladění ocirollback($con); echo "<h1> Zdá se, že poslední volné místo si stihnul zapsat někdo těsně před vámi.</h1>"; } else { echo "<H1>Úspěšně zapsán do databáze </h1>"; ocicommit($con); } } VypisZapsane($_GET[’RODCIS’]); myFooter(); ?> Při zapisování studenta je nutné prové st dvě nezávisle operace. • Přidat další záznam do tabulky registrace. Tento pokus skonč í chybou, pokud se student pokouší zapsat si termín, kterýuž jednou zapsanýmá. Tato tabulka má totiž dva primární klíč e z č ehož plyne nutná jedineč nost tě chto dvou položek. Primárními klíč i jsou rodné č íslo a identifikač ní č íslo termínu. • Snížit poč et volných míst zapisované ho termínu o jednič ku. Tato změ na hodnoty skonč í chybou v případě , že poč et volných termínů je již nulový. V tom případě je nutné vrátit zpě t i předchozí úspě šně provedenou operaci přidáním záznamu do tabulky registrace. Vrátit operaci zpě t je možné zavoláním funkce OCIRallBack()na řádku 23. Zavolání té to funkce má svůj efekt, jen pokud voláme předešlé funkci OCIParse() a OCIExecute() s druhým parametrem OCI_DEFAULT. V případě úspě šné aktualizace obou tabulek je zavolána funkce OCICommit()(řádek 28), která změ ny potvrdí. 6.4 Testová nírychlosti Testováním je možné zjišťovat jakývliv mají různé hodnoty nastavení a použité programovací techniky na celkovývýkon systé mu. Je té ž možné monitorovat zatížení systé mu v průbě hu testu. Tedy zatížení procesoru disků atd. K testování WWW serverů, existuje celá řada speciálního software. Jeden z jednodušších programů je mnou požívanýab, což je zkratka pro appache bench. Tento testovací prográmek je standardně dodáván s webovým serverem apache. Stač í jej tedy nelé zt v ně které m z podadresářů apache a testování může zač ít. Nově jší testovací - 30 - program od stejných autorů se jmenuje flood a je možné jej nalé zt na http://httpd.apache.org/test/flood/. Velké překvapení pro mě bylo zjiště ní, že provádě ní lokálního testování, kde testovací program bě ží přímo na WWW serveru dává podobné výsledky jako testování z jiné ho poč ítač e v lokální síti. Liší se především poč et nadprůmě rně a podprůmě rně rychle zpracovaných požadavků. Zdá se, že lokální síťje natolik rychlá, že té mě ř nezpůsobuje žádné zpoždě ní. Jiné vysvě tlení by mohlo být takové , že zpoždě ní sítě mě lo v mé m případě podobnývliv jako zatížení poč ítač e WWW serveru testovacím programem. Testování výkonnosti se zde pokusím přiblížit na jednom příkladě . Zvolil jsem testování PHP skriptu generujícího informace z více tabulek bez použití HTML cache. Například při vypisování již zapsaných termínů jedním konkré tním studentem nelze předpokládat opakovanýpožadavek na vypsaní stejné tabulky- tudíž je bezpředmě tné využívat HTML-cache. Test probě hl následovně : Příklad testová nírychlost PHP skriptu: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 [soukup@pc-3wtest soukup]$ ./ab -n3000 -c300 http://pcldap.ro.vutbr.cz/CESA/tajne/VypisZapsane.php?RODCIS=500&odeslat=Odeslat [1] 10365 [soukup@pc-3wtest soukup]$ This is ApacheBench, Version 1.3d <$Revision: 1.67 $> apache1.3 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/ Benchmarking pc-ldap.ro.vutbr.cz (be patient) Completed 300 requests Completed 2700 requests Finished 3000 requests Server Software: Apache/1.3.27 Server Hostname: pc-ldap.ro.vutbr.cz Server Port: 80 Document Path: Document Length: /CESA/tajne/VypisZapsane.php?RODCIS=500 1217 bytes Concurrency Level: Time taken for tests: Complete requests: Failed requests: (Connect: 0, Length: Broken pipe errors: Total transferred: HTML transferred: Requests per second: Time per request: Time per request: Transfer rate: 300 28.190 seconds 3000 1876 1876, Exceptions: 0) 0 4196500 bytes 3620308 bytes 106.42 [#/sec] (mean) 2819.00 [ms] (mean) 9.40 [ms] (mean, across all concurrent requests) 148.86 [Kbytes/sec] received Connnection Times (ms) min mean[+/-sd] median max Connect: 0 310 1106.8 0 20993 Processing: 120 1838 1123.0 1493 14692 Waiting: 89 1838 1123.1 1492 14692 Total: 120 2149 1710.7 1599 23673 Percentage of the requests served within a certain time (ms) - 31 - 39 40 41 42 43 44 45 46 47 50% 66% 75% 80% 90% 95% 98% 99% 100% 1599 2186 2586 2770 4002 4786 6192 10149 23673 (last request) Apache benchmark byl svými parametry nastaven (viz první řádek) k testování 3000 přístupů (-n3000), při maximálním poč tu 300 souč asných spojení (-c300). Předpokládám, že zvládání té to zátě že v rozumné m č ase je dostateč ným předpokladem, aby bylo možné předpokládat, že systé m bude dobře průchozí i při ostré m provozu. Výstupem testu jsou různé statistické údaje vypovídající o chování zatížené ho serveru. Za nejpodstatně jší bych označ il tři údaje: • Ú daj na řádku 28. „Request per seconds”–udává průmě rnýpoč et žádostí vyřízených za jednu sekundu. Tento údaj nám dává dobrou představu o průchodnosti systé mu. • Následující řádek „Time per request”, udává průmě rnou dé lku, kterou musí klient č ekat na zobrazení informací. V tomto případě je střední doba kolem tří sekund. Zajímavýje ovšem fakt, že když jsem v době testu generoval další požadavky svým webovým prohlížeč em na třetím poč ítač i, č asové prodlevy tě chto požadavků byly výrazně nižší. • Poslední významnýúdaj je na řádku 23. „Failed requests”–poč et neúspě šných žádostí. Jak je zřejmé z řádku 24, jsou tři druhy neúspě šných žádostí. Nutno poznamenat, že testovací program oč ekává, že bude WWW serverem vrácena stránka vždy o stejné velikosti. Pokud je souč ástí stránky například č ítač přístupů, ve které m v průbě hu testování přibude další č íslice, může testovací program všechny odpově di s jedním znakem navíc považovat za chybné . V našem případě se tak ale nestalo. 1876 neúspě šných žádostí je zřejmě způsobeno nedostateč ně velkým poč tem povolených připojení k databázi. Lze tak soudit z obsahu tě chto vadných odpově dí, které je možné získat a zobrazit na třetím poč ítač i v průbě hu testování. Zobrazí se chybová zpráva oznamující, že se nezdařilo přihlášení k databázi. Zajímavý je také fakt, že poč et tě chto chybných odpově dí se č asto s každým novým testem výrazně liší. K nejč astě ji vypisovaným tabulkám budou zajisté patřit tabulky s informacemi o jednotlivých termínech. Každýstudent si jistě nechá vypsat ně kolik možných sportů předtím, než se pro ně jakýrozhodne. Lze tak předpokládat, že využíváním HTML cache můžeme ušetřit více jak polovinu zátě že databáze. Testy jsem provádě l na dvou poč ítač ích různé ho výkonu a výsledky shrnul do tabulky. - 32 - poč ítač měřená velič ina bez HTML cache s HTML cache 37,68 117,11 86 0 průmě rná doba nutná k vyřízení 7,08s 2,56s obsloužených žádostí za sekundu 106,42 231,77 poč et chybných odpově dí 1876 0 průmě rná doba nutná k vyřízení 2,82s 1,29s obsloužených žádostí za sekundu Pentium 2, 400Mhz Pentium 4 , 2GHz poč et chybných odpově dí tabulka 6.1 - Vý sledky testování provádě né na dvou různě vý konný ch poč ítač ích Pokud beru v úvahu fakt, že chybné odezvy jsou výrazně rychlejší než ty správné , lze konstatovat, že využití HTML cache přináší přibližně trojnásobné zrychlení. Je také zřejmé , že výkonnost poč ítač e, na které m bě ží webovýserver má velkývliv na dobu odezvy celé ho systé mu. - 33 - 7. Závě r Cílem projektu bylo navrhnout a naprogramovat změ ny potřebné k plynulé mu zapisování do sportů CESA. Byla vybrána jiná technologie v podobě webové ho serveru Apache s užitím PHP a databází Oracle, která je pro velké zatížení vhodně jší. Samotnou změ nou technologie z Oracle Portal je možné dosáhnout ně kolikanásobné ho zrychlení. Užitím skriptovacího jazyka PHP se také otevírají další možnosti optimalizace výkonu, kterými se v práci detailně zabývám. Hlavní úsporu přináší fakt, že č asto zobrazované tabulky není potřeba generovat při každé m požadavku, ale naprosto dostateč né je např. jednou za 10 sekund nebo dokonce ně kolik minut. Za tímto úč elem jsem naprogramoval a v té to práci popsal vlastní knihovnu, která je oproti již podobným hotovým knihovnám volně stažitelným na internetu menší, jednodušší a tedy i nezanedbatelně rychlejší. V té to souvislosti je také možné využít pamě ti proxy serverů, což by mohlo představovat další výraznou úsporu zatížení serveru i sítě . Při implementaci byl kladen velkýdůraz na univerzálnost kódu a snadné provádě ní změ n. Např. při vypisování tabulek jsou plně využita data vrácená příkazem select, a tak při změ ně tabulek obvykle stač í změ nit jen samotnýpříkaz select. Přestože by se mohlo zdát, že přechod od vyšších nástrojů jako je Oracle Portal k programování PHP skriptů je krokem zpě t, je možné i s využitím PHP vytvářet aplikace rychle a efektivně . Tato cesta znamená především vytváření různých pomocných knihoven, popřípadě využít objektově orientované ho programování. Je dokonce možné PHP skripty nechat generovat jinými skripty v závislosti na šablonách a sloupcích obsažených v používaných tabulkách. Tímto by se dalo vyhnout snížené mu výkonu při zachování dobré udržovatelnosti. Je samozřejmě možné využívat unixové nástroje pro práci s textovými soubory. Zamýšlení se nad psaním takové ho kódu č i implementace dalších optimalizací jako např. komprese by mohlo být náplní další práce. - 34 - Literatura [1] Stig Sćther Bakken aj.: PHP manual. Dokument dostupnýna http://www.php.net/docs.php (březen 2003) [2] Bráza Jiří : PHP 4 uč ebnice základů jazyka. vydání první, Grada publishing a.s.2002 [3] Š imůnek Milan : SQL kompletní kapesní průvodce, vydání první, Grada publishing a.s.2002 [4] Reagan Patrik: Using Oracle with php, 29. č erven 2001, Článek dostupnýna http://hotwired.lycos.com/webmonkey/01/26/index4a.html?tw=backend (březen 2003) [5] Balwin Dirk: Oracle:SQL*plus tutorial,11. prosinec 2000, Článek dostupnýna http://www.uwp.edu/academic/mis/baldwin/sqlplus.htm (březen 2003) [6] Davison D. Brian: Caching Tutorial for Web Authors and Webmasters, Materiály dostupné na http://www.web-caching.com/ (březen 2003) [7] Lim John:Tuning Apache and PHP for Speed on Unix, 18. únor 2001, Článek dostupnýna http://php.weblogs.com/tuning_apache_unix (březen 2003) [8] Lim Johm:A HOWTO on Optimizing PHP with tips and methodologies,2002,Článek dostupný na http://phplens.com/lens/php-book/optimizing-debugging-php.php (březen 2003) [9] Kamath Harish: Output buffering with php, 2002, Článek dostupnýna http://www.devshed.com/Server_Side/PHP/OutputBuffering/page1.html (březen 2003) [10] Jeff :More speed - for webmasters,8. říjen 2002, Článek dostupnýna http://www.webmasterjoint.com/articles/1002/more_speed_1.php (březen 2003) [11] Young Sean,Making your website super fast-loading , září 2002, Článek dostupnýna http://www.msxnet.org/fast-website (březen 2003) [12] Pierre Jain: jpcache ,2002, Struč nýmanuál, FAQ a zdrojovýkód dostupnýna http://www.jpcache.com/ (březen 2003) [13] ionCube: PHP Accelerator, Dokumentace a program dostupnýna http://www.phpaccelerator.co.uk/ (březen 2003) - 35 -