ajax a php

54
E N C Y K L O P E D I E W E B D E S I G N E R A www.zonerpress.cz AJAX a PHP tvoříme interaktivní webové aplikace PROFESIONÁLNĚ Cristian Darie, Bogdan Brinzarea, Filip Cherecheş-Toşa, Mihai Bucica © Foto: Jiří Heller

Upload: zoner-software-as

Post on 10-Mar-2016

237 views

Category:

Documents


3 download

DESCRIPTION

Ajax a PHP

TRANSCRIPT

Page 1: Ajax a PHP

AJA

X a

PH

Ptv

ořím

e in

tera

ktiv

web

ové

aplik

ace

PRO

FESI

ON

ÁLN

Ě

E N C Y K L O P E D I E W E B D E S I G N E R A

ENCYKLOPEDIE WEBDESIGNERACristian Darie, Bogdan Brinzarea, Filip Cherecheş-Toşa, Mihai Bucica

AJAX a PHPtvoříme interaktivní webové aplikace

Zoner Press tel.: 532 190 883 fax: 543 257 245e-mail: [email protected]://www.zonerpress.cz

ZONER software, s.r.o., Nové sady 18, 602 00 Brno

Kniha vás zavede do vzrušujícího světa moderního budování webových aplikací a umožní vám vytvářet skutečně interaktivní webové stránky, které budou schopny okamžitě reagovat na akce prováděné uživatelem bez nutnosti jejich opětovného načítání. Autoři se zaměřili velmi prakticky na možnosti jak v AJAXu psát efektivní kód, jak dosáhnout funkcionality, která vám dovolí snadno integrovat vaše řešení do současných i budoucích webových apli-kací. Kniha tak obsahuje vedle množství obecných informací, také velmi praktické a do detailu předvedené příklady a ukázky řešení. Po úvodní kapitole, která je úvodem do světa AJAXu, rychle přejdete k obecným technologiím JavaScript, DOM, objekt XMLHttpRequest a XML, které se používají k vytváření webových klientů AJAXu. V další části vstoupíte do světa PHP a MySQL. Mimo jiné se např. dozvíte, jak zkontrolovat platnost dat, která byla uživatelem vlo-žena do webového formuláře, jak si naprogramovat vlastní chat v AJAXu, jak do formulářů doplnit funkci automatického dokon-čování (což je obdoba funkce Autocomplete v Internet Exploreru), jak vytvářet editovatelné části stránek a jak prostřednictvím AJAXu zprovoznit vlastní agregátor RSS nebo jak v reálném čase genero-vat graf založený na SVG a jak do stránek implementovat funkci pro přetahování položek pomocí myši (drag-and-drop).

Zdrojové soubory k této knize je možné získat na adrese vydavatelství www.zonerpress.cz/download/ajax.zip.

E N C Y K L O P E D I E W E B D E S I G N E R A

Pod tímto logem vycházejí publikace určené pro každého, kdo se zajímá o tvorbu webových stránek. Od ryze praktických příruček a průvodců až po komplexní publikace o všem, co potřebuje web-designér při každodenní práci. Na vydavatelský plán a výhody, kte-ré můžete získat, se informujte na adrese vydavatelství.

Věrným čtenářům je určen výhodný PRÉMIOVÝ PLUS PROGRAM.

www.zonerpress.cz

AJAX a PHP

© F

oto:

Jiří

Hel

ler,

ww

w.h

elle

r.cz

Foto

grafi

e z

nabí

dky

foto

bank

y H

ELLE

R.CZ

tvoříme interaktivní webové aplikace

PROFESIONÁLNĚ

Cristian Darie, Bogdan Brinzarea, Filip Cherecheş-Toşa, Mihai Bucica

© Foto: Jiří Heller

PROFESIONÁLNĚ

Dar

ie, B

rinza

rea,

Cher

eche

ş-To

şa, B

ucic

a

9 7 8 8 0 8 6 8 1 5 4 7 3

ISBN 80-86815-47-1KATALOGOVÉ ČÍSLO: ZR614DOPORUČENÁ CENA: 290 KČ

ZONER software, s.r.o. významný producent software v oblasti digitální fotografie,

počítačové grafiky a multimédií, poskytovatel internetových

služeb, souvisejících s prezentací na internetu a e-komercí,

a nakladatelství odborné literatury.

www.zoner.cz

Page 2: Ajax a PHP

AJAX a PHPtvoříme interaktivní

webové aplikace

PROFESIONÁLNĚ

Cristian Darie

Bogdan Brinzarea

Filip Cherecheş-Toşa

Mihai Bucica

Page 3: Ajax a PHP

Ajax and PHP: Building Responsive Web ApplicationsCristian Darie, Bogdan Brinzarea, Filip Cherecheş-Toşa, Mihai Bucica

Copyright © Packt Publishing 2006. First published in the English language under the title Ajax and PHP: Building Respon-sive Web Applications.

No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Packt Publishing.

Copyright © Packt Publishing 2006. První vydání v anglickém jazyce vyšlo pod názvem Ajax and PHP: Building Responsive Web Applications.

Žádná část této publikace nesmí být reprodukována nebo předávána žádnou formou nebo způsobem, elektronicky ani mecha-nicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení Packt Publishing.

AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚAutoři: Cristian Darie, Bogdan Brinzarea, Filip Cherecheş-Toşa a Mihai Bucica

Copyright © ZONER software, s.r.o. Vydání první v roce 2006. Všechna práva vyhrazena.

Zoner PressKatalogové číslo: ZR614

ZONER software, s.r.o.Nové sady 18, 602 00 Brno

Překlad: Roman SkřivánekOdpovědný redaktor: Miroslav KučeraŠéfredaktor: Ing. Pavel Kristián

DTP: Miroslav Kučera© Cover foto: Jiří Heller, HELLER.CZ s.r.o, www.heller.cz

Informace, které jsou v této knize zveřejněny, mohou byt chráněny jako patent. Jména produktů byla uvedena bez záruky jejich volného použití. Při tvorbě textů a vyobrazení bylo sice postupováno s maximální péčí, ale přesto nelze zcela vyloučit možnost výskytu chyb. Vydavatelé a autoři nepřebírají právní odpovědnost ani žádnou jinou záruku za použití chybných údajů a z toho vyplývajících důsledků. Všechna práva vyhrazena. Žádná část této publikace nesmí být reprodukována ani dis-tribuována žádným způsobem ani prostředkem, ani reprodukována v databázi či na jiném záznamovém prostředku či v jiném systému bez výslovného svolení vydavatele, s výjimkou zveřejnění krátkých částí textu pro potřeby recenzí.

Veškeré dotazy týkající se distribuce směřujte na:

Zoner Press ZONER software, s.r.o. Nové sady 18, 602 00 Brno

tel.: 532 190 883, fax: 543 257 245 e-mail: [email protected] http://www.zonerpress.cz

ISBN 80-86815-47-1

Page 4: Ajax a PHP

3

Obsah O autorech 6

O odborných recenzentech 6

Úvod 7

Co tato kniha obsahuje 8

Co potřebujete ke studiu této knihy 9

Konvence 9

Sdělte nám svůj názor 10

Zdrojové soubory 10

Kapitola 1 AJAX a budoucnost webových aplikací 11

Přenos funkcionality prostřednictvím webu 12

Přínosy webových aplikací 13

Tvorba webových stránek před rokem 1990 14

HTTP a HTML 14

PHP a další technologie na straně serveru 15

JavaScript a další technologie na straně klienta 16

Co chybí? 17

Porozumění AJAXu 18

Vytvoření jednoduché aplikace pomocí AJAXu a PHP 22

Závěr 34

Kapitola 2 Techniky na straně serveru založené na JavaScriptu 35

JavaScript a objektový model dokumentu 36

Události JavaScriptu a DOM 40

Ještě více DOMu 44

JavaScript, DOM a CSS 47

Použití objektu XMLHttpRequest 51

Vytvoření objektu XMLHttpRequest 51

Inicializace požadavků na server pomocí XMLHttpRequest 56

Zpracování odpovědi serveru 59

Práce se strukturami XML 67

Ošetření dalších chyb a generování výjimek 73

Vytváření XML struktury 76

Závěr 77

Kapitola 3 Techniky na straně serveru s PHP a MySQL 79

PHP a DOM 79

Page 5: Ajax a PHP

4

Vkládání parametrů a ošetřování chyb PHP 86

Připojení ke vzdáleným serverům a bezpečnost JavaScriptu 96

Použití zástupného skriptu na serveru 102

Pracovní rámec pro tvorbu opakovaných asynchronních požadavků 109

Práce s MySQL 121

Vytváření databázových tabulek 122

Manipulace s daty 125

Připojení k databázi a provádění dotazů 126

Zabalení funkcionality a rozvržení struktury 131

Závěr 144

Kapitola 4 Ověřování formulářových dat pomocí AJAXu 145

Implementace kontroly formulářů pomocí AJAXu 146

AJAX bezpečný vůči vláknům 149

Závěr 174

Kapitola 5 Chat v AJAXu 175

Úvod do ajaxového chatu 175

Již existující chaty v AJAXu 176

Implementace ajaxového chatu 177

Závěr 198

Kapitola 6 Návrhy a automatické dokončování v AJAXu 199

Úvod do návrhů a automatického dokončování v AJAXu 200

Google Suggest 200

Implementace návrhů a automatického dokončování v AJAXu 201

Závěr 226

Kapitola 7 Tvorba grafů v reálném čase pomocí SVG 227

Implementace grafů v reálném čase pomocí AJAXu a SVG 228

Závěr 242

Kapitola 8 Mřížky v AJAXu 243

Implementace mřížky v AJAXu pomocí XSLT na straně klienta 244

Závěr 268

Kapitola 9 Čtečka RSS 269

Pracujeme s RSS 269

Page 6: Ajax a PHP

5

Struktura RSS dokumentu 270

Google Reader 271

Implementace čtečky RSS pomocí AJAXu 271

Závěr 285

Kapitola 10 Přetahování myší 287

Použití přetahování myší na webu 287

Nákupní košík 288

Seřaditelné seznamy 288

Tvorba AJAXové aplikace seznamu s přetahovatelnými položkami 289

Závěr 306

Příloha A Příprava pracovního prostředí 307

Příprava pro Windows 308

Instalace Apache 308

Instalace MySQL 310

Instalace PHP 310

Příprava pro Unix 312

Instalace Apache 312

Instalace MySQL 313

Instalace PHP 313

Instalace phpMyAdmin 314

Příprava ajaxové databáze 316

Page 7: Ajax a PHP

6

O autorechCristian Darie je softwarový inženýr, který má zkušenosti se širokým spektrem moderních tech-nologií a je autorem mnoha technicky zaměřených knih, například populární série "Beginning E--Commerce". S počítači pracuje od dob, kdy byl schopen mačkat klávesy; prvních úspěchů v pro-gramování dosáhl na programátorské soutěži ve věku 12 let. Od té doby dosáhl Cristian mnoha dalších úspěchů. V současné době postgraduálně studuje distribuované architektury aplikací. Má rád reakce na své knihy, a proto neotálejte, a když budete mít chvilku času, pošlete mu zprávu. Cris-tiana lze kontaktovat prostřednictvím jeho osobní stránky na adrese www.cristiandarie.ro.

Chtěl bych vyjádřit své poděkování svým spoluautorům – Bogdanovi, Filipovi a Mihaimu, a technické-mu editorovi knihy Jimmymu za mnoho úsilí, vynaloženého na tvorbu této úžasné knihy. Cristian

Bogdan Brinzarea má v informatice silné zázemí – je držitelem magisterského a bakalářského di-plomu z Fakulty automatického řízení a počítačů Polytechnické univerzity v Bukurešti v Rumun-sku a také auditorského diplomu z Ústavu počítačových věd na polytechnice v Paříži ve Francii. Jeho zájmy obsahují začleněné programování (embedded programming), distribuované a mobilní systémy a nové webové technologie. V současné době je zaměstnán na pozici Alternative Channels Specialist v bance Romaneasca, která je členem National Bank of Greece. Zde je zodpovědný za projekt internetového bankovnictví a koordinuje další projekty spojené s bezpečnostními aplika-cemi a novými technologiemi implementovanými v bankovnictví.

Filip Cherecheş-Toşa je webový vývojář se silnou vírou v budoucnost webového software. Svou kariéru začal ve věku 9 let, kdy získal počítač Commodore 64 s kazetovou jednotkou. Doma v Ru-munsku rozjel Filip vývojářskou společnost eXigo, www.exigo.ro, která se aktivně zabývala tvor-bou webových aplikací a webovým designem. V současné době je studentem University of Oradea, kde studuje počítačovou vědu; je také aktivním členem rumunské PHP komunity www.phproma-nia.net.

