Za´padoˇceska´ univerzita v Plzni Fakulta aplikovany´ch vˇed Katedra informatiky a vy´poˇcetn´ı techniky
Diplomov´ a pr´ ace Framework pro v´ yvoj matematick´ ych webov´ ych her
Plzeˇ n 2012
Luboˇs Hanz´ık
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem diplomovou pr´aci vypracoval samostatnˇe a v´ yhradnˇe s pouˇzit´ım citovan´ ych pramen˚ u. V Plzni dne 16. kvˇetna 2012 Luboˇs Hanz´ık
Abstract This work provides a short introduction to some tools commonly used to create web applications. Namely the programming languages JavaScript and PHP as well as Adobe Flash technology are described. Another focus of this work is the matter of web security and the description of some common types of attack. The practical part begins with the description of a website called Frisky, which belongs to the Department of Mathematics. We analyzed the current implementation and identified the main issues. We propose and implement an optimal solution. Then we describe a JavaScript game called Puzzle. We analyze how it’s possible to cheat in the game and then explain how we changed the code of the game to prevent that. In the next chapter we talk about another goal of this work, which was to create a simple library to save and to present results of web games. The next chapter is dedicated to another library that we created. This library provides means for communication of visitors of a web page with each other. In the last chapter, we discuss the results and propose some future research directions.
i
Obsah ´ 1 Uvod
1
2 JavaScript 2.1 Historie JavaScriptu . . . 2.2 Z´aklady JavaScriptu . . . 2.3 Document Object Model . 2.4 Ud´alosti . . . . . . . . . . 2.5 Knihovna jQuery . . . . . 2.5.1 Zaˇc´ın´ame s jQuery 2.5.2 Selektory . . . . . 2.5.3 Reakce na ud´alosti 2.5.4 Animace . . . . . . 2.5.5 AJAX . . . . . . . 2.5.6 Knihovna qTip 2.0
. . . . . . . . . . .
2 2 2 4 5 5 5 8 9 9 11 11
3 PHP 3.1 Historie PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Z´aklady PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Prostˇredky pro komunikaci proces˚ u . . . . . . . . . . . . . . . . . . . .
14 14 15 18
4 Adobe Flash 4.1 Historie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Vlastnosti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20 20 21
5 Bezpeˇ cnost na webu 5.1 C´ıle bezpeˇcnosti . . . 5.1.1 Autentizace . 5.1.2 Autorizace . . 5.1.3 Soukrom´ı . . 5.1.4 Integrita dat . 5.1.5 Odpovˇednost
22 22 22 23 23 24 24
. . . . . .
. . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . . ii
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . .
OBSAH
OBSAH . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
24 25 25 26 26 27 27 28
6 Webov´ e str´ anky Frisky 6.1 Probl´emy k ˇreˇsen´ı . . . . . . . . . . . . . . . . . . . . 6.2 Anal´ yza probl´em˚ u a n´avrh ˇreˇsen´ı . . . . . . . . . . . 6.2.1 Nejednotn´ y layout str´anek . . . . . . . . . . . 6.2.2 Neexistence pˇrihlaˇsov´an´ı a registrace na Frisky 6.2.3 Str´anky nejsou samostatn´e . . . . . . . . . . . ˇ sen´ı jednotliv´ 6.3 Reˇ ych probl´em˚ u . . . . . . . . . . . . . 6.3.1 Nejednotn´ y layout str´anek . . . . . . . . . . . 6.3.2 Neexistence pˇrihlaˇsov´an´ı a registrace na Frisky 6.3.3 Str´anky nejsou samostatn´e . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
31 31 31 31 32 33 33 33 35 37
7 Anal´ yza her 7.1 Anal´ yza probl´emu a n´avrh ˇreˇsen´ı . . . . . . . . . . . . . . . . . . . . . 7.2 Odstranˇen´ı moˇznosti podv´adˇet . . . . . . . . . . . . . . . . . . . . . . .
40 40 40
8 Rozhran´ı pro ukl´ ad´ an´ı v´ ysledk˚ u her 8.1 Anal´ yza a n´avrh ˇreˇsen´ı . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Implementace rozhran´ı . . . . . . . . . . . . . . . . . . . . . . . . . . .
43 43 43
9 Knihovna pro komunikaci uˇ zivatel˚ u 9.1 Anal´ yza distribuce aktualizac´ı . . . . . . . . . . 9.2 Implementace metody long polling . . . . . . . 9.3 Kreslen´ı . . . . . . . . . . . . . . . . . . . . . . 9.3.1 Implementace kreslen´ı v elementu canvas 9.3.2 Z´ısk´av´an´ı aktualizac´ı od ostatn´ıch . . . . 9.3.3 Uloˇzen´ı dat na serveru . . . . . . . . . . 9.4 Galerie . . . . . . . . . . . . . . . . . . . . . . . 9.5 Chat . . . . . . . . . . . . . . . . . . . . . . . . 9.6 Zobrazen´ı pˇrihl´aˇsen´ ych uˇzivatel˚ u. . . . . . . . . 9.7 Navrhovan´a budouc´ı vylepˇs´ı knihovny . . . . . .
46 46 47 49 49 52 52 54 56 57 59
5.2 5.3
5.1.6 Dostupnost . . . . . . . . . . 5.1.7 Nepopiratelnost . . . . . . . . Typy u ´tok˚ u . . . . . . . . . . . . . . Zp˚ usoby napaden´ı poˇc´ıtaˇce . . . . . . ˇ 5.3.1 Cervi . . . . . . . . . . . . . . 5.3.2 Dalˇs´ı typy ˇskodliv´eho softwaru 5.3.3 Probl´em pˇreteˇcen´ı bufferu . . 5.3.4 SQL Injection . . . . . . . . .
10 Z´ avˇ er
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . . . .
. . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
60
iii
OBSAH
OBSAH
Seznam pouˇ zit´ ych zkratek
61
Seznam pouˇ zit´ e literatury
62
Pˇ r´ılohy
64
A Obsah DVD
65
B Galerie - uk´ azka tvorby animac´ı s knihovnou jQuery
66
C Vzor pro vˇ etˇ sinu str´ anek na Frisky
70
D Skript pro rozˇ s´ıˇ ren´ı layoutu str´ anek na Frisky
72
E Vzor str´ anek, jejichˇ z obsah se roztahuje pˇ res okno prohl´ıˇ zeˇ ce
74
F Uk´ azka pouˇ zit´ı knihovny pro ukl´ ad´ an´ı a zveˇ rejˇ nov´ an´ı v´ ysledk˚ u
76
G N´ avod na pouˇ zit´ı knihovny pro komunikaci uˇ zivatel˚ u
78
iv
´ 1 Uvod Katedra matematiky (KMA) usiluje o modernizaci a vylepˇsov´an´ı sv´ ych webov´ ych str´anek. Snahou je, aby byly pouˇz´ıv´any modern´ı technologie jako napˇr. HTML5 a CSS3. Z´aroveˇ n je db´ano na zabezpeˇcen´ı str´anek proti napaden´ı. C´ılem t´eto pr´ace bylo podpoˇrit rozvoj webov´ ych str´anek KMA. V teoretick´e ˇc´asti t´eto pr´ace jsou nejprve pops´any prostˇredky pro tvorbu webov´ ych str´anek, jako jsou jazyky PHP a JavaScript (spolu s rozborem knihovny jQuery) a tak´e je struˇcnˇe pops´ana technologie Adobe Flash. D´ale se v t´eto ˇc´asti pr´ace zab´ yv´ame oblast´ı bezpeˇcnosti na webu. Kromˇe z´akladn´ıch princip˚ u bezpeˇcnosti jsou rozebr´any i nˇekter´e bˇeˇzn´e zp˚ usoby napaden´ı. V praktick´e ˇca´sti pr´ace ˇcten´aˇr nejprve nalezne anal´ yzu nedostatk˚ u webov´ ych str´anek KMA, zvan´ ych Frisky. N´aslednˇe je pops´ano, jak byly identifikovan´e probl´emy odstranˇeny. Dalˇs´ı kapitola je vˇenov´ana rozboru webov´e hry Puzzle. Tento rozbor je zamˇeˇren na popis moˇzn´ ych zp˚ usob˚ u, jak ve hˇre podv´adˇet. N´aslednˇe jsou ˇcten´aˇri vysvˇetleny kroky, kter´e byly uˇcinˇeny pro zamezen´ı podv´adˇen´ı. Pˇredposledn´ı kapitola praktick´e ˇc´asti je vˇenov´ana tak´e webov´ ym hr´am. Zde se pod´ıv´ame na program´atorsk´e rozhran´ı, kter´e bylo vytvoˇreno pro ukl´ad´an´ı a zveˇrejˇ nov´an´ı v´ ysledk˚ u her. Posledn´ı kapitolu praktick´e ˇca´sti povaˇzuji za nejd˚ uleˇzitˇejˇs´ı. V n´ı je rozebr´ana knihovna vytvoˇren´a v r´amci t´eto diplomov´e pr´ace. Jedn´a se o knihovnu umoˇzn ˇuj´ıc´ı n´avˇstˇevn´ık˚ um webov´ ych str´anek jejich z´ajemnou komunikaci. Jedn´ım z poskytovan´ ych zp˚ usob˚ u komunikace je jednoduch´ y chat. Daleko zaj´ımavˇejˇs´ı je ale komunikace prostˇrednictv´ım kreslen´ı na HTML5 element canvas. Uˇzivatel´e mohou na tento element kreslit myˇs´ı a knihovna zajiˇst’uje ukl´ad´an´ı nakreslen´ ych ˇcar na serveru a jejich distribuci k ostatn´ım n´avˇstˇevn´ık˚ um str´anek.
1
2 JavaScript V t´eto kapitole se budu vˇenovat jazyku JavaScript. Nejv´ yznamˇejˇs´ı pouˇzit´ı tohoto jazyka je ke psan´ı aplikac´ı, kter´e jsou vykon´av´any webov´ ymi prohl´ıˇzeˇci. JavaScript bude v´ yznamn´ ym n´astrojem pˇri tvorbˇe praktick´e ˇca´sti t´eto diplomov´e pr´ace. V t´eto kapitole se pod´ıv´ame na jeho vznik a na z´aklady pr´ace s t´ımto jazykem.
2.1
Historie JavaScriptu
Zaˇc´atkem devades´at´ ych let dvac´at´eho stolet´ı, kdy byl vytvoˇren World Wide Web, neexistovala ˇz´adn´a interakce s webov´ ymi str´ankami. Bylo tedy potˇreba vytvoˇrit programovac´ı jazyk, kter´ y by dovolil nadefinovat, jak m´a str´anka reagovat na akce od uˇzivatele, aniˇz by bylo tˇreba str´anku naˇc´ıst znovu ze serveru. V t´eto dobˇe se nejv´ıce pouˇz´ıvaly dva prohl´ıˇzeˇce: Netscape Navigator a Internet Explorer. Firma Netscape jako prvn´ı zavedla programovac´ı jazyk, kter´ y pˇrinesl interaktivitu do webov´ ych str´anek. Jmenoval se Livescript a byl pˇr´ımo zaintergov´an do jejich prohl´ıˇzeˇce. Tehdy zaˇcal z´ısk´avat na popularitˇe programovac´ı jazyk Java. Firma Netscape se tedy rozhodla pˇrejmenovat Livescript na JavaScript. Kromˇe podobn´e syntaxe ovˇsem nemaj´ı jazyky Java a JavaScript mnoho spoleˇcn´eho. Aby Internet Explorer nez˚ ustal pozadu, byl brzy tak´e obohacen o podporu dokonce dvou programovac´ıch jazyk˚ u. Prvn´ı se jmenoval vbscript a byl zaloˇzen na programovac´ım jazyce BASIC. Druh´ y byl nazv´an JScript a velmi se podobal JavaScriptu. Vzhledem k d˚ uleˇzitosti JavaScriptu se jej v roce 1996 ujala standardizaˇcn´ı organizace ECMA, kter´a pak byla zodpovˇedn´a za dalˇs´ı v´ yvoj tohoto jazyka. JavaScript byl pot´e pˇrejmenov´an na ECMAScript nebo ECMA-262. Vˇetˇsina lid´ı ale tento jazyk st´ale oznaˇcuje jako JavaScript. V´ıce informac´ı o historii jazyka naleznete v [1].
2.2
Z´ aklady JavaScriptu
Programovac´ı jazyk JavaScript je case sensitive (rozliˇsuje mal´a a velk´a p´ısmena). Kaˇzd´ y pˇr´ıkaz se ukonˇcuje stˇredn´ıkem. Pokud chceme k´od JavaScriptu vloˇzit pˇr´ımo do HTML souboru, um´ıst´ıme jej do elementu SCRIPT: < s c r i p t type =”t e x t / j a v a s c r i p t ”> document . w r i t e (”
H e l l o World!
”) ;
2
JavaScript
Z´aklady JavaScriptu
Vˇetˇsinou je ale nejlepˇs´ı ps´at skripty do samostatn´eho souboru, kter´ y pak vloˇz´ıme do HTML str´anky takto: < s c r i p t s r c =”m u j s k r i p t . j s ” type =”t e x t / j a v a s c r i p t ” />
Promˇ enn´ e JavaScript je slabˇe typovan´ y jazyk. Pˇri deklaraci promˇenn´ ych tedy neuv´ad´ıme jejich datov´ y typ. Lok´aln´ı promˇenn´e se deklaruj´ı uvnitˇr funkc´ı a pˇred n´azvem promˇenn´e se p´ıˇse kl´ıˇcov´e slovo var. Kaˇzd´a promˇenn´a, kter´a je deklarov´ana vnˇe funkce, se st´av´a glob´aln´ı promˇennou. Promˇenn´e deklarovan´e bez pouˇzit´ı kl´ıˇcov´eho slova var se tak´e st´avaj´ı glob´aln´ımi promˇenn´ ymi. Cykly a podm´ınky Syntax podm´ınky i cykl˚ u je prakticky stejn´ y s programovac´ımi jazyky Java a C. Uvedu zde ale pˇresto uk´azky tˇechto konstrukc´ı. Smyˇcka for : var i ; f o r ( i =0; i <=5; i ++) { // nˇe j a k y ´ k´ od }
Cyklus while: var i =0; w h i l e ( i <=5) { // nˇe j a k y ´ k´ od }
Cyklus for..in je pouˇz´ıv´an k proch´azen´ı parametr˚ u objektu: var osoba={k r e s t n i J m e n o : ” A l o i s ” , p r i j m e n i : ”Manas ” , vek : 2 5 } ; f o r ( x i n osoba ) { document . w r i t e ( osoba [ x ] + ” ”) ; }
Podm´ınka if : i f ( podm´ınka1 ) { // zde um´ıstˇe n y ´ k´ o d s e vykon´a , pokud j e podm´ınka1 // s p l nˇe n a } e l s e i f ( podm´ınka2 ) {
3
JavaScript
Document Object Model
// zde um´ıstˇe n y ´ k´ o d s e vykon´a , pokud j e podm´ınka2 // s p l nˇe n a } else { // zde um´ıstˇe n y ´ k´ o d s e vykon´a , pokud // n e j s o u podm´ınka1 a n i podm´ınka2 s p l nˇe n y }
Vˇetven´ı pˇr´ıkazem switch: switch (n) { case 1: // k´ od , k t e r y ´ m´ a b´ y t vykon´a n , // pokud promˇenn´ a n nabyde hodnoty 1 break ; case 2: // k´ od , k t e r y ´ m´ a b´ y t vykon´a n , // pokud promˇenn´ a n nabyde hodnoty 2 break ; default : // k´ od , k t e r y ´ m´ a b´ y t vykon´a n , // pokud n nenab´ y v´ a hodnoty 1 a n i 2 }
Funkce Funkce se deklaruj´ı kl´ıˇcov´ ym slovem function: f u n c t i o n nazevFunkce ( parametr1 , . . . , parametrN ) { // k´ od f u n k c e }
Funkce vracej´ı svoj´ı n´avratovou hodnotu pˇr´ıkazem return. Dalˇs´ı z´akladn´ı informace o jazyce JavaScript naleznete v [2].
2.3
Document Object Model
Aby mohl JavaScript pracovat s HTML dokumentem, potˇrebuje, aby prohl´ıˇzeˇc vytv´aˇrel hierarchickou reprezentaci dokumentu, kter´a se naz´ yv´a Document Object Model (DOM). Prvek nejv´ yˇse v DOM hierarchii je Navigator - reprezentuje samotn´ y prohl´ıˇzeˇc. Navigator poskytuje napˇr´ıklad informaci o n´azvu a verzi prohl´ıˇzeˇce, zda m´a prohl´ıˇzeˇc zapnut´e cookies atd. Na dalˇs´ı u ´rovni DOM se nach´az´ı objekt Window. Ten reprezentuje okno prohl´ıˇzeˇce, lze z nˇej zjistit napˇr. ˇs´ıˇrku a v´ yˇsku okna, souˇradnice okna na obrazovce 4
JavaScript
Ud´alosti
a dalˇs´ı. Nejd˚ uleˇzitˇejˇs´ı prvek na dalˇs´ı u ´rovni stromu je objekt Document. Reprezentuje HTML dokument a poskytuje pˇr´ıstup k jednotliv´ ym HTML element˚ um. Obsahuje tyto kolekce: anchors, forms, images a links. Tyto kolekce lze pouˇz´ıt k pr´aci s pˇr´ısluˇsn´ ymi HTML elementy. Dalˇs´ı moˇznost´ı, jak pˇristupovat k element˚ um, je pomoc´ı n´asleduj´ıc´ıch metod objektu Document: getElementById(), getElementsByName(), getElementsByTagName(). Tyto metody dovoluj´ı pˇr´ıstup k element˚ um na z´akladˇe atribut˚ u ID a name, a na z´akladˇe n´azvu elementu.
2.4
Ud´ alosti
Ud´alosti (events) jsou akce, kter´e mohou b´ yt detekov´any JavaScriptem. Kaˇzd´ y element webov´e str´anky m´a urˇcitou sadu ud´alost´ı, na kter´e je moˇzn´e JavaScriptem reagovat. Pro nastaven´ı reakce JavaScriptu na ud´alost se pouˇzije pˇr´ısluˇsn´ y atribut HTML elementu a jako jeho hodnota se nastav´ı n´azev volan´e funkce JavaScriptu. V n´asleduj´ıc´ım pˇr´ıkladu chceme reagovat na klepnut´ı na tlaˇc´ıtko. Pouˇzijeme proto atribut onclick. Na tuto ud´alost se zde reaguje funkc´ı mojeFunkce.
Kompletn´ı seznam ud´alost´ı naleznete v tabulce 2.1. V´ıce informace o ud´alostech naleznete v [3].
2.5
Knihovna jQuery
jQuery je v´ yznamnou a hojnˇe pouˇz´ıvanou knihovnou pro jazyk JavaScript. Je obl´ıben´a d´ıky tomu, jak v´ yznamnˇe usnadˇ nuje program´ator˚ um pr´aci. jQuery mˇen´ı zp˚ usob, jak´ ym se p´ıˇs´ı JavaScriptov´e aplikace, podporuje snadnou manipulaci s HTML elementy, modifikaci CSS, snadnou tvorbu efekt˚ u a animac´ı. V neposledn´ı ˇradˇe tak´e ulehˇcuje pouˇz´ıv´an´ı technologie AJAX. Z tˇechto d˚ uvod˚ u bude jQuery velmi v´ yznamn´ ym n´astrojem pˇri realizaci praktick´e ˇca´sti t´eto pr´ace. V´ıce informac´ı o knihovnˇe jQuery naleznete v [4].
2.5.1
Zaˇ c´ın´ ame s jQuery
Aby mohly naˇse skripty vyuˇz´ıvat funkc´ı jQuery, mus´ıme nejprve vloˇzit odkaz na tuto knihovnu do naˇs´ı HTML hlaviˇcky, a to takto: < s c r i p t type =”t e x t / j a v a s c r i p t ” s r c =”j q u e r y . min . j s ”>
Pochopitelnˇe obsah atributu src je potˇreba zmˇenit podle toho, jak je konkr´etnˇe pojmenov´an n´aˇs soubor s knihovnou jQuery. 5
JavaScript Ud´ alost onAbort onBlur onChange onClick onDblClick onDragDrop onError onFocus onKeyDown onKeyPress onKeyUp onLoad onMouseDown onMouseMove onMouseOut onMouseOver onMouseUp onMove onReset onResize onSelect onSubmit onUnload
Knihovna jQuery Popis pˇri zruˇsen´ı nahr´av´an´ı obr´azku dan´ y objekt je deaktivov´an uˇzivatel zmˇenil obsah prvku formul´aˇre pˇri klepnut´ı na objekt pˇri poklep´an´ı na objekt pˇri pˇret´ahnut´ı ikony do prohl´ıˇzeˇce kdyˇz nastane chyba JavaScriptu pˇri aktivaci objektu kdyˇz uˇzivatel stiskne kl´avesu kdyˇz uˇzivatel stiskne nebo drˇz´ı stisknutou kl´avesu kdyˇz uˇzivatel pust´ı kl´avesu po dokonˇcen´ı naˇc´ıt´an´ı cel´e str´anky pˇri stisknut´ı tlaˇc´ıtka na myˇsi pˇri pohnut´ı myˇs´ı pˇri opuˇstˇen´ı dan´eho objektu kurzorem myˇsi pˇri najet´ı kurzorem myˇsi na dan´ y objekt kdyˇz uˇzivatel pust´ı tlaˇc´ıtko myˇsi kdyˇz uˇzivatel pohne oknem prohl´ıˇzeˇce kdyˇz uˇzivatel vyˇcist´ı formul´aˇr tlaˇcitkem reset kdyˇz uˇzivatel zmˇen´ı velikost okna prohl´ıˇzeˇce kdyˇz uˇzivatel oznaˇc´ı text v textov´em poli kdyˇz uˇzivatel klepne na tlaˇc´ıtko submit dan´eho formul´aˇre kdyˇz uˇzivatel opust´ı str´anku Tabulka 2.1: Tabulka ud´alost´ı
Funkce knihovny jQuery by se mˇely volat aˇz kdyˇz je dokument plnˇe naˇcten, proto by se mˇela vˇzdy pouˇz´ıvat funkce ready: jQuery . n o C o n f l i c t ( ) ; jQuery ( document ) . ready ( f u n c t i o n ( ) { // zde m˚ uˇze b´ y t k´ o d v y u ˇz´ı v a j´ı c´ı f u n k c´ı jQuery }) ;
Ve v´ yˇse uveden´em pˇr´ıkladu je vidˇet pouˇzit´ı dalˇs´ı d˚ uleˇzit´e funkce jQuery - noConflict. Jako z´astupce pro identifik´ator jQuery se implicitnˇe pouˇz´ıv´a $. Probl´emem je, ˇze ˇ sen´ım tˇechto konflikt˚ identifik´ator $ pouˇz´ıvaj´ı i jin´e knihovny, napˇr. Prototype. Reˇ u je pr´avˇe funkce noConflict, jej´ımˇz zavol´an´ım se jQuery vzd´a identifik´atoru $. Identifik´ator jQuery lze ovˇsem nad´ale pouˇz´ıvat. Chceme-li si nadefinovat jin´ y identifik´ator, lze toho dos´ahnout takto: // $ j bude nov´ ym z´ a stupcem pro i d e n t i f i k ´a t o r jQuery
6
JavaScript
Knihovna jQuery
$ j = jQuery . n o C o n f l i c t ( ) ; $ j ( document ) . ready ( f u n c t i o n ( ) { $ j (”# mujobrazek ”) . h i d e ( ) ; }) ;
N´asleduj´ıc´ı uk´azky jQuery budou operovat nad t´ımto HTML souborem: < s c r i p t type =”t e x t / j a v a s c r i p t ” s r c =”j q u e r y . min . j s ”> < s c r i p t type =”t e x t / j a v a s c r i p t ” s r c =”example . j s ”> < s t y l e type =”t e x t / c s s ”> . kotata { position : absolute ; } #k o t e 1 { l e f t : 0 px ; } #k o t e 2 { l e f t : 1 6 0 px ; } #k o t e 3 { l e f t : 3 2 0 px ; } #k o t e 4 { l e f t : 4 8 0 px ; }
h e i g h t =”102” c l a s s =”k o t a t a h e i g h t =”102” c l a s s =”k o t a t a h e i g h t =”102” c l a s s =”k o t a t a h e i g h t =”102” c l a s s =”k o t a t a
7
JavaScript
Knihovna jQuery
Obr´azky maj´ı absolutn´ı polohu kv˚ uli potˇreb´am pˇr´ıkladu demonstruj´ıc´ıho animace.
2.5.2
Selektory
Selektory slouˇz´ı k vybr´an´ı HTML element˚ u, se kter´ ymi chceme pracovat. Jejich syntaxe je velmi podobn´a syntaxi CSS. Uved’me si nˇekter´e pˇr´ıklady: jQuery(”#kote1”) vybere element s id kote1. jQuery(”.kotata”) vybere vˇsechny elementy patˇr´ıc´ı do tˇr´ıdy kotata. jQuery(”#galerie > div”) vybere pˇr´ım´e potomky elementu s id galerie, kter´e jsou typu DIV. V pˇr´ıkladu tedy vybere element s id zanorenyDiv. jQuery(”#galerie div”) vybere vˇsechny potomky elementu s id galerie, kter´e jsou typu DIV. V pˇr´ıkladu tedy vybere elementy zanorenyDiv i viceZanorenyDiv. Existuj´ı i speci´aln´ı selektory, napˇr. pro v´ ybˇer pouze prvn´ıho z mnoˇziny vybran´ ych element˚ u: jQuery(”.kotata:first”) vybere element s id kote1. Elementy lze tak´e vyb´ırat podle hodnot jejich atribut˚ u: jQuery(”div[name]”) vybere vˇsechny elementy DIV, kter´e maj´ı atribut name. jQuery(”div[name=’galerieKotat’]”) vybere element DIV, jehoˇz atribut name m´a hodnotu galerieKotat. jQuery(”div[name!=’galerieKotat’]”) vybere vˇsechny elementy DIV, jejichˇz atribut name nem´a hodnotu galerieKotat. jQuery(”div[name ∼=’muj’]”) vybere vˇsechny elementy DIV, jejichˇz atribut name obsahuje slovo muj oddˇelen´e mezerami, tedy zanorenyDiv. jQuery(”div[name*=’muj’]”) vybere vˇsechny elementy DIV, jejichˇz atribut name obsahuje ˇretˇezec muj, tj. zanorenyDiv a viceZanorenyDiv.
8
JavaScript
Knihovna jQuery
jQuery(”img[src$=’.jpg’]”) vybere vˇsechny elementy IMG, jejichˇz atribut src konˇc´ı ˇretˇezcem .jpg. jQuery(”div[nameˆ=’galerie’]”) vybere vˇsechny elementy DIV, jejichˇz atribut name zaˇc´ın´a ˇretˇezcem galerie.
2.5.3
Reakce na ud´ alosti
V JavaScriptu se standardnˇe definuj´ı reakce na ud´alosti pouˇzit´ım speci´aln´ım atribut˚ u HTML element˚ u, jako napˇr. onclick apod. Hodnotou takov´eho atributu pak je n´azev funkce, kter´a m´a b´ yt zavol´ana po nast´an´ı dan´e ud´alosti. jQuery n´am umoˇzn ˇuje definovat reakce na ud´alosti, aniˇz bychom museli modifikovat HTML k´od. Vyuˇzijeme k tomu selektory a speci´aln´ı funkce, napˇr: jQuery ( ”img ”) . c l i c k ( f u n c t i o n ( ) { a l e r t ( jQuery ( t h i s ) . a t t r ( ” i d ”) ) ; }) ;
V´ yˇse uveden´ y pˇr´ıklad reaguje na ud´alosti klepnut´ı myˇs´ı na libovoln´ y element IMG. JavaScript pak nech´a vyskoˇcit ok´enko, kter´e vyp´ıˇse id elementu, na kter´ y bylo klepnuto. Stejn´eho efektu lze dos´ahnout i pouˇzit´ım funkce bind : jQuery ( ”img ”) . bind ( ” c l i c k ” , f u n c t i o n ( ) { a l e r t ( jQuery ( t h i s ) . a t t r ( ” i d ”) ) ; }) ;
Kromˇe click nab´ız´ı samozˇrejmˇe jQuery i dalˇs´ı funkce pro jin´e typy ud´alost´ı, jako napˇr. hover (uˇzivatel najede myˇs´ı na dan´ y element), mouseout (uˇzivatel sjede myˇs´ı z dan´eho elementu) a dalˇs´ı.
2.5.4
Animace
jQuery dovoluje prov´adˇet animace jako pˇrechod mezi r˚ uzn´ ymi hodnotami CSS parametr˚ u vybran´ ych HTML element˚ u. Posledn´ım parametrem animaˇcn´ıch funkc´ı je tzv. callback funkce. Callback funkce se pouˇz´ıvaj´ı z toho d˚ uvodu, ˇze k´od, kter´ y n´asleduje za pˇr´ıkazem zavol´an´ı animaˇcn´ı funkce, se vykon´av´a paralelnˇe s danou animac´ı. Chceme-li ovˇsem nˇejakou ˇcinnost prov´est aˇz po dokonˇcen´ı animace, pouˇzijeme callback funkci. Ukaˇzme si jednoduch´ y pˇr´ıklad: jQuery (”# k o t e 3 ”) . fadeOut ( 1 0 0 0 , f u n c t i o n ( ) { a l e r t ( ”Kote 3 z m i z e l o ”) ; }) ;
Animace nech´a zmizet element s id kote3, jej´ı trv´an´ı je jedna sekunda (1000 ms). Po skonˇcen´ı animace vyskoˇc´ı ok´enko s n´apisem Kote 3 zmizelo. 9
JavaScript
Knihovna jQuery
jQuery nab´ız´ı ˇradu speci´aln´ıch animaˇcn´ıch funkc´ı, pod´ıvejme se na nˇekter´e pˇr´ıklady: jQuery(selektor).hide(doba trvani animace , callback) schov´a vˇsechny vybran´e elementy. Po dokonˇcen´ı animace je CSS vlastnost display nastavena na hodnotu none. jQuery(selektor).show(doba trvani animace, callback) zobraz´ı vˇsechny vybran´e elementy, pokud byly schovan´e. jQuery(selektor).fadeOut(doba trvani animace, callback) nech´a tak´e zmizet vybran´e elementy, ale na rozd´ıl od funkce hide toho doc´ıl´ı plynulou zmˇenou CSS vlastnosti opacity na hodnotu 0. jQuery(selektor).fadeIn(doba trvani animace, callback) opˇet uk´aˇze vybran´e elementy, pokud byly pˇredt´ım schov´any funkc´ı fadeOut. jQuery(selektor).fadeTo(doba trvani animace, opacity, callback) lze pouˇz´ıt, pokud nechceme schovat elementy u ´plnˇe. Parametr opacity n´am dovoluje nastavit v´ yslednou hodnotu pr˚ uhlednosti element˚ u. usob, jak nechat jQuery(selektor).slideUp(doba trvani animace, callback) je dalˇs´ı zp˚ zmizet vybran´e elementy, tentokr´at zmˇenou jejich v´ yˇsky. jQuery(selektor).slideDown(doba trvani animace, callback) znovu uk´aˇze elementy schovan´e funkc´ı slideUp. Nejd˚ uleˇzitˇejˇs´ı je ale funkce animate, kter´a n´am dovoluje animovat libovoln´e CSS vlastnosti, kter´e m´a smysl animovat. Jej´ı syntax je tento: jQuery(selektor).animate(animovane vlastnosti, doba trvani animace, easing, callback). Parametr animovane vlastnosti slouˇz´ı k vyjmenov´an´ı mnoˇziny vlastnost´ı, kter´e maj´ı b´ yt animov´any, spolu s jejich koncovou hodnotou. Parametr easing slouˇz´ı k v´ ybˇeru funkce, kter´a ud´av´a rychlost animace v kaˇzd´em bodu vykon´an´ı animace. Implicitn´ı hodnota je swing, druhou moˇznost´ı je hodnota linear, kter´a ˇr´ık´a, ˇze animace m´a b´ yt provedena konstantn´ı rychlost´ı. Sloˇzitˇejˇs´ı pˇr´ıklad, kter´ y pˇredv´ad´ı pouˇzit´ı funkce animate a tak´e vol´an´ı callback funkce v naˇs´ı uˇzivatelsk´e funkci, lze nal´ezt v pˇr´ıloze B.
10
JavaScript
2.5.5
Knihovna jQuery
AJAX
AJAX (Asynchronous JavaScript and XML) reprezentuje skupinu webov´ ych technologi´ı, kter´e jsou pouˇzity na stranˇe klienta ke tvorbˇe asynchronn´ıch webov´ ych aplikac´ı. S pouˇzit´ım AJAX je moˇzn´a v´ ymˇena dat mezi klientem a serverem, aniˇz by se t´ım naruˇsovalo zobrazen´ı nebo chov´an´ı aktu´aln´ı str´anky. AJAX je tvoˇren tˇemito technologiemi: • HTML (nebo XHTML) a CSS pro prezentaci dat. • DOM (Document Object Model) pro dynamick´e zobrazen´ı a interakci s daty. • XML pro v´ ymˇenu dat a XSLT pro jejich manipulaci. • XMLHttpRequest objekt pro asynchronn´ı komunikaci. • JavaScript. Data nen´ı nutn´e pˇren´aˇset ve form´atu XML. Nen´ı tedy ani povinn´e pouˇz´ıvat XSLT k jejich manipulaci. Alternativn´ım form´atem pro pˇrenos dat je JSON (JavaScript Object Notation). M˚ uˇze b´ yt ale pˇren´aˇsen i obyˇcejn´ y text. Dalˇs´ı informace o AJAX naleznete v [5]. Knihovna jQuery poskytuje velmi dobrou podporu pro AJAX. N´asleduj´ıc´ı uk´azka k´odu poˇsle na server asynchronn´ı HTTP dotaz: jQuery . a j a x ( { u r l : ” s k r i p t . php ” , type : ’ get ’ , data : { ”parametr1 ” : hodnota1 } }) ;
Parametr url slouˇz´ı k nastaven´ı URL, na kter´e m´a b´ yt HTTP dotaz zasl´an. Pro nastaven´ı typu poˇzadavku pouˇzijeme parametr type. M˚ uˇze nab´ yt hodnot get nebo post. Parametry HTTP dotazu nastav´ıme parametrem data. Informace o dalˇs´ıch parametrech funkce ajax naleznete v [6].
2.5.6
Knihovna qTip 2.0
V praktick´e ˇca´sti t´eto pr´ace potˇrebuji vytv´aˇret tooltipy k obr´azk˚ um v galerii. Standardn´ı tooltipy prohl´ıˇzeˇce nejsou dostaˇcuj´ıc´ı, proto jsem se rozhodl pouˇz´ıt knihovnu qTip 2.0. M˚ uj zdrojov´ y k´od pro vytvoˇren´ı tooltipu vypad´a n´asledovnˇe: jQuery (”#img”+ c u r r i d ) . q t i p ( { i d : ’ q t i p ’+ c u r r i d , content : {
11
JavaScript
Knihovna jQuery
text : ’< d i v c l a s s =”bubble”>
U l o ˇz i l : <span c l a s s =”bubble−a u t h o r ”> ’+ getLoginFromFullname ( c u r r s e n d e r ) +’
Datum: ’+ d a t e S t r i n g +’
Popis : ’+ c u r r d e s c r +’
’ }, position : { my : ’ bottom c e n t e r ’ , a t : ’ top c e n t e r ’ }, show : { e v e n t : ’ mouseenter ’ , solo : true }, hide : { e v e n t : ’ mouseleave ’ , f i x e d : true , delay :200 }, style : { c l a s s e s : ’ ui−t o o l t i p −dark ’ , tip : { corner : true } } }) ;
Struˇcnˇe zde vysvˇetl´ım v´ yznam jednotliv´ ych parametr˚ u tooltipu: • id - nastavuje atribut id tooltipu, lze jej pouˇz´ıt k jednoduch´e identifikaci tooltipu v dokumentu. • content - obsahuje v sobˇe atribut text. Jeho hodnotou je potom HTML, kter´e bude tvoˇrit obsah tooltipu. • position - slouˇz´ı k nastaven´ı pozice, kde se m´a tooltip zobrazovat. Zde je nastavena tak, ˇze stˇred doln´ıho okraje tooltipu m´a b´ yt um´ıstˇen nad prostˇredek horn´ıho okraje obr´azku.
12
JavaScript
Knihovna jQuery
• show - vnoˇren´ y atribut event slouˇz´ı k nastaven´ı ud´alost´ı, pˇri kter´ ych se m´a tooltip objevit. Zde pˇri najet´ı myˇs´ı na dan´ y obr´azek. D´ale atribut solo jsem nastavil na hodnotu true, coˇz ˇr´ık´a, ˇze m´a b´ yt vˇzdy zobrazen pouze jeden tooltip. • hide - i zde je vnoˇren atribut event. T´ım nastavujeme, pˇri jak´ ych ud´alostech m´a b´ yt tooltip schov´an. Zde pˇri opuˇstˇen´ı obr´azku myˇs´ı. Atribut fixed nastaven´ y na hodnotu true znamen´a, ˇze tooltip nem´a b´ yt schov´an, pokud na nˇej najedeme myˇs´ı. Atribut delay nastavuje dobu v milisekund´ach, po kter´e se m´a tooltip schovat, kdyˇz obr´azek nebo tooltip opust´ıme myˇs´ı. • style - slouˇz´ı k nastaven´ı vzhledu tooltipu. Vnoˇren´ y atribut classes n´am dovoluje vybrat CSS tˇr´ıdy, kter´e maj´ı b´ yt tooltip˚ um pˇriˇrazeny. Knihovna obsahuje nˇekolik tˇr´ıd, ze kter´ ych si m˚ uˇzeme vyb´ırat, nebo je moˇzn´e si nadefinovat i vlastn´ı vzhled tooltipu. Druh´ y vnoˇren´ y atribut tip slouˇz´ı k nastaven´ı toho, zda se m´a na okraji tooltipu zobrazit mal´a ˇsipka, kter´a ukazuje na element, ke kter´emu tooltip pˇr´ısluˇs´ı. Dalˇs´ı informace o knihovnˇe qTip 2.0 naleznete v [7].
13
3 PHP PHP je programovac´ı jazyk, kter´ y byl navrˇzen pro tvorbu dynamick´ ych webov´ ych str´anek. Tento jazyk bude m´ıt velk´e uplatnˇen´ı v praktick´e ˇc´asti t´eto pr´ace. V t´eto kapitole se nejprve pod´ıv´ame na vznik PHP a tak´e na z´aklady programov´an´ı v tomto jazyce.
3.1
Historie PHP
Prvn´ı verzi PHP vytvoˇril Rasmus Lerdorf v roce 1994. Jednalo se o jednoduchou sadu n´astroj˚ u, kterou Lerdorf pouˇz´ıval pro sledov´an´ı n´avˇstˇevnosti sv´eho osobn´ıho webu. Nazval ji Personal Home Page Tools. Postupem ˇcasu vznikly poˇzadavky na ˇsirˇs´ı funkcionalitu PHP Tools. Lerdorf vytvoˇril novou verzi, kter´a podporovala pr´aci s datab´azemi a mnoho dalˇs´ıho. D´ıky tomu bylo moˇzn´e pouˇz´ıvat tento framework k tvorbˇe jednoduch´ ych dynamick´ ych webov´ ych str´anek. V ˇcervnu roku 1995 zveˇrejnil Lerdorf zdrojov´ y k´od PHP Tools. V z´aˇr´ı tohoto roku bylo PHP opˇet rozˇs´ıˇreno a na kr´atkou dobu se nav´ıc upustilo od tohoto n´azvu. Nov´e oznaˇcen´ı bylo FI (Forms Interpreter). Programov´ y k´od se nyn´ı vkl´adal pˇr´ımo do HTML (do HTML koment´aˇr˚ u). Syntax byl velmi podobn´ y jazyku Perl, i kdyˇz byl mnohem omezenˇejˇs´ı. O mˇes´ıc pozdˇeji byla vyd´ana dalˇs´ı kompletnˇe pˇrepsan´a verze. S n´ı pˇriˇsel i n´avrat k n´azvu PHP. Jazyk byl u ´myslnˇe navrˇzen tak, aby byl svoj´ı strukturou bl´ızk´ y jazyku C. Zat´ım byl ale st´ale omezen na UNIX syst´emy. Dalˇs´ı verze vyˇsla v roce 1996, jej´ıˇz oznaˇcen´ı kombinovalo pˇredchoz´ı n´azvy - PHP/FI. V t´eto verzi se uˇz PHP zaˇcalo skuteˇcnˇe pˇretv´aˇret ze sady n´astroj˚ u na samostatn´ y jazyk. Obsahovala podporu pro datab´aze DBM, mSQL a Postgres95, cookies a dalˇs´ı. PHP/FI bylo prohl´aˇseno za verzi 2.0. V roce 1997 zaˇcali Andi Gutmans a Zeev Suraski pˇrepisovat parser PHP/FI 2.0 pro potˇreby jejich univerzitn´ıho projektu. Spolu s Lerdorfem prodiskutovali r˚ uzn´e aspekty st´avaj´ıc´ı implementace a n´aslednˇe zaˇcali vyv´ıjet nov´ y nez´avisl´ y programovac´ı jazyk. Tento jazyk byl novˇe oznaˇcov´an pouze jako PHP, coˇz je rekurzivn´ı akronym s v´ yznamem PHP: Hypertext Preprocessor. Nejsilnˇejˇs´ı str´ankou PHP 3.0 se stala jeho rozˇsiˇritelnost spolu s rozhran´ımi pro mnoho datab´az´ı a protokol˚ u. Dalˇs´ı velmi d˚ uleˇzitou vlastnost´ı verze 3.0 bylo zaveden´ı podpory pro objektovˇe orientovan´e programov´an´ı. V ˇcervnu 1998 bylo PHP 3.0 prohl´aˇseno za ofici´aln´ıho n´astupce PHP/FI 2.0. Aktivn´ı v´ yvoj PHP/FI 2.0 byl ofici´alnˇe ukonˇcen. PHP 3.0 uˇz bylo moˇzn´e provozovat i na syst´emech Windows a Macintosh. 14
PHP
Z´aklady PHP
V roce 1998, kr´atce po vyd´an´ı PHP 3.0, zaˇcali Andi Gutmans a Zeev Suraski pˇrepisovat j´adro jazyka PHP. C´ılem bylo zv´ yˇsit efektivitu sloˇzit´ ych aplikac´ı a zlepˇsit modularitu k´odu jazyka PHP. Na z´akladˇe tˇechto poˇzadavk˚ u byl vytvoˇren nov´ y engine nazvan´ y jako Zend Engine. Na nˇem bylo postaveno PHP 4.0. Do t´eto verze bylo nav´ıc pˇrid´ano mnoho nov´ ych funkc´ı jako podpora pro mnoho webov´ ych server˚ u, HTTP sessions, bufferov´an´ı v´ ystupu, nˇekolik nov´ ych jazykov´ ych konstrukc´ı a dalˇs´ı. PHP 4.0 bylo vyd´ano v kvˇetnu 2000. PHP 5.0 vyˇslo v ˇcervenci 2004. Pouˇz´ıv´a j´adro Zend Engine 2.0 s nov´ ym objektov´ ym modelem a spoustou dalˇs´ıch funkc´ı. V´ıce informac´ı o vzniku jazyka PHP naleznete v [8].
3.2
Z´ aklady PHP
Tato podkapitola obsahuje sezn´amen´ı s jazykem PHP. V´ıce informac´ı o pr´aci s t´ımto jazykem naleznete v [9]. Z´ akladn´ı syntax PHP k´od zaˇc´ın´a ˇretˇezcem . Na serverech s podporou zkr´acen´e formy lze zaˇc´ıt PHP k´od ˇretˇezcem
Pˇr´ıklad tak´e ukazuje, ˇze kaˇzd´a ˇra´dka k´odu se mus´ı ukonˇcit stˇredn´ıkem. Koment´aˇre se zapisuj´ı podobnˇe jako v jazyce C, ˇra´dkov´e zaˇc´ınaj´ı ˇretˇezcem // a blokov´e se um´ıst’uj´ı mezi /* a */. Promˇ enn´ e Kaˇzd´a promˇenn´a v PHP zaˇc´ın´a znakem $. Promˇenn´e jsou slabˇe typovan´e. Program´ator tedy nedeklaruje typ promˇenn´e, nebot’ PHP urˇc´ı typ automaticky podle kontextu, ve kter´em je promˇenn´a pouˇzita. Nav´ıc se typ promˇenn´e m˚ uˇze automaticky mˇenit:
15
PHP
Z´aklady PHP
Podm´ınky Podm´ınky jsou opˇet podobn´e klasick´ ym programovac´ım jazyk˚ um jako je C nebo Java. Podm´ınka if vypad´a takto: i f ( podminka1 ) { // k´ o d , k t e r ´y j e zde , s e provede , pokud j e podminka1 // s p l nˇe n a } e l s e i f ( podminka2 ) { // k´ o d , k t e r ´y j e zde , s e provede , pokud podminka2 //m´ a hodnotu t r u e a podminka1 m´ a // hodnotu f a l s e } else { // k´ o d , k t e r ´y j e zde , s e provede , pokud // podminka1 i podminka2 maj´ı hodnotu f a l s e }
Druh´ ym typem vˇetven´ı programu je pˇr´ıkaz switch: switch ( $promenna ) { case hodnota1 : // p r o v e d e se , pokud $promenna==hodnota1 break ; case hodnota2 : // p r o v e d e se , pokud $promenna==hodnota2 break ; default : // p r o v e d e se , pokud $promenna!= hodnota1 // a z ´ aroven ˇ $promenna!= hodnota2 }
Pˇr´ıkaz switch um´ı pracovat nejen s promˇenn´ ymi typu integer, ale i s typy float a string. Cykly I syntax cykl˚ u se velmi podob´a jazyku C. Smyˇcka for vypad´a takto: $pocetIteraci = 10; for ( $ i =1; $ i<=$ p o c e t I t e r a c i ; $ i ++) { echo ” I t e r a c e ” . $ i . ”
\n ” ; }
Pro pohodln´e proch´azen´ı pol´ı n´am PHP poskytuje smyˇcku foreach: $ p o l e=array ( ”prvek1 ” , ”prvek2 ” , ”prvek3 ”) ; foreach ( $ p o l e a s $hodnotaPrvkuPole ) { echo $hodnotaPrvkuPole . ”
\n ” ; }
Posledn´ım typem cyklu jsou smyˇcky while a do-while: 16
PHP
Z´aklady PHP
$i = 1; while ( $ i%5 != 0 ) { echo $ i . ”
\n ” ; $ i ++; } do { echo $ i . ”
\n ” ; $ i ++; } while ( $ i%5 != 0 )
Pole K vytv´aˇren´ı pol´ı pouˇz´ıv´ame konstrukci array(). PHP podporuje ˇc´ıselnˇe indexovan´a pole, ale i indexov´an´ı ˇretˇezcem (asociativn´ı pole). N´asleduj´ıc´ı pˇr´ıklad ukazuje tvorbu ˇc´ıselnˇe indexovan´eho pole: $ p o l e = array (0=>10, 1=>20, 3 0 ) ; $pole [ 3 ] = 40; $pole [ 4 ] = 50; $pole [ ] = 60; p ri nt r ( $ p o l e ) ; // v y p´ıˇs e : // Array ( [ 0 ] => 10 [ 1 ] => 20 [ 2 ] => 30 // [ 3 ] => 40 [ 4 ] => 50 [ 5 ] => 60 )
Prvn´ı ˇra´dka v´ yˇse uveden´eho pˇr´ıkladu ukazuje tvorbu pole, kter´e po vytvoˇren´ı obsahuje 3 prvky. Je zde vidˇet, ˇze m˚ uˇzeme sami definovat indexy prvk˚ u, nebo lze nechat PHP indexovat prvky automaticky, coˇz je zde pˇr´ıpad prvku s hodnotou 30. N´asleduj´ıc´ı 3 ˇra´dky ukazuj´ı, ˇze to sam´e plat´ı i pro vytv´aˇren´ı dalˇs´ıch prvk˚ u pole. Dalˇs´ı pˇr´ıklad ukazuje pr´aci s asociativn´ım polem. D´ale ukazuje, ˇze je moˇzn´e kombinovat indexov´an´ı pomoc´ı ˇretˇezc˚ u i ˇc´ısel. Stejnˇe tak i hodnoty uloˇzen´e v jednotliv´ ych prvc´ıch pole mohou b´ yt r˚ uzn´ ych datov´ ych typ˚ u: $ p o l e = array ( ” p r i j m e n i ”=>”Manas ”) ; $ p o l e [ ”jmeno ” ] = ” A l o i s ” ; $pole [ ] = 30; // i n d e x bude 0 echo $ p o l e [ ”jmeno ” ] . ” ” . $ p o l e [ ” p r i j m e n i ” ] . ” , vek : ” . $ p o l e [ 0 ] . ”
\n ” ;
Prvek pole m˚ uˇze b´ yt tak´e pole, ˇc´ımˇz lze tvoˇrit v´ıcedimenzion´aln´ı pole. Funkce Definice funkc´ı zaˇc´ınaj´ı kl´ıˇcov´ ym slovem function. V definici funkce se nespecifikuje n´avratov´ y typ ani datov´e typy vstupn´ıch parametr˚ u (i kdyˇz od verze 5 lze definovat, ˇze parametr mus´ı b´ yt objektem specifikovan´e tˇr´ıdy). N´asleduj´ıc´ı pˇr´ıklad ukazuje syntax funkc´ı a jejich vol´an´ı: 17
PHP
Prostˇredky pro komunikaci proces˚ u
function sectiDveCisla ( $cislo1 , $cislo2 ) { r e t u r n $ c i s l o 1+$ c i s l o 2 ; } echo s e c t i D v e C i s l a ( 1 , 2 ) . ”
\n ” ;
3.3
Prostˇ redky pro komunikaci proces˚ u
V realizaˇcn´ı ˇca´sti t´eto pr´ace potˇrebuji zajistit meziprocesovou komunikaci. Proto v t´eto podkapitole pop´ıˇsi prostˇredky jazyka PHP pro pr´aci se sd´ılenou pamˇet´ı a semafory. Sd´ılen´ a pamˇ et’ PHP nab´ız´ı funkce k pr´aci se sd´ılenou pamˇet´ı, kterou lze pouˇz´ıt pro komunikaci proces˚ u. Pod´ıvejme se na jednotliv´e tyto funkce: • shm attach - z´ısk´ame objekt, kter´ y pouˇzijeme pro pˇr´ıstup ke sd´ılen´e pamˇeti. Prvn´ım parametrem je celoˇc´ıseln´ y kl´ıˇc, kter´ y slouˇz´ı k identifikaci sd´ılen´e pamˇeti. K z´ısk´an´ı kl´ıˇce se obvykle pouˇz´ıv´a funkce ftok, kter´a kl´ıˇc vytvoˇr´ı na z´akladˇe cesty k existuj´ıc´ımu souboru a na z´akladˇe identifik´atoru projektu. Druh´ ym parametrem je velikost sd´ılen´e pamˇeti. Tˇret´ım parametrem jsou pˇr´ıstupov´a pr´ava ke sd´ılen´e pamˇeti. Pˇri prvn´ım vol´an´ı t´eto funkce dojde k vytvoˇren´ı sd´ılen´e pamˇeti. • shm detach - provede odpojen´ı sd´ılen´e pamˇeti. • shm has var - testuje, zda se ve sd´ılen´e pamˇeti nach´az´ı promˇenn´a se specifikovan´ ym kl´ıˇcem. • shm get var - vrac´ı promˇennou s dan´ ym kl´ıˇcem. • shm put var - uloˇz´ı promˇennou identifikovanou dan´ ym kl´ıˇcem do sd´ılen´e pamˇeti. • shm remove var - smaˇze promˇennou s dan´ ym kl´ıˇcem ze sd´ılen´e pamˇeti. • shm remove - smaˇze danou sd´ılenou pamˇet’. Semafory Pro v´ yluˇcn´ y pˇr´ıstup ke sd´ılen´e pamˇeti je potˇreba pouˇz´ıt semafory. Pro pr´aci s nimi n´am PHP nab´ız´ı tyto funkce: • sem get - slouˇz´ı k z´ısk´an´ı semaforu na z´akladˇe kl´ıˇce. Kl´ıˇc je cel´e ˇc´ıslo, kter´e si mus´ıme zvolit. Je moˇzn´e nastavit, kolik proces˚ u m˚ uˇze z´arovˇen ˇ z´ıskat z´amek. Implicitnˇe je semafor bin´arn´ı. D´ale je moˇzn´e nastavit pˇr´ıstupov´a pr´ava k semaforu a tak´e zda m´a b´ yt z´amek automaticky uvolnˇen po skonˇcen´ı skriptu. • sem acquire - z´ısk´an´ı z´amku. 18
PHP
Prostˇredky pro komunikaci proces˚ u
• sem release - uvolnˇen´ı z´amku. y semafor. • sem remove - odstran´ı dan´
19
4 Adobe Flash Adobe Flash je velmi v´ yznamn´ y n´astroj pro tvorbu interaktivn´ıch animac´ı, vide´ı i her. V t´eto kapitole se pod´ıv´ame na historii vzniku tohoto n´astroje a na nˇekter´e jeho vlastnosti.
4.1
Historie
Flash se vyvinul z programu SmartSketch, jehoˇz autorem byl Jonathan Gay. Jonathan Gay zaloˇzil v roce 1993 firmu FutureWave Software, kter´a zaˇcala pracovat na programu SmartSketch, jehoˇz c´ılem bylo usnadnit kreslen´ı perem na dotykov´e displeje. Ovˇsem v roce 1994 byla firma Go, kter´a vyv´ıjela operaˇcn´ı syst´em pro poˇc´ıtaˇce s dotykov´ ym displejem, koupena firmou AT&T a jej´ı ˇcinnost byla zastavena. T´ım zmizel trh pro SmartSketch. FutureWave se tedy rozhodli portovat SmartSketch na Windows a Macintosh. V roce 1995 se uˇz zaˇcalo zd´at, ˇze by se mohl Internet st´at popul´arn´ı z´aleˇzitost´ı. Ve FutureWave zaˇcali pˇrem´ yˇslet o tom, ˇze lid´e jistˇe budou cht´ıt pˇres internet pˇren´aˇset grafiku a animace. Zaˇcali tedy pˇrid´avat animaci do SmartSketch. V t´e dobˇe jedinou moˇznost´ı, jak pˇrehr´at animaci v prohl´ıˇzeˇci, bylo pomoc´ı Javy. FutureWave tedy napsali jednoduch´ y pˇrehr´avaˇc zaloˇzen´ y na Javˇe. Probl´emem ale bylo, ˇze bˇeˇzel ne´ unosnˇe pomalu. Naˇstˇest´ı na podzim roku 1995 vydali Netscape API pro tvorbu z´asuvn´ ych modul˚ u do jejich webov´eho prohl´ıˇzeˇce. To koneˇcnˇe dovolilo FutureWave vytvoˇrit efektivnˇe funguj´ıc´ı pˇrehr´avaˇc. V´ ysledn´ y produkt byl pojmenov´an FutureSplash Animator a byl vyd´an v l´etˇe 1996. V roce 1996 se FutureSplash zal´ıbil Microsoftu. Ti pr´avˇe pracovali na jejich sluˇzbˇe MSN (The Microsoft Network) a rozhodli se FutureSplash pouˇz´ıt v jejich produktu. Druh´ ym v´ yznamn´ ym z´akazn´ıkem FutureWave byl Disney Online. Ti pouˇzili FutureSplash k tvorbˇe uˇzivatelsk´eho rozhran´ı jejich webu Disney Daily Blast. V prosinci roku 1996 koupila FutureWave Software firma Macromedia. FutureSplash Animator byl pak pˇrejmenov´an na Macromedia Flash 1.0. V souˇcasnosti v´ yv´ıj´ı a distribuuje Flash firma Adobe Systems, kter´a v roce 2005 koupila firmu Macromedia. V´ıce o vzniku Adobe Flash si m˚ uˇzete pˇreˇc´ıst v [10].
20
Adobe Flash
4.2
Vlastnosti
Vlastnosti
Flash tedy slouˇz´ı ke tvorbˇe animac´ı a jejich prezentaci pˇredevˇs´ım na webu. Um´ı pracovat s vektorovou i rasterovou grafikou. Umoˇzn ˇuje animovat text, kresby a obr´azky. Podporuje ˇradu video a audio form´at˚ u jako napˇr. MP3, avi nebo wmv. Flash animace mohou b´ yt nav´ıc interaktivn´ı. K tomu se pouˇz´ıv´a skriptovac´ı jazyk ActionScript, kter´ y dovoluje definovat reakce na r˚ uzn´e akce, jako je napˇr. stisknut´ı tlaˇc´ıtka, nebo m˚ uˇze b´ yt akce sv´az´ana se sn´ımkem animace. Dalˇs´ı d˚ uleˇzitou vlastnost´ı je, ˇze animace mohou b´ yt streamov´any a jejich pˇrehr´av´an´ı m˚ uˇze zaˇc´ıt dˇr´ıve, neˇz je cel´a animace staˇzena do pˇrehr´avaˇce. Flash ukl´ad´a svoje animace do souboru ve form´atu SWF (Small Web Format). Obvykle maj´ı pˇr´ıponu .swf a lze je pˇrehr´at ve Flash pˇrehr´avaˇci. Pˇr´ıpadnˇe mohou b´ yt ve formˇe samostatnˇe spustiteln´eho souboru (soubor m´a potom pod OS Windows pˇr´ıponu .exe). Dalˇs´ım form´atem je Flash Video. Tyto soubory maj´ı pˇr´ıponu .flv. Mohou b´ yt vloˇzeny do .swf soubor˚ u nebo m˚ uˇze b´ yt pro jejich pˇrehr´an´ı pouˇzit nˇekter´ y z pˇrehr´avaˇc˚ u, kter´ y m´a pro tento form´at podporu. Pouˇzit´ı vektorov´e grafiky spolu s programov´ ym k´odem dovoluje Flash soubor˚ um, aby byly menˇs´ı, neˇz koresponduj´ıc´ı videa v jin´ ych form´atech. Na druhou stranu m˚ uˇze pˇrehr´av´an´ı Flash soubor˚ u v´ıce zatˇeˇzovat CPU, pokud v nich obsaˇzen´ y programov´ y k´od prov´ad´ı sloˇzit´e operace. Dalˇs´ı informace o Adobe Flash naleznete v [11].
21
5 Bezpeˇcnost na webu V t´eto kapitole se budeme zab´ yvat r˚ uzn´ ymi aspekty bezpeˇcnosti na webu. Pod´ıv´ame se tak´e na nˇekter´e zn´am´e zp˚ usoby napaden´ı a u nˇekter´ ych uvedu zp˚ usob obrany. V´ıce informac´ı na t´ema bezpeˇcnosti naleznete v [12].
5.1
C´ıle bezpeˇ cnosti
Bezpeˇcnost se skl´ad´a z r˚ uzn´ ych aspekt˚ u. Abychom dos´ahli urˇcit´e rozumn´e u ´rovnˇe bezpeˇcnosti, mus´ı b´ yt bezpeˇcnost celistv´a. Dos´ahnout absolutn´ı bezpeˇcnosti je obvykle nemoˇzn´e, snahou je ale vˇzdy riziko prolomen´ı ochrany co nejv´ıce minimalizovat. Uvaˇzuje se tak, ˇze bezpeˇcnost je tˇreba m´ıt na takov´e u ´rovni, aby se snaha o jej´ı prolomen´ı u ´toˇcn´ıkovi nevyplatila. O syst´emu se tvrd´ı, ˇze je bezpeˇcn´ y tak, jak je zabezpeˇcen´ y jeho nejslabˇs´ı prvek. Pod´ıvejme se d´ale na jednotliv´e koncepty bezpeˇcnosti.
5.1.1
Autentizace
Jedn´a se o probl´em zjiˇstˇen´ı identity, typicky osoby nebo stroje. Napˇr. pˇred t´ım, neˇz urˇcit´ y syst´em vyd´a nˇejak´e citliv´e informace, mus´ı se ujistit, ˇze v´ı, s k´ ym komunikuje. Prvn´ım zp˚ usobem, jak se o tom ujistit, je na z´akladˇe nˇeˇceho, co komunikuj´ıc´ı osoba zn´a a co by nemˇel zn´at nikdo jin´ y. Typicky se jedn´a o zad´an´ı hesla. V´ yhodou hesel je jejich snadn´a implementace (na rozd´ıl napˇr. od sn´ım´an´ı otisk˚ u prst˚ u) a obvykle ani pˇr´ıliˇs nekomplikuj´ı ˇzivot uˇzivatel˚ um. Probl´emem ovˇsem m˚ uˇze b´ yt, kdyˇz je uˇzivatel˚ um ˇ dovoleno vybrat si libovoln´e heslo. Casto se pak najde nezanedbateln´e procento uˇzivatel˚ u, jejichˇz heslo je snadno uh´adnuteln´e. Jednou moˇznost´ı, jak tento probl´em vyˇreˇsit, je, kdyˇz syst´em s´am pˇridˇel´ı kaˇzd´emu uˇzivateli heslo. Takov´a generovan´a hesla ale jsou tˇeˇzk´a na zapamatov´an´ı. Lepˇs´ı ˇreˇsen´ı je nechat uˇzivatele vybrat si heslo, ale z´aroveˇ n vynutit urˇcitou sloˇzitost hesla - napˇr. kaˇzd´e heslo mus´ı b´ yt dlouh´e alespoˇ n osm znak˚ u a mus´ı obsahovat kromˇe p´ısmen abecedy alespoˇ n dvˇe ˇc´ıslice. Druh´ ym zp˚ usobem, jak urˇcit identitu, je na z´akladˇe nˇeˇceho, co osoba vlastn´ı. Pˇr´ıkladem mohou b´ yt ˇcipov´e karty. Ty mohou fungovat tak, ˇze uˇzivatel vloˇz´ı kartu do ˇcteˇcky. Karta vyˇsle ˇcteˇcce v´ yzvu. Uˇzivatel mus´ı n´aslednˇe zadat do ˇcteˇcky PIN. Na z´akladˇe PIN pak ˇcteˇcka spoˇcte odpovˇed’, kterou pˇred´a ˇcipov´e kartˇe. Pokud je odpovˇed’ spr´avn´a, je uˇzivatel povaˇzov´an za autentizovan´eho a pˇr´ıstup k informac´ım uloˇzen´ ym na kartˇe (pˇr´ıpadnˇe v syst´emu) je povolen.
22
Bezpeˇcnost na webu
C´ıle bezpeˇcnosti
Tˇret´ı zp˚ usob autentizace je na z´akladˇe biometrick´ ych parametr˚ u ˇclovˇeka. Jedn´a se napˇr´ıklad o sn´ım´an´ı otisk˚ u prst˚ u nebo jeˇstˇe l´epe o sn´ım´an´ı obrysu ruky, kdy se z´aroveˇ n tak´e sn´ımaj´ı otisky vˇsech prst˚ u. Dalˇs´ı metody jsou napˇr´ıklad skenov´an´ı duhovky nebo sn´ım´an´ı podpisu. Kaˇzd´a z tˇechto metod vygeneruje bin´arn´ı reprezentaci osoby, kter´a by mˇela b´ yt unik´atn´ı pro kaˇzdou osobu. Pˇri kaˇzd´e autentizaci uˇzivatele se pak v´ ysledky mˇeˇren´ı porovn´avaj´ı se z´aznamy v datab´azi a zjiˇst’uje se, zda doˇslo k dostateˇcnˇe velk´e shodˇe, abychom mohli prohl´asit, ˇze se podaˇrilo uˇzivatele identifikovat. D˚ uleˇzit´ ym c´ılem pˇri v´ yvoji tˇechto metod je, aby nedoch´azelo k pˇr´ıpad˚ um, kdy biometrick´a metoda pˇridˇel´ı uˇzivateli nespr´avnou indentitu - napˇr. prohl´as´ı o osobˇe, kter´a v˚ ubec v datab´azi nen´ı, ˇze se jedn´a o ˇclovˇeka, kter´ y m´a pln´ y pˇr´ıstup do syst´emu. Opaˇcn´ ym probl´emem je, kdyˇz nen´ı rozpozn´an legitimn´ı uˇzivatel, jehoˇz biometrick´e u ´daje se v datab´azi nach´azej´ı. Jako posledn´ı pozn´amku o autentizaci bych r´ad zm´ınil, ˇze pro zlepˇsen´ı bezpeˇcnosti lze v´ yˇse uveden´e metody identifikace kombinovat. Napˇr. trezor banky se otevˇre pouze tehdy, kdyˇz jej´ı ˇreditel si nejprve nech´a oskenovat duhovku oka a pak jeˇstˇe vloˇz´ı svoje heslo.
5.1.2
Autorizace
C´ılem autorizace je urˇcit, jak´a opr´avnˇen´ı m´a dan´ y uˇzivatel. V operaˇcn´ıch syst´emech se toto ˇreˇs´ı napˇr. pomoc´ı Access Control List (ACL). Jedn´a se o seznam, ve kter´em je nadefinov´ano, ke kter´ ym zdroj˚ um maj´ı jednotliv´ı uˇzivatel´e pˇr´ıstup, a jak´e operace (ˇcten´ı, z´apis, spuˇstˇen´ı) mohou nad zdroji prov´adˇet. V lepˇs´ım syst´emu je moˇzn´e z´aroveˇ n uˇzivatele pˇriˇrazovat do skupin. Kaˇzd´a skupina m´a pak opˇet nadefinovan´e zdroje, ke kter´ ym m´a pˇr´ıstup, a operace nad nimi. Dalˇs´ı autorizaˇcn´ı syst´em je napˇr. Bell-LaPadula model, kter´ y je urˇcen pˇredevˇs´ım pro arm´adu. Dokumenty v syst´emu maj´ı nadefinovan´ y stupeˇ n utajen´ı. Kaˇzd´ y uˇzivatel m´a pˇriˇrazen stupeˇ n opr´avnˇen´ı, kter´ y odpov´ıd´a nˇekter´e z u ´rovn´ı utajen´ı. Prvn´ım pravidlem, kter´e plat´ı v tomto syst´emu, je No Read Up. To znamen´a, ˇze uˇzivatel nesm´ı ˇc´ıst dokumenty s vyˇsˇs´ı u ´rovn´ı utajen´ı, neˇz je jeho opr´avnˇen´ı. Druh´ ym pravidlem je No Write Down. To znamen´a, ˇze uˇzivatel nesm´ı vytvoˇrit dokument, kter´ y m´a niˇzˇs´ı u ´roveˇ n utajen´ı, neˇz je stupeˇ n opr´avnˇen´ı autora. Filozofi´ı pro toto pravidlo je, ˇze osoby s vysokou u ´rovn´ı opr´avnˇen´ı budou typicky generovat dokumenty, kter´e budou obsahovat nˇejak´e tajn´e informace. Proto syst´em zajiˇst’uje, aby nebylo moˇzn´e nedopatˇren´ım uˇzivatele zveˇrejnit tajn´e informace.
5.1.3
Soukrom´ı
Pˇri komunikaci dvou stanic pˇres poˇc´ıtaˇcovou s´ıt’ je ˇcasto ˇz´adouc´ı, aby nikdo dalˇs´ı nemohl tuto komunikaci ˇc´ıst. Napˇr´ıklad v s´ıti ethernet, kde je pouˇzit ethernetov´ y hub, 23
Bezpeˇcnost na webu
C´ıle bezpeˇcnosti
je veˇsker´a komunikace rozes´ıl´ana vˇsem stanic´ım. Operaˇcn´ı syst´em sice standardnˇe komunikaci, kter´a mu nen´ı urˇcena, zahazuje. Je ovˇsem moˇzn´e pouˇz´ıt tzv. promiskuitn´ı reˇzim, kter´ y dovol´ı programu ˇc´ıst vˇsechny zpr´avy. Pro zajiˇstˇen´ı soukrom´ı je potˇreba pouˇz´ıt ˇsifrov´an´ı zpr´av. Obvykle se ˇsifruje na z´akladˇe kl´ıˇce. Kl´ıˇc mus´ı b´ yt informace, kterou znaj´ı pouze ty stanice, kter´e chtˇej´ı spolu komunikovat. Existuj´ı algoritmy pro bezpeˇcnou v´ ymˇenu kl´ıˇc˚ u - napˇr. algoritmus Diffie–Hellman.
5.1.4
Integrita dat
Dalˇs´ı probl´em, kter´ y m˚ uˇze pˇri komunikaci nastat, je u ´tok typu man in the middle. V situaci, kdy dvˇe stanice chtˇej´ı mezi sebou komunikovat, je moˇzn´e, aby tˇret´ı stanice zachyt´avala a modifikovala pos´ılan´e zpr´avy. V s´ıt’ov´ ych protokolech se k ovˇeˇren´ı integrity dat pouˇz´ıv´a napˇr´ıklad CRC (cyclic redundancy check). S pouˇzit´ım CRC dok´aˇzeme detekovat, ˇze nˇekter´e bity zpr´avy byly ztraceny nebo zmˇenˇeny. CRC je funkc´ı pos´ılan´e zpr´avy. Tento zp˚ usob kontroly integrity je ale vhodn´ y pouze v pˇr´ıpadˇe, kdy pˇredpokl´ad´ame, ˇze zpr´ava m˚ uˇze b´ yt zmˇenˇena chybou pˇrenosu. Jako obrana proti u ´toku typu man in the middle nen´ı dostaˇcuj´ıc´ı, nebot’ u ´toˇcn´ık m˚ uˇze zmˇenit nejen obsah zpr´avy, ale i CRC tak, aby pˇr´ıjemce modifikaci nedetekoval. ˇ sen´ım m˚ Reˇ uˇze b´ yt pos´ılat spolu se zpr´avou MAC (message authentication code). ´ cn´ık, kter´ MAC je funkc´ı nejenom samotn´e zpr´avy, ale tak´e tajn´eho kl´ıˇce. Utoˇ y nezn´a tajn´ y kl´ıˇc, nen´ı schopen k modifikovan´e zpr´avˇe vygenerovat odpov´ıdaj´ıc´ı MAC.
5.1.5
Odpovˇ ednost
Odpovˇednost je dalˇs´ı d˚ uleˇzit´ y prvek pˇri zajiˇstˇen´ı bezpeˇcnosti. Jedn´a se o to, ˇze pokud dojde k urˇcit´emu u ´toku, chceme b´ yt schopni zjistit, kdo u ´tok provedl. Napˇr´ıklad pokud urˇcit´a vysoce postaven´a osoba ve firmˇe m´a pravomoc manipulovat s bankovn´ım u ´ˇctem firmy, mus´ı b´ yt moˇzno zjistit, zda si tato osoba nepˇrev´ad´ı pen´ıze napˇr´ıklad na sv˚ uj osobn´ı u ´ˇcet. K tomu je potˇreba pouˇz´ıvat logov´an´ı. Do log˚ u se mus´ı ukl´ad´at kdo, kdy, co provedl. Nav´ıc mus´ı b´ yt zajiˇstˇeno, ˇze zmiˇ novan´ y zamˇestnanec firmy nem˚ uˇze logy modifikovat a t´ım po sobˇe zahladit stopy.
5.1.6
Dostupnost
Dostupnost znamen´a, ˇze server dok´aˇze dostateˇcnˇe rychle odpov´ıdat na dotazy. K naruˇsen´ı dostupnosti se pouˇz´ıvaj´ı tzv. Denial of Service (DoS) u ´toky, kter´e obvykle funguj´ı tak, ˇze nˇejak´ y stroj zaˇcne pos´ılat na server nadmˇern´ y poˇcet dotaz˚ u, ˇc´ımˇz zp˚ usob´ı znaˇcn´e zpomalen´ı serveru nebo i jeho p´ad. Situace, kdy nˇekolik stanic najedou zaˇcne 24
Bezpeˇcnost na webu
Typy u ´tok˚ u
takto zahlcovat server, se naz´ yv´a Distributed Denial of Service (DDoS). K proveden´ı takov´ ychto u ´tok˚ u se ˇcasto pouˇz´ıvaj´ı poˇc´ıtaˇcov´e viry, kter´e, jakmile dostanou povel, zaˇcnou z postiˇzen´ ych stanic zahlcovat urˇcit´ y server dotazy. DoS u ´tok je tak´e napˇr. moˇzn´e prov´est zaplnˇen´ım pevn´eho disku postiˇzen´eho stroje. M˚ uˇze k tomu doj´ıt na serverech, kter´e dovoluj´ı uˇzivatel˚ um ukl´adat soubory na disk serveru. Proto je nutn´e vˇzdy limitovat mnoˇzstv´ı dat, kter´a mohou uˇzivatel´e nahr´at na server.
5.1.7
Nepopiratelnost
C´ılem je, aby po proveden´ı urˇcit´e transakce nemohla ˇza´dn´a ze z´ uˇcastnˇen´ ych stran tuto transakci popˇr´ıt. Pˇr´ıkladem m˚ uˇze b´ yt, kdyˇz Alenka m´a zaplatit pen´ıze Bobovi, ale nechce mu je poslat pˇr´ımo, aby Bob nemohl pozdˇeji tuto platbu popˇr´ıt. K vyˇreˇsen´ı t´eto situace se vˇetˇsinou pouˇzije tˇret´ı strana, kter´e vˇeˇr´ı Bob i Alenka. Potom Alenka poˇsle pen´ıze t´eto tˇret´ı stranˇe a ta ozn´am´ı Bobovi, ˇze m˚ uˇze Alence poslat zakoupen´ y produkt. Jakmile Alenka obdrˇz´ı objednan´ y produkt, dostane Bob pen´ıze od d˚ uvˇeryhodn´e tˇret´ı strany.
5.2
Typy u ´ tok˚ u
Webov´ y vandalismus Jedn´a se o u ´tok, jehoˇz c´ılem je nahradit urˇcit´e webov´e str´anky ´ cn´ıkem nˇejak´ ymi jin´ ymi. Obˇet´ı tˇechto u ´tok˚ u mohou b´ yt typicky politick´e strany. Utoˇ je obvykle osoba nebo skupina osob, kter´ ym se napˇr´ıklad nel´ıb´ı ide´aly a n´azory dan´e politick´e strany. C´ılem u ´toku pak m˚ uˇze b´ yt napˇr. zesmˇeˇsnit danou politickou stranu. Napˇr´ıklad v letech 1999 a 2001 doˇslo k u ´tok˚ um tohoto typu na webov´e str´anky B´ıl´eho ´ domu. Udajnˇe za nimi st´ala skupina anti-NATO aktivist˚ u. Infiltrace Infiltrace je u ´tok, kdy neautorizovan´a osoba z´ısk´a kontrolu nad poˇc´ıtaˇcov´ ym syst´emem. Tento u ´tok lze obvykle vykonat zneuˇzit´ım chyb v softwaru, jako je napˇr. pˇreteˇcen´ı bufferu. Infitraci je moˇzn´e vyuˇz´ıt ke zmˇenˇe str´anek nˇejak´e organizace. Horˇs´ı situace m˚ uˇze nastat, pokud u ´toˇcn´ık dok´aˇze ˇc´ıst obsah datab´aze. M˚ uˇze pak napˇr. z´ıskat z datab´aze tajn´e informace a/nebo jm´ena a hesla uˇzivatel˚ u. Proto je d˚ uleˇzit´e nikdy neukl´adat hesla v ˇcist´e textov´e podobˇe. Phishing Phishing je metodou jak z´ıskat pˇrihlaˇsovac´ı u ´daje uˇzivatel˚ u napˇr. nˇejak´eho bankovn´ıho syst´em. Obvykle se realizuje pomoc´ı e-mailu, ve kter´em je uˇzivatel informov´an o tom, ˇze doˇslo k nˇejak´emu probl´emu nebo jin´e ud´alosti, a je tˇreba, aby se uˇzivatel pˇrihl´asil na str´anky banky, kde se dozv´ı bliˇzˇs´ı informace. E-mail pak obsahuje odkaz, jehoˇz textem je spr´avn´e URL banky. Ovˇsem parametr odkazu HREF obsahuje adresu str´anky u ´toˇcn´ıka, kter´a se snaˇz´ı vypadat stejnˇe jako legitimn´ı str´anky banky. Pokud
25
Bezpeˇcnost na webu
Zp˚ usoby napaden´ı poˇc´ıtaˇce
uˇzivatel do formul´aˇre na narafiˇcen´e str´ance zad´a svoje pˇrihlaˇsovac´ı u ´daje, zmocn´ı se jich u ´toˇcn´ık. Pharming C´ılem t´eto metody je, stejnˇe jako v pˇr´ıpadˇe Phishingu, pˇrelst´ıt uˇzivatele, aby zadal svoje pˇrihlaˇsovac´ı u ´daje do narafiˇcen´e str´anky. Pharming je ale na rozd´ıl od Phishingu sofistikovanˇejˇs´ı. Jeho kl´ıˇcem je totiˇz napaden´ı DNS serveru a modifikace jeho tabulek pro pˇrevod dom´enov´eho jm´ena na IP adresu. Pokud se takov´eto napaden´ı DNS serveru podaˇr´ı, nem´a uˇzivatel prakticky ani moˇznost si u ´toku vˇsimnout. Pˇrestoˇze zad´a do webov´eho prohl´ıˇzeˇce spr´avn´e URL, je smˇerov´an na server u ´toˇcn´ıka. ˇ ´ Utoky zevnitˇ r Casto se st´av´a, ˇze za kr´adeˇze dat firmy mohou samotn´ı pracovn´ıci firmy. To je ˇcasto v d˚ usledku toho, ˇze nˇekteˇr´ı pracovn´ıci maj´ı zbyteˇcnˇe velk´e pravomoce a pˇr´ıstup k dat˚ um, kter´a nepotˇrebuj´ı ke sv´e pr´ace. To d´av´a moˇznost u ´niku dat, kter´e pak mohou b´ yt prod´any jedinc˚ um nebo organizac´ım, kter´e je mohou zneuˇz´ıt. Proto je potˇreba nastavit pravomoce tak, aby se k citliv´ ym dat˚ um dostala pouze mal´a mnoˇzina d˚ uvˇeryhodn´ ych osob. Denial of Service Tento typ u ´toku byl jiˇz zmiˇ nov´an v´ yˇse. DoS m˚ uˇze urˇcit´ ym organizac´ım zp˚ usobit znaˇcn´e ˇskody, napˇr. pokud se jedn´a o internetov´e obchody. Ty mohou pˇri takov´ ych u ´toc´ıch pˇrij´ıt k citeln´ ym ˇskod´am, protoˇze legitimn´ı uˇzivatel´e nemohou nakupovat.
5.3 5.3.1
Zp˚ usoby napaden´ı poˇ c´ıtaˇ ce ˇ Cervi
ˇ Cerv je ˇskodliv´ y software, kter´ y se ˇs´ıˇr´ı pomoc´ı poˇc´ıtaˇcov´e s´ıtˇe. Internet dovoluje ˇ ˇcerv˚ um ˇs´ıˇrit se velmi vysokou rychlost´ı. Cervi obvykle zneuˇz´ıvaj´ı chyb v softwaru, jako je napˇr. pˇreteˇcen´ı bufferu. D˚ uleˇzitou ochranou poˇc´ıtaˇce je tedy m´ıt zapnuto co nejm´enˇe sluˇzeb, kter´e je moˇzn´e z internetu napadnout. Pokud urˇcit´ y operaˇcn´ı syst´em v z´akladn´ım nastaven´ı spouˇst´ı nˇejakou ˇspatnˇe zabezpeˇcenou aplikaci, mohou toho ˇcervi vyuˇz´ıt k velmi rychl´emu ˇs´ıˇren´ı. Napˇr. ˇcerv Code Red vyuˇzil chyby v serveru Internet Information Server (IIS) na operaˇcn´ıch syst´emech Microsoft Windows. Code Red umˇel zneuˇz´ıt pˇreteˇcen´ı bufferu ˇ v tomto serveru. Cerv se ˇs´ıˇril velmi rychle, nebot’ jakmile infikoval poˇc´ıtaˇc, zaˇcal neust´ale generovat nov´e IP adresy a pokouˇsel se napadnout dalˇs´ı poˇc´ıtaˇce na tˇechto adres´ach. Nav´ıc antiviry jej nebyly schopny detekovat, protoˇze neukl´adal nic na disk, ale byl uloˇzen pouze v operaˇcn´ı pamˇeti. Bylo tedy moˇzn´e se jej zbavit prost´ ym re-
26
Bezpeˇcnost na webu
Zp˚ usoby napaden´ı poˇc´ıtaˇce
startov´an´ım poˇc´ıtaˇce, ovˇsem pravdˇepodobnost, ˇze bude poˇc´ıtaˇc znovu napaden, byla vysok´a. Daleko nebezpeˇcnˇejˇs´ı byl ˇcerv Nimda. Nimda se dok´azal ˇs´ıˇrit z jednoho webov´eho serveru na druh´ y. Nav´ıc se dok´azal ˇs´ıˇrit i na klienty, nebot’ napadal soubory na serveru. Z klient˚ u se pak ˇs´ıˇril d´al rozes´ıl´an´ım e-mail˚ u, kter´e obsahovaly k´od ˇcerva.
5.3.2
Dalˇ s´ı typy ˇ skodliv´ eho softwaru
Rootkits Jedn´a se o podvodnou sadu n´astroj˚ u operaˇcn´ıho syst´emu. C´ılem u ´toˇcn´ıka je nahradit standardn´ı verzi n´astroj˚ u operaˇcn´ıho syst´emu jejich podvodnou verz´ı. Pokud se toto podaˇr´ı, m˚ uˇze rootkit slouˇzit k maskov´an´ı bˇehu jin´eho ˇskodliv´eho SW. Botnets Jedn´a se o mnoˇzinu poˇc´ıtaˇc˚ u pˇripojen´ ych k internetu, kter´e napadl malware. Tento typ malware je typicky neaktivn´ı do doby, neˇz obdrˇz´ı pˇres internet pˇr´ıkaz k urˇcit´e akci. Typicky se pouˇz´ıv´a k DDoS u ´tok˚ um, kdy u ´toˇcn´ık rozeˇsle vˇsem stroj˚ um v botnetu pˇr´ıkaz, aby zaˇcali urˇcitou IP adresu zaplavovat s´ıt’ov´ ymi pakety. Dalˇs´ım pˇr´ıkladem pouˇzit´ı botnetu je rozes´ıl´an´ı nevyˇz´adan´e poˇsty. Spyware Spyware je software, kter´ y monitoruje aktivitu uˇzivatele poˇc´ıtaˇce bez jeho svolen´ı. Napˇr. m˚ uˇze monitorovat, jak´e webov´e str´anky uˇzivatel navˇstˇevuje a zjiˇstˇen´e informace pos´ılat na centr´aln´ı server k jejich dalˇs´ımu zpracov´an´ı. Spyware m˚ uˇze na z´akladˇe zjiˇstˇen´ ych u ´daj˚ u zobrazovat uˇzivateli infikovan´eho poˇc´ıtaˇce reklamu. Keyloggers Keylogger monitoruje vstupy z kl´avesnice a myˇsi, coˇz dovoluje zjistit a zcizit velmi citliv´e u ´daje, jako jsou pˇrihlaˇsovac´ı jm´ena a hesla do r˚ uzn´ ych syst´em˚ u. Adware C´ılem adware je zobrazovat reklamu na obrazovce poˇc´ıtaˇce. Tento typ malware tedy nemus´ı nutnˇe zp˚ usobovat ˇskodu poˇc´ıtaˇci, ale pochopitelnˇe m˚ uˇze znaˇcnˇe obtˇeˇzovat uˇzivatele vyskakov´an´ım oken a podobnˇe. Trojsk´ e konˇ e Jedn´a se o program, kter´ y se tv´aˇr´ı jako legitimn´ı software, ale kromˇe jist´e ˇza´douc´ı ˇcinnosti prov´ad´ı tajnˇe jinou, ˇskodlivou ˇcinnost. Tato ˇskodliv´a ˇcinnost m˚ uˇze odpov´ıdat aktivit´am nˇekter´eho z v´ yˇse popsan´ ych typ˚ u malware. Trojsk´e konˇe mohou tak´e d´at u ´toˇcn´ıkovi vzd´alen´ y pˇr´ıstup k napaden´emu poˇc´ıtaˇci.
5.3.3
Probl´ em pˇ reteˇ cen´ı bufferu
Tento probl´em se typicky t´ yk´a kompilovan´ ych programovac´ıch jazyk˚ u, jako je C nebo C++. Pˇreteˇcen´ı bufferu m˚ uˇze napˇr´ıklad nastat pˇri naˇc´ıt´an´ı ˇretˇezce ze vstupu, kdy nen´ı 27
Bezpeˇcnost na webu
Zp˚ usoby napaden´ı poˇc´ıtaˇce
omezeno, kolik znak˚ u m˚ uˇze uˇzivatel zadat. Ovˇsem velikost bufferu, do kter´eho vstupn´ı ˇretˇezeˇc ukl´ad´ame, omezen´a je. Vstup od vˇetˇsiny legitimn´ıch uˇzivatel˚ u se sice do bufferu vejde, ale pokud u ´toˇcn´ık odhal´ı moˇznost pˇreteˇcen´ı bufferu, m˚ uˇze ji zneuˇz´ıt napˇr. k nestandardn´ımu ukonˇcen´ı bˇehu programu nebo dokonce k ˇr´ızen´ı bˇehu programu. Pokud je totiˇz uloˇzen buffer v z´asobn´ıku, je moˇzn´e jeho pˇreteˇcen´ım pˇrepsat n´avratovou adresu z podprogramu. Pokud k pˇreps´an´ı n´avratov´e adresy dojde omylem, zp˚ usob´ı to pravdˇe´ podobnˇe nestandardn´ı ukonˇcen´ı programu. Utoˇcn´ık ale m˚ uˇze zvolit vstupn´ı ˇretˇezec tak, aby pˇrepsal n´avratovou adresu adresou funkce, kterou chce zavolat (a jej´ıˇz vol´an´ı je norm´alnˇe podm´ınˇeno napˇr´ıklad zad´an´ım spr´avn´eho hesla). Pokud m´a u ´toˇcn´ık zdrojov´ y k´od programu, m˚ uˇze si jej´ı adresu nechat vypsat programem. Pokud m´a pouze bin´arn´ı ´ cn´ık m˚ verzi programu, m˚ uˇze adresu zjistit pomoc´ı debuggeru. Utoˇ uˇze dokonce vloˇzit t´ımto zp˚ usobem do programu sv˚ uj vlastn´ı k´od. Tento k´od se vloˇz´ı za n´avratovou adresu do u ´toˇcn´ıkova vstupn´ıho ˇretˇezce. N´avratov´a adresa se nastav´ı na adresu vloˇzen´eho k´odu. Pˇreteˇcen´ı bufferu je tedy tˇreba pˇredch´azet kontrolov´an´ım poˇctu pˇreˇcten´ ych znak˚ u. Existuj´ı i r˚ uzn´e speci´aln´ı metody, kter´e se snaˇz´ı detekovat pˇreteˇcen´ı bufferu. Jednou takovou metodou je StackGuard. Ten vkl´ad´a do z´asobn´ıku pˇred n´avratovou adresu nˇekolik n´ahodnˇe generovan´ ych byt˚ u. Pak vˇzdy, neˇz je proveden n´avrat z podprogramu, je zkontrolov´ano, zda ochrann´e byty nebyly pˇreps´any. Pokud ano, je v´ ypoˇcet programu zastaven.
5.3.4
SQL Injection
SQL Injection je speci´aln´ım pˇr´ıpadem Command Injection - situace, kdy uˇzivatel m˚ uˇze pomoc´ı sv´eho vstupu vloˇzit do programu nˇejak´ y pˇr´ıkaz. Obvykle k tomu m˚ uˇze doj´ıt v d˚ usledku nedostateˇcn´e kontroly vstupn´ıho ˇretˇezce. Command Injection m˚ uˇze znaˇcn´ ym zp˚ usobem naruˇsit bezpeˇcnost. SQL Injection je pˇr´ıpad, kdy uˇzivatel m˚ uˇze ˇsikovn´ ym vstupn´ım ˇretˇezcem modifikovat SQL dotaz a z´ıskat napˇr. citliv´a data z datab´aze. Tento probl´em se typicky ˇreˇs´ı ve webov´ ych aplikac´ıch. SQL Injection lze vyrobit, kdyˇz aplikace vezme ˇretˇezec, kter´ y uˇzivatel zadal do webov´eho formul´aˇre, a pouˇzije jej pˇr´ımo ve sv´em SQL dotazu. Probl´em si ilustrujme na pˇr´ıkladu p˚ ujˇcovny DVD, jej´ıˇz webov´a aplikace dovoluje uˇzivatel˚ um prohl´ıˇzet si pˇres web historii film˚ u, kter´e si zap˚ ujˇcili. Kaˇzd´ y uˇzivatel by mˇel b´ yt schopen zobrazit si pouze svoj´ı vlastn´ı historii v´ yp˚ ujˇcek. Dejme tomu, ˇze webov´a aplikace chce nejprve od uˇzivatele, aby do textov´eho pol´ıˇcka vyplnil rok, za kter´ y chce historii zobrazit. Probl´emy mohou velmi snadno nastat, pokud SQL pˇr´ıkaz pro zjiˇstˇen´ı historie v´ yp˚ ujˇcek bude vypadat n´asledovnˇe a za pˇredpokladu, ˇze promˇenn´a rok je 28
Bezpeˇcnost na webu
Zp˚ usoby napaden´ı poˇc´ıtaˇce
ˇretˇezec, kter´ y zadal uˇzivatel do pol´ıˇcka formul´aˇre: String sql = ”SELECT i d u z i v a t e l e , nazev , datum vypujcky , r o k v y p u j c k y FROM vypujcky WHERE i d u z i v a t e l e=”+i d u z i v a t e l e+” AND r o k v y p u j c k y=”+rok ;
Pokud uˇzivatel zad´a ˇc´ıslo roku, probˇehne vˇse v poˇra´dku. Zad´a-li ovˇsem uˇzivatel n´asleduj´ıc´ı ˇretˇezec, z´ısk´a informace o v´ yp˚ ujˇck´ach vˇsech uˇzivatel˚ u: 2011 OR 1=1. V´ ysledn´ y SQL pˇr´ıkaz totiˇz bude vypadat takto: SELECT i d u z i v a t e l e , nazev , datum vypujcky , r o k v y p u j c k y FROM vypujcky WHERE i d u z i v a t e l e =1 AND r o k v y p u j c k y =2011 OR 1=1
Podm´ınka se vyhodnocuje takto: (id uzivatele=1 AND rok vypujcky=2011) OR 1=1. ˇ ast podm´ınky za z´avorkou je vˇzdy pravdiv´a, vyp´ıˇse tedy program vˇsechny poloˇzky C´ v datab´azi. ˇ Situace ale m˚ uˇze b´ yt jeˇstˇe mnohem horˇs´ı. Reknˇ eme, ˇze p˚ ujˇcovna DVD m´a ve sv´e datab´azi tak´e u ´daje o z´akazn´ıc´ıch a to vˇcetnˇe jejich dat narozen´ı a ˇc´ısel kreditn´ıch karet. Uˇzivatel d´ıky naˇs´ı naivnˇe naprogramovan´e webov´e aplikaci m˚ uˇze z´ıskat vˇsechny tyto informace, pokud pouˇzije mnoˇzinov´e sjednocen´ı (UNION) a druh´ y pˇr´ıkaz SELECT: 2011 AND 1=0 UNION SELECT id , jmeno , datum narozeni , c i s l o p l a t e b n i k a r t y FROM u z i v a t e l
Pokud uˇzivatel zad´a v´ yˇse uveden´ y ˇretˇezec do formul´aˇre, zobraz´ı se mu vˇsechny citliv´e informace o z´akazn´ıc´ıch p˚ ujˇcovny. Escapov´an´ı je jeden ze zp˚ usob˚ u, jak upravit vstupn´ı ˇretˇezec, aby znaky se speci´aln´ım v´ yznamem byly povaˇzov´any datab´az´ı za obyˇcejn´a data. Napˇr. apostrof m˚ uˇze b´ yt datab´az´ı povaˇzov´an za zaˇca´tek nebo konec ˇretˇezce. Abychom jej mohli pouˇz´ıt jako souˇca´st dat, mus´ıme pˇred nˇej vloˇzit jeˇstˇe jeden apostrof. Jazyk PHP poskytuje napˇr. pro pr´aci s datab´az´ı MySQL funkci mysql real escape string, kter´a ve vstupn´ım ˇretˇezci escapuje tyto znaky: \x00, \n, \r, \, ’, ” a \x1a. Escapov´an´ı pom´ah´a zabr´anit SQL injection pouze v pˇr´ıpadˇe, kdy vstupn´ı data od uˇzivatele vkl´ad´ame do SQL dotazu jako datov´ y typ ˇretˇezec. K vyˇreˇsen´ı v´ yˇse uveden´eho probl´emu, kde m´a uˇzivatel zadat rok, za kter´ y chce zobrazit historii v´ yp˚ ujˇcek DVD, n´am escapov´an´ı nepom˚ uˇze. V tomto pˇr´ıpadˇe totiˇz uˇzivatel nemus´ı zadat ˇza´dn´e speci´aln´ı znaky, aby mohl prov´est sv˚ uj u ´tok. 29
Bezpeˇcnost na webu
Zp˚ usoby napaden´ı poˇc´ıtaˇce
Nejlepˇs´ım zp˚ usobem, jak zabr´anit SQL injection, je pouˇzit´ı tzv. Prepared Statements. Ty dovoluj´ı oddˇelit pˇr´ıkazy a data jednoznaˇcnˇe od sebe. K´od v jazyce Java zabezpeˇcen´ y proti SQL Injection by vypadal takto: PreparedStatement ps = con . p r e p a r e S t a t e m e n t ( ” SELECT i d u z i v a t e l e , nazev , datum vypujcky , rok vypujcky FROM vypujcky WHERE i d u z i v a t e l e =? AND r o k v y p u j c k y=?”) ; ps . s e t I n t ( 1 , i d u z i v a t e l e ) ; ps . s e t I n t ( 2 , I n t e g e r . p a r s e I n t ( rok ) ) ; R e s u l t S e t r s = ps . executeQuery ( ) ;
Otazn´ıky v SQL pˇr´ıkazu n´am drˇz´ı m´ısto pro hodnoty parametr˚ u, kter´e se pak nastavuj´ı pomoc´ı setX metod (napˇr. zde setInt). Tato implementace n´am zaruˇcuje, ˇze data nebudou nikdy interpretov´ana jako pˇr´ıkazy.
30
6 Webov´e str´anky Frisky ´ celem tˇechto str´aFrisky patˇr´ı mezi webov´e str´anky Katedry matematiky (KMA). Uˇ nek je ale sp´ıˇse pobaven´ı n´avˇstˇevn´ık˚ u, neˇz pˇr´ımo v´ yuka matematiky. Frisky je web pln´ y r˚ uzn´ ych javascriptov´ ych her a hraˇcek, kter´e maj´ı vˇetˇs´ı ˇci menˇs´ı spojitost s matematikou nebo s KMA. Jednotliv´e str´anky jsou tedy velmi r˚ uznorod´e. Vˇetˇsina str´anek je naps´ana v jazyce HTML4, nˇekter´e ale vyuˇz´ıvaj´ı moˇznost´ı HTML5 a CSS3. Serverov´a ˇc´ast je naps´ana v jazyce PHP5.
6.1
Probl´ emy k ˇ reˇ sen´ı
• Layout str´anek nen´ı jednotn´ y a neobsahuje menu. Vzhled tak´e nen´ı konzistentn´ı 1 se str´ankami Trial . • Nen´ı implementov´ano pˇrihlaˇsov´an´ı uˇzivatel˚ u. • Str´anky nejsou samostatn´e (nefunkˇcnost pˇri pˇresunu na jin´ y server).
6.2 6.2.1
Anal´ yza probl´ em˚ u a n´ avrh ˇ reˇ sen´ı Nejednotn´ y layout str´ anek
Jedn´ım z hlavn´ıch probl´em˚ u webov´ ych str´anek Frisky je neexistence jednotn´eho layoutu str´anek. Jedin´ ym spoleˇcn´ ym prvkem str´anek je hlaviˇcka. Jej´ı vzhled ale nen´ı konzistentn´ı s nov´ ym vzhledem webov´ ych str´anek Trial. Hlaviˇcka na Frisky je realizovan´a tak, ˇze se roztahuje na ˇs´ıˇrku okna prohl´ıˇzeˇce. Obsah str´anek je velmi r˚ uznorod´ y, na nˇekter´ ych str´ank´ach m´a obsah pevnou ˇs´ıˇrku, na jin´ ych se roztahuje pˇres cel´e okno prohl´ıˇzeˇce. Jako ˇreˇsen´ı jsem navrhl odstranit hlaviˇcku a vytvoˇrit jednotn´ y layout str´anek, kter´ y bude m´ıt tyto z´akladn´ı prvky: • Hlaviˇcka str´anky, kter´a bude obsahovat logo a pˇr´ıpadnˇe odkazy na dalˇs´ı str´anky Katedry matematiky. • Horn´ı liˇsta obsahuj´ıc´ı prvky pro pˇrihlaˇsov´an´ı uˇzivatel˚ u. • Menu. 1
Trial jsou dalˇs´ı webov´e str´ anky patˇr´ıc´ı KMA.
31
Webov´e str´anky Frisky
Anal´yza probl´em˚ u a n´avrh ˇreˇsen´ı
• Obsah str´anky. • Patiˇcka. D´ale jsem navrhl, ˇze vˇetˇsina str´anek by mˇela m´ıt jednotnou ˇs´ıˇrku, konkr´etnˇe 1020px, coˇz odpov´ıd´a ˇs´ıˇrce menu. Mˇelo by b´ yt z´aroveˇ n moˇzn´e layout jednoduˇse rozˇs´ıˇrit u str´anek, jejichˇz obsah nelze vmˇestnat do t´eto ˇs´ıˇrky. Na str´ank´ach Frisky tak´e existuj´ı nˇekter´e str´anky, u kter´ ych je potˇreba, aby se ˇs´ıˇrka jejich obsahu mˇenila podle ˇs´ıˇrky okna prohl´ıˇzeˇce. Proto jsem navrhl vytvoˇrit speci´aln´ı layout, kter´ y bude obsahovat hlaviˇcku a obsah, jehoˇz ˇs´ıˇrka se bude mˇenit podle ˇs´ıˇrky zbytku okna prohl´ıˇzeˇce. Menu je v souˇcasnosti na Frisky um´ıstˇeno pouze na u ´vodn´ı str´ance, coˇz nen´ı vyhovuj´ıc´ı. Zadavatel si ale tak´e nepˇreje, aby bylo menu um´ıstˇeno napevno do vˇsech str´anek, nebot’ by zab´ıralo pˇr´ıliˇs mnoho m´ısta. Proto bylo rozhodnuto, ˇze pˇri vstupu na kaˇzdou str´anku (s v´ yjimkou u ´vodn´ı str´anky) bude menu schovan´e a uk´aˇze se aˇz po stisknut´ı nˇejak´eho tlaˇc´ıtka. Um´ıstˇen´ı tohoto pˇrep´ınaˇce bylo navrˇzeno zadavatelem pomˇernˇe nekonvenˇcnˇe - menu se uk´aˇze, kdyˇz uˇzivatel klepne na logo str´anky. Na prvn´ı pohled se toto m˚ uˇze zd´at jako nedobr´e ˇreˇsen´ı, nebot’ podle konvence by klepnut´ı na logo str´anek mˇelo vˇzdy v´est na u ´vodn´ı str´anku. V pˇr´ıpadˇe str´anek Frisky ale je takov´e ˇreˇsen´ı ve skuteˇcnosti vhodn´e, nebot’ jedin´e, co u ´vodn´ı str´anka obsahuje, je menu. Nyn´ı tedy m´ısto toho, aby se uˇzivatel musel vracet kv˚ uli menu na u ´vodn´ı str´anku, staˇc´ı kdyˇz klepne na logo a menu se mu objev´ı na aktu´aln´ı str´ance, aniˇz by ji musel opustit. D´ale je potˇreba, aby vzhled str´anek Frisky byl konzistentn´ı se vzhledem str´anek Trial. Zadavatel rozhodl, ˇze dostateˇcn´e bude pouˇzit´ı stejn´eho loga a stejn´eho obr´azku v patiˇcce. Poˇzadavkem zadavatele bylo, ˇze logo mus´ı b´ yt na kaˇzd´e str´ance vˇzdy v lev´em horn´ım rohu okna prohl´ıˇzeˇce, stejnˇe jako na str´ank´ach Trial. D´ale se hlaviˇcka pˇri skorolov´an´ı str´anky doprava mus´ı schovat pod obsah str´anky a pˇri odskrolov´an´ı doleva mus´ı b´ yt hlaviˇcka vidˇet v lev´e ˇca´sti okna prohl´ıˇzeˇce.
6.2.2
Neexistence pˇ rihlaˇ sov´ an´ı a registrace na Frisky
V souˇcasnosti na str´ank´ach Frisky neexistuje moˇznost registrace ani pˇrihlaˇsov´an´ı uˇzivatel˚ u. Zadavatel proto poˇzaduje, aby bylo toto implementov´ano. Pˇrihlaˇsov´an´ı by mˇelo b´ yt moˇzn´e pomoc´ı syst´emu Orion i pomoc´ı m´ıstn´ı registrace. M´ıstn´ı registrace bude urˇcena pˇredevˇs´ım pro uˇzivatele, kteˇr´ı nejsou registrov´ani v syst´emu Orion. D´ale bylo poˇzadavkem, aby registrace na Frisky obsahovala ochranu proti registraci robot˚ u, 32
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
mus´ı b´ yt tedy pouˇzita CAPTCHA2 . Zadavatel si tak´e pˇra´l, aby uˇzivatel´e museli povinnˇe pˇri registraci vyplnit svoj´ı e-mailovou adresu. Pravost t´eto adresy by mˇela b´ yt ovˇeˇrena aktivaˇcn´ım e-mailem obsahuj´ıc´ım URL, po jehoˇz navˇst´ıven´ı je uˇzivateli dovoleno se pˇrihl´asit. Registrace uˇzivatel˚ u tak´e mus´ı b´ yt oˇsetˇren´a proti SQL a HTML injection.
6.2.3
Str´ anky nejsou samostatn´ e
Jedn´ım z poˇzadavk˚ u zadavatele byla tak´e samostatnost str´anek. T´ım je myˇsleno, ˇze by mˇelo b´ yt moˇzn´e jednotliv´e hry, kter´e se na str´ank´ach Frisky vyskytuj´ı, pˇrekop´ırovat na jin´ y server, kde by pak okamˇzitˇe fungovaly bez potˇreby jak´ ychkoliv u ´prav. Kaˇzd´a str´anka na Frisky m´a sv˚ uj vlastn´ı adres´aˇr. Je tedy potˇreba, aby kaˇzd´a str´anka mˇela ve sv´em adres´aˇri vˇsechny potˇrebn´e knihovny. D´ale bude potˇreba vytvoˇrit novou verzi hlavn´ıho PHP skriptu. Ta by nemˇela obsahovat ˇzadn´e prvky layoutu str´anky s v´ yjimkou samotn´eho obsahu.
6.3
ˇ sen´ı jednotliv´ Reˇ ych probl´ em˚ u
Pod´ıvejme se, jak byly vyˇreˇseny jednotliv´e probl´emy na z´akladˇe pˇredchoz´ı anal´ yzy.
6.3.1
Nejednotn´ y layout str´ anek
Podle pˇredchoz´ı anal´ yzy jsem vytvoˇril layout str´anek, kter´ y obsahuje vˇsechny v´ yˇse uveden´e prvky. Z´aklad str´anky (horn´ı liˇsta, obsah, patiˇcka) je sloˇzen z DIV HTML element˚ u, kter´e maj´ı CSS atribut position nastaven na hodnotu relative a parametr float nastaven na left. Tento pˇr´ıstup je povaˇzov´an za lepˇs´ı neˇz tvorba layoutu pomoc´ı HTML tabulky. Jednou v´ yjimkou je hlaviˇcka, kter´a m´a atribut relative nastaven na hodnotu fixed, coˇz bylo poˇzadavkem zadavatele. Druhou v´ yjimkou je menu, kter´e je pˇri pˇr´ıchodu na str´anku schovan´e nad vˇs´ım, co je vidˇet v oknˇe prohl´ıˇzeˇce. Atribut position m´a tedy nastaven na hodnotu absolute. Vzor PHP skriptu, kter´ y vytvoˇr´ı pr´azdnou str´anku o ˇs´ıˇrce 1020px, kter´a ale obsahuje vˇsechny prvky layoutu, naleznete v pˇr´ıloze C. Obsah str´anky m˚ uˇzeme vkl´adat do elementu DIV s id content. Zm´ın´ım zde, ˇze m´ısto souboru hlavicka-bez-odkazu.php je moˇzn´e vloˇzit soubor hlavicka.php. Rozd´ıl je v tom, ˇze pod logem Trial se pak jeˇstˇe objev´ı odkazy na str´anky Trial. Druh´ ym rozd´ılem je, ˇze klepnut´ı na logo nezp˚ usob´ı zobrazen´ı menu. Nam´ısto toho je uˇzivatel odk´az´an na u ´vodn´ı str´anku Frisky. Tato verze hlaviˇcky se tedy nyn´ı pouˇz´ıv´a pouze na u ´vodn´ı str´ance, na 2
CAPTCHA je test, kter´ ym bychom mˇeli b´ yt schopni ovˇeˇrit, ˇze uˇzivatel je ˇclovˇek. Obvykle od uˇzivatele poˇzadujeme, aby spr´ avnˇe opsal deformovan´ y textu z obr´azku.
33
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
str´ance pro registraci uˇzivatele a na str´ance pro editaci profilu. Tˇret´ı verz´ı je soubor hlavicka2.php. Zde jsou vidˇet odkazy na Trial, ale klepnut´ı na logo vyvol´a zobrazen´ı menu. Tato varianta zat´ım nen´ı pouˇz´ıv´ana na ˇz´adn´e str´ance. Patiˇcka je tak´e ve v´ıce variant´ach. Zde pouˇzit´ y soubor paticka2.php obsahuje pouze ˇ obr´azek s logy Evropsk´eho soci´aln´ıho fondu v CR, Evropsk´e unie, Ministerstva ˇskolstv´ı, ml´adeˇze a tˇelov´ ychovy, Operaˇcn´ıho programu Vzdˇel´av´an´ı pro konkurencechopnost. Druh´a moˇznost - paticka.php - nav´ıc obsahuje odkazy na nˇekter´e rozpracovan´e hry. Tyto odkazy jsou ale aktu´alnˇe nefunkˇcn´ı. Poˇzadavkem zadavatele bylo, ˇze logo mus´ı b´ yt na kaˇzd´e str´ance vˇzdy v lev´em horn´ım rohu prohl´ıˇzeˇce, stejnˇe jako je to na str´ank´ach Trial. Tedy, jak jiˇz bylo zm´ınˇeno, CSS parametr position hlaviˇcky musel b´ yt nastaven na hodnotu fixed. D´ale musel b´ yt do str´anky vloˇzen element DIV, kter´ y m´a stejnou ˇs´ıˇrku jako hlaviˇcka a je um´ıstˇen vlevo od obsahu str´anky (jeho id je hlavicka-space). Ten je potˇrebn´ y proto, aby drˇzel m´ısto“ ” hlaviˇcce. Bez nˇej by byla hlaviˇcka vˇzdy schovan´a pod obsahem str´anky, pokud by bylo okno prohl´ıˇzeˇce uˇzˇs´ı neˇz obsah str´anky. Pot´e bylo potˇreba nastavit barvu pozad´ı obsahu str´anky, aby se hlaviˇcka skuteˇcnˇe schovala, kdyˇz bude uˇzivatel skrolovat doprava. Nakonec jsem nastavil parametr z-index hlaviˇcky a hlavn´ı ˇc´asti str´anky tak, aby hlaviˇcka mˇela z-index nastaven na niˇzˇs´ı hodnotu. Jak jiˇz bylo zm´ınˇeno, menu je pˇri pˇr´ıchodu na str´anku schovan´e. Kdyˇz uˇzivatel klikne na logo str´anek, vysune se menu shora a um´ıst´ı se nad obsah str´anky. Obsah str´anky je z´aroveˇ n pˇrekryt ˇca´steˇcnˇe pr˚ uhledn´ ym DIV elementem. Ten slouˇz´ı jednak estetick´ ym u ´ˇcel˚ um, ale tak´e u ´ˇcel˚ um praktick´ ym. Tento DIV totiˇz zp˚ usobuje, ˇze uˇzivatel nem˚ uˇze interagovat myˇs´ı s obsahem str´anky, kdyˇz m´a zobrazen´e menu. To je pomˇernˇe d˚ uleˇzit´e, protoˇze nechceme, aby uˇzivatel mohl omylem klepnout na nˇejak´ y prvek str´anky ve chv´ıli, kdy chce pouˇz´ıvat menu. Za zm´ınku stoj´ı, ˇze jako obsah str´anky je myˇslen pouze element DIV s id content a jeho obsah. To znamen´a, ˇze s ostatn´ımi prvky layoutu (s horn´ı liˇstou, s patiˇckou atd.) je interakce moˇzn´a, i kdyˇz je menu zobrazen´e. Vzhled str´anek, kdy je menu schovan´e, ilustruje obr´azek 6.1. Stejn´a str´anka se zobrazen´ ym menu je vidˇet na obr´azku 6.2. Nev´ yhodou tohoto layoutu je ale jeho pevn´a ˇs´ıˇrka 1020 pixel˚ u, kter´a je pro nˇekter´e str´anky nedostaˇcuj´ıc´ı. Jako ˇreˇsen´ı jsem napsal skript, kter´ y naleznete v pˇr´ıloze D. Jak jsem jiˇz zm´ınil v anal´ yze, bylo tak´e potˇreba vytvoˇrit layout pro str´anky, jejichˇz obsah je navrˇzen tak, aby se roztahoval pˇres cel´e okno prohl´ıˇzeˇce. Vytvoˇril jsem tedy velmi jednoduch´ y layout, kde v lev´e ˇca´sti okna prohl´ıˇzeˇce je um´ıstˇena hlaviˇcka a ve 34
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
Obr´azek 6.1: Str´anka na Frisky, menu je schovan´e ˇ adn´e dalˇs´ı prvky jsem do tohoto speci´aln´ıho layoutu zbytku okna je obsah str´anky. Z´ neumist’oval. Klepnut´ı na logo zde odkazuje na u ´vodn´ı str´anku Frisky. Vzor HTML tˇechto str´anek a pˇr´ısluˇsn´ y JavaScript naleznete v pˇr´ıloze E.
6.3.2
Neexistence pˇ rihlaˇ sov´ an´ı a registrace na Frisky
V anal´ yze bylo uvedeno, ˇze pˇrihlaˇsov´an´ı na Frisky mus´ı b´ yt moˇzn´e pomoc´ı m´ıstn´ı registrace i pomoc´ı syst´emu Orion. Do horn´ı ˇc´asti kaˇzd´e str´anky jsem tedy um´ıstil formul´aˇr pro pˇrihl´aˇsen´ı pˇres lok´aln´ı registraci, d´ale tlaˇc´ıtko pro registraci a tlaˇc´ıtko pro pˇrihl´aˇsen´ı pomoc´ı syst´emu Orion. Po pˇrihl´aˇsen´ı vid´ı uˇzivatel v horn´ı liˇstˇe svoje uˇzivatelsk´e jm´eno a tlaˇc´ıtko pro odhl´aˇsen´ı. Moˇznost lok´aln´ı registrace na str´ank´ach Frisky byla vytvoˇrena pˇredevˇs´ım pro uˇzivatele, kteˇr´ı nejsou registrov´ani v syst´emu Orion. Pˇri registraci mus´ı uˇzivatel vyplnit celkem tˇri povinn´e u ´daje - uˇzivatelsk´e jm´eno, heslo a svoj´ı e-mailovou adresu. JavaScriptov´ y program na str´ance ihned kontroluje vyplnˇen´e u ´daje. V pˇr´ıpadˇe uˇzivatelsk´eho jm´ena je hned po jeho vyplnˇen´ı zkontrolov´ano, zda je voln´e - duplicitn´ı uˇzivatelsk´a jm´ena nejsou povolena. K doc´ılen´ı t´eto funkcionality byla pouˇzita technologie AJAX. D´ale heslo mus´ı b´ yt pro kontrolu vyplnˇeno dvakr´at, program tedy hned po vyplnˇen´ı 35
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
Obr´azek 6.2: Str´anka na Frisky, menu je zobrazen´e obou pol´ıˇcek zkontroluje, zda se hesla shoduj´ı. Heslo m˚ uˇze b´ yt libovoln´e d´elky, jen nesm´ı b´ yt d´elka nulov´a. Posledn´ım kontrolovan´ ym u ´dajem je e-mail. Je ovˇeˇreno, zda zadan´ y e-mail odpov´ıd´a form´atu validn´ı e-mailov´e adresy, t´ımto regul´arn´ım v´ yrazem (pˇrevzato z [13]): ˆ [A−Z0 −9. %−]+@[ A−Z0 −9. −]+\.[A−Z ] { 2 , 4 } $
Uveden´ y regul´arn´ı v´ yraz poˇc´ıt´a s t´ım, ˇze validace nen´ı case sensitive (nerozhoduje velikost p´ısmen). D´ale pˇr´ısluˇsn´ y formul´aˇr obsahuje tˇri nepovinn´e u ´daje - kˇrestn´ı jm´eno, pˇr´ıjmen´ı a pohlav´ı. Posledn´ım prvkem formul´aˇre je CAPTCHA. Ke generov´an´ı obr´azk˚ u a ovˇeˇrov´an´ı jejich spr´avn´eho ops´an´ı byla pouˇzita knihovna reCAPTCHA. Po odesl´an´ı vyplnˇen´eho formul´aˇre na server je PHP skriptem znovu zkontrolov´ana spr´avnost vyplnˇen´ı vˇsech povinn´ ych u ´daj˚ u a tak´e je zkontrolov´ano spr´avn´e ops´an´ı textu z obr´azku knihovnou reCAPTCHA. Je-li vˇse v poˇra´dku, jsou u ´daje uloˇzeny do datab´aze. Hesla nejsou ukl´ad´ana v ˇcist´e podobˇe, ale jako ˇretˇezec vytvoˇren´ y hashovac´ı funkc´ı SHA-1. Ukl´ad´an´ı zadan´ ych u ´daj˚ u do datab´aze je oˇsetˇreno proti SQL Injection pouˇzit´ım tzv. prepared statement, viz kapitola 5.3.4. Pouˇzil jsem PHP knihovnu mysqli 36
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
(PHP knihovna mysql prepared statements nepodporuje). D´ale je tak´e zamezeno HTML Injection - tj. vloˇzen´ı HTML znaˇcek do formul´aˇre a jejich n´asledn´e uloˇzen´ı do datab´aze. Pˇresnˇeji vloˇzit HTML znaˇcky do pol´ıˇcek formul´aˇre a n´aslednˇe je odeslat na server lze, ale PHP skript na stranˇe serveru vˇsechny tyto znaˇcky odstran´ı pouˇzit´ım knihovn´ı funkce strip tags. Po zaregistrov´an´ı mus´ı uˇzivatel sv˚ uj u ´ˇcet aktivovat pˇred t´ım, neˇz je mu dovoleno se pˇrihl´asit. Smysl aktivace je v ovˇeˇren´ı poskytnut´e e-mailov´e adresy. Na zadanou emailovou adresu je posl´an aktivaˇcn´ı e-mail. Byla pouˇzita knihovna PHPMailer. E-mail obsahuje URL, kter´e je potˇreba navˇst´ıvit pro aktivaci u ´ˇctu. Aktivaˇcn´ı URL obsahuje dva parametry: uˇzivatelsk´e jm´eno a aktivaˇcn´ı k´od. Aktivaˇcn´ı k´od je n´ahodnˇe vygenerovan´ y ˇretˇezec, kter´ y byl pˇri registraci uloˇzen do datab´aze. Je generov´an t´ımto zp˚ usobem: $code = sha1 ( u n i q i d ( rand ( ) , true ) ) ;
Nen´ı zaruˇceno, ˇze tento k´od bude unik´atn´ı. Proto je jako prvn´ı parametr uˇzivatelsk´e jm´eno. Po navˇst´ıven´ı aktivaˇcn´ı URL adresy je pˇreˇcten aktivaˇcn´ı k´od z datab´aze, kter´ y pˇr´ısluˇs´ı k dan´emu uˇzivatelsk´emu jm´enu. Tento k´od je pot´e porovn´an se zaslan´ ym k´odem. Je-li mezi nimi shoda, je do datab´aze uloˇzeno, ˇze byl dan´ yu ´ˇcet aktivov´an. Uˇzivatel se m˚ uˇze pot´e pˇrihl´asit. Vzhled registraˇcn´ıho formul´aˇre ilustruje obr´azek 6.3. Uˇzivatel, kter´ y je pˇrihl´aˇsen pˇres lok´aln´ı u ´ˇcet na Frisky, m˚ uˇze editovat sv˚ uj u ´ˇcet po kliknut´ı na svoje uˇzivatelsk´e jm´eno na horn´ı liˇstˇe str´anek. Editovat lze pouze kˇrestn´ı jm´eno, pˇr´ıjmen´ı a pohlav´ı. Tak´e je moˇzn´e zmˇenit heslo. Pro zmˇenu hesla je potˇreba nejprve do pˇr´ısluˇsn´eho formul´aˇre zadat st´avaj´ıc´ı heslo a pot´e dvakr´at nov´e heslo. Vzhled str´anky pro editaci profilu je vidˇet na obr´azku 6.4. Pod´ıvejme se nyn´ı na pˇrihlaˇsov´an´ı pomoc´ı syst´emu Orion. Pˇr´ısluˇsn´e pˇrihlaˇsovac´ı tlaˇc´ıtko funguje tak, ˇze odk´aˇze uˇzivatele na stejnou str´anku, na kter´e se pr´avˇe nach´az´ı, ale s t´ım rozd´ılem, ˇze tentokr´at se pouˇzije protokol HTTPS. Server pot´e uˇzivatele automaticky pˇresmˇeruje na pˇrihlaˇsovac´ı str´anku Orionu. Po u ´spˇeˇsn´em vyplnˇen´ı pˇrihlaˇsovac´ıch u ´daj˚ u je uˇzivatel pˇresmˇerov´an na str´anky Frisky. Nyn´ı nad´ale komunikuj´ı server a klient protokolem HTTPS. Odhl´aˇsen´ı je zat´ım moˇzn´e pouze ukonˇcen´ım prohl´ıˇzeˇce.
6.3.3
Str´ anky nejsou samostatn´ e
Jako prvn´ı krok ke splnˇen´ı tohoto u ´kolu jsem pˇrekop´ıroval vˇsechny sd´ılen´e knihovny pˇr´ımo do adres´aˇre kaˇzd´e str´anky, kter´a danou knihovnu potˇrebuje. Ve druh´em kroku jsem pro kaˇzdou str´anku vytvoˇril nov´ y PHP skript main2.php (Na Frisky je hlavn´ım 37
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
Obr´azek 6.3: Registraˇcn´ı formul´aˇr PHP skriptem kaˇzd´e str´anky, na kter´ y se vˇzdy vzn´aˇs´ı HTTP dotaz pˇri ˇz´adosti o str´anku, soubor main.php). Do souboru main2.php kaˇzd´e str´anky jsem vloˇzil pouze samotn´ y obsah str´anky, bez vˇsech ostatn´ıch prvk˚ u layoutu. V tomto PHP skriptu jsem tak´e nastavil vˇsechny odkazy tak, aby ukazovaly pouze na zdroje, kter´e jsou uvnitˇr adres´aˇre dan´e str´anky. Nyn´ı lze tedy snadno pˇrekop´ırovat libovolnou str´anku na jin´ y server a ihned bude moˇzn´e pracovat s jej´ım obsahem.
38
ˇ sen´ı jednotliv´ych probl´em˚ Reˇ u
Webov´e str´anky Frisky
Obr´azek 6.4: Editace profilu uˇzivatele
39
7 Anal´yza her Webov´e str´anky Frisky obsahuj´ı nˇekolik her, kter´e jsou naps´any v jazyce JavaScript. ´ Ukolem od zadavatele bylo prov´est anal´ yzu hry, kter´a se jmenuje Puzzle. Tato anal´ yza by mˇela b´ yt zamˇeˇrena na identifikaci moˇzn´ ych zp˚ usob˚ u podv´adˇen´ı v t´eto hˇre. Na z´akladˇe anal´ yzy poˇzaduje zadavatel odstranˇen´ı vˇsech v souˇcasnosti moˇzn´ ych zp˚ usob˚ u podv´adˇen´ı.
7.1
Anal´ yza probl´ emu a n´ avrh ˇ reˇ sen´ı
Hra Puzzle spoˇc´ıv´a v tom, ˇze uˇzivateli je uk´az´an obr´azek, kter´ y je n´aslednˇe rozdˇelen na 9 d´ılk˚ u a ty jsou pak zam´ıch´any. Hr´aˇc mus´ı prohazov´an´ım d´ılk˚ u myˇs´ı sloˇzit p˚ uvodn´ı obr´azek. Dosaˇzen´e v´ ysledky jsou na serveru ukl´ad´any do textov´ ych soubor˚ u. Klient prov´ad´ı m´ıch´an´ı d´ılk˚ u a tak´e detekci, zda byl obr´azek aktu´aln´ım tahem sloˇzen. D´ale klient tak´e mˇeˇr´ı ˇcas hran´ı a poˇc´ıt´a tahy uˇzivatele. Kdyˇz klient detekuje, ˇze byl obr´azek sloˇzen, jsou hern´ı v´ ysledky posl´any na server, kter´ y je pˇrijme a uloˇz´ı. Vzhledem k tomu, ˇze hra je naps´ana v jazyce JavaScript, uˇzivatel si m˚ uˇze snadno prohl´ednout zdrojov´ y k´od hry a pˇr´ıpadnˇe si jej m˚ uˇze i upravit. Nen´ı tedy tˇeˇzk´e si nastavit hern´ı v´ ysledky na libovoln´e hodnoty a pot´e nechat program tyto v´ ysledky poslat na server, aniˇz by uˇzivatel v˚ ubec musel hru hr´at. Navrhovan´ ym ˇreˇsen´ım tˇechto probl´em˚ u je pˇresunut´ı vˇsech zm´ınˇen´ ych aktivit na server. Klient nesm´ı vˇedˇet, jak jsou d´ılky zam´ıchan´e a tud´ıˇz nesm´ı b´ yt ani schopen s´am detekovat, zda aktu´aln´ı tah vedl k u ´spˇeˇsn´emu sloˇzen´ı obr´azku.
7.2
Odstranˇ en´ı moˇ znosti podv´ adˇ et
Na z´akladˇe pˇredchoz´ı anal´ yzy jsem probl´em s podv´adˇen´ım vyˇreˇsil n´asleduj´ıc´ım zp˚ usobem. Nejprve jsem pˇresunul zam´ıch´an´ı obr´azku na stranu serveru. Zah´ajen´ı hry tedy funguje tak, ˇze server provede zam´ıch´an´ı a klient si pak z nˇej nahraje jednotliv´e d´ılky, aniˇz by tuˇsil, kter´ y d´ılek patˇr´ı na kterou pozici v celkov´em obr´azku. Klient pouze v´ı, ˇze si stahuje obr´azky (d´ılky) 0 aˇz 8. Server napˇr. dostane dotaz na d´ılek ˇc´ıslo 0 a zp´atky pak zaˇsle obr´azek odpov´ıdaj´ıc´ı d´ılku na pozici 0, podle aktu´aln´ıho zam´ıch´an´ı. Po dokonˇcen´ı t´eto f´aze m˚ uˇze uˇzivatel zaˇc´ıt hr´at. Nyn´ı uˇz nen´ı moˇzn´e na stranˇe klienta rozhodnout, zda pr´avˇe proveden´ y tah vedl k u ´spˇeˇsn´emu sloˇzen´ı cel´eho obr´azku. Klient tedy pomoc´ı AJAX pos´ıl´a vˇsechny tahy na server, kter´ y pak odpov´ıd´a, zda je obr´azek sloˇzen nebo ne. V pˇr´ıpadˇe spr´avn´eho sloˇzen´ı d´a server klientovi toto na vˇedom´ı a nav´ıc mu poˇsle i nˇekter´e statistiky, tj. poˇcet tah˚ u a dobu ˇreˇsen´ı. Jak jiˇz bylo uvedeno v anal´ yze, ani 40
Anal´yza her
Odstranˇen´ı moˇznosti podv´ adˇet
poˇc´ıt´an´ı tˇechto informac´ı nen´ı bezpeˇcn´e svˇeˇrit klientovi. Posledn´ı akc´ı, kterou server provede, je uloˇzen´ı v´ ysledk˚ u hry. Pro realizaci tohoto ˇreˇsen´ı bylo ale potˇreba vyˇreˇsit probl´em s pˇrednaˇc´ıt´an´ım (preloading) obr´azk˚ u. P˚ uvodn´ı implementace hry fungovala tak, ˇze klient si pouze nahr´al cel´ y obr´azek, kter´ y pak byl programovˇe rozdˇelen na d´ılky. Nov´a implementace takto fungovat nem˚ uˇze, protoˇze m´ıch´an´ı d´ılk˚ u prov´ad´ı server. Klient si tedy stahuje kaˇzd´ y d´ılek jako samostatn´ y obr´azek. Je potˇreba, aby byly jednotliv´e d´ılky staˇzeny pˇred t´ım, neˇz zaˇcne hra. Implementace pˇrednaˇc´ıt´an´ı d´ılk˚ u vypad´a takto: for ( var i = 0 ; i < 9 ; i ++) { t h i s . tempImg [ i ] = new Image ( ) ; t h i s . tempImg [ i ] . s r c = ”getImage . php? imgid=”+i+ ”×tamp=”+t h i s . s t a r t T i m e . getTime ( ) ; t h i s . tempImg [ i ] . o n l o a d = f u n c t i o n ( ) { Exploder . l o a d e d I m a g e s = Exploder . l o a d e d I m a g e s + 1 ; i f ( Exploder . l o a d e d I m a g e s == 9 ) { Exploder . startGame ( ) ; } }; }
Parametrem URL obr´azk˚ u je kromˇe identifik´atoru d´ılku tak´e ˇcasov´a znaˇcka zaˇc´atku hry. Tento parametr nen´ı na serveru nijak vyuˇz´ıv´an, ale je souˇca´st´ı URL z toho d˚ uvodu, aby byl URL obr´azk˚ u pˇri kaˇzd´e hˇre jin´ y. T´ım je zajiˇstˇeno, ˇze klient pˇri dalˇs´ı hˇre nepouˇzije stejn´ y obr´azek d´ılku (uloˇzen´ y v cache), ale je nucen si jej znovu naˇc´ıst ze serveru. Po staˇzen´ı posledn´ıho dev´at´eho d´ılku se spust´ı hra zavol´an´ım metody startGame. Na serveru se zaˇcne mˇeˇrit ˇcas hran´ı od chv´ıle, kdy byl odesl´an dev´at´ y obr´azek. Je potˇreba zajistit, aby bˇehem hran´ı byly obr´azky uloˇzeny v cache. Jinak by se pˇrednaˇcten´e obr´azky zaˇcaly v nˇekter´ ych prohl´ıˇzeˇc´ıch znovu naˇc´ıtat ve chv´ıli, kdy bychom je chtˇeli zobrazit. Proto je potˇreba na serveru spr´avnˇe nastavit HTTP hlaviˇcky odpovˇedi na ˇza´dost o obr´azek: h e a d e r ( ’ Cache−C o n t r o l : ’ ) ; $expires = 60∗60∗24∗14; h e a d e r ( ’ E x p i r e s : ’ . gmdate ( ’D, d M Y H: i : s ’ , time ( )+$ e x p i r e s ) . ’ GMT’ ) ;
Toto nastaven´ı HTTP hlaviˇcek prohl´ıˇzeˇc informuje, ˇze si m´a obr´azky uloˇzit do cache. Platnost obr´azk˚ u vyprˇs´ı aˇz za dva t´ ydny. Vzhled hry Puzzle pˇri naˇc´ıt´an´ı d´ılk˚ u ukazuje obr´azek 7.1. Hra Puzzle po naˇcten´ı a zam´ıch´an´ı obr´azk˚ u je vidˇet na obr´azku 7.2. 41
Anal´yza her
Odstranˇen´ı moˇznosti podv´ adˇet
Obr´azek 7.1: Hra Puzzle, naˇc´ıt´an´ı d´ılk˚ u
Obr´azek 7.2: Hra Puzzle po naˇcten´ı d´ılk˚ u a zam´ıch´an´ı
42
8 Rozhran´ı pro ukl´ad´an´ı v´ysledk˚ u her 8.1
Anal´ yza a n´ avrh ˇ reˇ sen´ı
V´ ysledky her na Frisky se nyn´ı ukl´adaj´ı do textov´ ych soubor˚ u. Pro jednoduˇsˇs´ı a efektivnˇejˇs´ı pr´aci s nimi je vhodnˇejˇs´ı pouˇz´ıt datab´azi. Z´aroveˇ n je potˇreba vytvoˇrit jednotn´e znovupouˇziteln´e rozhran´ı pro ukl´ad´an´ı a z´ısk´av´an´ı v´ ysledk˚ u her. Rozhran´ı jsem navrhl tak, ˇze bude obsahovat pouze dvˇe funkce, jednu pro ukl´ad´an´ı v´ ysledk˚ u a druh´a bude vracet nejlepˇs´ı hern´ı v´ ysledky v podobˇe HTML tabulky. D´ale jsem rozhodnul, ˇze v´ ysledky vˇsech her budou ukl´ad´any do jedn´e tabulky. V´ ysledky jednotliv´ ych her budou od sebe odliˇseny jednoznaˇcn´ ym identifik´atorem hry. Jako hern´ı v´ ysledek by se mˇel ukl´adat poˇcet dosaˇzen´ ych bod˚ u nebo doba ˇreˇsen´ı u ´kolu.
8.2
Implementace rozhran´ı
Vytvoˇril jsem rozhran´ı, kter´a se skl´ad´a z n´asleduj´ıc´ıch soubor˚ u: • scorelib.php - obsahuje funkce pro uloˇzen´ı v´ ysledk˚ u a z´ısk´an´ı nejlepˇs´ıch v´ ysledk˚ u v HTML podobˇe. • scorelib.css - obsahuje nastaven´ı vzhledu tabulky, ve kter´e se zobrazuj´ı nejlepˇs´ı v´ ysledky. • scorelib.js - obsahuje funkci, kter´a je vol´ana, kdyˇz uˇzivatel klikne na nˇekterou ze z´aloˇzek v tabulce v´ ysledk˚ u. • scorebox.png - pozad´ı tabulky v´ ysledk˚ u. Pro ukl´ad´an´ı v´ ysledk˚ u byla zvolena datab´aze MySQL. Podle pˇredchoz´ı anal´ yzy jsou v´ ysledky her ukl´ad´any do jedn´e tabulky. Pojmenoval jsem ji gameResults. Jako v´ ysledek hry je moˇzn´e ukl´adat bodov´e sk´ore nebo dobu, za kterou hr´aˇc vyˇreˇsil danou u ´lohu, pˇr´ıpadnˇe oboj´ı. Podle toho je potom tak´e moˇzn´e pˇri zobrazen´ı nejlepˇs´ıch hern´ıch v´ ysledk˚ u nechat zobrazit dosaˇzen´e sk´ore, dobu ˇreˇsen´ı nebo oboj´ı. Tabulka s nejlepˇs´ımi v´ ysledky m˚ uˇze b´ yt ˇrazena tak´e podle libovoln´eho z tˇechto ukazatel˚ u, a to sestupnˇe nebo vzestupnˇe. Soubor scorelib.php obsahuje celkem dvˇe funkce, kter´e bude uˇzivatel knihovny volat: • saveResults($gameID, $playerName, $score, $gameDuration, $otherInfo) - slouˇz´ı k ukl´ad´an´ı v´ ysledk˚ u her. Jednotliv´e parametry maj´ı n´asleduj´ıc´ı v´ yznam: 43
Rozhran´ı pro ukl´ad´an´ı v´ysledk˚ u her
Implementace rozhran´ı
– – – –
$gameID - Celoˇc´ıseln´ y identifik´ator hry, jej´ıˇz v´ ysledky chceme ukl´adat. $playerName - Uˇzivatelsk´e jm´eno uˇzivatele, jehoˇz hern´ı v´ ysledek ukl´ad´ame. $score - Dosaˇzen´e sk´ore. Mus´ı se jednat o cel´e ˇc´ıslo. $gameDuration - Doba ˇreˇsen´ı u ´lohy. Mus´ı b´ yt ud´ana tak´e cel´ ym ˇc´ıslem jako poˇcet milisekund. – $otherInfo - Sem je moˇzn´e uloˇzit libovoln´e dalˇs´ı informace jako ˇretˇezec d´elky maxim´alnˇe 300 znak˚ u.
• getBestResults($game, $timePeriod, $order, $columns) - slouˇz´ı k z´ısk´an´ı nejlepˇs´ıch hern´ıch v´ ysledk˚ u, kter´e jsou ve formˇe HTML odesl´any klientovi. Parametry maj´ı tento v´ yznam: ˇ ıseln´ – $game - C´ y identifik´ator hry. – $timePeriod - Vyb´ır´a, za jak´e ˇcasov´e obdob´ı chceme zobrazit nejlepˇs´ı v´ ysledky. M˚ uˇze nab´ yvat tyto hodnoty: ∗ 1 - Nejlepˇs´ı v´ ysledky za tento den. ∗ 2 - Nejlepˇs´ı v´ ysledky za tento t´ yden. ∗ 3 - Nejlepˇs´ı v´ ysledky za tento mˇes´ıc. ∗ 4 - Nejlepˇs´ı v´ ysledky vˇsech dob. ∗ 5 - Nejlepˇs´ı v´ ysledky vˇsech dob, ale kaˇzd´ y uˇzivatel zde m´a nejv´ yˇse jeden (sv˚ uj nejlepˇs´ı) v´ ysledek. ∗ 6 - Nejlepˇs´ı v´ ysledky za posledn´ıch 30 dn´ı. – $order - Ud´av´a, jak maj´ı b´ yt v´ ysledky ˇrazeny. Lze ˇradit podle dosaˇzen´eho ˇcasu nebo z´ıskan´eho sk´ore. Knihovna definuje n´asleduj´ıc´ı konstanty: ∗ $ORDER BY TIME DESC - seˇrad´ı v´ ysledky sestupnˇe podle dosaˇzen´eho ˇcasu. ysledky vzestupnˇe podle dosaˇze∗ $ORDER BY TIME ASC - seˇrad´ı v´ n´eho ˇcasu. ysledky sestupnˇe podle dosaˇze∗ $ORDER BY SCORE DESC - seˇrad´ı v´ n´eho sk´ore. ∗ $ORDER BY SCORE ASC - seˇrad´ı v´ ysledky vzestupnˇe podle dosaˇzen´eho sk´ore. ˇ ık´a, kter´e sloupce by mˇely b´ – $columns - R´ yt zobrazeny v tabulce v´ ysledk˚ u jako ukazatele dosaˇzen´eho hern´ıho v´ ysledku. Je moˇzn´e zobrazit dosaˇzen´ y ˇcas nebo dosaˇzen´e sk´ore nebo oboj´ı. Knihovna definuje pˇr´ısluˇsn´e konstanty: ∗ $SHOW TIME - zobraz´ı se dosaˇzen´ y ˇcas. ∗ $SHOW SCORE - zobraz´ı se dosaˇzen´e sk´ore. ∗ $SHOW BOTH - zobraz´ı se dosaˇzen´ y ˇcas i dosaˇzen´e sk´ore. 44
Rozhran´ı pro ukl´ad´an´ı v´ysledk˚ u her
Implementace rozhran´ı
Uk´azku pouˇzit´ı t´eto knihovny naleznete v pˇr´ıloze F.
45
9 Knihovna pro komunikaci uˇzivatel˚ u ´ Ukolem od zadavatele bylo vytvoˇrit prostˇredky pro komunikaci uˇzivatel˚ u na webov´ ych str´ank´ach. Prvn´ım zp˚ usobem komunikace, kter´ y mˇel b´ yt implementov´an, bylo kreslen´ı na HTML5 element canvas. Kreslit by se mˇelo myˇs´ı. Vˇse, co nˇekter´ y z n´avˇstˇevn´ık˚ u str´anky nakresl´ı, by se mˇelo zobrazit u vˇsech ostatn´ıch n´avˇstˇevn´ık˚ u. Zadavatel si tak´e pˇra´l, aby bylo moˇzn´e nakreslen´e obr´azky ukl´adat do galerie. Dalˇs´ım zp˚ usobem komunikace by mˇela b´ yt textov´a komunikace (chat). Knihovna by tak´e mˇela umoˇznit zobrazit seznam uˇzivatel˚ u, kteˇr´ı jsou pˇr´ıtomni na str´ance.
9.1
Anal´ yza distribuce aktualizac´ı
Hlavn´ım probl´emem, kter´ y zde mus´ıme rozebrat, je zp˚ usob distribuce napsan´ ych zpr´av nebo nakreslen´ ych ˇcar (d´ale oznaˇcujme jednoduˇse jako aktualizace) od jejich autora k ostatn´ım uˇzivatel˚ um. Abychom doc´ıli t´eto funkcionality, bude nejprve potˇreba zajistit ukl´ad´an´ı vˇsech aktualizac´ı na serveru. Klient bude muset vˇsechny aktualizace pos´ılat na server prostˇrednictv´ım technologie AJAX. Na serveru bude nejlepˇs´ı aktualizace ukl´adat do datab´aze. D´ale je potˇreba rozhodnout, jak budou klienti z´ısk´avat aktualizace, kter´e na serveru nˇekdo jin´ y uloˇzil. Jedn´ım moˇzn´ ym ˇreˇsen´ım by mohlo b´ yt pos´ıl´an´ı dotaz˚ u na server v pravideln´ ych intervalech. Tˇemi bychom se serveru ptali, zda se objevila v datab´azi aktualizace, kterou jeˇstˇe nem´ame. Takov´a implementace by ale nebyla pˇr´ıliˇs optim´aln´ı, nebot’, pokud chceme aktualizace dost´avat s mal´ ym zpoˇzdˇen´ım, museli bychom server zatˇeˇzovat ˇcast´ ymi dotazy. Z toho d˚ uvodu jsem se rozhodl zvolit lepˇs´ı ˇreˇsen´ı - pouˇz´ıt program´atorsk´ y model, kter´emu se ˇr´ık´a Comet. Konkr´etnˇe jsem zvolil jeho variantu long polling s pouˇzit´ım technologie AJAX. Metoda long polling funguje tak, ˇze klient se dot´aˇze prostˇrednictv´ım AJAX dotazu serveru, zda je v datab´azi nˇeco nov´eho. Pokud ano, skript poˇsle klientovi pˇr´ısluˇsn´a data a skonˇc´ı. Pokud ne, skript na serveru hned neodpov´ı, ale pt´a se v pravideln´ ych intervalech datab´aze, zda je nˇeco nov´eho. Klientovi je posl´ana odpovˇed’ aˇz ve chvili, kdy se objev´ı nˇejak´a aktualizace. Jakmile klient dostane odpovˇed’, zpracuje si z´ıskan´a data a poˇsle na server nov´ y dotaz. U t´eto metody bude kritick´e zajistit, aby pˇr´ısluˇsn´ y PHP skript vˇzdy ukonˇcil sv˚ uj bˇeh pot´e, co uˇzivatel opust´ı str´anku. Tento skript se tedy bude muset vˇzdy po urˇcit´e maxim´aln´ı dobˇe bˇehu ukonˇcit a klient pak bude muset obnovit spojen´ı. Bylo by sice moˇzn´e v javascriptu reagovat na ud´alosti unload a beforeunload, ale takov´e ˇreˇsen´ı by nebylo spolehliv´e.
46
Knihovna pro komunikaci uˇzivatel˚ u
Implementace metody long polling
Metodu long polling bude moˇzn´e pouˇz´ıt pro kreslen´ı, chat, galerii i pro z´ısk´av´an´ı aktu´aln´ıho seznamu pˇrihl´aˇsen´ ych uˇzivatel˚ u pˇr´ıtomn´ ych na str´ance. Nyn´ı je potˇreba rozmyslet, jak budeme udrˇzovat seznam pˇrihl´aˇsen´ ych uˇzivatel˚ u a jak ˇ sen´ı druh´eho zm´ınˇen´eho probl´emu budeme detekovat, ˇze uˇzivatel opustil str´anku. Reˇ jsem uˇz uvedl v´ yˇse. Od kaˇzd´eho uˇzivatele budou muset pˇrich´azet pravidelnˇe nov´e dotazy. Kdyˇz nedostaneme dotaz do urˇcit´e doby od posledn´ıho dotazu, budeme uˇzivatele povaˇzovat za nepˇr´ıtomn´eho. Seznam pˇr´ıtomn´ ych uˇzivatel˚ u mus´ıme m´ıt uloˇzen´ y tak, aby s n´ım mohly pracovat vˇsechny procesy. Bude tedy potˇreba pouˇz´ıt napˇr. datab´azi nebo sd´ılenou pamˇet’. Dalˇs´ı probl´em, kter´ y rozebereme, je, kdy by mˇel klient poslat aktualizaci na server. V pˇr´ıpadˇe chatu a galerie je toto jasn´e - aktualizaci odeˇsleme, kdyˇz uˇzivatel klepne na tlaˇc´ıtko Odeslat zpr´avu“ nebo Uloˇzit obr´azek“. V pˇr´ıpadˇe kreslen´ı se ale nab´ız´ı v´ıce ” ” moˇznost´ı. Jednou moˇznost´ı by bylo poslat na server aktualizaci vˇzdy, kdy i u m´ıstn´ıho klienta vol´ame pˇrekreslen´ı canvasu. To znamen´a vˇzdy, kdy n´am pˇribyde nov´ y bod kreslen´e ˇc´ary. Tento pˇr´ıstup by byl z hlediska efektu pro uˇzivatele nejhezˇc´ı. Je ale jasn´e, ˇze by se potom na server pos´ılalo extr´emnˇe vysok´e mnoˇzstv´ı poˇzadavk˚ u. Dalˇs´ı moˇznost´ı je pos´ılat data na server vˇzdy, kdy uˇzivatel dokresl´ı danou ˇca´ru. To znamen´a ve chv´ıli, kdy pust´ı lev´e tlaˇc´ıtko myˇsi. Toto bych povaˇzoval za rozumn´e ˇreˇsen´ı. Bylo by ale moˇzn´e jej vylepˇsit pos´ıl´an´ım ˇcar po ˇca´stech v pˇr´ıpadˇe, kdy uˇzivatel kresl´ı dlouhou ˇca´ru. Napˇr. by se aktualizace pos´ılala po nakreslen´ı kaˇzd´ ych dvaceti bod˚ u ˇca´ry. U tohoto ˇreˇsen´ı by ale bylo implementaˇcnˇe n´aroˇcn´e udrˇzet konzistence obr´azk˚ u tak, aby ˇca´ra zapoˇcat´a pozdˇeji byla i se vˇsemi sv´ ymi u ´seky kreslena pˇres ˇc´aru zapoˇcatou dˇr´ıve (a pˇres vˇsechny jej´ı pozdˇeji dodan´e u ´seky).
9.2
Implementace metody long polling
Podle pˇredchoz´ı anal´ yzy jsem pro distribuci aktualizac´ı implementoval metodu long polling. Princip t´eto metody byl jiˇz pops´an v anal´ yze - klient mus´ı poslat technologi´ı AJAX dotaz na server, odpovˇed’ dostane aˇz kdyˇz server nalezne v datab´azi novou aktualizaci. Pro kaˇzd´eho uˇzivatele tedy bˇeˇz´ı na serveru jeden PHP skript (s t´ım, ˇze vˇzdy po nˇejak´e dobˇe skonˇc´ı a po pˇr´ıchodu nov´eho poˇzadavku se spust´ı znovu), kter´ y se pravidelnˇe dotazuje datab´aze. Pokud je na str´ance pˇr´ıtomno mnoho uˇzivatel˚ u, mohou tyto pravideln´e datab´azov´e dotazy zp˚ usobit znateln´e zat´ıˇzen´ı serveru. Uˇzivatel knihovny tedy bude muset nastavit jejich periodu. Pˇri delˇs´ı periodˇe se sn´ıˇz´ı zat´ıˇzen´ı serveru, ale zase se prodlouˇz´ı doba, za kterou se aktualizace rozeˇsle uˇzivatel˚ um. V anal´ yze bylo tak´e zm´ınˇeno, ˇze mus´ı b´ yt oˇsetˇreno, aby PHP skript nesmˇel za ˇza´dn´ ych okolnost´ı bˇeˇzet nekoneˇcnˇe dlouho. Nebezpeˇc´ı vznik´a pˇredevˇs´ım t´ım, ˇze skript 47
Knihovna pro komunikaci uˇzivatel˚ u
Implementace metody long polling
pravidelnˇe vol´a funkci set time limit, ˇc´ımˇz si zajiˇst’uje potenci´alnˇe nekoneˇcnou dobu bˇehu, server jej nem˚ uˇze automaticky ukonˇcit. Provedl jsem tedy tato opatˇren´ı: • Timeout. Skript se ukonˇc´ı vˇzdy nejpozdˇeji po 45 sekund´ach a klient mus´ı spojen´ı obnovit. • Pouˇzit´ı ud´alost´ı beforeunload a unload. Jejich pouˇzit´ı nen´ı pˇr´ıliˇs spolehliv´e, nebot’ zat´ımco napˇr´ıklad ud´alost unload nastane v nˇekter´ ych prohl´ıˇzeˇc´ıch pˇri odchodu ze str´anky i pˇri zavˇren´ı pˇr´ısluˇsn´eho okna/tabu, v jin´ y nastane pouze pˇri odchodu ze str´anky. Ud´alost beforeunload nˇekter´e prohl´ıˇzeˇce neznaj´ı v˚ ubec. Pokud je ale nˇekter´a z tˇechto ud´alost´ı vyvol´ana, poˇsle se na server zpr´ava, ˇze skript, kter´ y pro n´as zjiˇst’uje pˇr´ıtomnost nov´e aktualizace, se m´a ihned ukonˇcit. • PHP skript na serveru tak´e um´ı detekovat, ˇze pro stejn´eho uˇzivatele bˇeˇz´ı dalˇs´ı skript, kter´ y by mu tak´e mˇel dod´avat aktualizace. Tato situace napˇr´ıklad nastane, kdyˇz uˇzivatel provede opˇetovn´e naˇcten´ı (reload) str´anky. Pokud skript tedy tuto situaci detekuje a zjist´ı, ˇze je starˇs´ı, neˇz druh´ y bˇeˇz´ıc´ı skript, s´am se ukonˇc´ı. T´eto funkcionality jsem dos´ahl pouˇzit´ım sezen´ı (session), kam si skript vˇzdy uloˇz´ı ˇcas, kdy zaˇcal bˇeˇzet. Kdyˇz se skript ukonˇcuje, vˇzdy si tento z´aznam smaˇze. Pokud tedy pˇri sv´em bˇehu skript zjist´ı, ˇze takov´e z´aznamy jsou v sezen´ı dva (nebo v´ıce) a ˇze nˇekter´ y z tˇechto z´aznam˚ u obsahuje vyˇsˇs´ı ˇcasovou znaˇcku, neˇz je znaˇcka uloˇzen´a dan´ ym skriptem, pak se skript ukonˇc´ı, nebot’ v´ı, ˇze existuje jin´ y novˇejˇs´ı skript. D´ale bylo potˇreba vyˇreˇsit probl´em s pouˇzit´ım sezen´ı. Pˇri vol´an´ı PHP funkce session start se skript z´aroveˇ n snaˇz´ı z´ıskat bin´arn´ı z´amek sezen´ı, kter´ y je standardnˇe uvolnˇen po ukonˇcen´ı skriptu. V naˇsem pˇr´ıpadˇe chceme, aby skript mohl bˇeˇzet dlouhou dobu a z´aroveˇ n mohl pouˇz´ıvat sezen´ı. Pokud by ale n´aˇs skript uzamknul sezen´ı, nemohl by uˇzivatel pos´ılat dalˇs´ı poˇzadavky na jin´e PHP skripty, kter´e tak´e pouˇz´ıvaj´ı sezen´ı. Napˇr. by tedy uˇzivatel nemohl pˇrej´ıt na jinou str´anku (v dan´e dom´enˇe) do doby, neˇz by se skript sleduj´ıc´ı aktualizace ukonˇcil. Naˇstˇest´ı nab´ız´ı PHP funkci session write close, kter´a ukonˇc´ı pr´aci se sezen´ım a vzd´a se z´amku. Tuto funkci tedy vol´am vˇzdy neˇz se skript usp´ı. Po probuzen´ı mus´ı n´aˇs skript znovu zavolat funkci session start, aby mohl opˇet pouˇz´ıvat sezen´ı. Toto ovˇsem pˇrin´aˇs´ı dalˇs´ı probl´em, nebot’ PHP pˇri vol´an´ı t´eto funkce vˇzdy automaticky zap´ıˇse do HTTP hlaviˇcky odpovˇedi cookie PHPSESSID. Kolikr´at bˇehem sv´eho bˇehu skript zavol´a session start, tolikr´at se v HTTP hlaviˇcce (v parametru Set-Cookie) tato cookie objev´ı (vˇzdy se stejnou hodnotou). Kromˇe toho, ˇze pak pos´ıl´ame zbyteˇcnˇe ˇ sen´ım dlouhou odpovˇed’, m˚ uˇze toto tak´e zp˚ usobit probl´emy v nˇekter´ ych prohl´ıˇzeˇc´ıch. Reˇ je pˇrepsat parametr Set-Cookie takto: h e a d e r ( ’ Set−Cookie : ’ . SID . ’ ; path=/ ’ , true ) ;
48
Knihovna pro komunikaci uˇzivatel˚ u
9.3 9.3.1
Kreslen´ı
Kreslen´ı Implementace kreslen´ı v elementu canvas
V t´eto podkapitole pop´ıˇsi, jak jsem implementoval kreslen´ı v elementu canvas, aniˇz bych se zat´ım zab´ yval distribuc´ı nakreslen´ ych ˇcar k ostatn´ım uˇzivatel˚ um. Vytvoˇren´ı elementu canvas prov´ad´ım n´asledovnˇe: canvasWidth = ”600 px ” ; c a n v a s H e i g h t = ”400 px ” ; var canvasDiv = document . getElementById ( ’ canvasDiv ’ ) ; canvas = document . c r e a t e E l e m e n t ( ’ canvas ’ ) ; canvas . s e t A t t r i b u t e ( ’ width ’ , canvasWidth ) ; canvas . s e t A t t r i b u t e ( ’ h e i g h t ’ , c a n v a s H e i g h t ) ; canvas . s e t A t t r i b u t e ( ’ i d ’ , ’ canvas ’ ) ; canvasDiv . appendChild ( canvas ) ; c o n t e x t = canvas . g e t C o n t e x t ( ”2d ”) ; o ld i m a g e = c o n t e x t . getImageData ( 0 , 0 , canvasWidthInt , canvasHeightInt ) ;
Zde je d˚ uleˇzit´a pˇredposledn´ı ˇra´dka. Zavol´an´ım metody getContext dostaneme ukazatel na objekt reprezentuj´ıc´ı 2D kontext canvasu. Ten d´ale pouˇzijeme k tomu, abychom mohli na canvas kreslit. Posledn´ı ˇra´dka je tak´e d˚ uleˇzit´a, zde si totiˇz ukl´ad´ame bin´arn´ı reprezentaci obr´azku na canvasu. Tu budeme d´ale vyuˇzivat pˇri pˇrekreslov´an´ı obr´azku. Nyn´ı se pod´ıvejme, jak vlastnˇe funguje kreslen´ı na element canvas, aniˇz bychom se zat´ım zab´ yvali distribuc´ı nakreslen´ ych ˇcar na ostatn´ı poˇc´ıtaˇce. Na element canvas kresl´ıme myˇs´ı. Pokud je stisknuto tlaˇc´ıtko myˇsi, kresl´ı se ˇc´ara podle pohybu kurzoru myˇsi. Nad elementem canvas tedy potˇrebujeme sledovat n´asleduj´ıc´ı ud´alosti: • mousedown - pˇri t´eto ud´alosti si uloˇz´ıme, ˇze pr´avˇe ted’ kresl´ıme. Pot´e si uloˇz´ıme aktu´aln´ı souˇradnice kurzoru myˇsi jako prvn´ı bod kreslen´e ˇc´ary a provedeme pˇrekreslen´ı. • mousemove - pokud m´ame uloˇzeno, ˇze pr´avˇe ted’ kresl´ıme (je stisknut´e tlaˇc´ıtko myˇsi), potom si uloˇz´ıme aktu´aln´ı pozici kurzoru myˇsi jako dalˇs´ı bod kreslen´e ˇc´ary a pˇrekresl´ıme canvas.
49
Knihovna pro komunikaci uˇzivatel˚ u
Kreslen´ı
• mouseup - uloˇz´ıme si, ˇze kreslen´ı aktu´aln´ı ˇc´ary bylo dokonˇceno. N´asleduj´ıc´ı ud´alosti mousemove jsou tedy ignorov´any do doby, neˇz opˇet uˇzivatel stiskne lev´e tlaˇc´ıtko myˇsi nad elementem canvas. Tato ud´alost je sledov´ana nad elementem body. Je tomu tak pro pˇr´ıpad, kdy uˇzivatel pˇri kreslen´ı sjede s myˇs´ı z elementu canvas a pak pust´ı lev´e tlaˇc´ıtko myˇsi. Pod´ıvejme se zjednoduˇsenˇe na to, jak funguje funkce zajiˇst’uj´ıc´ı pˇrekreslen´ı canvasu. Tato funkce je v programu pojmenov´ana jako redraw. Pokud by se pˇri kreslen´ı vˇzdy ˇ ary by pouze vykreslila dalˇs´ı ˇca´st ˇca´ry, prohl´ıˇzeˇc by neprovedl antialiasing obr´azku. C´ potom byly nevzhlednˇe kostrbat´e. Nejprve tedy pˇrekresl´ıme canvas jeho bin´arn´ı reprezentac´ı, kterou jsme si uloˇzili pˇri posledn´ım pˇrekreslen´ı. Pˇrekreslen´ı obr´azku provedeme takto: c o n t e x t . putImageData ( oldimage , 0 , 0 ) ;
N´aslednˇe budeme kreslit na canvas podle toho, co uˇzivatel pr´avˇe provedl. Kreslen´ı zaˇcneme zavol´an´ım funkce beginPath: c o n t e x t . beginPath ( ) ;
Tato funkce vyˇcist´ı seznam vˇsech primitiv, kter´a jsme doposud nakreslili. Dalˇs´ı postup je z´avisl´ y na tom, zda pr´avˇe zaˇc´ın´ame kreslit novou ˇc´aru, nebo zda pouze kresl´ıme spojnici s dalˇs´ım bodem uˇz zapoˇcat´e ˇca´ry. Pokud pokraˇcujeme v kreslen´ı zapoˇcat´e ˇca´ry, mus´ıme pouˇz´ıt funkci moveTo, abychom naˇse neviditeln´e pero pˇresunuli na m´ısto, kter´e budeme spojovat s nov´ ym bodem ˇc´ary. Pokud zaˇc´ın´ame s novou ˇcarou, pˇresuneme se na jej´ı zaˇca´tek, tj. na aktu´aln´ı pozici myˇsi. Uvaˇzujme nyn´ı tedy, ˇze zaˇc´ın´ame kreslit novou ˇca´ru. V tuto chv´ıli mus´ıme vykreslit teˇcku v uloˇzen´e aktu´aln´ı pozici myˇsi: c o n t e x t . a r c ( c l i c k X [ i ] , c l i c k Y [ i ] , c l i c k S i z e [ i ] / 2 . 0 , 0 , Math . PI ∗ 2 , true ) ; context . closePath () ; context . f i l l S t y l e = clickColor [ i ] ; context . f i l l () ;
Vˇsechna pole, kter´a jsou vidˇet v t´eto uk´azce k´odu, obsahuj´ı informace o pr´avˇe kreslen´e ˇc´aˇre. Z pol´ı clickX a clickY si pˇreˇcteme aktu´aln´ı souˇradnice myˇsi. V poli clickSize m´ame uloˇzenou aktu´aln´ı ˇs´ıˇrku ˇc´ary a v poli clickColor aktu´aln´ı zvolenou barvu. Kruˇznice se vykresl´ı funkc´ı arc, jej´ı vyplnˇen´ı je pak provedeno funkc´ı fill. Pokud chceme vykreslit spojnici s dalˇs´ım bodem ˇca´ry, pouˇzijeme m´ısto funkce arc funkci lineTo a m´ısto funkce fill zavol´ame stroke:
50
Knihovna pro komunikaci uˇzivatel˚ u
Kreslen´ı
context . lineTo ( clickX [ i ] , clickY [ i ] ) ; context . closePath () ; context . strokeStyle = clickColor [ i ] ; context . lineWidth = c l i c k S i z e [ i ] ; context . stroke () ;
N´aslednˇe si po vykreslen´ı nov´eho obr´azku uloˇz´ıme jeho bin´arn´ı reprezentaci, kterou pouˇzijeme pˇri dalˇs´ım pˇrekreslen´ı obr´azku. To provedeme n´asledovnˇe: o ld i m a g e = c o n t e x t . getImageData ( 0 , 0 , canvasWidthInt , canvasHeightInt ) ;
Z v´ yˇse uveden´ ych pˇr´ıklad˚ u je vidˇet, ˇze uˇzivateli je dovoleno zvolit si barvu a ˇs´ıˇrku kreslen´e ˇc´ary. Knihovna je implementov´ana tak, ˇze jej´ı uˇzivatel si m˚ uˇze nadefinovat rozbalovac´ı seznam (elementem select), ve kter´em si bude moci uˇzivatel kreslen´ı volit ˇs´ıˇrku ˇca´ry v pixelech. Pro v´ ybˇer barvy lze pouˇz´ıt napˇr. nˇekter´ y z volnˇe dostupn´ ych modul˚ u do knihovny jQuery. Ve sv´e uk´azce pouˇzit´ı knihovny, kter´a je nasazena na str´ank´ach Frisky, jsem pouˇzil plug-in farbtastic. V´ ysledn´e kreslen´ı na HTML5 element canvas (spolu s pouˇzit´ ym farbtastic modulem) ukazuje obr´azek 9.1. Tato implementace kreslen´ı byla ˇc´asteˇcnˇe zaloˇzena na n´avodu v [14].
Obr´azek 9.1: Kreslen´ı
51
Knihovna pro komunikaci uˇzivatel˚ u
9.3.2
Kreslen´ı
Z´ısk´ av´ an´ı aktualizac´ı od ostatn´ıch
Z´ısk´av´an´ı aktualizac´ı je zaloˇzeno na jiˇz popsan´e implementaci metody long polling. Pod´ıvejme se, jak´e informace se vymˇen ˇuj´ı mezi klientem a serverem. Server vˇzdy pos´ıl´a s aktualizacemi tak´e identifik´ator nejnovˇejˇs´ı pos´ılan´e aktualizace. Klient si tento identifik´ator ukl´ad´a do pˇr´ısluˇsn´e promˇenn´e. Identifik´ator odpov´ıd´a sloupci id v pˇr´ısluˇsn´e tabulce datab´aze, kter´ y je nastaven takto: BIGINT UNSIGNED NOT NULL y ˇc´ıseln´ y identifiAUTO INCREMENT. Jedn´a se tedy o automaticky inkrementovan´ ˇ k´ator ˇr´adku tabulky. C´ıslo poslednˇe obdrˇzen´eho identifik´atoru aktualizace klient vˇzdy pos´ıl´a jako parametr sv´eho poˇzadavku o aktualizaci. Pˇri prvn´ım poˇzadavku pos´ıl´a hodnotu nula. Pak skript na serveru zaˇcne naˇc´ıtat z datab´aze vˇsechny posledn´ı aktualizace obr´azku, dokud souˇcet d´elek ˇcar, kter´e tyto aktualizace obsahuj´ı, nepˇrekroˇc´ı urˇcitou maxim´aln´ı hodnotu, nebo dokud nenaˇcte vˇsechno, co je v datab´azi. Vˇsechny naˇcten´e aktualizace jsou pak posl´any klientovi a zde vykresleny na canvas. T´ım by mˇel tedy uˇzivatel po pˇr´ıchodu na str´anku vidˇet, co ostatn´ı uˇzivatel´e doposud nakreslili. Po tomto u ´vodn´ım naˇcten´ı obr´azku poˇsle klient nov´ y dotaz na server. Nyn´ı uˇz budou klientovi zas´ıl´any pouze ty aktualizace, kter´e maj´ı v datab´azi vyˇsˇs´ı identifik´ator, neˇz jak´ y mˇela posledn´ı klientem obdrˇzen´a aktualizace. D´ale je potˇreba zd˚ uraznit, ˇze po uloˇzen´ı aktualizace obr´azku je tato detekov´ana vˇsemi skripty, kter´e pos´ılaj´ı uˇzivatel˚ um aktualizace. Vyj´ımkou by ale mˇel b´ yt skript pˇr´ısluˇsej´ıc´ı samotn´emu autorovi aktualizace. Jak bude d´ale podrobnˇeji rozebr´ano, je to zajiˇstˇeno t´ım, ˇze pˇri pˇr´ıjmu aktualizace si server pomoc´ı session zapamatuje, ˇze danou aktualizaci m´a jej´ı autor vykreslenou a nen´ı potˇreba mu ji pos´ılat znovu. M˚ uˇze ale nastat jedna vyj´ımka. Jedn´a se o situaci, kdy server pˇrijal aktualizaci od jin´eho uˇzivatele tˇesnˇe pˇredt´ım, neˇz uloˇzil naˇsi aktualizaci. Probl´em je v tom, ˇze pro udrˇzen´ı konzistence obr´azk˚ u by se ciz´ı aktualizace mˇela vykreslit pod tu naˇsi (pokud se ˇc´ary pˇrekr´ yvaj´ı). Tuto speci´aln´ı situaci server vyˇreˇs´ı tak, ˇze n´am poˇsle ciz´ı i naˇsi aktualizaci. Klient je pak obˇe vykresl´ı v tomto poˇrad´ı a konzistence obr´azk˚ u je t´ım zachov´ana.
9.3.3
Uloˇ zen´ı dat na serveru
Podle pˇredchoz´ı anal´ yzy jsem se rozhodl pos´ılat aktualizace na server vˇzdy po dokreslen´ı dan´e ˇca´ry, nebot’ toto ˇreˇsen´ı povaˇzuji za nejrozumnˇejˇs´ı z hlediska funkˇcnosti i implementaˇcn´ı sloˇzitosti. K odesl´an´ı dat na server pouˇz´ıv´am technologii AJAX a nad n´ı AjaxManager, coˇz je pˇr´ıdavn´ y modul do knihovny jQuery. Tento modul pouˇz´ıv´am, abych zajistil, ˇze jednotliv´e poˇzadavky budou na serveru zpracov´any ve spr´avn´em poˇrad´ı. AjaxManager totiˇz um´ı zajistit odesl´an´ı nov´eho poˇzadavku aˇz po z´ısk´an´ı odpovˇedi na ten pˇredchoz´ı. K´od, kter´ y vloˇz´ı AJAX poˇzadavek do fronty, ze kter´e bude vybr´an a odesl´an aˇz na nˇej pˇrijde ˇrada, vypad´a n´asledovnˇe: 52
Knihovna pro komunikaci uˇzivatel˚ u
Kreslen´ı
drawingAjaxManager . add ( { url : url , type : ’POST ’ , b e f o r e S e n d : f u n c t i o n (jqXHR , s e t t i n g s ) { sendingDrawingUpdate = true ; s e t t i n g s . data += ”&l a s t i d=”+encodeURIComponent ( l a s t i d ) ; }, data : { ”msg ” : msg } , success : function ( transport ) { var i n c = p a r s e I n t ( t r a n s p o r t ) ; i f ( inc > 0) { l a s t i d = l a s t i d + inc ; } }, complete : f u n c t i o n ( ) { sendingDrawingUpdate = f a l s e ; processQueuedCanvasUpdates ( ) ; } }) ;
Data jsou pos´ıl´ana metodou POST HTTP protokolu. Velikost dat m˚ uˇze b´ yt totiˇz relativnˇe velk´a. Z´aleˇz´ı na d´elce nakreslen´e ˇca´ry. Na server je pos´ıl´an tak´e identifik´ator (d´ale zkr´acenˇe id) posledn´ı zobrazen´e aktualizace. Pokud aktualizace, kterou se nyn´ı snaˇz´ıme uloˇzit, bude m´ıt v datab´azi id o jedno vyˇsˇs´ı, server n´as o tom informuje v odpovˇedi na tento AJAX poˇzadavek. Klient si pak podle toho m˚ uˇze inkrementovat svoj´ı promˇennou, ve kter´e uchov´av´a id posledn´ı zobrazenen´e aktualizace. Pokud byla tˇesnˇe pˇred naˇs´ı aktualizac´ı uloˇzena aktualizace ciz´ı, id inkrementovat nem˚ uˇzeme, ale pravdˇepodobnˇe by n´am mˇela brzo pˇrij´ıt zpr´ava, kter´a bude obsahovat obˇe aktualizace. Ve skuteˇcnosti, pokud pr´avˇe odes´ıl´ame aktualizaci na server, zpracovn´an´ı pˇr´ıchoz´ı aktualizace je odloˇzeno a provede se po dokonˇcen´ı odes´ıl´an´ı naˇs´ı aktualizace (viz callback funkce jako hodnota parametru complete v AJAX poˇzadavku). Je tomu tak, aby pˇri dalˇs´ıch poˇzadavc´ıch na server byl parametr id nastaven na spr´avnou hodnotu podle toho, jakou posledn´ı aktualizaci m´ame skuteˇcnˇe zobrazenou. Naprogramoval jsem celkem tˇri form´aty aktualizac´ı, kter´e lze na server pos´ılat. • Obecn´y form´at - Tento typ form´atu zpr´av slouˇz´ı k pos´ıl´an´ı v´ıce ˇcar najednou. Ty jsou reprezentov´any jako s´erie bod˚ u. Kaˇzd´ y bod je reprezentov´an jeho souˇradnicemi. D´ale je ke kaˇzd´emu bodu uloˇzeno, zda m´a b´ yt spojen s pˇrechoz´ım bodem, a pˇr´ıpadnˇe jak tlustou ˇcarou a jak´a m´a b´ yt barva t´eto ˇca´ry. Tento form´at zpr´av je nyn´ı pouˇzit na str´ank´ach Frisky pro automatick´e vykreslen´ı souˇradn´ ych os po stisknut´ı pˇr´ısluˇsn´eho tlaˇc´ıtka na str´ance.
53
Knihovna pro komunikaci uˇzivatel˚ u
Galerie
• Speci´aln´ı form´at pro kreslen´ı - Slouˇz´ı k uloˇzen´ı informac´ı o jedn´e jednobarevn´e ˇc´aˇre jednotn´e tlouˇst’ky. To je ide´aln´ı pro potˇreby kreslen´ı myˇs´ı, kdy se aktualizace pos´ılaj´ı vˇzdy po dokreslen´ı jedn´e ˇca´ry. Form´at tedy obsahuje barvu a tlouˇst’ku ˇc´ary a souˇradnice vˇsech bod˚ u, jejichˇz spojen´ım se ˇc´ara vykresl´ı. • Smaz´an´ı obr´azku - Tento posledn´ı typ zpr´av slouˇz´ı k uloˇzen´ı informace o tom, ˇze se m´a smazat obsah canvasu. Maz´an´ı by ˇslo prov´est i jednoduˇse pouˇzit´ım jednoho z pˇredchoz´ıch typ˚ u form´at˚ u, kdy bychom zkr´atka uloˇzili b´ılou ˇca´ru, kter´a pˇrekresl´ı vˇse, co je nyn´ı na canvasu. Nakonec to i pˇri pˇr´ıjmu t´eto zpr´avy klient provede. Speci´aln´ı form´at jsem ale pouˇzil k tomu, aby server mohl pˇri pos´ıl´an´ı aktualizac´ı snadno detekovat, ˇze dan´a aktualizace maˇze vˇse na canvasu. Nen´ı tedy potˇreba, aby pos´ılal cokoliv, co bylo uloˇzeno pˇred n´ı. Na serveru jsou data ukl´ad´ana bez ohledu na pouˇzit´ y form´at do stejn´e tabulky datab´aze. Data poslan´a v jedn´e zpr´avˇe (typicky obsahuj´ıc´ı informace o jedn´e nakreslen´e ˇc´aˇre) jsou uloˇzena do jedn´e ˇra´dky tabulky. Data poslan´a v obecn´em form´atu jsou uloˇzena jako MySQL typ MEDIUMTEXT do jednoho sloupce tabulky. Zvl´aˇst je uloˇzena pouze d´elka ˇc´ar a typ zpr´avy. V pˇr´ıpadˇe speci´aln´ıho form´atu pro kreslen´ı ukl´ad´ame do jednoho sloupce souˇradnice vˇsech bod˚ u. Barvu a tlouˇst’ku ˇc´ary ale ukl´ad´am zvl´aˇst’ do jin´ ych sloupc˚ u tabulky. U zpr´avy informuj´ıc´ı o smaz´an´ı canvasu ukl´ad´am do datab´aze pouze pˇr´ısluˇsn´ y typ zpr´avy.
9.4
Galerie
Galerie tak´e pouˇz´ıv´a metodu long polling. Ta je pouˇzita k poˇc´ateˇcn´ımu naplnˇen´ı galerie a pak k z´ısk´av´an´ı novˇe uloˇzen´ ych obr´azk˚ u. Po pˇr´ıchodu na str´anku se do galerie st´ahne urˇcit´ y poˇcet nejnovˇejˇs´ıch obr´azk˚ u (z´aleˇz´ı na nastaven´ı knihovny). Na ˇz´adost uˇzivatele je moˇzn´e do galerie st´ahnout i starˇs´ı obr´azky. Ke stahov´an´ı starˇs´ıch obr´azk˚ u se uˇz pochopitelnˇe long polling nepouˇz´ıv´a. Klient od serveru vˇzdy nejprve z´ısk´av´a pouze informace o obr´azc´ıch, tj. identifik´ator obr´azku, popis, pˇrezd´ıvku autora a ˇcas uloˇzen´ı. Z´ıskan´e identifik´atory jsou pak pouˇzity klientem k sestaven´ı URL jednotliv´ ych obr´azk˚ u. Tyto URL jsou pak pouˇzity ke staˇzen´ı obr´azk˚ u. JavaScript obr´azky stahuje popoˇradˇe. Pˇri poˇca´teˇcn´ım naplnˇen´ı a pˇri stahov´an´ı starˇs´ıch obr´azk˚ u se obr´azky stahuj´ı od nejnovˇejˇs´ıho po nejstarˇs´ı. Pˇri stahov´an´ı novˇe uloˇzen´ ych obr´azk˚ u je tomu naopak. Po staˇzen´ı prvn´ıho obr´azku je tento vloˇzen do galerie a zaˇcne se stahovat dalˇs´ı obr´azek atd. K naˇc´ıt´an´ı obr´azk˚ u je tedy pouˇzita technika pˇrednaˇc´ıt´an´ı obr´azk˚ u (image preloading). Zdrojov´ y k´od pro pˇrednaˇcten´ı obr´azku vypad´a takto: img = new Image ( ) ; img . o n l o a d = f u n c t i o n ( ) { putImageIntoGallery () ;
54
Knihovna pro komunikaci uˇzivatel˚ u
Galerie
}; img . s r c = ”getImage . php? i d=”+c u r r i d ;
Tento k´od zaˇcne pˇrednaˇc´ıtat jeden obr´azek. Po dokonˇcen´ı naˇc´ıt´an´ı je tento vloˇzen do galerie funkc´ı putImageIntoGallery. Ta jako posledn´ı operaci zavol´a znovu funkci obsahuj´ıc´ı v´ yˇse uveden´ y k´od, ˇc´ımˇz se zaˇcne stahovat dalˇs´ı obr´azek v poˇrad´ı. Uˇzivatel knihovny si mus´ı nastavit rozmˇery galerie v poˇctu obr´azk˚ u a tak´e rozmˇery samotn´ ych obr´azk˚ u v galerii v poˇctu pixel˚ u. V souˇcasnosti je knihovna implementov´ana tak, ˇze jsou obr´azky stahov´any v pln´e velikosti, jejich zmenˇsen´ı na poˇzadovanou velikost prov´ad´ı webov´ y prohl´ıˇzeˇc na z´akladˇe atribut˚ u width a height elementu img. Kolik obr´azk˚ u se st´ahne do galerie po pˇr´ıchodu na str´anku nastavuje tak´e uˇzivatel knihovny. Pod galeri´ı je um´ıstˇen n´apis V´ıce“. Kdyˇz na nˇej uˇzivatel klepne, st´ahnou se do galerie ” dalˇs´ı starˇs´ı obr´azky. St´ahne se jich tolik, aby celkov´ y poˇcet obr´azk˚ u v galerii byl n´asobkem velikosti galerie (aktu´aln´ı poˇcet obr´azk˚ u nemus´ı b´ yt vˇzdy n´asobkem velikosti galerie, nebot’ do galerie pˇrib´ yvaj´ı novˇe uloˇzen´e obr´azky hned po jejich uloˇzen´ı). Na str´ank´ach Frisky se po klepnut´ı na libovoln´ y obr´azek v galerii nejprve schov´a kresl´ıc´ı pl´atno (canvas) a dalˇs´ı ovl´adac´ı prvky, a na jejich m´ıstˇe se dan´ y obr´azek zobraz´ı v pln´e velikosti. Pokud chceme obr´azek zase schovat, staˇc´ı na nˇej klepnout myˇs´ı (je jedno, jestli na jeho zvˇetˇsenou verzi, nebo na jeho menˇs´ı verzi v galerii). Oˇsetˇren´ı toho, co se m´a st´at po klepnut´ı na obr´azek v galerii, nen´ı ale souˇc´ast´ı knihovny a mˇel by si toto jej´ı uˇzivatel naprogramovat podle sv´eho uv´aˇzen´ı. Informace o obr´azku, tj. uˇzivatelsk´e jm´eno autora (pokud obr´azek uloˇzil nepˇrihl´aˇsen´ y uˇzivatel, je nastaveno jako Anonymous), datum uloˇzen´ı a popisek, zobrazuji jako tooltip po najet´ı myˇs´ı na dan´ y obr´azek v galerii. K vytvoˇren´ı tˇechto tooltip˚ u byla pouˇzita knihovna qTip 2.0, viz podkapitola 2.5.6. Ukl´ad´an´ı obr´azk˚ u je naprogramov´ano tak, ˇze klient z´ısk´a reprezentaci obr´azku na elementu canvas pouˇzit´ım funkce toDataUrl : document . getElementById ( ”canvas ”) . toDataURL ( ) ;
Data jsou z´ısk´ana ve form´atu data URL“, kter´ y je pops´an v RFC 2397. Tato data ” jsou n´aslednˇe na server zasl´ana AJAX dotazem. Na serveru jsou data pˇrevedena z textov´e podoby do bin´arn´ı odstranˇen´ım nepotˇrebn´eho zaˇca´tku obdrˇzen´eho ˇretˇezce, kter´ y obsahuje deklaraci typu dat, a n´asledn´ ym pouˇzit´ım PHP funkce base64 decode: $image = b a s e 6 4 d e c o d e ( s t r r e p l a c e ( ’ data : image /png ; base64 , ’ , ’ ’ , $dataUrl ) ) ;
Z´ıskan´ y PNG obr´azek je pak uloˇzen do datab´aze. Vzhled galerie na str´ank´ach Frisky si m˚ uˇzete prohl´ednout na obr´azku 9.2. 55
Knihovna pro komunikaci uˇzivatel˚ u
Chat
Obr´azek 9.2: Galerie
9.5
Chat
Chat je opˇet zaloˇzen na metodˇe long polling. Po pˇr´ıchodu na str´anku je uˇzivateli zobrazena historie posledn´ıch zpr´av. Maximum zpr´av, kter´e jsou uˇzivateli na poˇca´tku posl´any, definuje uˇzivatel knihovny. Stejnˇe tak definuje, jak daleko do minulosti m˚ uˇze tato historie sahat. Z´ısk´av´an´ı zpr´av od ostatn´ıch uˇzivatel˚ u funguje podobnˇe jako z´ısk´av´an´ı aktualizac´ı kreslen´ı. Jedin´ ym rozd´ılem je to, ˇze se nezajiˇst’uje konzistentnost poˇrad´ı zobrazen´ ych zpr´av. Je tomu tak, protoˇze jsem chtˇel, aby zpoˇzdˇen´ı mezi odesl´an´ım zpr´avy a jej´ım zobrazen´ım v chatu autora zpr´avy bylo nulov´e. To znamen´a, ˇze klient neˇcek´a pˇri odesl´an´ı zpr´avy na potrvzen´ı od serveru, ˇze tˇesnˇe pˇred pˇrijet´ım naˇs´ı zpr´avy nepˇrijal zpr´avu od nˇekoho jin´eho, kter´a by se tedy pro zachov´an´ı konzistence mˇela zobrazit v chatu nad naˇs´ı zpr´avou. Vloˇzit takovou zpr´avu dodateˇcnˇe nad tu naˇsi by tak´e nebylo vhodn´e, nebot’ pak by ji mohl uˇzivatel pˇrehl´ednout. Toto rozhodnut´ı 56
Knihovna pro komunikaci uˇzivatel˚ u
Zobrazen´ı pˇrihl´aˇsen´ych uˇzivatel˚ u
jsem uˇcinil, nebot’ si mysl´ım, ˇze tato nekonzistentnost nezp˚ usobuje ˇza´dn´e probl´emy. Zpr´avy od ostatn´ıch uˇzivatel˚ u budou zobrazeny vˇzdy v takov´em poˇrad´ı, v jak´em je server uloˇzil. V chatu je vˇzdy pˇred zpr´avou zobrazen´e uˇzivatelsk´e jm´eno uˇzivatele, kter´ y je jej´ım autorem, a ˇcas odesl´an´ı zpr´avy. Pokud nen´ı autor zpr´avy pˇrihl´aˇsen, je m´ısto uˇzivatelsk´eho jm´ena vyps´ano slovo Anonymous. Jm´eno autora a ˇcas u zpr´avy maj´ı zelenou barvu, pokud je uˇzivatel autorem dan´e zpr´avy. V opaˇcn´em pˇr´ıpadˇe maj´ı ˇcervenou barvu. Pro pˇrihl´aˇsen´e uˇzivatele toto plat´ı i v zobrazen´e historii chatu po opˇetovn´em naˇcten´ı str´anky. V tomto ohledu je knihovna pˇrizp˚ usobena speci´alnˇe pro fungov´an´ı na str´ank´ach Frisky, kde je povoleno b´ yt pˇrihl´aˇsen pˇres syst´em Orion nebo pˇres m´ıstn´ı registraci. Kdyˇz uˇzivatel nap´ıˇse zpr´avu, je do datab´aze tak´e uloˇzeno, jak´ ym zp˚ usobem byl jej´ı autor pˇrihl´aˇsen. Uˇzivatel je povaˇzov´an za pˇrihl´aˇsen´eho, pokud nalezneme jeho uˇzivatelsk´e jm´eno bud’ v promˇenn´e $ SESSION[”login”] (m´ıstn´ı registrace) nebo v promˇenn´e $ SERVER[’WEBAUTH USER’] (Orion login). JavaScript tak´e potˇrebuje vˇedˇet o tom, jak´e je uˇzivatelsk´e jm´eno m´ıstn´ıho uˇzivatele. Rozhodl jsem, ˇze v pˇr´ıpadˇe, kdy je uˇzivatel pˇrihl´aˇsen pˇres m´ıstn´ı registraci, bude uˇzivatelsk´e jm´eno vyps´ano v HTML elementu s id usernameLocal. Pokud je uˇzivatel pˇrihl´aˇsen pˇres syst´em Orion, mˇelo by b´ yt uvnitˇr elementu s id usernameOrion. Chat je oˇsetˇren proti SQL a HTML injection stejn´ ym zp˚ usobem jako napˇr. formul´aˇre pro registraci na str´ank´ach Frisky, tj. pouˇzit´ım prepared statements a PHP funkce strip tags.
9.6
Zobrazen´ı pˇ rihl´ aˇ sen´ ych uˇ zivatel˚ u
Posledn´ı ˇca´st´ı knihovny je zobrazen´ı uˇzivatelsk´ ych jmen pˇrihl´aˇsen´ ych uˇzivatel˚ u, kteˇr´ı jsou pr´avˇe pˇr´ıtomni na dan´e str´ance. K dosaˇzen´ı t´eto funkcionality je potˇreba sd´ılet data mezi procesy. Rozhodl jsem se tedy pouˇz´ıt prostˇredky jazyka PHP pro pr´aci se sd´ılenou pamˇet´ı. Ve sd´ılen´e pamˇeti si ukl´ad´am celkem dvˇe promˇenn´e. Jedna je asociativn´ı pole, kde kl´ıˇcem je uˇzivatelsk´e jm´eno a hodnotou je ˇcasov´a znaˇcka, kdy jsme naposledy od dan´eho uˇzivatele dostali dotaz. Druhou promˇennou je identifik´ator posledn´ı zmˇeny, kter´ y je pˇri kaˇzd´e zmˇenˇe seznamu inkrementov´an. Kaˇzd´ y klient pos´ıl´a na server dotaz alespoˇ n kaˇzd´ ych 45 sekund. Pˇri pˇr´ıjmu tohoto dotazu je do sd´ılen´e pamˇeti uloˇzena informace o uˇzivateli, kter´ y dotaz poslal (pokud je pˇrihl´aˇsen). Pokud uˇzivatel v seznamu jeˇstˇe nen´ı, je uloˇzeno jeho uˇzivatelsk´e jm´eno spolu s aktu´aln´ı ˇcasovou znaˇckou a je inkrementov´an
57
Knihovna pro komunikaci uˇzivatel˚ u
Zobrazen´ı pˇrihl´aˇsen´ych uˇzivatel˚ u
identifik´ator posledn´ı zmˇeny. Jinak je pouze aktualizov´ana ˇcasov´a znaˇcka pˇr´ısluˇsej´ıc´ı k dan´emu uˇzivatelsk´emu jm´enu. K distribuci zmˇen seznamu pˇrihl´aˇsen´ ych uˇzivatel˚ u je opˇet pouˇzita metoda long polling. Skript na serveru pravidelnˇe proch´az´ı cel´e asociativn´ı pole uloˇzen´e ve sd´ılen´e pamˇeti a odstraˇ nuje z nˇej uˇzivatelsk´a jm´ena vˇsech uˇzivatel˚ u, od kter´ ych jsme uˇz d´ele neˇz 60 sekundy nedostali ˇz´adn´ y dotaz. Pokud jsme pˇri t´eto akci smazali nˇekter´eho uˇzivatele ze seznamu, inkrementujeme tak´e identifik´ator posledn´ı zmˇeny. Klient pˇri sv´ ych dotazech pos´ıl´a identifik´ator posledn´ı zmˇeny seznamu, kterou m´a zobrazenou. Pokud nen´ı shoda mezi identifik´atorem poslan´ ym od klienta a aktu´aln´ım identifik´atorem, zaˇsleme klientovi cel´ y aktu´aln´ı seznam pˇrihl´aˇsen´ ych uˇzivatel˚ u. V´ ysledn´ y vzhled cel´eho kreslen´ı na str´ank´ach Frisky je vidˇet na obr´azku 9.3.
Obr´azek 9.3: Kreslen´ı se vˇsemi doplˇ nky
N´avod na pouˇzit´ı knihovny naleznete v pˇr´ıloze G.
58
Knihovna pro komunikaci uˇzivatel˚ u
9.7
Navrhovan´a budouc´ı vylepˇs´ı knihovny
Navrhovan´ a budouc´ı vylepˇ s´ı knihovny
• Agregace zpr´av. Napˇr. aktualizace kreslen´ı a aktualizace galerie se pos´ılaj´ı v samostatn´ ych zpr´av´ach. V´ yhodn´e by bylo spojovat je do jedn´e zpr´avy, pokud je to v aktu´aln´ı situaci moˇzn´e. • Podpora tˇr´ıdˇen´ı obr´azk˚ u v galerii podle kategori´ı. • Odstraˇ nov´an´ı obr´azk˚ u z galerie pˇr´ımo ve webov´em rozhran´ı (v souˇcasnosti lze obr´azky mazat pouze pˇr´ımo z datab´aze). • Stahov´an´ı obr´azk˚ u do galerie v miniaturn´ı velikosti.
59
10 Z´avˇer V r´amci diplomov´e pr´ace jsem se nejprve sezn´amil s technologiemi, kter´e se pouˇz´ıvaj´ı k tvorbˇe webov´ ych str´anek. Konkr´etnˇe se jedn´a o jazyky JavaScript (spolu s knihovnou jQuery) a PHP, kter´e byly pouˇzity pˇri dalˇs´ı pr´aci. Sezn´amil jsem se tak´e s n´astrojem Adobe Flash, kter´ y ale nakonec nebyl pouˇzit, protoˇze pro zadanou pr´aci byly vhodnˇejˇs´ı jin´e prostˇredky. V teoretick´e ˇca´sti pr´ace jsem d´ale zmapoval oblast bezpeˇcnosti webu. Sezn´amil jsem ˇcten´aˇre s r˚ uzn´ ymi aspekty bezpeˇcnosti a s hlavn´ımi typy u ´tok˚ u. V prvn´ı f´azi praktick´e ˇca´sti diplomov´e pr´ace jsem provedl anal´ yzu webov´ ych str´anek Frisky. V r´amci t´eto anal´ yzy jsem identifikoval nedostatky str´anek a pot´e jsem navrhl jejich ˇreˇsen´ı. Pˇri n´asledn´e realizaci byl nejprve vytvoˇren nov´ y jednotn´ y layout str´anek. D´ale byla implementov´ana registrace a pˇrihlaˇsov´an´ı uˇzivatel˚ u a tak´e moˇznost pˇresunu obsahu jednotliv´ ych str´anek na jin´ y server. Pˇri implementaci bylo db´ano na pravidla bezpeˇcnosti, tj. aby uˇzivatel´e nemohli ve formul´aˇr´ıch odeslat data, kter´a by slouˇzila k napaden´ı serveru nebo jeho ostatn´ıch uˇzivatel˚ u. V dalˇs´ı f´azi byla provedena anal´ yza hry Puzzle. Byly nalezeny zp˚ usoby, jak´ ymi bylo moˇzn´e v t´eto hˇre podv´adˇet. Na z´akladˇe anal´ yzy byly n´aslednˇe jednotliv´e probl´emy odstranˇeny. D´ale jsem implementoval rozhran´ı pro ukl´ad´an´ı v´ ysledk˚ u a pro z´ısk´av´an´ı v´ ysledk˚ u v HTML podobˇe. Toto rozhran´ı bylo u ´spˇeˇsnˇe nasazeno. V posledn´ı f´azi praktick´e ˇca´sti pr´ace jsem navrhl a implementoval knihovnu pro komunikaci uˇzivatel˚ u na webov´ ych str´ank´ach. Knihovna obsahuje nˇekolik komponent: kreslen´ı, galerii, chat a zobrazen´ı seznamu pˇrihl´aˇsen´ ych uˇzivatel˚ u pˇr´ıtomn´ ych na str´ance. Libovoln´e komponenty knihovny lze nasadit na jak´ekoliv str´ance. Knihovna je nyn´ı nasazena na str´ank´ach Frisky na samostatn´e str´ance, kde umoˇzn ˇuje komunikaci vˇsech n´avˇstˇevn´ık˚ u. Vˇsechny poˇzadavky zadavatele byly u ´spˇeˇsnˇe splnˇeny. Rozhran´ı pro ukl´ad´an´ı v´ ysledk˚ u her, knihovna pro komunikaci n´avˇstˇevn´ık˚ u i layout str´anek Frisky byly nasazeny. V kapitole 9.7 navrhuji budouc´ı rozˇs´ıˇren´ı a vylepˇsen´ı komunikaˇcn´ı knihovny. KMA uvaˇzuje, ˇze v budoucnu budou tato rozˇs´ıˇren´ı implementov´ana.
60
Seznam pouˇ zit´ ych zkratek • AJAX - Asynchronous JavaScript and XML. • API - Application programming interface. • CPU - Central processing unit. • CRC - Cyclic redundancy check. • CSS - Cascading Style Sheets. • DDoS - Distributed denial-of-service. • DOM - Document Object Model • DoS - Denial-of-service. • HTML - HyperText Markup Language. • IIS - Internet Information Services, dˇr´ıve Internet Information Server. • IP - Internet Protocol. • KMA - Katedra matematiky. • MAC - Message authentication code. • MSN - The Microsoft Network. • PHP - PHP: Hypertext Preprocessor. • SQL - Structured Query Language. • SW - Software. • SWF - Small Web Format. • URL - Uniform resource locator.
61
Seznam pouˇ zit´ e literatury [1] CHAPMAN, Stephen. A Brief History of Javascript [online]. [cit. 15. z´aˇr´ı 2011]. URL:
. [2] JavaScript Tutorial [online]. [cit. 2. ˇr´ıjna 2011]. URL: . [3] DOYLE, Matt. Events and Event Handlers [online]. Zveˇrejnˇeno 11.12. 2001 [cit. 6. ˇr´ıjna 2011]. URL: . [4] jQuery Tutorial [online]. [cit. 20. listopadu 2011]. URL: . [5] Ajax (programming) [online]. [cit. 26. listopadu 2011]. URL: . [6] jQuery.ajax() [online]. [cit. 25. listopadu 2011]. URL: . [7] qTip 2 jQuery plugin [online]. [cit. 21. u ´nora 2012]. URL: . [8] History of PHP [online]. [cit. 20. ˇr´ıjna 2011]. URL: . [9] PHP Tutorial [online]. [cit. 21. ˇr´ıjna 2011]. URL: . [10] GAY, Jonathan. The History of Flash [online]. [cit. 23. ˇr´ıjna 2011]. URL: . [11] Adobe Flash [online]. [cit. 27. ˇr´ıjna 2011]. URL: .
62
ˇ E ´ LITERATURY SEZNAM POUZIT
ˇ E ´ LITERATURY SEZNAM POUZIT
[12] DASWANI, Neil - KERN, Christoph - KESAVAN, Anita. Foundations of Security: What Every Programmer Needs to Know. 1. vyd´an´ı. [United States of America]: Apress, 2007. ISBN-13 (pbk): 978-1-59059-784-2. [13] How to Find or Validate an Email Address [online]. Posledn´ı u ´prava 2. 12. 2010 [cit. 10. u ´nora 2012]. URL: . [14] MALONE, William. Create a Drawing App with HTML5 Canvas and JavaScript [online]. [cit. 12. bˇrezna 2011]. URL: .
63
Pˇ r´ılohy
64
A Obsah DVD Adres´aˇrov´a struktura DVD pˇriloˇzen´eho k t´eto pr´aci, vypad´a n´asledovnˇe: • - doc - zde naleznete diplomovou pr´aci v elektronick´e podobˇe. Adres´aˇr doc obsahuje tyto podadres´aˇre: – pdf - obsahuje diplomovou pr´aci ve form´atu PDF. – src - obsahuje zdrojov´e soubory pro vygenerov´an´ı pr´ace programem TeX. • - src - zde se nach´az´ı programov´e vybaven´ı vytvoˇren´e v r´amci t´eto diplomov´e pr´ace. Obsahuje tyto podadres´aˇre: – lib - zde je v podadres´aˇri komunikacni knihovna um´ıstˇena knihovna pro komunikaci uˇzivatel˚ u webov´ ych str´anek, viz kapitola 9. V podadres´aˇri uklaydani vysledku naleznete program´atorsk´e rozhran´ı pro ukl´ad´an´ı hern´ıch v´ sledk˚ u a pro z´ısk´av´an´ı nejlepˇs´ıch v´ ysledk˚ u v HTML form´atu. V´ıce o tomto rozhran´ı naleznete v kapitole 8. – php - zde naleznete uk´azky nasazen´ı vytvoˇren´ ych program´atorsk´ ych prostˇredk˚ u um´ıstˇen´ ych ve v´ yˇse popsan´em adres´aˇri lib. V podadres´aˇri drawing se nach´az´ı uk´azka nasazen´ı knihovny pro komunikaci uˇzivatel˚ u webov´ ych str´anek. V podadres´aˇri Puzzle naleznete hru, kter´a pouˇz´ıv´a vytvoˇren´e rozhran´ı pro ukl´ad´an´ı a zveˇrejˇ nov´an´ı v´ ysledk˚ u. Tato hra byla tak´e oˇsetˇrov´ana proti podv´adˇen´ı, viz kapitola 7. – sql - zde jsou um´ıstˇeny SQL skripty pro vytvoˇren´ı datab´azov´ ych tabulek, kter´e pro sv´e fungov´an´ı potˇrebuje knihovna pro komunikaci uˇzivatel˚ u a rozhran´ı pro ukl´ad´an´ı a zveˇrejˇ nov´an´ı v´ ysledk˚ u her.
65
B Galerie - uk´azka tvorby animac´ı s knihovnou jQuery jQuery . n o C o n f l i c t ( ) ; jQuery ( document ) . ready ( f u n c t i o n ( ) { probihaAnimace = f a l s e ; idZvetsenehoObrazku = ” ” ; sirkaObrazku = 150; vyskaObrazku = 1 0 2 ; okrajObrazku = 10 pocetObrazkuVGalerii = 4 ; sirkaZvetsenehoObrazku = 500; vyskaZvetsenehoObrazku = 3 4 2 ; poziceZvetsenehoObrazkuX = ( p o c e t O b r a z k u V G a l e r i i ∗ ( s i r k a O b r a z k u+ okrajObrazku ) −okrajObrazku − s i r k a Z v e t s e n e h o O b r a z k u ) / 2 ; poziceZvetsenehoObrazkuY = vyskaObrazku + 2 0 ; idZvetsenehoObrazku = null ; jQuery ( ” . k o t a t a ”) . c l i c k ( f u n c t i o n ( ) { i f ( ! probihaAnimace ) { probihaAnimace = true ; var idObrazku = jQuery ( t h i s ) . a t t r ( ” i d ”) ;
// k l e p n u l − l i u ˇz i v a t e l na p r ´ a vˇe z v ˇe tˇs e n ´y // o b r ´ a z e k , o pˇe t j e j zmenˇs´ıme // a v r ´ a t´ım e na p˚ u vo d n´ı p o z i c i i f ( idObrazku == idZvetsenehoObrazku ) { zmensiAVratObrazek ( idObrazku , f u n c t i o n ( ) { idZvetsenehoObrazku = null ; probihaAnimace = f a l s e ; }) ; } else { // j e p r ´ a vˇe z v ˇe tˇs e n j i n ´y o b r ´ azek , // neˇz k t e r ´y c h c e u ˇz i v a t e l ?
66
Galerie - uk´azka tvorby animac´ı s knihovnou jQuery
i f ( idZvetsenehoObrazku != null ) { // pokud ano , zmenˇseme j e j a vrat’me j e j // na p˚ u vo d n´ı p o z i c i zmensiAVratObrazek ( idZvetsenehoObrazku , f u n c t i o n ( ) { // pak m˚ uˇzeme v y b r a n´y o b r ´ azek vyndat // z g a l e r i e a z v ˇe t ˇs i t p r e m i s t i A Z v e t s i O b r a z e k ( idObrazku , f u n c t i o n ( ) { idZvetsenehoObrazku = idObrazku ; probihaAnimace = f a l s e ; }) ; }) ; } else { //ˇz ´ a dn´y o b r a ´ z e k n e n´ı a k t u ´ a l n ˇe z v ˇe tˇs e n ´y //muˇzeme t e d y rovnou v y b r a n´y o b r a ´zek // v y n d a t z g a l e r i e a z v ˇe t ˇs i t p r e m i s t i A Z v e t s i O b r a z e k ( idObrazku , f u n c t i o n ( ) { idZvetsenehoObrazku = idObrazku ; probihaAnimace = f a l s e ; }) ; } } } }) ; // zmenˇs´ı o b r ´ azek a v r ´ a t´ı j e j na j e h o p˚ u vo d n´ı // p o z i c i v g a l e r i i f u n c t i o n zmensiAVratObrazek ( idObrazku , c a l l b a c k ) { // na ˇc ´ı s l a v i d o b r ´ a z k u urˇc´ıme j e h o p˚ u vo d n´ı // p o z i c i var puvodniPoziceX = ( p a r s e I n t ( idObrazku . s u b s t r i n g ( 4 ) ) −1) ∗ ( s i r k a O b r a z k u+okrajObrazku ) ; var puvodniPoziceY = 0 ; // zmenˇs´ıme o b r ´ a z e k do p˚ uv o d n´ı v e l i k o s t i jQuery ( ”#”+idObrazku ) . animate ( { width : sirkaObrazku , h e i g h t : vyskaObrazku } , 1 0 0 0 , f u n c t i o n ( ) { // pˇr esuneme o b r ´ a z e k na j e h o p˚ uv o d n´ı X p o z i c i jQuery ( ”#”+idObrazku ) . animate ( { l e f t : puvodniPoziceX } , 1000 , f u n c t i o n ( ) { // zasuneme o b r ´ a z e k do g a l e r i e jQuery ( ”#”+idObrazku ) . animate ( { top : puvodniPoziceY } , 500 , f u n c t i o n ( ) {
67
Galerie - uk´azka tvorby animac´ı s knihovnou jQuery
// z d e j e v i d ˇe t z a v o l ´ a n´ı c a l l b a c k f u n k c e , // pokud b y l a nˇe j a k ´ a zad´ a na i f ( t y p e o f c a l l b a c k == ’ f u n c t i o n ’ ) { c a l l b a c k . c a l l ( this ) ; } }) ; }) ; }) ; } // v y b e r e o b r ´ a z e k z g a l e r i e a z v ˇe t ˇs´ı ho f u n c t i o n p r e m i s t i A Z v e t s i O b r a z e k ( idObrazku , c a l l b a c k ) { // v y t ´ ahni obr´ azek z g a l e r i e jQuery ( ”#”+idObrazku ) . animate ( { top : poziceZvetsenehoObrazkuY } , 500 , functio n ( ) { // pˇr es u n ˇ obr´ a z e k na c´ı l o v o u X p o z i c i t ak , // aby b y l u p r o s tˇr e d g a l e r i e jQuery ( ”#”+idObrazku ) . animate ( { l e f t : poziceZvetsenehoObrazkuX } , 1000 , f u n c t i o n ( ) { // z v ˇe t ˇs i o b r ´ azek jQuery ( ”#”+idObrazku ) . animate ( { width : s i r k a Z v e t s e n e h o O b r a z k u , h e i g h t : vyskaZvetsenehoObrazku } , 1 0 0 0 , f u n c t i o n ( ) { // z d e j e v i d ˇe t z a v o l ´ a n´ı c a l l b a c k f u n k c e , // pokud b y l a nˇe j a k ´ a zad´ a na i f ( t y p e o f c a l l b a c k == ’ f u n c t i o n ’ ) { c a l l b a c k . c a l l ( this ) ; } }) ; }) ; }) ; } }) ;
Vzhled galerie ilustruje Obr´azek B.1.
68
Galerie - uk´azka tvorby animac´ı s knihovnou jQuery
Obr´azek B.1: Galerie
69
C Vzor pro vˇetˇsinu str´anek na Frisky Zde uk´aˇzi vzor PHP skriptu, kter´ y lze na Frisky pouˇz´ıt k vytvoˇren´ı pr´azdn´e str´anky o ˇs´ıˇrce 1020 px, kter´a ale obsahuje vˇsechny prvky layoutu: <meta http−e q u i v=”Content−Type ” c o n t e n t=” t e x t / html ; c h a r s e t=u t f −8 ” /> < s c r i p t type= ’ t e x t / j a v a s c r i p t ’ s r c= ’ . . / s y s / j q u e r y . min . j s ’> < s c r i p t type= ’ t e x t / j a v a s c r i p t ’ s r c= ’ . . / s y s /menu . j s ’> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” . . / j q u e r y . e a s i n g . 1 . 3 . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” . . / s y s / G r o j e c t . ImageSwitch . y u i . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” . . / s y s / e u l o g o . j s ”> < s c r i p t type=” t e x t / j a v a s c r i p t ” s r c=” . . / s y s / l o g i n b o x . j s ”>   ;