Artykuł w formie elektronicznej pochodzi z magazynu PHP Solutions. Wszelkie prawa zastrzeżone.
Rozpowszechnianie artykułu bez zgody Software Wydawnictwo Sp. z o.o. Zabronione.
Software Wydawnictwo Sp. z o.o., ul. Piaskowa 3, 01-067 Warszawa, POLSKA.
Kontakt: redakcja@phpsolmag.org
PHP Solutions Nr 1/2006
www.phpsolmag.org
48
Techniki
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
49
Techniki
A
JAX pozwala stworzyć dodatkowy
kanał komunikacji między klientem
a serwerem PHP, a tym samym
wysyłać i odbierać dane bez przeładowy-
wania strony. Otwiera to zupełnie nowe
możliwości, a w połączeniu z operacjami
na modelu DOM z poziomu JavaScriptu,
oznacza nadejście ery bogato wyposażo-
nych, interaktywnych aplikacji PHP, wol-
nych od irytującego klikania i czekania.
W tym artykule przedstawimy prak-
tyczne wprowadzenie do techniki AJAX
na przykładzie dwóch bibliotek PHP i nie-
wielkiej aplikacji o działaniu podobnym do
Google Suggest.
Czym jest AJAX?
AJAX (skrót od Asynchronous JavaScript
And XML) jest nazwą nowej metody pro-
gramowania, łączącej kilka różnych tech-
nik: (X)HTML i CSS do tworzenia interfej-
su użytkownika, DOM (Document Object
Model) do obsługi elementów dynamicz-
nych i interakcji oraz
XMLHttpRequest
do
Aplikacje tworzone w PHP pozwalają
osiągnąć bardzo wiele przy ograniczonym
oprogramowaniu klienckim, co oznacza łatwe
wdrażanie i aktualizacje, a tym samym szybkie
efekty pracy. Architektura ta ma też dotkliwe
wady, jak opóźnienia między wyświetlaniem
kolejnych stron lub brak możliwości pobierania
nowych danych bez wysyłania formularza.
Na szczęście istnieje mechanizm AJAX.
asynchronicznej wymiany danych. Techni-
ki te są łączone w jedną całość za pomocą
JavaScriptu, odpowiedzialnego za logikę
aplikacji i dynamiczną aktualizację interfej-
su użytkownika stosownie do potrzeb.
Pomimo XML w nazwie, AJAX nie-
koniecznie wymaga używania formatu
XML do wymiany danych. Poza XML-em
obsługiwane są między innymi zwykły
tekst, sformatowany HTML (dodawany
do bieżącej strony poprzez właściwość
innerHTML
) oraz format JSON (JavaScript
AJAX – wyjątkowo interaktywne
i wydajne aplikacje WWW
Joshua Eichorn, Werner M. Krauß
W SIECI
1. http://sourceforge.net/
projects/jpspan/ – strona
główna projektu JPSpan
2. http://pear.php.net/package/
HTML_AJAX/ – strona głów-
na pakietu HTML_AJAX
3. http://www.google.com/
webhp?complete=1&hl=en
– Google Suggest
4. http://www.ajaxpatterns.org/
– serwis poświęcony wzor-
com aplikacji AJAX
5. http://www.ajaxpatterns.org/
Suggestion – opis wzorca
w stylu Google Suggest
6. http://blog.joshuaeichorn.
com/archives/category/php/
ajax – blog Joshuy Eichorna
poświęcony AJAX-owi
Powinieneś wiedzieć...
Powinieneś się dobrze orientować
w zasadach programowania obiektowe-
go w PHP4 lub PHP5. Przyda się też
pewna znajomość JavaScriptu.
Obiecujemy...
Po przeczytaniu artykułu będziesz znał
zasadę działania i stosowania techniki
AJAX oraz śledzenia kodu. Pokażemy
też możliwości bibliotek implementują-
cych tę technikę.
PHP Solutions Nr 1/2006
www.phpsolmag.org
48
Techniki
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
49
Techniki
Object Notation), który można przepuścić
przez
eval()
w celu uzyskania typów
JavaScript. Można też korzystać z dowol-
nego innego formatu danych dającego się
obsłużyć w JavaScripcie i PHP.
AJAX-a można najprościej zde-
finiować jako metodę wykorzystania
JavaScriptu do komunikacji z serwerem
niezależnie od tradycyjnych żądań POST
i GET. Strona techniczna jest tu jednak
mniej istotna – najważniejsze są zupełnie
nowe możliwości tworzenia aplikacji inter-
netowych.
Podstawą pracy AJAX-a jest obiekt
XMLHttpRequest
, stanowiący standar-
dowy element wielu przeglądarek. Jeśli
postanowisz dodać obsługę AJAX-a do
swojej aplikacji za pomocą biblioteki,
to nie musisz wiele wiedzieć o samym
XMLHttpRequest
, gdyż wszystkim zajmie
się biblioteka. Fizyczna implementacja
obiektu
XMLHttpRequest
zależy od kon-
kretnej przeglądarki – w Internet Explo-
rerze jest to wbudowany obiekt ActiveX,
natomiast w Firefoksie, Safari i większości
innych przeglądarek jest on wewnętrznym
obiektem JavaScriptu.
XMLHttpRequest
udostępnia proste API,
pozwalające wysyłać do serwera żądania
HTTP metodami GET i POST. Dla serwe-
ra są to zwyczajne żądania przeglądarki,
zawierające nawet wszystkie pliki cookie
dla bieżącej domeny oraz autoryzację
HTTP (jeśli oczywiście jest włączona). Od
strony JavaScriptu,
XMLHttpRequest
daje
dostęp do treści i nagłówków podczas
wysyłania i odbioru żądań. Możliwość ta
jest często używana do poinformowania
serwera, że żądanie nie zostało zgłoszo-
możliwość uzyskania znacznie wyższego
poziomu interaktywności w aplikacjach
internetowych. Reakcje programu na dzia-
łania użytkownika są dużo szybsze, bez
nużącego klikania i czekania, przez co ob-
sługa całego programu znacznie bardziej
przypomina pracę z tradycyjną aplikacją
stacjonarną.
Rysunek 1 przedstawia przepływ da-
nych w typowej aplikacji internetowej. Użyt-
kownik wypełnia formularz i wysyła go na
serwer WWW, który przetwarza formularz
i odsyła dane do czekającego użytkownika.
Zwracanym wynikiem jest pełna strona
HTML, którą przeglądarka klienta musi za-
ładować w całości (treść i strukturę). Mar-
nuje się w ten sposób czas i pasmo, gdyż
kod strony wynikowej najczęściej niewiele
się różni od kodu poprzedniej strony.
Aplikacja AJAX wysyła do serwera
wyłącznie żądania pobierające nowe, po-
trzebne dane, a odpowiedź serwera jest
przetwarzana przez JavaScript po stronie
klienta. Dzięki wprowadzeniu tej dodatko-
wej warstwy JavaScriptu, przetwarzanie
danych nie spowalnia działania interfejsu
użytkownika. Cała aplikacja działa znacz-
nie szybciej, gdyż między serwerem,
a klientem przesyłanych jest nieporów-
nanie mniej danych, a spora część prze-
twarzania odbywa się po stronie klienta
(Rysunek 2).
Praktycznie rzecz ujmując, stworze-
nie aplikacji AJAX wymaga zatem dwóch
����
����������������
������
�����������������������
������������������
���������������������
������������������
���������������������
���
����
�����������������
��������������������
�������������������
Rysunek 1.
Przepływ danych w tradycyjnej aplikacji internetowej
����
������
���
����
����
����������������
������������������
������
������������������
������
������������������������
�������������������
���������������
�������������������
���������������
��������������
������������������������
������������
������������������
��������������
������������������������
�������������
Rysunek 2.
Przepływ danych w aplikacji AJAX
ne bezpośrednio przez użytkownika, lecz
poprzez
XMLHttpRequest
. Odebraną treść
można traktować jako zwykły tekst, ale
w przypadku treści typu
text/xml
można
też stworzyć obiekt XML DOM. Obsługa
modelu DOM przyczyniła się do popular-
ności XML-a jako formatu wymiany da-
nych między klientem a serwerem, nato-
miast utrzymanie obsługi zwykłego tekstu
pozwala korzystać z dowolnego formatu
dającego się przetworzyć na poziomie
JavaScriptu.
Dlaczego AJAX?
Najważniejszym argumentem przema-
wiającym za korzystaniem z AJAX-a jest
PHP Solutions Nr 1/2006
www.phpsolmag.org
50
Techniki
elementów: odpowiednich skryptów po
stronie klienta i specjalnego kanału komu-
nikacji z serwerem.
Zalety techniki AJAX
AJAX ma wiele zalet, z których najbardziej
zauważalną jest znaczące rozszerzenie
zakresu możliwości interfejsu użytkowni-
ka. Jednak samo w sobie to nie wystar-
czy – w końcu istnieje też wiele innych
technologii o zbliżonych możliwościach.
O wyjątkowości AJAX-a stanowi przede
wszystkim to, że bazuje on na uznanych
standardach, więc w przeciwieństwie do
innych narzędzi do tworzenia interaktyw-
nych aplikacji internetowych (na przykład
Flasha) można go z łatwością wpasować
w istniejące procesy deweloperskie. Moż-
na więc dalej korzystać ze swojego ulu-
bionego edytora czy środowiska programi-
stycznego, bez konieczności poznawania
nowych narzędzi.
Istnieje też wiele darmowych zesta-
wów narzędzi Open Source ułatwiających
tworzenie i rozwijanie aplikacji AJAX,
a przy okazji redukujących objętość kodu
JavaScriptu, jaki trzeba wpisywać ręcznie.
W dalszej części artykułu zobaczymy, jak
dołączać obsługę AJAX-a do własnych
aplikacji z pomocą popularnych bibliotek.
Wady AJAX-a
Opisywana metoda interakcji z klientem
ma też swoje wady. Nie można przewi-
dzieć, z jakiej przeglądarki korzysta użyt-
kownik, więc aplikacja może nie działać
na niekompatybilnych przeglądarkach
lub przy wyłączonej obsłudze JavaScrip-
tu. Oznacza to, że dobrą praktyką jest
uwzględnienie awaryjnej metody obsługi,
na przykład poprzez stworzenie bazowej
aplikacji z wykorzystaniem tradycyjnych
technik, a następnie rozbudowanie jej
o opcjonalne usprawnienia używające
AJAX-a.
Trzeba też pamiętać, że aplikacje
z AJAX-em nie będą działać w Internet
Listing 1.
Serwer JPSpan
<?
php
session_start
()
;
// Klasa powitania
class
HelloWorld
{
function
HelloWorld
()
{
if
(
!
isset
(
$_SESSION
[
'strings'
]))
{
$_SESSION
[
'strings'
]
=
array
(
'Hello'
,
'World'
,
'Hello World'
)
;
}
}
function
addString
(
$string
)
{
$_SESSION
[
'strings'
][]
=
$string
;
return
$this
-
>
stringCount
()
;
}
function
randomString
()
{
$index
=
rand
(
0,
count
(
$_SESSION
[
'strings'
])
-1
)
;
return
$_SESSION
[
'strings'
][
$index
]
;
}
function
stringCount
()
{
return
count
(
$_SESSION
[
'strings'
])
;
}
}
// Ustawienie stałej JPSPAN
require_once
'jpspan-0.4.3/JPSpan.php'
;
// Załadowanie serwera PostOffice
require_once JPSPAN .
'Server/PostOffice.php'
;
// Utworzenie serwera PostOffice
$S
= &
new
JPSpan_Server_PostOffice
()
;
// Rejestracja klasy w serwerze
$S
-
>
addHandler
(
new
HelloWorld
())
;
// Obsługa wyświetlania JavaScriptu po dodaniu
// ciągu ?client do URL-a serwera
if
(
isset
(
$_SERVER
[
'QUERY_STRING'
])
&&
strcasecmp
(
$_SERVER
[
'QUERY_STRING'
]
,
'client'
)
==0
)
{
// Wyłączenie kompresji wynikowego JavaScriptu
// (m.in. usuwania białych znaków) z powodu
// problemów wydajnościowych
define
(
'JPSPAN_INCLUDE_COMPRESS'
,false
)
;
// Wyświetlenie klienckiego JavaScriptu
$S
-
>
displayClient
()
;
}
else
{
// Początek faktycznej obsługi żądań
// Dołączenie obsługi błędów
// błędy, ostrzeżenia i komunikaty serializowane do JS
// Obsługiwanie żądań
$S
-
>
serve
()
;
}
?>
JPSpan i PEAR
Wersja biblioteki JPSpan dla repozy-
torium PEAR jest dostępna w serwisie
http://www.pearified.com. Do instalacji
będzie potrzebny PEAR w nowej wersji
1.4, obsługujący inne kanały niż tylko
http://pear.php.net. Poleceniem
pear
channel-discover pearified.com
na-
leży dodać kanał do repozytorium, po
czym można już zainstalować JPSpan
poleceniem
pear install pearified/
JavaScript_JPSpan
.
Explorerze z wyłączoną obsługą ActiveX,
co często dotyczy na przykład kafejek
internetowych. Może się także zdarzyć,
że aplikacja będzie działać nieco inaczej
w różnych przeglądarkach i na różnych
platformach, choć to samo dotyczy
tworzenia tradycyjnych aplikacji interne-
towych.
AJAX oferuje spore możliwości inte-
rakcji, ale do wielu zadań po prostu się
nie nadaje, na przykład do dynamicznego
rysowania elementów czy obsługi anima-
cji – w takich sytuacjach lepiej korzystać
z Flasha. Warto w tym miejscu zaznaczyć,
że pomimo teoretycznej możliwości połą-
czenia zalet AJAX-a i Flasha w ramach
jednej aplikacji, złożoność takiego rozwią-
zania jest na tyle duża, że lepiej używać
tych technik osobno.
Wykorzystanie bibliotek
Istnieje wiele bibliotek narzędziowych
mających na celu ułatwienie integracji Ja-
vaScriptu i PHP. Wszystkie uwzględniają
jakąś metodę przesyłania danych, ale
większość oferuje dodatkowe możliwości,
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
51
Techniki
od bezpośredniego odwzorowania metod
klas PHP na pośrednika JavaScriptu, po
środowisko tworzenia elementów inter-
fejsu użytkownika. Przyjrzyjmy się bliżej
dwóm popularnym pakietom: bibliotekom
JPSpan i HTML_AJAX.
JPSpan
Najpierw zajmiemy się pakietem JPSpan
– jedną z bardziej dojrzałych bibliotek
AJAX dla PHP, dostępną od listopada
2004 r. Podstawową funkcją biblioteki
jest niezależna od przeglądarki obsłu-
ga mechanizmu AJAX bazująca na
XMLHttpRequest
, z możliwością wyboru
pracy synchronicznej lub asynchronicz-
nej. Dostępne jest wspólne, obiektowe
API dla JavaScriptu i PHP. JPSpan obsłu-
guje też wiele innych funkcji, na przykład
przezroczyste odwzorowania obiektów
z bardzo dobrą serializacją danych, po-
zwalającą odwzorowywać tablice PHP na
obiekty JavaScriptu. Strona z serwera jest
dołączana do wynikowych stron HTML ze
znacznikiem
client
, generując pośrednie
klasy JavaScript o takim samym API, jak
klasy PHP. Ze względu na ograniczenia
PHP4, wszystkie nazwy klas i metod są
zapisywane małymi literami. Domyślny
serwer JPSpan nosi nazwę
JPSpan_
Server_PostOffice
i może służyć do
odwzorowywania na JavaScript zarówno
całych klas, jak i ich części. Korzystając
z serwera w dużym serwisie można
rozważyć dodanie znacznika
class
, co
pozwoli ograniczyć liczbę klas dołącza-
nych i rejestrowanych na serwerze, a tym
samym zmniejszy koszt przetwarzania.
Osobiście nie doświadczyłem jednak
żadnych problemów wydajnościowych
nawet przy pięciu stale zarejestrowanych
klasach integracyjnych.
Wywołania polegają na utworzeniu
instancji odpowiedniej klasy JavaScrip-
tu, a następnie wywoływaniu jej metod.
W chwili utworzenia instancji w trybie
asynchronicznym, określana jest klasa
zwrotna, po czym wyniki są przesyłane
jej metodom o takich samych nazwach,
jak metody pierwotnie wywoływane.
JPSpan dodatkowo obsługuje złożone ty-
py danych, w tym wielowymiarowe tablice
i obiekty, jak również serializację i prze-
kazywanie błędów PHP do JavaScriptu
z możliwością konfiguracji obsługi błędów
po stronie klienta.
Strona serwera
Przyjrzyjmy się działaniu JPSpan nieco
bliżej na prostym przykładzie typu Hello
World, wyświetlającym losowy napis
w reakcji na kliknięcie i pozwalającym
dodawać nowe napisy. Zaczynamy od
utworzenia klasy
helloworld
, zawierającej
proste metody PHP do obsługi dodawania
napisów do tablicy sesyjnej, zwracania
długości tablicy i wyświetlania losowe-
go napisu z tablicy. Są to odpowiednio
metody
addString()
,
stringCount()
i
randomString()
, a ich kod przedstawia
Listing 1.
Praca z klasami JPSpan nie różni się
niczym od obsługi zwykłych klas. Trzeba
tylko pamiętać, że klasa ta jest odtwa-
rzana przy każdym wywołaniu ze strony
JavaScriptu, więc utrzymywanie danych
składowych między wywołaniami wymaga
pamiętania instancji klasy w ramach sesji.
Musimy jeszcze dołączyć JPSpan
i odpowiedni plik serwera PostOffice, po
czym możemy stworzyć nową instancję
serwera i zarejestrować w niej naszą
klasę wywołując
$S->addHandler(new
Listing 2.
Klient JPSpan
<
html
>
<
head
>
<
title
>
Hello World w JPSpan
<
/title
>
<
script type=
'text/javascript'
src=
'jpspan_server.php?client'
><
/script
>
<
script
>
// Klasa JavaScript zawierająca metody zwrotne
var
hwCallback
=
{
randomstring:
function
(
result
) {
document
.getElementById
(
'canvas'
)
.
innerHTML
+= '
<
p
>
'+result+'
<
/p
>
';
},
stringcount:
function
(
result
) {
document
.getElementById
(
'count'
)
.
innerHTML
=
result
;
},
addstring:
function
(
result
) {
document
.getElementById
(
'count'
)
.
innerHTML
=
result
;
}
}
// Utworzenie obiektu zdalnego. Jego nazwa jest odwzorowana małymi literami,
// gdyż w nazwach klas i funkcji PHP4 wielkość liter nie jest rozpoznawana.
// Rejestrując każdą klasę na serwerze można przywrócić rozróżnianie
// wielkości liter.
var
remoteHW
=
new
helloworld
(
hwCallback
)
;
function
do_addString
() {
remoteHW
.addstring
(
document
.getElementById
(
'string'
)
.
value
)
;
document
.getElementById
(
'string'
)
.
value
=
''
;
}
<
/script
>
<
/head
>
<
body onLoad=
"remoteHW.stringcount()"
>
<
input type=
"button"
name=
"check"
value=
"Pokaż losowy napis"
onclick=
"remoteHW.randomstring(); return false;"
>
<
div
>
Liczba losowych napisów:
<
span id=
"count"
><
/span
><
/div
>
<
div id=
"canvas"
style=
"border: solid 1px black; margin: 1em; padding: 1em;"
><
/div
>
<
div
>
Podaj nowy napis:
<
input type=
"text"
name=
"string"
id=
"string"
size=
"20"
>
<
input type=
"button"
name=
"check"
value=
"Dodaj nowy napis"
onclick=
"do_addString(); return false;"
>
<
/div
>
<
/body
>
<
/html
>
HTML_AJAX
a nazwy klas
Nazwy klas zwracane przez PHP4 są
zawsze zapisane małymi literami. Jeśli
koniecznie chcesz zachować rozróż-
nienie wielkości liter lub potrzebujesz
zgodności między PHP4 i PHP5,
musisz skorzystać z dodatkowych pa-
rametrów metody
registerClass()
,
określających nazwę klasy rejestrowa-
nej w JavaScripcie oraz tablicę ekspor-
towanych metod:
$server = new HTML_AJAX_Server();
$hello = new HelloWorld();
$methods = array('foo','bar');
$server->registerClass($hello,
§
'Example', $methods);
PHP Solutions Nr 1/2006
www.phpsolmag.org
52
Techniki
HelloWorld())
. Pozostaje jeszcze tylko
określić, czy chcemy wysłać kliencki kod
JavaScript, czy też obsługiwać żądania.
Jak widać na Listingu 1, obiektowe API
JPSpan bardzo ułatwia przygotowania po
stronie serwera.
Strona klienta
Teraz zajmiemy się stroną kliencką naszej
prostej aplikacji – Listing 2 przedstawia
kod klienta. Od razu zwraca uwagę wyraź-
ne rozdzielenie kodu HTML i PHP podczas
pracy z JPSpan. Wystarczy tylko umieścić
w ramach strony HTML poniższy, automa-
tycznie generowany kod, odpowiedzialny
za faktyczne połączenie HTML i PHP:
<script type='text/javascript'
src='jpspan_server.php?client'>
</script>
Przy odrobinie pracy nagłówkami po-
zwala to wygodnie obsłużyć składowanie
znanych informacji po stronie klienta,
co bardzo przydaje się na przykład przy
dodawaniu do istniejącego serwisu pola
autouzupełniania.
Następnie tworzymy klasę JavaScriptu
o nazwie
hwCallback
, zawierającą metody
zwrotne zastępujące treść odpowiednich
elementów
<div>
wartościami podanymi
przez serwer z wykorzystaniem właści-
wości
innerHTML
. Pozostaje już tylko utwo-
rzyć zdalny obiekt:
var remoteHW=new helloworld(hwCallback);
Klasa
helloworld
jest wyeksportowaną
klasą PHP, którą wcześniej utworzyliśmy
po stronie serwera. Nazwa klasy zawie-
ra wyłącznie małe litery, gdyż PHP4 nie
rozróżnia wielkości liter w nazwach klas
i funkcji. Reszta kodu z Listingu 2. to już
tylko dodanie formularza HTML z odpo-
wiednimi metodami obsługi – i już może-
my się pobawić naszą pierwszą aplikacją
stworzoną w technologii AJAX.
HTML_AJAX
Biblioteka HTML_AJAX daje znacznie
większe możliwości niż JPSpan, ale dla
uproszczenia przykładu skorzystamy z po-
dobnej konfiguracji, co w przypadku po-
przedniego przykładu: zewnętrzna stro-
na serwera generuje kod pośredni Java-
Scriptu, który jest dołączany i faktycznie
wykonywany na stronie HTML. HTML_
AJAX potrafi też generować cały kod po-
średnika i serwera w jednym skrypcie, ale
Listing 3.
HTML_AJAX może posłużyć do pobierania treści z innej strony na tym
samym serwerze
<
html
>
<
head
>
<
script type=
'text/javascript'
src=
"server.php?client=main"
><
/script
>
<
script type=
'text/javascript'
src=
"server.php?client=dispatcher"
><
/script
>
<
script type=
'text/javascript'
src=
"server.php?client=HttpClient"
><
/script
>
<
script type=
'text/javascript'
src=
"server.php?client=Request"
><
/script
>
<
script type=
'text/javascript'
src=
"server.php?client=json"
><
/script
>
<
/head
>
<
body
>
<
script type=
"text/javascript"
>
function
clearTarget() {
document
.getElementById
(
'target'
)
.
innerHTML
=
'clear'
;
}
// Operacja 'grab' jest najprostszym zastosowaniem HTML_AJAX, polegającym na
// wysłaniu żądania do strony i pobraniu wyników. Można jej używać w trybie
// synchronicznym lub asynchronicznym (z wywołaniem zwrotnym).
var
url
=
'README'
;
function
grabSync
() {
document
.getElementById
(
'target'
)
.
innerHTML
= HTML_AJAX.grab
(
url
)
;
}
function
grabAsync
() {
HTML_AJAX.grab
(
url
,
grabCallback
)
;
}
function
grabCallback
(
result
) {
document
.getElementById
(
'target'
)
.
innerHTML
=
result
;
}
// Operacja 'replace' może działać albo na adresie (tak jak grab), albo na
// zdalnej metodzie. W tym drugim przypadku trzeba ustawić defaultServerUrl na adres
// eksportujący wywoływaną metodę. Obecnie replace używa wyłącznie synchronicznych
// wywołań AJAX - wywołania asynchroniczne mogą się pojawić w przyszłości.
function
replaceUrl
() {
HTML_AJAX.replace
(
'target'
,
url
)
;
}
<
/script
>
<
ul
>
<
li
><
a href=
"javascript:clearTarget()"
>
Czyszczenie pola docelowego
<
/a
><
/li
>
<
li
><
a href=
"javascript:grabSync()"
>
Przykład pobrania synchronicznego
<
/a
><
/li
>
<
li
><
a href=
"javascript:grabAsync()"
>
Przykład pobrania asynchronicznego
<
/a
><
/li
>
<
li
><
a href=
"javascript:replaceUrl()"
>
Zastąpienie zawartości treścią pobraną
spod wskazanego adresu
<
/a
><
/li
>
<
/ul
>
<
div style=
"white-space: pre; padding: 1em; margin: 1em; width: 600px; height:
300px; border: solid 2px black; overflow: auto;"
id=
"target"
>
Pole docelowe
<
/div
>
<
/body
>
<
/html
>
Listing 4.
Klasa implementująca serwer podpowiedzi (plik suggest.class.php)
class
suggest
{
function
suggest
()
{
require_once
'pear_array.php'
;
$this
-
>
strings =
$aPear
;
}
function
getString
(
$input
=
''
)
{
if
(
$input
==
''
)
return
''
;
$input
=
strtolower
(
$input
)
;
$suggestStrings
=
array
()
;
foreach
(
$this
-
>
strings as
$string
)
{
if
(
strpos
(
strtolower
(
$string
)
,
$input
)
=== 0
)
{
$suggestStrings
[]
=
$string
;
}
}
return
$suggestStrings
;
}
}
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
53
Techniki
nie polecałbym tej metody, gdyż tracimy
wtedy możliwość lokalnego składowania
wcześniej wygenerowanego kodu Java-
Scriptu.
Instalacja pakietu HTML_AJAX jest
bardzo prosta – wystarczy wykonać po-
lecenie
pear install HTML_AJAX-alpha
.
Jeśli na serwerze nie masz narzędzia
PEAR, możesz po prostu pobrać pakiet
http://pear.php.net/package/HTML_AJAX,
rozpakować go i ręcznie umieścić w wy-
branym katalogu, wymienionym oczywi-
ście w ramach parametru
include_path
w php.ini.
Rysunek 3.
Serwer podpowiedzi w akcji
R
E
K
L
A
M
A
Serwer
Strona HTML_AJAX działająca na serwe-
rze jest bardzo prosta – jej działanie polega
na utworzeniu instancji serwera
HTML_AJAX_
Server
, zarejestrowaniu wszystkich ekspor-
towanych klas (zwanych tu stubs, czyli na-
miastkami) i obsługiwaniu nadchodzących
żądań. Istnieją trzy możliwe rodzaje żądań:
Żądanie
klienckie,
zawierające
?client=all
w ciągu zapytania.
Zamiast
all
można też podać jedną
z części składowych klienta. Obecnie
obsługiwanych jest pięć części (
Ma-
in
,
Dispatcher
,
HttpClient
,
Request
i
JSON
), a w przyszłości zostanie do-
dana obsługa dodatkowych, opcjonal-
nych części.
Żądanie generowanej namiastki, za-
wierające
?stub=nazwaklasy
w ciągu
zapytania (można też podać wartość
all
).
Żądanie AJAX, zawierające w ciągu
zapytania
?c=nazwaklasy&m=nazwame
tody
.
Pierwsze dwa rodzaje żądań można
łączyć w jednym żądaniu, lecz trzeba
pamiętać, że wiąże się to z pewnym
kompromisem: mniej żądań to mniej po-
łączeń z serwerem, ale z drugiej strony
generowane namiastki zmieniają się
częściej od danych klienckich, co może
negatywnie wpłynąć na efektywność
lokalnego składowania kodu. Ostrożnie
należy też korzystać z żądań
stub=all
,
gdyż namiastka dla, na przykład, dzie-
sięciu klas może już być spora. W ko-
lejnej wersji biblioteki HTML_AJAX po-
jawi się możliwość podawania wielu klas
w ramach jednego żądania namiastki
w postaci listy rozdzielanej przecinkami,
a więc
stub=test,test2
.
PHP Solutions Nr 1/2006
www.phpsolmag.org
54
Techniki
Łatwa aktualizacja
treści bez AJAX-a
HTML_AJAX pozwala też korzystać z pod-
stawowych możliwości AJAX-a wyłącznie
po stronie klienckiego JavaScriptu, dzięki
czemu można bardzo szybko dodać do
strony proste elementy używające AJAX-a
lub włączyć HTML_AJAX do istniejącego
środowiska. Typowym zastosowaniem jest
aktualizacja zawartości elementu HTML za
pomocą treści wygenerowanej przez inną
stronę PHP, co daje elastyczność ramek
<iframe>
bez ich wad (patrz Listing 3).
Po dołączeniu do strony niezbędnego
kodu JavaScriptu można pobierać treść
ze wskazanego adresu na serwerze
w trybie synchronicznym za pomocą
HTML_
AJAX.grab(url)
lub w trybie asynchronicz-
nym za pomocą
HTML_AJAX.grab(url,grab
Callback)
, gdzie argument
grabCallback
wskazuje funkcję zwrotną automatycznie
wywoływaną przez HTML_AJAX po po-
braniu treści. Można też wywołać
HTML_A
JAX.replace('target',url)
, by zastąpić
zawartość elementu o identyfikatorze
podanym jako
target
treścią pobraną
z adresu
url
. Ze względów bezpieczeń-
stwa można w ten sposób pobierać treści
wyłącznie z adresów na tym samym
serwerze. Nie jest to jednak ograniczenie
biblioteki HTML_AJAX, lecz ograniczenie
przeglądarki, mające na celu zapobieganie
atakom cross site scripting (XSS).
Przykład w stylu Google
Suggest z HTML_AJAX
Pora na nieco bardziej zaawansowany
przykład: pole podpowiedzi podobne do
mechanizmu Google Suggest (http://
www.google.com/webhp?complete=1&hl=
en), ale służące do wyszukiwania pakie-
tów PEAR (patrz też Ramka Wzorzec
AJAX Suggest).
HTML_AJAX pozwala zarządzać inte-
rakcją klienta z serwerem w kilku prostych
wierszach kodu. Jak widać na Listingu 4.,
klasa obsługująca stronę PHP jest dość
prosta. Dla potrzeb przykładu korzystamy
z tablicy zawierającej możliwe hasła wy-
szukiwania, choć w rzeczywistej aplikacji
byłyby one prawdopodobnie pobierane
z bazy danych. Lista wyszukiwania wy-
maga tylko jednej metody
getString()
,
która porównuje przekazany ciąg znaków
z kolejnymi pozycjami tablicy. Pasujące
elementy są następnie kopiowane do
tablicy wyników, która jest ostatecznie
zwracana.
Teraz uruchamiamy serwer usługi (Li-
sting 5). W tym przykładzie skorzystamy
z klasy
AutoServer
, która rozszerza pod-
stawową klasę serwera i dodaje metodę
inicjalizacyjną dla każdej klasy. Pozwala
to zarządzać eksportem kilku klas PHP
za pomocą jednego serwera – wystarczy
ustawić wartość zmiennej
$initMethods
na
true
i nadać metodom inicjalizacyjnym
nazwy w postaci
initNazwaKlasy
, co dla
naszej klasy oznacza utworzenie meto-
dy
initSuggest()
. Wykorzystanie klasy
AutoServer
w tak prostym przykładzie to
oczywiście strzelanie z armaty do muchy,
ale pokazuje ciekawe możliwości biblio-
teki HTML_AJAX, które mogą się bardzo
przydać w większych projektach.
I to by było na tyle po stronie PHP.
Jeśli nasza metoda działa poprawnie
i nie generuje żadnych błędów, to nie
musimy jej więcej zmieniać i możemy się
zająć implementacją po stronie klienta.
Rzut oka na Listing 6 pokazuje, że za-
czynamy od dołączenia JavaScriptu dla
serwera:
<script type='text/javascript'
src='auto_server.php?client=
all&stub=suggest'></script>
Następnie tworzymy kod obsługi żądania
w postaci metody
do_suggest()
oraz funk-
cję zwrotną do wyświetlania wyników, a na
koniec tworzymy nową instancję zdalnej
wyszukiwarki AJAX. Reszta kodu to po
prostu formularz z jednym polem teksto-
wym i elementem
<div>
do wyświetlania
wyników. Dodanie do pola tekstowego ob-
sługi zdarzenia
onkeyup="do_suggest();
return false;"
powoduje wywołanie
funkcji
do_suggest()
po każdym zwolnie-
niu klawisza (zdarzenie
onkeypress
byłoby
obsługiwane zbyt wcześnie).
Jak to działa?
Każda zmiana wartości pola tekstowego
powoduje wywołanie funkcji
do_suggest()
,
która z kolei wywołuje metodę
remoteSu
ggest.getstring()
javascriptowej klasy
Wzorzec AJAX Suggest
Podpowiadanie użytkownikom możliwych sposobów uzupełnienia tekstu wprowadzanego
w polu tekstowym uatrakcyjnia stronę i ułatwia korzystanie z niej – wystarczy zapropono-
wać kilka słów lub wyrażeń, które mogą pasować do danych wprowadzanych przez użyt-
kownika. Do implementacji mechanizmu uzupełniania służy najczęściej połączenie pola
tekstowego z listą rozwijaną wraz z synchronizacją tych elementów.
Użytkownik może podać dowolny tekst, a bieżąca pozycja na liście będzie odpowia-
dać dotychczas wprowadzonemu ciągowi. Możliwe jest również wybranie elementu z listy,
co spowoduje zastąpienie zawartości pola tekstowego wybranym hasłem.
Implementacja tego wzorca wiąże się z reguły z wykorzystaniem zwykłego pola tek-
stowego i stworzeniem niewidocznej z początku warstwy (elementu
<div>
), w której będą
umieszczane kolejne podpowiedzi. Do pola tekstowego trzeba dołączyć funkcję obsługi
zdarzenia, kontrolującą zawartość pola w celu zapewnienia poprawnego wyświetlania
pasujących podpowiedzi na liście.
Nie będziemy oczywiście wysyłać żądania po każdym naciśnięciu klawisza – lepiej sko-
rzystać z techniki dławienia zgłoszeń. W tym przypadku przeglądarka sprawdza co (na przy-
kład) 350 milisekund, czy zawartość pola uległa zmianie – jeśli tak, to do serwera wysyłane
jest odpowiednie żądanie. Pozwala to ograniczyć liczbę żądań (i tym samym zaoszczędzić
nieco pasma), a przy okazji nie będzie przeszkadzać szybko piszącemu użytkownikowi.
Serwer odpowiada na żądanie wysyłając uporządkowaną listę pasujących podpowie-
dzi, którą po stronie klienta odbiera funkcja zwrotna. Funkcja ta wprowadza w modelu doku-
mentu odpowiednie zmiany, by użytkownik mógł przejrzeć nowe podpowiedzi i ewentualnie
wybrać jedną z nich. Z każdą pozycją listy skojarzona jest funkcja obsługi kliknięcia, odpo-
wiadająca za aktualizację pola tekstowego treścią wybranej przez użytkownika pozycji.
Tryb synchroniczny i asynchroniczny
Biblioteki JPSpan i HTML_AJAX obsługują pracę zarówno w trybie asynchronicznym
(z wywołaniami zwrotnymi), jak i synchronicznym (z bezpośrednim zwracaniem wartości).
Ogólnie lepiej jest stosować operacje asynchroniczne, gdyż wywołania synchroniczne
mogą wstrzymywać pracę interfejsu użytkownika w oczekiwaniu na odpowiedź drugiej
strony. Oczywiście niekiedy jest to zachowanie pożądane, ale przesyłając większe ilości
danych trzeba wtedy zawsze pamiętać o wyświetleniu komunikatu typu proszę czekać.
Wywołania synchroniczne są znacznie łatwiejsze do oprogramowania, ale mimo to
lepiej oprzeć się pokusie bezkrytycznego ich stosowania. Żądania AJAX w sieci lokalnej
najczęściej trwają nie dłużej niż 50 ms, ale w przypadku przesyłania danych przez Internet
czas ten najczęściej wzrasta do ponad 250 ms. Oznacza to, że użytkownik nie będzie
w stanie skorzystać z żadnego elementu strony czy nawet przełączyć się na inną zakładkę
przeglądarki przez ćwierć, a często i pół sekundy.
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
55
Techniki
HTML_AJAX. Ta komunikuje się z ser-
werem, który odsyła tablicę pasujących
podpowiedzi, przekazywaną następnie
funkcji zwrotnej, która kończy cały proces
dokonując niezbędnych zmian w struktu-
rze dokumentu i wyświetlając podpowiedzi
w ramach elementu
<div>
.
W ten sposób mamy już działający,
choć nie najpiękniejszy przykład. Po
pierwsze, funkcja autouzupełniania prze-
glądarki w tym przypadku tylko przeszka-
dza. Możemy ją jednak łatwo wyłączyć
dodając do pola tekstowego atrybut
autocomplete="off"
. Po drugie, sposób
wyświetlania podpowiedzi pozostawia
bardzo wiele do życzenia. Spróbujmy
więc ulepszyć funkcję zwrotną – Listing 7.
przedstawia poprawiony kod.
Po usunięciu poprzedniej zawartości
elementu
resultDiv,
wyświetlającego wy-
niki, opakowujemy każdy wynik w osobny
znacznik
<span>
dla uzyskania lepszej kon-
troli nad formatowaniem, po czym w pętli
for
dodajemy kolejne wyniki do warstwy
resultDiv
. Etap opakowania wykonujemy
wywołując metody JavaScriptu
document.
createElement("span")
i
appendChild()
.
Dla zwiększenia czytelności można popra-
cować nad stylem (Listing 8). Najważniej-
szy jest tu wpis powodujący wyświetlanie
podpowiedzi jedna pod drugą zamiast
w jednym wierszu:
#suggestions span {
display: block;
}
Listing 8.
Style CSS dla klienta
podpowiedzi
*
{
padding
: 0;
margin
: 0;
font-family
: Arial, sans-serif;
}
#suggestions
{
max-height
: 200px;
width
: 306px;
border
: 1px solid #000;
overflow
: auto;
margin-top
: -1px;
float
: left;
}
#string
{
width
: 300px;
font-size
: 13px;
padding-left
: 4px;
}
#suggestions span
{
display
: block;
}
Listing 5.
Serwer podpowiedzi w HTML_AJAX (plik auto_server.php)
session_start
()
;
require_once
'HTML/AJAX/Server.php'
;
class
AutoServer
extends
HTML_AJAX_Server
{
// Ustawienie tego znacznika jest konieczne, by korzystać z metod inicjalizacyjnych
var
$initMethods
=
true
;
// Metody inicjalizacyjne dla klasy podpowiedzi
function
initSuggest
()
{
require_once
'suggest.class.php'
;
$suggest
=
new
suggest
()
;
$this
-
>
registerClass
(
$suggest
)
;
}
}
$server
=
new
AutoServer
()
;
$server
-
>
handleRequest
()
;
Listing 6.
Prosty klient podpowiedzi
<
html
>
<
head
>
<
title
>
HTML_AJAX Suggest
<
/title
>
<script type='text/javascript' src='auto_server.php?client=all&stub=suggest'>
</script>
<
script
>
function
do_suggest
() {
remoteSuggest.getstring
(
document
.getElementById
(
'string'
)
.
value
)
;
}
// Stworzenie tablicy asocjacyjnej do składowania metod zwrotnych
var
suggestCallback
=
{
getstring:
function
(
result
) {
document
.getElementById
(
'suggestions'
)
.
innerHTML
=
result
;
}
}
// Utworzenie obiektu zdalnego. Jego nazwa jest odwzorowana małymi literami,
// gdyż w nazwach klas i funkcji PHP4 wielkość liter nie jest rozpoznawana.
// Rejestrując każdą klasę na serwerze można przywrócić rozróżnianie
// wielkości liter.
var
remoteSuggest
=
new
suggest
(
suggestCallback
)
;
<
/script
>
<
/head
>
<
body
>
<
div
>
Podaj nazwę pakietu PEAR:
<
input type=
"text"
name=
"string"
id=
"string"
size=
"20"
onkeyup=
"
do_suggest(); return false;"
>
<
input type=
"button"
name=
"check"
value=
"Podpowiedz..."
onclick=
"do_suggest();
return false;"
>
<
/div
>
<
div id=
"suggestions"
>
<
/div
>
<
/body
>
<
/html
>
Listing 7.
Ulepszona metoda zwrotna
var
suggestCallback
=
{
getstring:
function
(
resultSet
) {
var
resultDiv
=
document
.getElementById
(
'suggestions'
)
;
resultDiv.innerHTML = '';
for
(
var
f
=0;
f
<
resultSet.length
; ++
f
){
var
result
=
document
.createElement
(
"span"
)
;
result
.
innerHTML
=
resultSet
[
f
]
;
resultDiv
.appendChild
(
result
)
;
}
}
}
PHP Solutions Nr 1/2006
www.phpsolmag.org
56
Techniki
Warstwa wyników powinna początkowo
być ukryta, więc w pliku CSS podajemy
dla niej atrybut
display: none
, który po
otrzymaniu wyników przełączamy na war-
tość
block
w ramach metody zwrotnej:
resultDiv.style.display='block';
if (!resultSet)
resultDiv.style.display='none';
Dodatkowe sprawdzenie zapobiega wy-
świetleniu warstwy, gdy serwer nie zwróci
żadnych podpowiedzi.
Pora dodać do wyników nieco interak-
cji – na razie tylko widzimy podpowiedzi,
ale nie możemy wybierać pozycji z listy.
Efekt wybierania osiągniemy dodając
obsługę zdarzeń do elementu
<span>
każ-
dego wyniku:
result.onmouseover = highlight;
result.onmouseout = unHighlight;
result.onmousedown = selectEntry;
Spowoduje to dodanie funkcji Java-
Script do każdego zdefiniowanego
zdarzenia. Działanie funkcji
highlight()
i
unHighlight()
polega po prostu na
zmianie klasy CSS elementu
<span>
:
function highlight (){
this.className='highlight';
}
Klasa CSS
highlight
wygląda tak:
.highlight {
background-color: 0000ff;
color: fff;
}
Minimalna wersja naszej wyszukiwarki
powinna obsługiwać zastąpienie zawar-
tości pola tekstowego podpowiedzią
klikniętą przez użytkownika. Pole ma
identyfikator
string
, więc podmiana jego
treści jest prosta:
function selectEntry () {
document.getElementById('string')
.value = this.innerHTML;
}
Wartość pola tekstowego jest zastępowa-
na zawartością danego elementu
<span>
,
czyli jednym z wyników zwróconych przez
serwer AJAX.
Całość wygląda już znacznie lepiej
(Rysunek 3). Przykład działa poprawnie,
Listing 9.
Ostateczna wersja klienta podpowiedzi
<
html
>
<
head
>
<
title
>
Podpowiedzi HTML_AJAX
<
/title
>
<
link rel=
"StyleSheet"
type=
"text/css"
href=
"suggest3.css"
/
>
<script type='text/javascript' src='auto_server.php?client=all&stub=suggest'>
<
/script
><
script
>
var
string
= '';
var
oldstring
= '';
var
timeout
=
1000
;
/* czas w ms między sprawdzeniami - dobrą wartością jest 250*/
function
do_suggest
() {
string
=
document
.getElementById
(
'string'
)
.
value
;
if
(
string
!= oldstring
)
{
/* Przy pustym polu nie wysyłaj żądania... */
if
(
string
) {
remoteSuggest.getstring(
string
)
;
}
/* ... tylko ukryj warstwę */
else
{
document
.getElementById
(
'suggestions'
)
.style.display =
'none'
;
}
oldstring
=
string
;
}
window
.setTimeout
(
'do_suggest()'
,
timeout
)
;
}
// Stworzenie tablicy asocjacyjnej do składowania metod zwrotnych
var
suggestCallback
=
{
getstring:
function
(
resultSet
) {
var
resultDiv
=
document
.getElementById
(
'suggestions'
)
;
resultDiv
.innerHTML =
''
;
resultDiv
.style.display =
'block'
;
if
(
!
resultSet
)
resultDiv
.style.display =
'none'
;
else
{
for
(
var
f
=0;
f
<
resultSet.length; ++f
){
var
result=
document
.
createElement
(
"span"
)
;
result.innerHTML = resultSet
[
f
]
;
result.onmouseover = highlight;
result.onmouseout = unHighlight;
result.onmousedown = selectEntry;
resultDiv.appendChild
(
result
)
;
}
}
}
}
// Utworzenie obiektu zdalnego
var
remoteSuggest =
new
suggest
(
suggestCallback
)
;
// Funkcje obsługi interakcji
function
highlight
() {
this
.
className
=
'highlight';
}
function
unHighlight
()
{
this
.
className
=
'';
}
function
selectEntry
()
{
document
.getElementById(
'string'
)
.
value
=
this
.innerHTML;
}
<
/script
>
<
/head
>
<
body onload=
"do_suggest()"
>
<
h1
>
HTML_AJAX Example: Suggest
<
/h1
>
<
p
>
Uwaga: czas między sprawdzeniami jest ustawiony na 1000ms dla celów
demonstracyjnych. W praktyce lepiej korzystać z wartości rzędu 350ms.
<
/p
>
<
div id=
"error"
><
/div
>
Podaj nazwę pakietu PEAR:
<
form method=
"get"
id=
"suggest"
>
<
input type=
"text"
name=
"string"
id=
"string"
size=
"20"
autocomplete=
"off"
>
<
input type=
"button"
name=
"check"
value=
"Podpowiedz..."
onkeyup=
"do_suggest();
return false;"
>
<
div id=
"suggestions"
>
<
/div
>
<
/form
>
<
/body
>
<
/html
>
AJAX
PHP Solutions Nr 1/2006
www.phpsolmag.org
57
Techniki
ale do serwera wysyłanych jest zbyt wie-
le żądań – jeśli użytkownik wpisze coś
bardzo szybko, a korzysta z powolnego
łącza, to może dochodzić do wysyłania
kolejnego żądania podpowiedzi przed
otrzymaniem odpowiedzi na żądanie
poprzednie. Spróbujmy jakoś temu za-
pobiec.
Skorzystajmy z techniki zwanej
dławieniem zgłoszeń (ang. submission
throttling). W tym przypadku kliencki
JavaScript będzie co jakiś czas (na przy-
kład co 350 milisekund) sprawdzał, czy
wartość pola tekstowego uległa zmianie
– jeśli tak, to zostanie wysłane żądanie
do serwera (patrz Listing 9). Dodatkowo
sprawdzimy też, czy pole nie jest przy-
padkiem puste – w takiej sytuacji nie
wysyłamy żądania i ukrywamy warstwę
wyników.
Jak widać, dodanie imponującej in-
terakcji do formularzy i aplikacji nie jest
wcale trudne. Nasz prosty przykład moż-
na oczywiście rozbudować, dodając na
przykład możliwość przechodzenia po li-
ście wyników klawiszami kursora czy też
obsługę lokalnego składowania danych,
pozwalającego oszczędzić sporo pasma.
Śledzenie kodu AJAX
Podczas eksperymentów z AJAX-em
zauważysz zapewne, że technika ta
wymaga nowego podejścia do śledzenia
kodu. Nie wystarczy już śledzić kodu PHP
– trzeba jeszcze pilnować JavaScriptu
i obsługiwanej przez AJAX-a komunikacji
między klientem i serwerem. Na szczęście
nie jest to trudne.
Przede wszystkim, każdy moduł
kodu należy testować osobno. Pracując
w JavaScripcie dobrze jest stworzyć funk-
cję pomocniczą, na przykład prościutki
odpowiednik
print_r()
z PHP:
function print_r(input) {
var ret;
..for(var i in input) {
....ret += "["+i+"] = "+input[i]+"\n";
..}
..alert(ret);
}
Możliwości obserwacji w bibliotece
JPSpan pozwalają też rejestrować między
innymi błędy i udane wywołania funkcji
AJAX. W domyślnej konfiguracji serwera
błędy PHP są przekazywane jako ostrze-
żenia JavaScript. Niekiedy można też na-
trafić na ostrzeżenia wynikające z błędów
JavaScriptu, co wynika z tego, że JPSpan
przechwytuje również te błędy i zgłasza je
jako ostrzeżenia.
Podczas pracy z HTML_AJAX można
dodać własną funkcję obsługi błędu, która
będzie podmieniać zawartość elementu
<div>
o identyfikatorze
error
:
HTML_AJAX.onError = function(e) {
msg = "\nn";
for(var i in e) {
msg += i + ':' + e[i] +"\n";
}
document.getElementById('error').
innerHTML += msg;
}
Pozwoli to przechwytywać wszystkie błę-
dy AJAX – najczęściej będą to zwyczajne
błędy PHP, ale mogą się też pojawiać błę-
dy 404, błędy wygaśnięcia i inne.
Na koniec zalecałbym tworzenie apli-
kacji dla przeglądarki Firefox, a dopiero
potem testowanie ich w Internet Explo-
rerze. Firefox ma nieporównanie lep-
sze narzędzia programistyczne od IE,
a w dodatku oferuje bardzo wiele przydat-
nych rozszerzeń.
Podsumowanie
Wiedząc już czym jest AJAX i jak z niego
korzystać, możesz rozważyć zastosowa-
nie tej techniki w swoich stronach. Prawi-
dłowe używanie AJAX-a pozwala często
osiągnąć imponujące wyniki, ale nie zna-
czy to, że należy bezkrytycznie stosować
tę technikę we wszystkich witrynach. Za-
wsze trzeba mieć na uwadze podstawowe
przeznaczenie danego serwisu – być mo-
że w konkretnym przypadku lepiej byłoby
dopracować nawigację lub prezentację
treści, niż dodawać interakcję korzystającą
z AJAX-a. Koniecznie trzeba też uwzględ-
niać docelowych odbiorców – jeśli więk-
szość użytkowników z różnych względów
ma wyłączoną obsługę JavaScriptu, to
wprowadzenie AJAX-a raczej nie będzie
dobrym pomysłem. Podobną rolę odgrywa
skala – aplikacja wyposażona w AJAX-a
znacznie lepiej sprawdzi się w przypadku
niewielkich serwisów intranetowych (gdzie
łatwo rozwiązać problemy konfiguracyjne
i ujednolicić przeglądarki) niż w przypadku
rozbudowanych, publicznie dostępnych
witryn. Krótko mówiąc, wprowadzenie
AJAX-a może dać dobre wyniki pod
warunkiem, że nadrzędnym celem pozo-
stanie uzyskanie jak najlepszych walorów
użytkowych.
n
Joshua Eichorn tworzy serwisy PHP
od siedmiu lat. Jest autorem phpDocu-
mentor – wielokrotnie nagradzanego
i szeroko używanego narzędzia doku-
mentującego kod PHP. Jest też szefem
projektu HTML_AJAX, dostarczającego
implementację techniki AJAX dla repozy-
torium PEAR. Obecnie pracuje jako star-
szy architekt oprogramowania w firmie
Uversa Inc., gdzie tworzy dla klientów
unikatowe rozwiązania. Technikę AJAX
stosował jeszcze przed jej oficjalnym
opracowaniem i popularyzacją. Mieszka
w Phoenix w stanie Arizona (USA).
Kontakt: josh@bluga.net
Werner M. Krauß programuje w PHP od
1999 r. Gdy nie gra na gitarze, zajmuje
się tworzeniem dokumentacji dla frame-
worka Seagull.
Kontakt: werner.krauss@hallstatt.net
O autorze
Komunikat ładowania
Uruchamiając przykłady z HTML_AJAX zauważysz, że przy każdym wywołaniu AJAX po-
jawia się czerwone okienko z komunikatem loading. Powiadomienie to jest automatycznie
wyświetlane przez HTML_AJAX i jest po prostu warstwą o określonym identyfikatorze,
tworzoną jeśli wcześniej nie istniała. Jeśli więc chcesz zmienić ten komunikat, wystarczy
gdzieś w kodzie HTML umieścić na przykład taki fragment:
<div id="HTML_AJAX_LOADING" style=
"background-color : blue; color : white; display : none; position : absolute;
right : 50px; top : 50px;">
Ładowanie nowego napisu...</div>
Wyświetlania komunikatu nie da się w obecnej wersji wyłączyć po stronie serwera, ale
w przyszłych wersjach HTML_AJAX taka możliwość już będzie. Aby zapobiec wyświetla-
niu komunikatu trzeba nadpisać generującą go funkcję JavaScriptu:
HTML_AJAX.onOpen = function(){
// nic
}