Mihai Bucica začal programovat a soutěžit v programátorských soutěžích (mnoho z nich vyhrál) ve věku dvanácti let. S bakalářským diplomem v oboru počítačových věd z Fakulty automatické-ho řízení a počítačů Polytechnické univerzity v Bukurešti v Rumunsku pracuje na komunikačním software s mnoha elektronickými trhy. I po zkušenostech s mnoha jazyky a technologiemi zůstává jeho oblíbeným programovacím jazykem C++; oblíbil si také svět LGPL. Mihai byl také spoluau-torem knihy Beginning PHP 5 and MySQL E-Commerce a lze ho kontaktovat prostřednictvím jeho osobní webové stránky www.valentinbucica.ro.

O odborných recenzentechEmilian Balanescu je programátor, který má zkušenosti s mnoha technologiemi, například PHP, Java, .NET, PostgreSQL, MS SQL Server, MySQL a mnoho dalších. V současné době pracuje jako

Page 8: Ajax a PHP

7

administrátor bezdrátových sítí ve společnosti accessNET International S.A. Romania, která po-skytuje služby bezdrátových komunikačních sítí s celonárodním pokrytím. Jeho posledním pro-jektem na této pozici byla tvorba ajaxového realtime systému pro správu sítí (pomocí technologií SNMP, Perl, PHP a PostgreSQL), který se používá pro vzdálené ladění a monitorování výkonu sys-tému, a pro izolaci a odstraňování problémů. Emiliana zastihnete prostřednictvím jeho stránky http://www.emilianbalanescu.ro.

Paula Badascu je studentkou třetího ročníku Polytechnické univerzity v Bukurešti, která je v Ru-munsku jednou z nejslavnějších technických vysokých škol. Studuje elektroniku, telekomunikace a informační technologie. V současné době pracuje jako programátorka a analytička ve společnosti NCH Advisors Romania, pro kterou za použití technologií UML, OOP, PHP, SQL, JavaScript a CSS tvoří webové aplikace. Rozhodujícím způsobem přispěla k analýze a vývoji pracovního rámce, po-užívaného k trasování a monitoringu rumunského kapitálového trhu.

ÚvodAJAX je složitý fenomén, který má pro různé lidi různé významy. Uživatelé počítačů oceňují, že jsou jejich oblíbené webové stránky více přátelské a cítí se lépe. Vývojáři webů se učí novým schop-nostem, které jim při vynaložení malého úsilí umožní vytvářet elegantní aplikace. AJAX je určitě skvělá věc!

AJAX je ve své podstatě směs technologií, které nám umožňují zbavit se aktualizací stránek, jež představují mrtvý čas při navigaci mezi stránkami. Eliminace aktualizací stránek je však pouze jedním krokem z mnoha, které zavádějí do webových prezentací další vlastnosti – kontrola dat v reálném čase, technologie přetahování myší (drag-and-drop), a mnoho dalších, které dříve neby-ly spojovány s webovými aplikacemi vůbec. Přestože jsou prvky AJAXu již vyspělé (objekt XMLHttp-Request, který je srdcem AJAXu, byl firmou Microsoft vyvinut v roce 1999), jsou jejich role v nad-cházející vlně webových trendů velmi mladé. Budeme tedy jistě svědky mnoha změn před tím, než se tyto technologie budou správně používat tak, aby koncovým uživatelům přinášely co největší užitek. V době psaní této knihy je jméno "AJAX" asi jeden rok staré.

AJAX samozřejmě není řešením všech problémů na webu, jak by jeho současná popularita mohla napovídat. Stejně jako jiné technologie může být i AJAX špatně používán, nebo se stát zprofano-vaným. AJAX má také své vlastní problémy: je nutné se potýkat s nekonzistencemi prohlížečů, stránky v něm vytvořené nefungují v prohlížečích bez JavaScriptu, nemohou být jednoduše vklá-dány do oblíbených položek uživatele, nehledě na to, že vyhledávací stroje si vždy nemusí poradit s jejich parsováním. AJAX také není oblíben všemi. Zatímco v něm někteří vývojáři vytvářejí celé architektury, jiní jej nepoužívají vůbec. Až opadne počáteční nadšení, převládne zřejmě ten názor, že ve většině případů bude nejrozumnější jakási střední cesta.

V této knize jsme se pragmaticky věnovali nejlepším možným technikám a vzorům, o kterých si myslíme, že budou dříve či později užitečné všem webovým vývojářům. Dozvíte se zde, jak se vyhnout záludnostem, jak psát v AJAXu efektivní kód a jak dosáhnout takové funkcionality, která

Page 9: Ajax a PHP

8

vám bez nutnosti přetváření celého řešení v AJAXu umožní snadnou integraci do současných i bu-doucích webových aplikací. Znalosti, které získáte četbou této knihy, budete moci využít ve vašich aplikacích napsaných v PHP.

Doufáme, že se tato kniha stane užitečným pomocníkem pro řešení vašich projektů. Na adrese http://ajaxphp.packtpub.com naleznete podrobnější informace a doplňky k této knize. Na tomto místě si také můžete volně stáhnout další kapitoly a informace, které vám doporučujeme k prozkoumání.

Co tato kniha obsahujeKapitola 1 – AJAX a budoucnost webových aplikací je úvodem do světa AJAXu a mnoha mož-ností, které nabízí webovým vývojářům i společnostem. V této kapitole také vytvoříme svou první webovou stránku založenou na AJAXu, která nás přivede k technologii komponent.

Kapitola 2 – Techniky na straně serveru založené na JavaScriptu nás zavede mezi technologie JavaScript, DOM, objekt XMLHttpRequest a XML, které budeme používat k vytváření webových klientů AJAXu. Kapitola se nezabývá detailními postupy jejich používání, ale jejich společným vy-užitím, čímž tak dává základ tvorbě aplikací v budoucnosti.

Kapitola 3 – Techniky na straně serveru s PHP a MySQL ukazuje, jak vytvářet inteligentní serve-ry komunikující s klientem AJAXu. Zde jsou dokončeny tak teoretické základy. Dozvíte se mnoho o technikách, které vám pomohou implementovat různé úlohy, včetně základů problematiky bez-pečnosti JavaScriptu a problémů se zpracováním chyb.

Kapitola 4 – Ověřování formulářových dat pomocí AJAXu vás provede tvorbou moderního, vstřícného a bezpečného systému pro kontrolu formulářovách dat, který implementuje jak kontro-lu AJAXu v reálném čase, tak i kontrolu formuláře na straně serveru po jeho odeslání.

Kapitola 5 – Chat v AJAXu prezentuje jednoduchý online chat, který pracuje pouze s využitím kódu AJAXu – není zde tedy použit JavaScript, Flash, ani žádná jiná specializovaná knihovna, která je pro tyto účely obvykle použita.

Kapitola 6 – Návrhy a automatické dokončování v AJAXu představuje vyhledávací prvek zalo-žený na Googlu, který vám pomůže rychle najít funkce PHP a nasměruje vás na oficiální stránku s nápovědou k dané funkci.

Kapitola 7 – Tvorba grafů v reálném čase pomocí SVG vysvětluje, jak pomocí AJAXu a SVG implementovat v reálném čase grafy. SVG (Scalable Vector Graphics) je grafický jazyk založený na textu, který se využívá k tvorbě geometrických tvarů a textu.

Kapitola 8 – Mřížky v AJAXu ukazuje, jak pomocí AJAXu vytvářet výkonné datové mřížky. Dozví-te se, jak pomocí XSLT parsovat dokumenty XML a vytvářet výstupy vašich mřížek.

Kapitola 9 – Čtečka RSS ukazuje vytvoření jednoduchého agregátoru RSS pomocí PHP knihovny SimpleXML, XML a XSLT.

Page 10: Ajax a PHP

9

Kapitola 10 – Přetahování myší je demonstrací pracovního rámce script.aculo.us k vytvoření jed-noduchého seznamu elementů s funkcionalitou přetahování pomocí myši.

Příloha A – Příprava pracovního prostředí vysvětluje, jak instalovat a konfigurovat potřebný software: Apache, PHP, MySQL a phpMyAdmin. Kvůli příkladům v této knize se předpokládá, že máte připraveno pracovní prostředí a databázi se vzorky dat tak, jak je zde uvedeno.

Co potřebujete ke studiu této knihyPro zpracování příkladů v této knize budete potřebovat PHP 5, webový server a databázový ser-ver. Kód jsme testovali v několika různých prostředích, většinou ale za použití webového serveru Apache 2 a databází MySQL 4.1 a MySQL 5.

Samozřejmě můžete použít jiný webový (případně databázový) server, v takovém případě ale ne-musí být procedury popisované v knize stoprocentně přesné. Je důležité použít PHP verze 5 nebo novější, protože používáme některé prvky, které nejsou ve starších verzích k dispozici – jedná se například o podporu objektově orientovaného programování.

O přípravě vašeho počítače si, prosím, přečtěte podrobnější informace v příloze A. Pokud již máte instalován požadovaný software, bude potřebné si přečíst pouze jeho poslední část, která obsahuje instrukce k vytvoření databáze, jež se používá v příkladech v knize.

KonvenceV této knize naleznete mnoho odlišných stylů textu, pomocí kterých se rozlišují různé typy infor-mací. Zde jsou uvedeny příklady těchto stylů společně s vysvětlením jejich významu.

Pro zápis kódu se používají tři styly. Slova kódu v textu se zapisují tímto způsobem: "Pomocí direk-tivy include můžeme vložit další kontexty".

Blok kódu bude uveden takto:

// funkce zavolá server použitím objektu XMLHttpRequest

function process()

{

name = document.getElementById("myName").value;

xmlHttp.open("GET", "quickstart.php?name=" + name, false);

xmlHttp.send(null);

handleServerResponse(); }

Když budeme chtít poukázat na určitou část bloku kódu a zvýraznit ji, budou její řádky tučné:

// funkce zavolá server použitím objektu XMLHttpRequest

function process()

{

name = document.getElementById("myName").value;

Page 11: Ajax a PHP

10

xmlHttp.open("GET", "quickstart.php?name=" + name, false); xmlHttp.open("GET", "quickstart.php?name=" + name, false);

xmlHttp.send(null); xmlHttp.send(null);

handleServerResponse(); handleServerResponse(); }

Vstup a výstup pomocí příkazové řádky bude zapsán takto:

./configure --prefix=/usr/local/apache2

--enable-so --enable-ssl --with-ssl --enable-auth-digest

Upozornění nebo důležité poznámky budou zvýrazněny tímto způsobem.

Zde bude nějaká důležitá poznámka.

Sdělte nám svůj názorJako čtenáři této knihy se stáváte těmi nejdůležitějšími kritiky a komentátory. Vážíme si vašeho názoru a chtěli bychom vědět, co děláme správně, co bychom mohli dělat lépe, ve kterých oblas-tech bychom měli publikovat a také vaše další podnětné myšlenky, o které jste ochotni se s námi podělit.

Jako odborný redaktor Zoner Press vítám vaše názory. Můžete mi psát – poslat e-mail nebo dopis – a sdělit mi, co se vám v této knize lí bilo nebo nelíbilo, stejně tak, co bychom měli udělat, aby naše další knihy byly lepší. Pokud mi napíšete, nezapomeňte prosím připojit název knihy, ISBN, jméno autora, vaše jméno, telefon, fax nebo e-mail. Pozorně zhodnotím vaše názory a poskytnu je autoro-vi a redaktorům, kteří pracovali na této knize.

Prosím, vězte, že nemohu pomoci s technickými problémy, které se týkají obsahu knihy, a že díky velkému množství e-mailů, které dostávám, nemohu zaručit odpověď na každou zprávu.

E-mail: [email protected] nebo [email protected].

Adresa: Zoner Press, ZONER software, s.r.o., Miroslav Kučera, Nové sady 18, 602 00 Brno.

Zdrojové souboryZdrojové soubory k této knize je možné stáhnout na adrese http://www.zonerpress.cz/download/ajax.zip (2,9 MB) nebo na adrese http://www.packtpub.com/support, kde v se-znamu knih vyberte knihu Ajax And Php: Building Responsive Web Applications. Zdrojové soubory jsou rozděleny do samostatných adresářů podle kapitol.

Page 12: Ajax a PHP

KAPITOLA 2Techniky na straně serveruzaložené na JavaScriptuŘíká se, že jeden obrázek vydá za více než tisíc slov. To stejné můžeme říci o dobře napsaném kusu kódu. V této a v následující kapitole se vám při vytváření základů vašich budoucích ajaxových apli-kací dostane obojího dostatek.

První kapitola nepochybně dostatečně vzbudila váš zájem o AJAX, takže jistě vydržíte i kapitolu druhou, která je plná teorie, již je potřeba se naučit. Na druhou stranu – jestliže byl pro vás první příklad příliš těžký, buďte ujištěni, že nyní budeme pokračovat pomaleji. Teorii se naučíme po částech tak, že si ukážeme mnoho krátkých příkladů. V této kapitole si stručně popíšeme klientské technologie AJAXu, které zahrnují následující:

• JavaScript.• JavaScript DOM.• Kaskádové styly (CSS).• Objekt XMLHttpRequest.• Jazyk XML (Extensible Markup Language).

Dozvíte se, jak přimět tyto technologie, aby plynule spolupracovaly a zjistíte, jak vytvořit silné zá-klady pro budoucí ajaxové aplikace. Uvidíte, jak implementovat účinné techniky pro zachytávání chyb a jak psát efektivní kód. V kapitole 3 pak budou dokončeny prezentace technik a technologií, které se používají na straně serveru – v našem případě PHP, MySQL a další.

Abyste se stal dobrým ajaxovým programátorem, musíte dobře vědět, jak samostatně pracují jed-notlivé součásti, a pak si osvojit jejich spolupráci. V této knize předpokládáme, že máte s těmito technologiemi alespoň nějaké zkušenosti.

V závislosti na vašich zkušenostech věnujte nějakou dobu (ať už před čtením kapitoly 2 a 3 nebo až poté) příloze B na adrese http://ajaxphp.packtpub.com, ve které je zmíněno mnoho nástro-jů, jež programátorům usnadňují život. Nepřeskakujte ji, protože je velmi důležitá – vlastnictví a správné používání vhodných nástrojů může být pro vás velkým přínosem.

Všechny ukázkové aplikace této knihy naleznete na adrese http://ajaxphp.packtpub.com/.

Page 13: Ajax a PHP

36 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

JavaScript a objektový model dokumentuJak bylo uvedeno v kapitole 1, srdcem AJAXu je JavaScript. Ten má podobnou syntaxi jako starý dobrý jazyk C. JavaScript je interpretovaný jazyk (tedy nikoliv kompilovaný) a má určité možnosti objektově-orientovaného programování (OOP). Tento jazyk nebyl původně navržen pro vytváření velkých a výkonných aplikací, ale pro jednoduché skripty, které zajišťují funkcionalitu webových aplikací na straně klienta (moderní trendy se však snaží jej transformovat na univerzální jazyk pro vývoj podnikových aplikací – výsledek teprve uvidíme).

JavaScript je plně podporován naprostou většinou webových prohlížečů. Přestože je možné spouš-tět skripty JavaScriptu samostatně, obvykle jsou do klientských prohlížečů načítány společně s HTML kódem, který potřebuje jejich funkcionalitu. Skutečnost, že do klienta se musí celý kód v JavaScriptu dostat nezměněný, je současně jeho silnou i slabou stránkou, kterou je potřeba brát v úvahu. Kvalitní úvodní texty o JavaScriptu můžete najít na následujících adresách:

• http://www.echoecho.com/javascript.htm.

• http://www.devlearn.com/javascript/jsvars.html.

• http://www.w3schools.com/js/default.asp.

Součást síly JavaScriptu na straně klienta leží v jeho schopnosti manipulovat s rodičovským HTML dokumentem, což se děje pomocí rozhraní DOM. To je k dispozici pro mnoho dalších jazyků a technologií, například Javu, PHP, C#, C++ a další. V této kapitole uvidíte, jak použít DOM spo-lečně s JavaScriptem a s PHP. DOM má schopnost manipulovat (tzn. vytvářet, modifikovat, parso-vat, vyhledávat) s dokumenty, které jsou založeny na XML (včetně HTML).

Na straně klienta můžete DOM a JavaScript použít k:

• Manipulaci s HTML stránkou během práce na ní.

• Čtení a parsování dokumentů XML, získaných ze serveru.

• Tvorbě nových dokumentů XML.

Na straně serveru můžete DOM a PHP použít k:

• Vytváření XML dokumentů, obvykle pro jejich následné zaslání klientovi.

• Čtení XML dokumentů, získaných z různých zdrojů.

Dva dobré úvodní texty o DOM naleznete na http://www.quirksmode.org/dom/intro.html a http://www.javascriptkit.com/javatutors/dom.shtml. Hezkou hru s DOM si můžete za-hrát zde: http://www.topxml.com/learning/games/b/default.asp. Vyčerpávající reference o DOM a JavaScriptu naleznete na http://krook.org/jsdom/. Reference Mozilly o tomto téma-tu jsou na http://www.mozilla.org/docs/dom/reference/javascript.html.

V prvním příkladu této kapitoly použijeme DOM z JavaScriptu pro manipulaci s dokumentem HTML. Když do souboru HTML přidáváme kód JavaScriptu, je jednou z možností zapsat jej do

Page 14: Ajax a PHP

37AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

elementu <script> uvnitř elementu <body>. Vezměme si například následující soubor HTML, který po načtení spustí jednoduchý kód JavaScriptu. Povšimněme si objektu document, který je v JavaScriptu výchozím objektem pro komunikaci s DOM na stránce HTML. Pro přidání obsahu do stránky použijeme metodu write:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>AJAX Foundations: JavaScript and DOM</title>

<script type="text/javascript"> <script type="text/javascript">

// deklarace nových proměnných

var date = new Date();

var hour = date.getHours();

// demonstrace příkazu if

if (hour >= 22 || hour <= 5)

document.write("You should go to sleep."); document.write("You should go to sleep.");

else

document.write("Hello, world!"); document.write("Hello, world!");

</script>

</head>

<body>

</body>

</html>

Příkazy document.write generují výstup, který se při spuštění skriptu vloží do elementu <body> na stránce. Obsah, který vygenerujete, se stane součástí kódu HTML, takže pokud chcete, můžete přidat i značky jazyka HTML.

Je-li to možné, doporučujeme vám vytvářet platný kód HTML. Použití kódu, který odpovídá speci-fikaci HTML, zvyšuje šance, že vaše webové stránky budou pracovat s většinou stávajících i budou-cích webových prohlížečů. Užitečný článek o webových standardech naleznete na adrese http://www.w3.org/QA/2002/04/Web-Quality. Debata o standardech ovšem vypadá jako by byla neko-nečná – zatímco jedna skupina lidí se tvrdošíjně drží standardů, jiní se na svých stránkách zabývají určitou množinou prohlížečů.

Příklady v této knize obsahují platný kód HTML, mimo několika málo příkladů, kde jsme pravidla trochu porušili, aby byl kód snáze pochopitelný. Je však nemilou skutečností, že velmi málo dneš-ních webů přesně dodržuje webové standardy.

Obvykle budeme upřednostňovat zápis kódu JavaScriptu do odděleného souboru .js, na který se pak odkážeme ze souboru .html. To nám umožní udržet HTML kód čistý a mít současně komplet-ní kód JavaScriptu na jednom místě. Na soubor s JavaScriptem se v kódu HTML odkážeme tak, že do elementu <head> přidáme element <script>, například takto:

Page 15: Ajax a PHP

38 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

<html>

<head>

<script type="text/javascript" src="file.js"></script> <script type="text/javascript" src="file.js"></script>

</head>

</html>

I když však mezi značkami <script> a </script> nemáte žádný kód, nepoužívejte zkrácenou for-mu <script type="text/javascript" src="file.js" />. Toto způsobuje problémy v prohlí-žeči Internet Explorer 6, který pak není schopen načíst externě specifikovaný kód JavaScriptu.

Věnujme se nyní krátkému příkladu.

Čas pro akci – Hra s JavaScriptem a DOM 1. Ve složce ajax vytvořte podsložku nazvanou foundations. Tato složka bude použita pro

všechny příklady v této a v následující kapitole.

2. Ve složce foundations vytvořte podsložku nazvanou jsdom.

3. Ve složce jsdom vytvořte soubor nazvaný jsdom.html, který bude obsahovat následující kód:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>AJAX Foundations: JavaScript and DOM</title>

<script type="text/javascript" src="jsdom.js"></script>

</head>

<body>

I love you!

</body>

</html>

4. Ve stejné složce vytvořte soubor nazvaný jsdom.js a vložte do něj tento kód:

// deklarace nových proměnných

var date = new Date();

var hour = date.getHours();

// demonstrace příkazu if

if (hour >= 22 || hour <= 5)

document.write("Goodnight, world!");

else

document.write("Hello, world!");

Page 16: Ajax a PHP

39AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

5. Ve svém webovém prohlížeči načtete stránku http://localhost/ajax/foundations/jsdom/jsdom.html, a pokud předpokládáme, že ještě není pozdě, uvidíte zprávu jako na obrázku 2.1 (je-li po desáté večer, bude zpráva jiná, ale stejně romantická).

Obrázek 2.1. Příklad "Hello, world!" s technologiemi JavaScript a DOM.

Jak to funguje?Kód je velice jednoduchý, takže nepotřebuje mnoho vysvětlování. Zde jsou základní principy, kte-rým je potřeba porozumět:

• Protože zde není žádný skript na straně serveru (například kód PHP), není nutné přistupovat k souboru prostřednictvím webového serveru HTTP, ale postačí jeho načtení do prohlížeče přímo z disku. Spustíte-li jej tímto způsobem, prohlížeč jej otevře pomocí nějaké lokální adresy typu file:///C:/Apache2/htdocs/ajax/foundations/jsdom/jsdom.html.

• Při načítání stránky HTML s JavaScriptem z lokálního umístění (file://), vás bude pro-hlížeč Internet Explorer pravděpodobně varovat, že spouštíte kód, který vyžaduje vysokou úroveň oprávnění (bezpečností se více zabývá kapitola 3).

• JavaScript nevyžaduje deklaraci proměnných, takže se teoreticky můžete vyhnout klíčovým slovům var. Není to ale doporučováno.

• JavaScript se spouští automaticky při načtení HTML souboru. Kód však můžete seskupit do javascriptových funkcí, které se provedou pouze při jejich výslovném volání.

• Kód JavaScriptu se provádí před parsováním ostatního kódu HTML, takže se jeho výstup zobrazí před výstupem HTML. Povšimněme si, že text "Hello World" se zobrazí před textem "I love you!".

Jedním z problémů uvedeného kódu je skutečnost, že nemáte kontrolu nad tím, kde se má zobrazit výstup kódu JavaScriptu. Nejdříve se objeví tento výstup, a až poté obsah elementu <body>. Není nutné říkat, že tento scénář není vhodný ani pro ty nejjednodušší aplikace.

Takže – kromě nejjednodušších případů je tento typ kódu JavaScriptu, který se bez dalších pod-mínek spustí při načtení stránky, nevyhovující. Obvykle chceme mít větší kontrolu nad tím, jaké části kódu JavaScriptu se provedou a kdy – nejobvyklejším případem je použití funkcí JavaScriptu a jejich spouštění na základě vyvolání určitých událostí (například kliknutí na tlačítko).

Page 17: Ajax a PHP

40 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

Události JavaScriptu a DOMV následujícím cvičení vytvoříme pomocí kódu JavaScriptu strukturu HTML. Během přípravy tvorby webové stránky, která bude mít dynamicky generované části, musíme nejdříve vytvořit její šablonu (která bude obsahovat statické části) a použít zástupce pro dynamické části. Takovým zá-stupcem musí být jedinečně pojmenovaný element HTML (tedy element s atributem id). Až dosud jsme takto používali pouze element <div>, ale v této knize se setkáme i s dalšími příklady.

Podívejte se na následující HTML dokument:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>AJAX Foundations: More JavaScript and DOM</title>

</head>

<body>

Hello Dude! Here's a cool list of colors for you:

<br/>

<ul>

<li>Black</li>

<li>Orange</li>

<li>Pink</li>

</ul>

</body>

</html>

Předpokládejte, že vše, co je v elementu <ul>, chcete generovat dynamicky. V ajaxové aplikaci toho obvykle dosáhnete tím, že tam, kde chcete mít dynamický obsah, umístíte prázdný (ale pojmeno-vaný) element <div>:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>AJAX Foundations: More JavaScript and DOM</title>

</head>

<body>

Hello Dude! Here's a cool list of colors for you:

<br/>

<div id="myDivElement"/> <div id="myDivElement"/>

</body>

</html>

Page 18: Ajax a PHP

41AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

V tomto případě jsme pro generování HTML dokumentu z JavaScriptu použili element <div>, ale pamatujte si, že identifikátory id můžeme přiřadit všem elementům v HTML. Když se vykoná kód JavaScriptu a do elementu <div> přidáme element <ul>, získáme dále uvedenou strukturu HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>Colors</title>

</head>

<body>

Hello Dude! Here's a cool list of colors for you:

<br/>

<div id="myDivElement"><div id="myDivElement">

<ul> <ul>

<li>Black</li> <li>Black</li>

<li>Orange</li> <li>Orange</li>

<li>Pink</li> <li>Pink</li>

</ul> </ul>

</div> </div>

</body>

</html>

Pro následující cvičení máme následující cíle:

• Pomocí funkce JavaScriptu programově zpřístupnit pojmenovaný element <div>.

• Spustíme-li kód JavaScriptu poté, co je načtena HTML šablona, můžeme přistupovat k ele-mentu <div> (HTML elementy nejsou dostupné z kódu JavaScriptu, který se spouští od-kazem z elementu <head>). Toho dosáhneme tím, že zavoláme kód JavaScriptu z události onload elementu <body>.

• Seskupit kód JavaScriptu do funkce (kvůli snadnější manipulaci s ním).

Čas pro akci – Použití událostí JavaScriptu a DOM 1. Ve složce foundations, kterou jste vytvořili v předchozím cvičení, vytvořte novou složku,

nazvanou morejsdom.

2. V této složce vytvořte soubor morejsdom.html a vložte do něj následující kód:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

Page 19: Ajax a PHP

42 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

<title>AJAX Foundations: More JavaScript and DOM</title>

<script type="text/javascript" src="morejsdom.js"></script>

</head>

<body onload="process()">

Hello Dude! Here's a cool list of colors for you:

<br /><div id="myDivElement" />

</body>

</html>

3. Přidejte nový soubor morejsdom.js, který bude mít tento obsah:

function process()

{

// Vytvoř nový kód HTML

var string;

string = "<ul>"

+ "<li>Black</li>"

+ "<li>Orange</li>"

+ "<li>Pink</li>"

+ "</ul>";

// získej referenci na element <div> na stránce

myDiv = document.getElementById("myDivElement");

// přidej obsah do elementu <div>

myDiv.innerHTML = string;

}

4. Načtete morejsdom.html do webového prohlížeče. Měli byste vidět okno, které bude podob-né tomu na obrázku 2.2:

Obrázek 2.2. Naše malá stránka HTML v akci.

Jak to funguje?Kód je hezky jednoduchý. V následujícím HTML kódu stránky jsem zvýraznil důležité části:

Page 20: Ajax a PHP

43AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head>

<title>AJAX Foundations: More JavaScript and DOM</title>

<script type="text/javascript" src="morejsdom.js"></script> <script type="text/javascript" src="morejsdom.js"></script>

</head>

<body onload="process()"onload="process()">

Hello Dude! Here's a cool list of colors for you:

<br/>

<div id="myDivElement" /> <div id="myDivElement" />

</body>

</html>

Všechno začíná odkazem na zdrojový soubor JavaScriptu pomocí elementu <script>. Soubor s JavaScriptem obsahuje funkci nazvanou process(), která se používá pro zpracování události onload elementu <body>. Tato událost se odpálí po úplném načtení souboru HTML, takže když je funkce process() spuštěna, má přístup k celé struktuře HTML. Naše funkce process() začne s vytvářením HTML kódu, který chceme přidat do elementu div.

function process()

{

var string;

string = "<ul>"

+ "<li>Black</li>"

+ "<li>Orange</li>"

+ "<li>Pink</li>"

+ "</ul>";

Dále pomocí funkce getElementById objektu document získáme referenci na myDivElement. Pa-matujme si, že document je standardní objekt JavaScriptu, který se odkazuje na tělo dokumentu HTML.

// získej referenci na element <div> na stránce

myDiv = document.getElementById("myDivElement");

Poznamenejme, že JavaScript umožňuje pro proměnné řetězce používat jak uvozovky, tak i apostrofy. Předchozí řádek tak může být korektně zapsán i tímto způsobem:

myDiv = document.getElementById('myDivElement');

V JavaScriptu jsou obě možnosti stejně dobré, pokud konzistentně používáte pouze jednu z nich. Pou-žíváte-li v jednom skriptu obě varianty současně, riskujete vznik chyb při parsování. V této knize bude-me v programech JavaScriptu používat uvozovky.

Page 21: Ajax a PHP

44 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

A nakonec do elementu myDivElement vložíme HTML kód, který jsme sestavili v proměnné string:

// přidej obsah do elementu <div>

myDiv.innerHTML = string;

}

V tomto případě jsme pro přidání vytvořeného HTML použili vlastnost innerHTML DOMu.

Ještě více DOMuV předchozím cvičení jsme seznam elementů vytvořili spojením řetězců do jednoduché HTML struktury. Stejná struktura ovšem může být pomocí DOMu vytvořena programově. Tímto způso-bem budeme v následujícím cvičení generovat tento obsah:

<div id="myDivElement">

Hello Dude! Here's a cool list of colors for you:

<br/>

<ul>

<li>Black</li>

<li>Orange</li>

<li>Pink</li>

</ul>

</div>

Dokument DOMu je hierarchická struktura elementů, přičemž každý z nich může mít jeden nebo více atributů. V tomto příkladu je použit jediný element <div>, který má atribut id s hodnotou my-DivElement. Kořenovým uzlem, pomocí kterého můžeme zpřístupnit objekt document, je <body>. Když implementujeme HTML kód uvedený výše, výsledkem bude struktura jako na následujícím obrázku:

Obrázek 2.3. Hierarchie elementů HTML.

Page 22: Ajax a PHP

45AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

Na obrázku 2.3 vidíme strukturu HTML, ve které jsou použity elementy <body>, <div>, <br>, <ul> a <li> a čtyři textové uzly ("Hello…", "Black", "Orange", "Pink"). ). V následujícím cvičení vytvoří-me tuto strukturu pomocí funkcí DOMu createElement, createTextNode a appendChild.

Čas pro akci – Ještě více DOMu 1. Ve složce foundations vytvořte podsložku nazvanou evenmorejsdom.

2. Ve složce evenmorejsdom vytvořte soubor pojmenovaný evenmorejsdom.html a vložte do něj následující text:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN“ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd“>

<html>

<head>

<title>AJAX Foundations: Even More JavaScript and DOM</title>

<script type=“text/javascript“ src=“evenmorejsdom.js“></script>

</head>

<body onload=“process()“>

<div id=“myDivElement“ />

</body>

</html>

3. Vytvořte nový soubor nazvaný evenmorejsdom.js s tímto obsahem:

function process()

{

// vytvoří první textový uzel

oHello = document.createTextNode

("Hello Dude! Here's a cool list of colors for you:“);

// vytvoří element <ul>

oUl = document.createElement("ul“)

// vytvoří první element <li> a přidá do něj textový uzel

oLiBlack = document.createElement("li“);

oBlack = document.createTextNode("Black“);

oLiBlack.appendChild(oBlack);

// vytvoří druhý element <li> a přidá do něj textový uzel

oLiOrange = document.createElement("li“);

oOrange = document.createTextNode("Orange“);

oLiOrange.appendChild(oOrange);

// vytvoří třetí element <li> a přidá do něj textový uzel

oLiPink = document.createElement("li“);

oPink = document.createTextNode("Pink“);

oLiPink.appendChild(oPink);

Page 23: Ajax a PHP

46 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

// přidá elementy <li> jako potomky do elementu <ul>

oUl.appendChild(oLiBlack);

oUl.appendChild(oLiOrange);

oUl.appendChild(oLiPink);

// získá referenci na element <div> na stránce

myDiv = document.getElementById("myDivElement“);

// přidá obsah do elementu <div>

myDiv.appendChild(oHello);

myDiv.appendChild(oUl);

}

4. Do prohlížeče načtěte evenmoredom.html. Výsledek by měl vypadat jako na obrázku 2.4:

Obrázek 2.4. Ještě další JavaScript a DOM.

Jak to funguje?Nyní došlo přesně k tomu samému jako v předchozím cvičení, ale tentokrát je zde mnohem více kódu – stačí, když se podíváte na funkci process(). Přestože je zde mnoho řádků kódu, funk-cionalita je jednoduchá. Je zřejmé, že využití DOMu pro vytváření struktury HTML nemusí být vždy tou nejlepší volbou. V některých případech však může programování dosti usnadnit, zejména z následujících důvodů:

• Tvorba dynamických struktur HTML je programově (například pomocí cyklu for) pohodl-ná, protože se nemusíme starat o formátování textu, ale o tvorbu jednotlivých elementů dané struktury.

• V důsledku toho není například nutné manuálně přidávat uzavírací značky. Když budete chtít přidat nějaké elementy <li>, DOM se postará o vygenerování značky <li> a s ní sou-visející uzavírací značky </li>.

• S uzly můžete zacházet jako by byly zcela nezávislé a o jejich hierarchii rozhodnout později. O detaily implementace se opět postará DOM – vy mu pouze řeknete co chcete.

Page 24: Ajax a PHP

47AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

JavaScript, DOM a CSSPojem CSS (Cascading Style Sheets, kaskádové styly) je vám jistě známý. CSS vám umožňuje spe-cifikovat formátování HTML stránky z jediného *.css dokumentu. Je-li vše uděláno správně a CSS je na stránkách použito konzistentně, je možné provádět vizuální změny webu (nebo jeho části) s minimálním úsilím – pouhým editováním CSS souboru. O CSS existuje mnoho knih a tutoriá-lů, včetně těch volně dostupných, které jsou k dispozici na adresách http://www.w3.org/Sty-le/CSS/ a http://www.w3schools.com/css/default.asp. Přestože je v článku, kde bylo úplně poprvé použito jméno AJAX (http://www.adaptivepath.com/publications/essays/archi-ves/000385.php), uvedeno CSS jako jedna ze součástí AJAXu, z technického hlediska není CSS potřebné pro úspěšné vytvoření dynamických webových aplikací. Jeho použití je však velice dopo-ručeno, protože má mnoho výhod.

Pro demonstraci použití CSS a manipulaci se styly pomocí DOM si předvedeme jednoduché cvi-čení. Jedná se o úlohy, které jsou při tvorbě ajaxových aplikací obvyklé. V tomto cvičení nakreslíme hezkou tabulku a vytvoříme dvě tlačítka, pojmenovaná jako Set Style 1 a Set Style 2. Tato tlačítka budou schopna přepínáním stylů změnit barvu a vzhled tabulky. To, co budeme vytvářet, znázor-ňuje obrázek 2.5, který je o několik stránek knihy dále.

Čas pro akci – Práce s CSS a JavaScriptem 1. Ve složce foundations vytvořte novou podsložku csstest.

2. V této nově vytvořené složce vytvořte soubor nazvaný csstest.html, který bude mít násle-dující obsah:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN“ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd“>

<html>

<head>

<title>AJAX Foundations: CSS</title>

<script type=“text/javascript“ src=“csstest.js“></script>

<link href=“styles.css“ type=“text/css“ rel=“stylesheet“/>

</head>

<body>

<table id=“table“>

<tr>

<th id=“tableHead“>

Product Name

</th>

</tr>

<tr>

<td id=“tableFirstLine“>

Page 25: Ajax a PHP

48 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

Airplane

</td>

</tr>

<tr>

<td id=“tableSecondLine“>

Big car

</td>

</tr>

</table>

<br />

<input type=“button“ value=“Set Style 1“ onclick=“setStyle1();“ />

<input type=“button“ value=“Set Style 2“ onclick=“setStyle2();“ />

</body>

</html>

3. Vytvořte nový soubor nazvaný csstest.js a vložte do něj následující obsah:

// Nastav styl tabulky na styl č. 1

function setStyle1()

{

// získej odkazy na elementy HTML

oTable = document.getElementById("table“);

oTableHead = document.getElementById("tableHead“);

oTableFirstLine = document.getElementById("tableFirstLine“);

oTableSecondLine = document.getElementById("tableSecondLine“);

// nastav styly

oTable.className = "Table1“;

oTableHead.className = "TableHead1“;

oTableFirstLine.className = "TableContent1“;

oTableSecondLine.className = "TableContent1“;

}

// Nastav styl tabulky na styl č. 2

function setStyle2()

{

// získej odkazy na elementy HTML

oTable = document.getElementById("table“);

oTableHead = document.getElementById("tableHead“);

oTableFirstLine = document.getElementById("tableFirstLine“);

oTableSecondLine = document.getElementById("tableSecondLine“);

// nastav styly

oTable.className = "Table2“;

oTableHead.className = "TableHead2“;

oTableFirstLine.className = "TableContent2“;

Page 26: Ajax a PHP

49AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

oTableSecondLine.className = "TableContent2“;

}

4. Nakonec vytvořte soubor CSS nazvaný jako styles.css:

.Table1

{

border: DarkGreen 1px solid;

background-color: LightGreen;

}

.TableHead1

{

font-family: Verdana, Arial;

font-weight: bold;

font-size: 10pt;

}

.TableContent1

{

font-family: Verdana, Arial;

font-size: 10pt;

}

.Table2

{

border: DarkBlue 1px solid;

background-color: LightBlue;

}

.TableHead2

{

font-family: Verdana, Arial;

font-weight: bold;

font-size: 10pt;

}

.TableContent2

{

font-family: Verdana, Arial;

font-size: 10pt;

}

5. Do svého webového prohlížeče zadejte adresu http://localhost/ajax/foundations/csstest/csstest.html a otestujte, zdali tlačítka fungují tak, jak by podle popisu měla.

Page 27: Ajax a PHP

50 Kapitola 2 – Techniky na straně serveru založené na JavaScriptu

Obrázek 2.5. Tabulka s CSS a JavaScriptem.

Jak to funguje?Náš soubor styles.css obsahuje dvě skupiny stylů, které mohou být aplikovány na tabulku v souboru csstest.html. Když uživatel klikne na některé z tlačítek "Set Style", použije se DOM JavaScriptu k přiřazení zvoleného stylu k elementům tabulky.

V první části metod SetStyle je použita funkce getElementByID, abychom získali odkazy na HTML elementy, na které chceme aplikovat CSS:

// získej odkazy na elementy HTML

oTable = document.getElementById("table“);

oTableHead = document.getElementById("tableHead“);

oTableFirstLine = document.getElementById("tableFirstLine“);

oTableSecondLine = document.getElementById("tableSecondLine“);

Stejně jako u mnoha jiných aspektů vývoje webu může být i práce s CSS předmětem výrazných ne-konzistencí mezi různými webovými prohlížeči. Zkuste například v předchozím úseku kódu přejmeno-vat jména objektů tak, aby byla stejná jako mají asociované elementy HTML (přejmenujte například oTable na table) – uvidíte, že stránka v Internet Exploreru rázem přestane pracovat. Tento prohlížeč prostě nemá rád, pokud je už v HTML souboru nějaký objekt se stejným ID. Problém sice není tak zá-sadní, protože objekty mají jiný jmenný rozsah, nicméně si tuto skutečnost dobře ověřte, pokud chce-te, aby váš kód v Internet Exploreru pracoval správně.

Když máme tyto objekty inicializované, pomocí vlastnosti className nastavíme styl pro jednot-livé elementy:

// nastav styly

oTable.className = "Table1";

oTableHead.className = "TableHead1";

oTableFirstLine.className = "TableContent1";

oTableSecondLine.className = "TableContent1";

Page 28: Ajax a PHP

KAPITOLA 3Techniky na straněserveru s PHP a MySQLJe-li AJAX o tvorbě chytrých klientů, pak i obdobně chytré musejí být i servery, které s těmito kli-enty komunikují – jinak by s nimi nemohly dlouho držet krok.

V kapitole 2 jsme ze serveru získávali pouze statický text nebo soubory XML. V této kapitole za-čneme pracovat s technikami na straně serveru. Začneme používat PHP, které bude generovat dy-namický výstup a databázi MySQL, jež pracuje s daty. V této kapitole se dozvíte, jak:

• Použít PHP k tvorbě funkcionality na straně serveru.

• Umožnit klientům komunikovat se serverem pomocí předávání parametrů.

• Použít XML na klientovi i na serveru.

• Pomocí skriptů PHP předejít možným bezpečnostním problémům s JavaScriptem.

• Provádět na klientovi opakované úlohy.

• Pracovat s databázemi MySQL.

• Optimalizovat architekturu naší aplikace.

PHP a DOMV kapitole 2 jsme data ze serveru četli asynchronně. Tento mechanismus je standardní a stejné postupy se v knize používají mnohokrát. Nestandardní je však to, že data předaná serverem byla v podobě statického souboru (ať už v textového nebo XML).

Ve většině praktických situací budeme potřebovat, aby server nějakým způsobem zpracovával a ge-neroval dynamický výstup. V této knize použijeme pro tuto funkcionalitu serverové části jazyk PHP. Nejste-li v PHP příliš zběhlí, dotaz "php tutorial" zadaný do Google najde mnoho zajíma-vých zdrojů, včetně oficiálního tutoriálu na adrese http://php.net/tut.php. Pokud dáváte před-nost praktické výuce, doporučujeme jednu z knih Cristiana Darie a Mihai Bucica o elektronickém

Page 29: Ajax a PHP

80 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

obchodě, například Beginning PHP 5 and MySQL E-Commerce: From Novice to Professional. Dob-rou volbou je také Pokročilé programování v PHP 5 (Zoner Press, www.zonerpress.cz).

Je také možné použít aplikace Suggest a Autocomplete, které vytvoříme v kapitole 6 – ty pro vás dokáží najít stránky obsahující popis jednotlivých funkcí PHP. Tyto aplikace naleznete na adrese http://ajaxphp.packtpub.com/ajax/suggest/.

V prvním cvičení této kapitoly vytvoříme PHP skript, který pomocí DOM funkcí v PHP vytvoří výstup ve formátu XML, jejž poté přečte klient. DOM funkcionalita v PHP je podobná funkciona-litě DOM v JavaScriptu – oficiální dokumentaci naleznete na http://www.php.net/manual/en/ref.dom.php.

XML dokument, který vytvoříme na serveru, bude skoro stejný jako statický XML soubor vytvoře-ný v kapitole 2, s tím rozdílem, že tentokrát bude vytvořen dynamicky:

<response>

<books>

<book>

<title>Building Reponsive Web Applications with AJAX and PHP</title>

<isbn>1-904811-82-5</isbn>

</book>

</books>

</response>

Čas pro akci – Práce s AJAXem a PHP 1. Ve složce foundations vytvořte podsložku nazvanou jako php.

2. Ve složce php vytvořte soubor phptest.html a vložte do něj následující text:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head><title>Practical AJAX: Using the PHP DOM</title>

<script type="text/javascript" src="phptest.js"></script>

</head>

<body onload="process()">

The AJAX book of 2006 is: <br />

<div id="myDivElement" />

</body>

</html>

3. Kód na straně klienta (phptest.js) bude skoro stejný, jako books.js z cvičení o XML v ka-pitole 2. Změněné části jsou zvýrazněny tučně:

// zde bude instance objektu XMLHttpRequest

Page 30: Ajax a PHP

81AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

var xmlHttp = createXmlHttpRequestObject();

// vytvoří instanci XMLHttpRequest

function createXmlHttpRequestObject()

{

// zde bude reference na objekt XMLHttpRequest

var xmlHttp;

// toto by mělo fungovat ve všech prohlížečích mimo IE6 a starší

try

{

// pokusí se vytvořit objekt XMLHttpRequest

xmlHttp = new XMLHttpRequest();

}

catch(e)

{

// předpokládá IE6 nebo starší

var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",

"MSXML2.XMLHTTP.5.0",

"MSXML2.XMLHTTP.4.0",

"MSXML2.XMLHTTP.3.0",

"MSXML2.XMLHTTP",

"Microsoft.XMLHTTP");

// vyzkoušej všechna prog id, dokud některé nebude funkční

for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++)

{

try

{

// pokusí se vytvořit objekt XMLHttpRequest

xmlHttp = new ActiveXObject(XmlHttpVersions[i]);

}

catch (e) {}

}

}

// vrátí vytvořený objekt nebo zobrazí chybovou zprávu

if (!xmlHttp)

alert("Error creating the XMLHttpRequest object.");

else

return xmlHttp;

}

// přečte soubor ze serveru

function process()

{

// pokračuj jen, není-li xmlHttp prázdné

Page 31: Ajax a PHP

82 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

if (xmlHttp)

{

// pokus se připojit k serveru

try

{

// iniciuj čtení souboru ze serveru

xmlHttp.open("GET", "phptest.php", true); xmlHttp.open("GET", "phptest.php", true);

xmlHttp.onreadystatechange = handleRequestStateChange;

xmlHttp.send(null);

}

// v případě selhání zobraz chybu

catch (e)

{

alert("Can't connect to server:\n" + e.toString());

}

}

}

// funkce se volá při změně stavu HTTP požadavku

function handleRequestStateChange()

{

// je-li readyState 4, můžeme přečíst odpověď serveru

if (xmlHttp.readyState == 4)

{

// pokračuj pouze, je-li stav HTTP "OK"

if (xmlHttp.status == 200)

{

try

{

// zpracuj odpověď ze serveru

handleServerResponse();

}

catch(e)

{

// zobraz chybovou zprávu

alert("Error reading the response: " + e.toString());

}

}

else

{

// zobraz zprávu o stavu

alert("There was a problem retrieving the data:\n" +

xmlHttp.statusText);

Page 32: Ajax a PHP

83AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

}

}

}

// zpracuje odpověď získanou od serveru

function handleServerResponse()

{

// přečte zprávu ze serveru

var xmlResponse = xmlHttp.responseXML;

// zachycení možných chyb u IE a Opery

if (!xmlResponse || !xmlResponse.documentElement)

throw("Invalid XML structure:\n" + xmlHttp.responseText);

// zachycení možných chyb u Firefoxu

var rootNodeName = xmlResponse.documentElement.nodeName;

if (rootNodeName == "parsererror") throw("Invalid XML structure");

// získá element dokumentu XML

xmlRoot = xmlResponse.documentElement;

// získá pole se jmény knih a jejich ISBN

titleArray = xmlRoot.getElementsByTagName("title");

isbnArray = xmlRoot.getElementsByTagName("isbn");

// generuje výstup HTML

var html = "";

// prochází pole a tvoří strukturu HTML

for (var i=0; i<titleArray.length; i++)

html += titleArray.item(i).firstChild.data +

", " + isbnArray.item(i).firstChild.data + "<br/>";

// získá odkaz na element <div> na stránce

myDiv = document.getElementById("myDivElement");

// zobrazí výstup HTML // zobrazí výstup HTML

myDiv.innerHTML = html; myDiv.innerHTML = html;

}

4. A nakonec soubor phptest.php:

<?php

// nastaví typ výstupu jako xml

header('Content-Type: text/xml');

// vytvoří nový dokument XML

$dom = new DOMDocument();

// vytvoří kořenový element <response>

$response = $dom->createElement('response');

$dom->appendChild($response);

// vytvoří element <books> a vloží jej jako potomek <response>

$books = $dom->createElement('books');

Page 33: Ajax a PHP

84 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

$response->appendChild($books);

// vytvoří element 'title'

$title = $dom->createElement('title');

$titleText = $dom->createTextNode

('Building Reponsive Web Applications with AJAX and PHP');

$title->appendChild($titleText);

// vytvoří element 'isbn'

$isbn = $dom->createElement('isbn');

$isbnText = $dom->createTextNode('1-904811-82-5');

$isbn->appendChild($isbnText);

// vytvoří element <book>

$book = $dom->createElement('book');

$book->appendChild($title);

$book->appendChild($isbn);

// přidá <book> jako potomek <books>

$books->appendChild($book);

// v řetězcové proměnné vytvoří strukturu XML

$xmlString = $dom->saveXML();

// výstup řetězce XML

echo $xmlString;

?>

5. Nejdříve provedeme jednoduchý test, abychom viděli, co phptest.php vrací. Do prohlížeče zadáme adresu http://localhost/ajax/foundations/php/phptest.php a ujistíme se, že se nám generuje správná struktura XML:

Obrázek 3.1. Jednoduchá struktura XML, která je generovaná pomocí PHP.

Page 34: Ajax a PHP

85AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

Jestliže výsledek není takový, jaký byste očekávali, zkontrolujte nejen kód, ale i svou instalaci PHP. Správným nastavením počítače se zabývá Příloha A.

6. Když víme, že server vrací správnou odpověď, otestujte celé řešení tak, že zadáte adresu http://localhost/ajax/foundations/php/phptest.html:

Obrázek 3.2. AJAX s použitím PHP.

Jak to funguje?Když se dostáváme ke generování struktur XML nejenom na straně klienta, ale i na straně serveru, musíme si vybrat mezi tvorbou XML dokumentu pomocí DOM nebo spojováním řetězců. Náš PHP skript phptest.php začíná nastavením typu výstupu na text/xml:

<?php

header('Content-Type: text/xml');

Dokumentace PHP pro header je na adrese http://www.php.net/manual/en/function.hea-der.php (slovo header také snadno můžete vyhledat v aplikaci Suggest, která vás nasměruje pří-mo na stránku nápovědy).

Přestože v souborech JavaScriptu používáme pro řetězce uvozovky, v jazyce PHP se snažíme používat apostrofy. Zpracovávají se rychleji, jsou bezpečnější a vedou k menšímu množství programátorských chyb. Více informací o řetězcích v PHP naleznete na adrese http://php.net/types.string. Na toto téma rovněž existují dva užitečné články – http://www.sitepoint.com/print/quick--php-tips a http://www.jeroenmulder.com/weblog/2005/04/php_single_and_dou-ble_quotes.php.

Není překvapivé, že DOM jazyka PHP vypadá trochu jako DOM JavaScriptu. Oba začínají tvorbou objektu dokumentu DOM, který je v PHP reprezentován třídou DOMDocument:

// vytvoří nový dokument XML

$dom = new DOMDocument();

Page 35: Ajax a PHP

86 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

Při vytváření struktury XML pak pokračujeme pomocí metod createElement, createTextNode, appendChild a tak dále:

// vytvoří kořenový element <response>

$response = $dom->createElement('response');

$dom->appendChild($response);

// vytvoří element <books> a vloží jej jako potomek <response>

$books = $dom->createElement('books');

$response->appendChild($books);

...

Nakonec pomocí funkce saveXML uložíme celou strukturu jako řetězec a příkazem echo ji vypíše-me na výstup:

$xmlString = $dom->saveXML();

echo $xmlString;

?>

Pomocí technik uvedených v kapitole 2 je pak XML dokument přečten a zobrazen.

Ve většině případů budeme XML dokumenty generovat na serveru a poté je číst v klientovi. Jde to však dělat i jinak. V kapitole 2 jsme viděli, jak vytvořit dokumenty a elementy XML pomocí DOMu JavaScriptu. Tyto struktury je pak možné přenášet do PHP (pomocí metody GET nebo POST, jak uvidí-me v následujícím cvičení). Pro čtení XML struktur v PHP je možné použít buď DOM, nebo jednodušší API (nazvané jako SimpleXML). S tímto API se naučíme pracovat v kapitole 9, při tvorbě RSS čtečky.

Vkládání parametrů a ošetřování chyb PHPPředchozí cvičení se nezmiňovalo o dvou podstatných aspektech psaní PHP skriptů:

• Skriptu na straně serveru (PHP) je obvykle potřeba zaslat nějaké parametry.

• Strana klienta je poměrně dobře zajištěna – techniku ošetření chyb je tedy dobré implemen-tovat i na straně serveru.

Parametry PHP skriptu je možné poslat buď pomocí metody GET nebo pomocí POST. Ošetřování chyb zajistíme pomocí techniky, která je specifická pro PHP. V následujícím cvičení vložíme do PHP skriptu parametry a implementujeme mechanismus ošetření chyb, který pak otestujeme za-dáním špatných hodnot. Aplikace bude vypadat jako na obrázku 3.3.

Tato stránka provede asynchronní volání serveru a požádá jej o vydělení dvou čísel. Pokud je vše v pořádku, server odpoví XML strukturou, která vypadá takto:

<?xml version="1.0"?>

Page 36: Ajax a PHP

87AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

<response>1.5</response>

Jestliže se v PHP objeví chyba, server neodpoví vygenerováním řetězce XML, ale vrátí chybovou zprávu. Tato zprává je ve formě prostého textu a je zachycena klientem. Na konci cvičení pochopí-te, proč tomu tak je.

Čas pro akci – Vkládání parametrů do PHP a ošetřování chyb 1. Ve složce foundations vytvořte novou složku, nazvanou morephp.

2. V této složce vytvořte soubor nazvaný morephp.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html>

<head><title>Practical AJAX: PHP Parameters and Error Handling</title>

<script type="text/javascript" src="morephp.js"></script>

</head>

<body>

Ask server to divide

<input type="text" id="firstNumber" />

by

<input type="text" id="secondNumber" />

<input type="button" value="Send" onclick="process()" />

<div id="myDivElement" />

</body>

</html>

3. Vytvořte soubor, pojmenovaný jako morephp.js:

// zde bude instance objektu XMLHttpRequest

var xmlHttp = createXmlHttpRequestObject();

// vytvoří instanci XMLHttpRequest

function createXmlHttpRequestObject()

{

// zde bude reference na objekt XMLHttpRequest

var xmlHttp;

// toto by mělo fungovat ve všech prohlížečích mimo IE6 a starší

try

{

// pokusí se vytvořit objekt XMLHttpRequest

xmlHttp = new XMLHttpRequest();

}

catch(e)

Page 37: Ajax a PHP

88 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

{

// předpokládá IE6 nebo starší

var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",

"MSXML2.XMLHTTP.5.0",

"MSXML2.XMLHTTP.4.0",

"MSXML2.XMLHTTP.3.0",

"MSXML2.XMLHTTP",

"Microsoft.XMLHTTP");

// vyzkoušej všechna prog id, dokud některé nebude funkční

for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++)

{

try

{

// pokusí se vytvořit objekt XMLHttpRequest

xmlHttp = new ActiveXObject(XmlHttpVersions[i]);

}

catch (e) {}

}

}

// vrátí vytvořený objekt nebo zobrazí chybovou zprávu

if (!xmlHttp)

alert("Error creating the XMLHttpRequest object.");

else

return xmlHttp;

}

// přečte soubor ze serveru

function process()

{

// pokračuj jen, není-li xmlHttp prázdné

if (xmlHttp)

{

// pokus se připojit k serveru

try

{

// vezme dvě hodnoty zadané uživatelem

var firstNumber = document.getElementById("firstNumber").value;

var secondNumber = document.getElementById("secondNumber").value;

// vytvoří řetězec parametrů

var params = "firstNumber=" + firstNumber +

"&secondNumber=" + secondNumber;

// iniciuje asynchronní požadavek HTTP

xmlHttp.open("GET", "morephp.php?" + params, true);

Page 38: Ajax a PHP

89AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

xmlHttp.onreadystatechange = handleRequestStateChange;

xmlHttp.send(null);

}

// v případě selhání zobraz chybu

catch (e)

{ alert("Can't connect to server:\n" + e.toString()); }

}

}

// funkce se volá při změně stavu HTTP požadavku

function handleRequestStateChange()

{

// je-li readyState 4, můžeme přečíst odpověď serveru

if (xmlHttp.readyState == 4)

{

// pokračuj pouze, je-li stav HTTP "OK"

if (xmlHttp.status == 200)

{

try

{ handleServerResponse(); }

catch(e)

{ alert("Error reading the response: " + e.toString()); }

}

else

{

alert("There was a problem retrieving the data:\n" +

xmlHttp.statusText);

}

}

}

// zpracuje odpověď získanou od serveru

function handleServerResponse()

{

// získá odpověď od serveru, zabalenou jako objekt XML DOM

var xmlResponse = xmlHttp.responseXML;

// zachycení možných chyb u IE a Opery // zachycení možných chyb u IE a Opery

if (!xmlResponse || !xmlResponse.documentElement) if (!xmlResponse || !xmlResponse.documentElement)

throw("Invalid XML structure:\n" + xmlHttp.responseText); throw("Invalid XML structure:\n" + xmlHttp.responseText);

// zachycení možných chyb u Firefoxu

var rootNodeName = xmlResponse.documentElement.nodeName;

if (rootNodeName == "parsererror") if (rootNodeName == "parsererror")

throw("Invalid XML structure:\n" + xmlHttp.responseText); throw("Invalid XML structure:\n" + xmlHttp.responseText);

// získá kořenový element (element dokumentu))

Page 39: Ajax a PHP

90 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

xmlRoot = xmlResponse.documentElement;

// testuje, zda jsme získali XML dokument, který očekáváme// testuje, zda jsme získali XML dokument, který očekáváme

if (rootNodeName != "response" || !xmlRoot.firstChild) if (rootNodeName != "response" || !xmlRoot.firstChild)

throw("Invalid XML structure:\n" + xmlHttp.responseText); throw("Invalid XML structure:\n" + xmlHttp.responseText);

// hodnota, kterou chceme zobrazit,

// je potomkem kořenového elementu <response>

responseText = xmlRoot.firstChild.data;

// zobrazí zprávu uživateli

myDiv = document.getElementById("myDivElement");

myDiv.innerHTML = "Server says the answer is: " + responseText;

}

4. Vytvořte soubor nazvaný morephp.php:

<?php

// zavedem modul ošetření chyb

require_once('error_handler.php');

// nastaví typ výstupu jako xml

header('Content-Type: text/xml');

// spočítá výsledek

$firstNumber = $_GET['firstNumber'];

$secondNumber = $_GET['secondNumber'];

$result = $firstNumber / $secondNumber;$result = $firstNumber / $secondNumber;

// vytvoří nový dokument XML

$dom = new DOMDocument();

// vytvoří kořenový element <response> a přidá jej do dokumentu

$response = $dom->createElement('response');

$dom->appendChild($response);

// spočítanou hodnotu vloží jako textový

// uzel, který je potomkem <response>

$responseText = $dom->createTextNode($result);

$response->appendChild($responseText);

// v řetězcové proměnné vytvoří strukturu XML

$xmlString = $dom->saveXML();

// výstup řetězce XML

echo $xmlString;

?>

5. Nakonec vytvořte soubor pro zpracování chyb, error_handler.php:

<?php

// nastaví uživatelskou metodu ošetření chyb na error_handler

set_error_handler('error_handler', E_ALL);

// funkce ošetření chyb

Page 40: Ajax a PHP

91AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

function error_handler($errNo, $errStr, $errFile, $errLine)

{

// smaže všechny výstupy, které byly dosud generovány

if(ob_get_length()) ob_clean();

// výstup chybové zprávy

$error_message = 'ERRNO: ' . $errNo . chr(10) .

'TEXT: ' . $errStr . chr(10) .

'LOCATION: ' . $errFile .

', line ' . $errLine;

echo $error_message;

// zabrání zpracování jiných skriptů PHP

exit;

}

?>

6. Do prohlížeče zadejte adresu http://localhost/ajax/foundations/morephp/morephp.html a vyzkoušejte tento příklad.

Obrázek 3.3. Parametry PHP a ošetření chyb.

Jak to funguje?Nyní vám musí být většina kódu na straně serveru určitě povědomá, a proto se zaměříme na stranu serveru, která se skládá ze dvou souborů: morephp.php a error_handler.php.

Očekává se, že výstupem souboru morephp.php bude struktura XML s výsledkem dělení čísel. Ta však začíná načtením rutiny pro zpracování chyb. Ta by měla zachytit jakoukoliv případnou chybu, vytvořit lépe zpracovanou chybovou zprávu (v porovnání s tou standardní) a zaslat ji zpět klien-tovi.

<?php

// načtení modulu pro zpracování chyb

require_once('error_handler.php');

Page 41: Ajax a PHP

92 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

Podobně jako jiné OOP jazyky, i PHP 5 podporuje výjimky. U tohoto jazyka jsme však omezeni na ob-jekty výjimek, které sami vyhodíme (throw) a následně zachytíme (catch), a jež nám mohou pomoci při tvorbě rozsáhlých architektur. Samotné jádro PHP při chybových událostech výjimky negeneruje. Když se objeví nějaký problém, generuje se chyba (error), která – v porovnání s výjimkami – předsta-vuje primitivní způsob zpracování chybových stavů vzniklých při běhu programu. Je to kvůli zpětné kompatibilitě. To znamená, že chybu není možné zachytit, lokálně ji zpracovat a poté pokračovat v normálním běhu skriptu, jak je tomu u výjimek. Nejlepší je specifikovat nějakou funkci, která se auto-maticky provede při výskytu chyby. Taková funkce je volána ještě před ukončením skriptu a dává tak poslední možnost provést nějaké závěrečné akce – logování chyby, ukončení databázových spojení, vypsání nějaké přívětivé chybové zprávy návštěvníkovi webu atd.

V našem kódu má skript error_handler.php ošetřovat chyby. Případnou chybu tak jednoduše přijme a příslušnou zprávu transformuje takovým způsobem, aby byla čitelnější, než standardní in-formace. Poznamenejme, že error_handler.php sice zachytí většinu chyb, ovšem určitě ne všech-ny! Fatální chyby nemohou být kódem PHP polapeny, přičemž generují výstup, který je mimo kontrolu programu. Ještě před spuštěním kódu PHP jsou například zachyceny chyby parsování, ke kterým může dojít třeba tehdy, když na začátku jména proměnné zapomenete na symbol $. Takové chyby nejsou zpracovány kódem PHP, ale jsou zapsány do chybového logu serveru Apache.

Chybový log Apache je důležité zkontrolovat vždy, když se skripty PHP chovají divně. Může vás totiž uchránit před spoustou starostí. Jeho výchozí umístění je v Apache2\logs\error.log.

Po nastavení rutiny pro ošetření chyb nastavíme typ obsahu na XML a první přijaté číslo vydělí-me druhým. Povšimněte si syntaxe $_GET pro čtení proměnných, které byly zaslány pomocí GET. Posíláme-li proměnné pomocí POST, měli bychom použít $_POST. Alternativně je možné použít $_REQUEST, které najde proměnné zaslané jakoukoliv metodou (včetně cookies), je však obecně doporučováno jej nepoužívat, protože je o něco pomalejší, než ostatní metody.

header('Content-Type: text/xml');

$firstNumber = $_GET['firstNumber'];

$secondNumber = $_GET['secondNumber'];

$result = $firstNumber / $secondNumber;

Bude-li $secondNumber rovno 0, bude operace dělení generovat chybu. Očekáváme, že tato chy-ba bude zachycena kódem pro ošetření chyb. Poznamenejme, že profesionálnější by bylo zajistit kon trolu hodnoty proměnné ještě před samotným dělením, nicméně nyní se zabýváme popisem skriptu pro ošetření chyb.

Po vypočítání hodnoty ji zabalíme do dokumentu XML a vypíšeme ji, podobně jako v předchozím cvičení:

$dom = new DOMDocument();

Page 42: Ajax a PHP

93AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

$response = $dom->createElement('response');

$dom->appendChild($response);

$responseText = $dom->createTextNode($result);

$response->appendChild($responseText);

$xmlString = $dom->saveXML();

echo $xmlString;

?>

Dále se pak podívejme na skript pro ošetření chyb – error_handler.php. Smyslem tohoto sou-boru je zachycování všech chybových zpráv generovaných PHP a generování vlastním chybových zpráv, které dávají smysl a jež mohou být zobrazeny kódem v JavaScriptu:

Obrázek 3.4. Hezky vypadající chybová zpráva.

Pokud bychom neupravili zpracování chyb, vypadala by chybová zpráva nějak takto:

Obrázek 3.5. Nepřehledná chybová zpráva.

Chybové zprávy budou vypadat jako na obrázku 3.5 v případě, že volba display_errors v php.ini je nastavena na On. Standardně je vypnuta (volba Off) , přičemž chyby se v takovém případě zapisují do chybového logu Apache. Zobrazování těchto chybových zpráv ovšem může být při vytváření kódu velmi užitečné. Pokud se však jedná o kód, který už běží v ostrém provozu, jsou obě chybové zprávy nevhodné. Uživatelům byste totiž nikdy neměli ukazovat ladicí informace.

Co se tedy děje v error_handler.php? V souboru je nejdříve použita funkce set_error_handler k tomu, aby nastavila novou funkci pro ošetření chyb:

<?php

set_error_handler('error_handler', E_ALL);

Page 43: Ajax a PHP

94 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

Když dojde k chybě, použijeme nejprve ob_clean() a smažeme výstup, který byl generován – jako je třeba část <response></response> z obrázku 3.5:

function error_handler($errNo, $errStr, $errFile, $errLine)

{

if(ob_get_length()) ob_clean();

Pokud však chceme během ladění ponechat tyto části kódu raději tam, kde jsou, můžete volání ob_clean() okomentovat. Chybová zpráva se tvoří pomocí systémových proměnných $errNo, $errStr, $errFile a $errLine. Konec řádku je generován funkcí chr.

$error_message = 'ERRNO: ' . $errNo . chr(10) .

'TEXT: ' . $errStr . chr(10) .

'LOCATION: ' . $errFile .

', line ' . $errLine;

echo $error_message;

exit;

}

?>

Zde představené schéma zpracování chyb je hodně zjednodušené a je vhodné pouze během psaní a ladění kódu. Ve finálním řešení je potřeba koncovému uživateli zobrazit přátelskou zprávu bez ja-kýchkoliv technických detailů. Chcete-li informace o chybě zabalit jako dokument XML, který přenese-te ke klientovi, mějte na paměti, že fatální chyby a chyby v parsování nebudou vaší funkcí zpracovány a budou se chovat podle nastavení v konfiguračním souboru PHP (php.ini).

Tento případ rovněž představuje scénář, ve kterém se uživatel může pokoušet o několik součas-ných požadavků na server (toho lze dosáhnout např. dostatečně rychlým vícenásobným kliknutím na tlačítko Send). Když se pokusíte vytvořit nový požadavek prostřednictvím zaneprázdněného objektu XMLHttpRequest, bude jeho metoda open generovat výjimku. Kód je pomocí konstrukce try/catch dobře chráněn, nicméně chybová zpráva na obrázku 3.6 nevypadá příliš přátelsky.

Obrázek 3.6. Požadavek na zaneprázdněný XMLHttpRequest.

Tato zpráva může být sice to, co potřebujete, ale za určitých okolností by mohlo být lepší reagovat na tento druh chyb jiným způsobem, než na ostatní typy chyb. Ve finálním kódu například můžete

Page 44: Ajax a PHP

95AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

chtít zobrazit nějakou poznámku na stránce, nebo přátelskou zprávu typu "zkuste to, prosím, poz-ději". Toho dosáhnete modifikací funkce process(), jak je ukázáno v následujícím úseku kódu:

// přečte soubor ze serveru

function process()

{

if (!xmlHttp) return; // pokračuj jen tehdy, není-li xmlHttp prázdné if (!xmlHttp) return; // pokračuj jen tehdy, není-li xmlHttp prázdné

// je-li XMLHttpObject zaneprázdněn, nepokoušej // je-li XMLHttpObject zaneprázdněn, nepokoušej

// se vytvořit požadavek na server // se vytvořit požadavek na server

if !(xmlHttp.readyState == 0 || xmlHttp.readyState == 4) if !(xmlHttp.readyState == 0 || xmlHttp.readyState == 4)

alert("Can't connect to server, please try again later."); alert("Can't connect to server, please try again later.");

else else

{ {

// pokus se připojit k serveru

try

{

// vezme dvě hodnoty zadané uživatelem

var firstNumber = document.getElementById("firstNumber").value;

var secondNumber = document.getElementById("secondNumber").value;

// vytvoří řetězec parametrů

var params = "firstNumber=" + firstNumber +

"&secondNumber=" + secondNumber;

// iniciuje asynchronní požadavek HTTP

xmlHttp.open("GET", "morephp.php?" + params, true);

xmlHttp.onreadystatechange = handleRequestStateChange;

xmlHttp.send(null);

}

// v případě selhání zobraz chybu

catch (e)

{

alert("Can't connect to server:\n" + e.toString());

}

}

}

Přesný způsob pro ošetření takových chyb se může měnit v závislosti na scénáři. V průběhu této knihy se setkáte s následujícími možnými řešeními:

• Někdy můžeme tyto chyby jednoduše ignorovat.

• Jindy zobrazíme připravenou chybovou zprávu, jako například v předchozím kódu.

Ve většině případů se pokusíme vzniku chyby předejít – vždy je totiž lepší problému zabránit, než jej následně řešit. Existuje několik způsobů, jak například zabránit zprávám typu "zaneprázdněné

Page 45: Ajax a PHP

96 Kapitola 3 – Techniky na straně serveru s PHP a MySQL

spojení" ("connection busy"), ke kterým dochází při pokusu vytvořit požadavek na server pomocí objektu XMLHttpRequest, jenž stále zpracovává požadavek předchozí:

• Pro každý požadavek, který chceme poslat na server, můžeme otevřít nové spojení (vytvořit nový objekt XMLHttpRequest). Tuto metodu lze sice jednoduše implementovat a v mnoha případech může velmi být užitečná, ovšem obecně byste se měli pokusit se jí vyhnout, pro-tože může vést ke snížení výkonu serveru (skript totiž pokračuje v otevírání nových spojení a iniciaci dalších požadavků, i když server nedokončil odpovědi na požadavky předchozí), a protože neexistuje žádná záruka toho, že odpovědi dostanete ve stejném pořadí, v jakém jste volali server (což platí hlavně v případě zaneprázdněného serveru nebo pomalé sítě).

• Požadavek je možné zaznamenat do fronty a odeslat ji později, až bude spojení opět do-stupné (tuto metodu uvidíme v činnosti v některých cvičeních v této knize, včetně kapitol popisujících kontrolu formulářových dat v AJAXu či chat vytvořený pomocí AJAXu).

• Požadavek úplně ignorovat. To je možné pouze tehdy, když můžete implementovat kód, kte-rý nedovolí prostřednictvím jednoho spojení odeslat více požadavků na server.

Připojení ke vzdálenýmserverům a bezpečnost JavaScriptuMůžete být překvapeni zjištěním, že cvičení v PHP, které jsme právě dokončili, pracovalo bez pro-blémů, protože PHP skripty na serveru, jež byly volány asynchronně, byly spuštěny na stejném serveru, ze kterého byl načten příslušný HTML soubor.

Webové prohlížeče mají velice striktní metody (které se v různých prohlížečích liší) pro kontrolu prostředků, jež můžeme využívat z kódu JavaScriptu. Chcete-li z JavaScriptu přistupovat k jinému serveru, můžeme s jistotou říci, že je to problém. Tímto tématem se budeme zabývat v následujícím cvičení, nyní ovšem bude následovat trocha teorie.

Kód v JavaScriptu běží s bezpečnostními oprávněními svého rodičovského HTML souboru. Když z nějakého serveru načteme HTML stránku, standardně bude kódu JavaScriptu na této stránce umožněno provádět HTTP požadavky na tento server. Ale pouze na tento! Jakýkoliv jiný server je potenciální nepřítel, se kterým se v každém prohlížeči zachází trochu jinak.

Internet Explorer patří k přátelským webovým prohlížečům, což znamená, že je pravděpodobně méně bezpečný, ale více praktický. Používá bezpečnostní model založený na zónách. Jedná se o čty-ři zóny: Internet, Místní intranet, Důvěryhodné servery a Servery s omezeným přístupem. Každá zóna má různé nastavení bezpečnosti, které lze změnit v menu Nástroje | Možnosti Internetu | Zabezpečení. Při přístupu k nějakému prostředku na webu mu bude automaticky přiřazena jedna z bezpečnostních zón, přičemž se použijí příslušná bezpečnostní nastavení.

V závislosti na systému se výchozí bezpečnostní nastavení mohou měnit. Internet Explorer stan-dardně dává plná práva skriptům, které jsou načteny z lokálních souborů (nikoliv skriptům načte-

Page 46: Ajax a PHP

KAPITOLA 5Chat v AJAXu

Žijeme ve světě, ve kterém je komunikace velice důležitá, a proto je nezbytné mít možnost snadno a rychle komunikovat s ostatními. E-mail, SMS zprávy, poštovní dopisy či online chat představují prostředky, pomocí kterých si lidé mohou vyměňovat myšlenky v textové podobě. Při komunikaci je důležitý faktor přístupnosti. Klasické dopisy (a vlastně ani e-maily) nedávají možnost bezpro-střední odezvy adresáta zprávy. Telefonáty a online chat však představují dynamičtější způsob ko-munikace, takže v této kapitole se budeme zabývat vytvářením ajaxového online chatu.

Úvod do ajaxového chatuVětšina komunikace uskutečňované pomocí počítače se odehrává prostřednictvím desktopových aplikací. Takové aplikace často komunikují s ostatními decentralizovaným způsobem, např. po-mocí P2P systémů (Peer to Peer). Jejich použití však není možné v případě, pokud jste připojení k Internetu ve firmě, jejíž bezpečnostní politika zabraňuje uživatelům otevírat spojení na jiném portu, než je HTTP (port 80). V tomto případě se jedná o skutečný problém.

Existuje mnoho audio (ale i video) chatů, přičemž většina z nich je založena na Java apletech. Ap-plety jsou ovšem pověstné svými bezpečnostními problémy v prohlížečích, nehledě na fakt, že pro komunikaci občas nepoužívají port 80. Pro spojení s přáteli mimo firmu proto nejsou řešením.

Zde do hry vstupuje AJAX, který přináší řešení našich problémů. S minimálním úsilím je tak mož-né do prohlížeče integrovat IRC (Internet Relay Chat) klienta, nebo vyvinout vlastní řešení, které bude podobné tomu, jež popíšeme dále v této kapitole.

Jste otráveni tím, že v práci nebo internetové kavárně nemůžete instalovat (a ani používat) svůj ob-líbený program pro výměnu zpráv? Možná se v uvedené situaci sami nacházíte. V takovém případě je ideální čas se podívat na to, jak tuto nepříjemnou situaci překonat pomocí vlastního ajaxového chatu.

Page 47: Ajax a PHP

176 Kapitola 5 – Chat v AJAXu

Již existující chaty v AJAXuAsi nejpůsobivějším řešením současné doby je www.meebo.com. Je možné, že jste o něm už někdy slyšeli; a pokud náhodou ne, je čas se na něj podívat. Jeho nejvýznamnější a nejzajímavější vlast-ností je, že vám pomocí webového rozhraní umožní se připojit do vašeho oblíbeného systému pro komunikaci s ostatními. Přihlašovací obrazovku systému Meebo vidíme na obrázku 5.1.

Obrázek 5.1. Meebo.

Meebo na své úvodní stránce nabízí přístup ke všem službám pomocí uživatelsky přívětivého roz-hraní – bez vyskakovacích oken, Java apletů a podobně. Použitím řešení, které bude založeno na AJAXu, můžete zapomenout na všechny problémy uvedené na začátku této kapitoly.

Meebo není jedinou webovou aplikací, která nabízí funkcionalitu chatu. I když je AJAX velice mla-dý, již dnes můžeme nalézt i další chatové aplikace a řešení na něm založená:

• http://www.plasticshore.com/projects/chat/index.html.

• http://treehouse.ofb.net/chat/?lang=en.

• http://www.chategory.org.

• http://www.socket7.net/lace/.

• http://drupal.org/node/27689.

Je čas začít pracovat. Ve zbývající části kapitoly implementujeme naši vlastní chatovou aplikaci.

Page 48: Ajax a PHP

177AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

Implementace ajaxového chatuNaše aplikace má být jednoduchá, modulární a rozšiřitelná. Z tohoto důvodu nechceme imple-mentovat např. registraci a přihlašování, chatovací místnosti, seznam online uživatelů a podobně. Díky jednoduchosti se můžeme lépe zaměřit na cíl této kapitoly – na samotný ajaxový chat. Bu-deme implementovat základní funkci chatu – odesílání a příjem zpráv bez nutnosti znovunačítání stránek. Uživateli dále umožníme změnit barvu jeho zpráv (týká se to ajaxového mechanismu, který bude dalším dobrým cvičením).

Aplikaci, kterou prezentujeme v této kapitole, můžeme snadno rozšířit implementací dalších mo-dulů, jež nalezete v řešeních uvedených jinde v této knize, a která v této kapitole nejsou zmiňována. Pokud se vám chce, můžete se o to pokusit jako za domácí úkol.

Aby byly tyto příklady funkční, potřebujete knihovnu GD. Instalační instrukce v Příloze A obsahu-jí podporu i pro tuto knihovnu. Chatovou aplikaci můžete otestovat na adrese http://ajaxphp.packtpub.com. Vypadá jako na obrázku 5.2.

Obrázek 5.2. Ajaxový chat.

Novinkou v této kapitole je, že budeme používat dva objekty XMLHttpRequest. První se bude za-bývat aktualizací okna s chatem, druhý bude ovládat výběr barev – když klikneme na obrázek, přenesou se souřadnice na server, který odpoví kódem vybrané barvy.

Zprávy pro ajaxový chat budou uloženy ve frontě (se strukturou FIFO), kterou jsme se zabývali v kapitole 4, takže o poslané zprávy nepřijdete ani v případě pomalého serveru. Zprávy budou na server poslány v takovém pořadí, v jakém byly odeslány. Na rozdíl od jiných chatovacích aplikací,

Page 49: Ajax a PHP

178 Kapitola 5 – Chat v AJAXu

které jsou v současně době k dispozici ke stažení zdarma, také zajistíme, že dokud nebude aktuální požadavek vyřízen, nebude server zatěžován požadavky dalšími.

Čas pro akci – Ajaxový chat 1. Připojte se k databázi ajax a pomocí následujícího kódu vytvořte tabulku chat:

CREATE TABLE chat

(

chat_id int(11) NOT NULL auto_increment,

posted_on datetime NOT NULL,

user_name varchar(255) NOT NULL,

message text NOT NULL,

color char(7) default '#000000',

PRIMARY KEY (chat_id)

);

2. Ve složce ajax vytvořte novou složku nazvanou chat.

3. Ze stažených zdrojových souborů zkopírujte do složky chat soubor palette.png.

4. Při tvorbě aplikace začneme s funkcionalitou serveru. Ve složce chat vytvořte soubor con-fig.php a vložte do něj kód pro konfiguraci databáze (hodnoty případně upravte tak, aby odpovídaly vašemu nastavení):

<?php

// definuje data pro spojení s databází

define('DB_HOST', 'localhost');

define('DB_USER', 'ajaxuser');

define('DB_PASSWORD', 'practical');

define('DB_DATABASE', 'ajax');

?>

5. Nyní přidejte standardní soubor pro zpracování chyb error_handler.php:

<?php

// nastaví uživatelskou metodu ošetření chyb na error_handler

set_error_handler('error_handler', E_ALL);

// funkce pro ošetření chyb

function error_handler($errNo, $errStr, $errFile, $errLine)

{

// smaže všechny výstupy, které byly dosud generovány

if(ob_get_length()) ob_clean();

// výstup chybové zprávy

$error_message = 'ERRNO: ' . $errNo . chr(10) .

Page 50: Ajax a PHP

KAPITOLA 7Tvorba grafův reálném čase pomocí SVGTechnologie SVG (Scalable Vector Graphics) je jednou z technologií, která má v oblasti webové grafiky šanci se stát další "velkou věcí", podobně jako Flash. SVG je jazyk pro definici dvouroz-měrné grafiky. SVG nemusí být nutně spojeno s vývojem webů, nicméně dobře zapadá do jeho kontextu, protože vhodně doplňuje prvky, které dnes nabízejí webové prohlížeče. V současnosti bohužel existuje mnoho implementací SVG, přičemž úroveň jejich standardizace není dobrá – vše však nasvědčuje tomu, že v budoucnu dojde ke změně k lepšímu.

SVG je doporučení konsorcia W3C (World Wide Web Consortium) z ledna 2003. Mezi známými jmény, která přispěla k jeho založení, můžeme uvést například Sun Microsystems, Adobe, Apple, IBM, nebo Kodak. Aktuální je specifikace SVG 1.2. SVG Mobile, SVG Print a sXBL jsou další do-poručení, na kterých W3C pracuje, a jež budou pravděpodobně mít podporu u většiny platforem a prohlížečů.

Hlavní prvky SVG jsou následující:

• Grafika SVG je definována ve formátu XML, takže se soubory lze jednoduše manipulovat pomocí stávajících editorů a parserů.

• Obrázky SVG jsou škálovatelné – je možné je zoomovat, měnit jejich velikost či orientaci bez ztráty kvality.

• SVG obsahuje elementy pro fonty, takže text i grafika jsou uchovány.

• SVG obsahuje deklarativní elementy pro animaci.

• SVG umožňuje používat XML aplikace s vícenásobnými jmennými prostory.

• SVG dovoluje skriptům manipulovat se stromem dokumentu pomocí podmnožiny XML DOM a SVG DOM.

Page 51: Ajax a PHP

228 Kapitola 7 – Tvorba grafů v reálném čase pomocí SVG

Jako úvod do světa SVG mohou posloužit tyto odkazy:

• Stránka o SVG konsorcia W3C na http://www.w3.org/Graphics/SVG/.

• Úvod do SVG na adrese http://www.w3schools.com/svg/svg_intro.asp.

• Užitečný seznam odkazů ohledně SVG na http://www.svgi.org/.

• Reference SVG na http://www.w3schools.com/svg/svg_reference.asp.

• Struktura dokumentu SVG je vysvětlena na http://www.w3.org/TR/SVG/struct.html.

• Příklady SVG na http://www.carto.net/papers/svg/samples/ a http://svg-whiz.com/samples.html.

Implementace grafův reálném čase pomocí AJAXu a SVGPředtím, než budete pokračovat, se, prosím, ujistěte, že váš prohlížeč podporuje SVG. Kód v této případové studii byl testován pomocí Firefoxu 1.5 a Internet Exploreru s programy Adobe SVG Viewer a Apache Batik. Demonstrační ukázku vztahující se k této kapitole můžete otestovat na stránkách http://ajaxphp.packtpub.com.

Firefox je dodáván s integrovanou podporou SVG. Jedná se o první verzi implementace, takže při psaní kódu je potřeba počítat s jistými problémy, např. výkon není nijak oslňující.

Pro zobrazení SVG v Internet Exploreru je potřeba instalovat externí SVG plug-in. Pro naše testy jsme použili plug-in od firmy Adobe, který je možné stáhnout na adrese http://www.adobe.com/svg/viewer/install/main.html. Instalační proces je velice jednoduchý – spočívá ve sta-žení a spuštění malého souboru SVGView.exe. Když se poprvé dostanete na stránku SVG, budete dotázáni, zdali souhlasíte s licenčními podmínkami.

Aplikaci jsme rovněž otestovali s SVG prohlížečem Apache Batik. Zde je však potřeba načíst SVG soubor přímo, protože Apache Batik nepodporuje načtení souboru HTML, který teprve poté načte příslušný SVG skript. Batik rozhodně doporučujeme vyzkoušet, protože obsahuje dobrý prohlížeč DOM, který zobrazí uzly SVG v pěkné hierarchické struktuře.

Pro případovou studii v této kapitole vytvoříme aplikaci s grafy, jejíž vstupní data budou asyn-chronně načítána z PHP skriptu. Generovanými daty může být cokoli – v našem případě použije-me jednoduchý algoritmus pro generování náhodných čísel. Na obrázku 7.1 je zobrazena ukázka výstupu aplikace.

Page 52: Ajax a PHP

229AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

Obrázek 7.1. Graf SVG.

Graf na obrázku 7.1 ukazuje statický SVG soubor temp.svg, který reprezentuje záznam výstu-pu generovaného běžící aplikací – nejedná se tedy o screenshot obrazovky s běžící aplikací. Tento skript je možné najít ve staženém zdrojovém kódu pro tuto kapitolu. Poté, co zajistíte, aby váš pro-hlížeč podporoval SVG, je možné jej přímo načíst do prohlížeče (není nutný webový server).

Nejprve se podíváme na obsah souboru temp.svg, abychom si udělali představu o tom, co všechno budeme v našem JavaScriptu dynamicky generovat. Poznamenejme, že SVG skript je možné gene-rovat buď na straně serveru, nebo na straně klienta. V naší aplikaci bude server generovat náhodné souřadnice, které klient následně použije k vytvoření SVG výstupu.

Podívejme se na zkrácenou verzi souboru temp.svg:

<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"

xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">

<a xlink:href="http://ajaxphp.packtpub.com">

<text x="200" y="20">

Demonstrace SVG s AJAXem a PHP

</text>

</a>

<!-- Všechny elementy grafu jsou seskupeny a přeloženy 50, 50 -->

<g transform="translate(50, 50)"> <g transform="translate(50, 50)">

<!-- Seskupení všech osových souřadnic (řádků a text. uzlů) -->

<g> <g>

<!-- Cesta kreslení mřížek os a jednotek -->

Page 53: Ajax a PHP

230 Kapitola 7 – Tvorba grafů v reálném čase pomocí SVG

<path stroke="black" stroke-width="2" d=" ... definice cesty zde..."/> <path stroke="black" stroke-width="2" d=" ... definice cesty zde..."/>

<!-- Textové uzly pro zobrazení svislých čísel jednotek -->

<text x="-10" y="322" stroke="black">0.0</text> <text x="-10" y="322" stroke="black">0.0</text>

...

... další textové uzly, které vykreslí vodorovná a svislá čísla

...

</g> </g>

<!-- Nakreslí čáry mezi uzly grafu -->

<path stroke="black" stroke-width="1" fill="none" d="... definice..."/> <path stroke="black" stroke-width="1" fill="none" d="... definice..."/>

<!-- Nakreslí uzly jako vyplněné modré kroužky -->

<circle cx="00" cy="239.143" r="3" fill="blue" /> <circle cx="00" cy="239.143" r="3" fill="blue" />

...

... další kroužky, reprezentující uzly grafu

...

</g> </g>

</svg>

Podívejme se podrobněji na tuto část kódu a popišme si všechny části grafu. Formát SVG pracuje se skupinami elementů, které jsou uzavřeny mezi značkami <g>. V souboru temp.svg máme dvě skupiny těchto značek – první skupina obsahuje všechny elementy grafu; druhý element <g> je potomkem prvního a obsahuje čáry os a jejich popisky.

SVG umí pracovat s mnoha typy elementů, které mohou být animované (ano – je to velice výkonný jazyk). V našem příkladu jsme použili několik základních: path (slouží pro vykreslení čar os a sa-motného grafu), text (slouží pro zobrazení čísel na osách a také pro dynamické zobrazení souřad-nic uzlu, na kterém je kurzor myši – tento druhý prvek není v kódu uveden) a circle (slouží pro vykreslení modrých teček, jež reprezentují jednotlivé uzly grafu).

Dokumentaci k těmto elementům nalezneme na:

• http://www.w3schools.com/svg/svg_path.asp.

• http://www.w3schools.com/svg/svg_circle.asp.

• http://www.w3schools.com/svg/svg_text.asp.

Cesty (path) jsou specifikovány definicí path. Úplný kód elementu path, který zobrazí čáry grafu na obrázku 7.1, vypadá takto:

<!-- Nakreslí čáry mezi uzly grafu -->

<path stroke="black" stroke-width="1" fill="none"

d="M0,239.143 L10,220.286 L20,213.429 L30,185.571 L40,145.714

L50,108.857 L60,129 L70,101.143 L80,58.2857 L90,78.4286"/>

Detailem, který byl v našem kousku kódu vynechán, jsou události mouseover a mouseout pro kroužky uzlů grafu. V našem případě bude událost mouseover (která se odpálí při pohybu kurzo-rem myši přes uzel) volat funkci JavaScriptu, jež nad uzlem zobrazí text, udávající jeho souřadnice.

Page 54: Ajax a PHP

231AJAX a PHP – tvoříme interaktivní webové aplikace PROFESIONÁLNĚ

Událost mouseout zajistí, že tento text zmizí. Tento prvek můžete vidět v akci na obrázku 7.2, který zobrazuje činnost SVG grafu.

Obrázek 7.2. Graf SVG v akci.

Abyste pomocí Firefoxu získali dynamicky vygenerovaný obsah SVG grafu, klikněte na graf pravým tlačítkem myši, zvolte Select All (Vybrat vše), pak opět klikněte na graf a zvolte View Selection Source (Zobrazit zdrojový kód výběru).

Když máme představu o tom, co budeme implementovat, můžeme začít. Je čas pro akci!

Čas pro akci – Tvorba SVG grafu v reálném čase 1. Začněte vytvořením nové složky ve složce ajax, která bude pojmenovaná svg_chart.

2. Ve složce svg_chart vytvořte soubor index.html s následujícím obsahem:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"

"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html><head><title>AJAX Realtime Charting with SVG</title>

</head>

<body>

<embed src="chart.svg" width="600" height="450" type="image/svg+xml" />

</body>

</html>