You are on page 1of 84

Spis treści

AKTUALNOŚCI 6
Krzysztof Trynkiewicz

Przyjemne z pożytecznym OPIS CD 10


Mówi się, że „pieniądze szczęścia nie dają”, ale na pewno każdy przyzna, że
Dorota Pączka
na małe przyjemności możemy sobie dzięki nim pozwolić.
W numerze, który macie przed sobą Paweł Grzesiak w dziale „Kasa dla
Webmastera” udowadnia, że posiadanie własnej strony internetowej może DLA POCZĄTKUJĄCYCH
przełożyć sie na niemałe korzyści majątkowe. Możecie zacząć tworzyć wła-
Szybkie i przyjemne
sne witryny WWW łącząc przyjemne z pożytecznym.
programowanie z Code Igniter 12
Jeżeli Wasza przygoda z PHP zaczęła się niedawno i nie czujecie się
jeszcze na siłach, aby tworzyć dochodowe strony internetowe, możecie pi- Piotr Maliński
sać inne aplikacje za pomocą Code Igniter. Piotr pokazuje jak profesjonalnie stworzyć apli-
Zachęcam również do przeczytania ciekawych artykułów, w rozbudo- kacje internetowe wg wzorca MVC. Wzorzec opi-
wanym dziale „Dla zaawansowanych”. Staramy się, aby z numeru na nu- sywany przez autora w jasny i klarowny sposób
mer umieszczać coraz więcej tekstów właśnie w tym dziale, ponieważ je- zapewni Ci uporządkowanie kodu, co zwiększy
steśmy w pełni świadomi, że programujecie coraz bardziej zaawansowa- jego czytelność.
ne aplikacje w PHP. Próbujemy wyjść naprzeciw Waszym oczekiwaniom
udzielając jeszcze więcej konkretnych porad i opisów narzędzi.
Przeprowadziliśmy również kolejny test konsumencki. Tym razem PROJEKTY
wzieliśmy pod lupę firmy oferujące hoteling. Tematem kolejnego testu bę-
Wsparcie SEO w systemach
dą serwery, jeśli chcecie, aby właśnie Wasza opinia ukazała się na łamach
zgodnych ze standardami W3C
naszego pisma, piszcie!
na przykładzie eZ Publish 20
Gorąco polecam też lekturę numeru extra poświęconego Xoops. Już
niedługo w kioskach! Zapraszam do czytania. Juliusz Całyniuk
Juliusz pokazuje, jaki jest związek pomiędzy stan-
dardami W3C i SEO. Przy okazji uczy również pod-
staw optymalizacji dla wyszukiwarek oraz jak spraw-
dzić, czy system CMS wspiera SEO.

DLA ZAAWANSOWANYCH
Ankiety w stylu rankingowym
z użyciem AJAX-a 26
Patrycja Wądołowska Krzysztof Trynkiewicz
patrycja.wadolowska@software.com.pl Krzysztof prezentuje, w jaki sposób stworzyć an-
kiety w stylu rankingowym przy pomocy techno-
logii AJAX. Ciekawy interfejs, oparty na CSS i
JavaScript, pozwoli Ci uatrakcyjnić wygląd Two-
jej strony internetowej.
Nasz magazyn ukazuje się w dwóch językach!
polskim francuskim ASwing + AMFPHP
czyli przepis na szybkie GUI 30
Rafał Malinowski
Rafał pokazuje, jak szybko i łatwo stworzyć GUI
dla aplikacji PHP-owej. Dowiesz się też, o pro-
stym sposobie przesyłania danych pomiędzy
PHP a Flashem. To artykuł dla wszystkich, któ-
rzy chcą ulepszyć swoją PHP-ową aplikację.

Przeglądarka bazy danych


przy użyciu PHP-Gtk2 44
Christian Weiske
Christian prezentuje, jakie nowe funkcje przyno-
si druga wersja PHP-Gtk. Autor nauczy Cię bu-
dować przeglądarkę baz danych z funkcją sorto-
wania i podziału na strony, dzięki połączeniu za-
Jeśli jesteś zainteresowany zakupem licencji na wydawanie naszych pism prosimy o kontakt:
Monika Godlewska monikag@software.com.pl tel.: 48 22 887 12 66, fax: 48 22 887 10 11 let dwóch aspektów programistycznych.

4 www.phpsolmag.org PHP Solutions Nr 2/2007


Spis treści

NARZĘDZIA
Pytania dotyczące Strona WWW/Forum
PHP5 WebServices vs MS .NET prenumeraty strona www: www.phpsolmag.org
vs Java vs Java Mobile tel. (22) 887 14 44 Tu znajdą Państwo informacje
– interoperability pełną parą! 52 e-mail: pren@software.com.pl dotyczące aktualnych i przyszłych
Software Wydawnictwo Sp. z o.o. numerów magazynu PHP Solutions.
Łukasz Budnik dział prenumeraty
Łukasz uczy pisania własnych usług sieciowych ul. Bokserska 1 Forum: www.phpsolmag.org/newforum
02-682 Warszawa Zachęcamy do dyskusji na naszym
oraz rozszerzania domyślnych klas PHP5 klien-
forum. Czekamy na propozycje
ta i serwera SOAP. Po przeczytaniu artykułu nie CD tematów, które chcieliby Państwo
będziesz miał też problemu z zabezpieczaniem tel. (22) 887 14 44
znaleźć w najbliższym numerze pisma.
swoich usług z rozszerzeniem WS Security En- e-mail: cd@software.com.pl
Zapraszamy także do wymiany
Software Wydawnictwo Sp. z o.o.
hancements i HTTPS. poglądów z innymi fanami PHP.
Defekty CD/DVD
ul. Bokserska 1 Cena
KASA DLA WEBMASTERA 02-682 Warszawa Prenumerata: 135 zł
Przelew na konto nr:
Jak zarobić na stronie www? Zamówienia 46 1440 1299 0000 0000 0391 8238
Poradnik dla przedsiębiorczych /Numery archiwalne Nordea Bank Polska S.A.
tel. (22) 887 14 44
webmasterów. 66 II Oddział w Warszawie
e-mail: pren@software.com.pl
Paweł Grzesiak sklep on-line: www.buyitpress.com
W dzisiajszych czasach istnieje wiele źródeł, Kontakt z redakcją
z których właściciel strony interentowej może e-mail: redakcja@phpsolmag.org
czerpać zyski. Autor w artykule prezentuje me- Software Wydawnictwo Sp. z o.o.
tody zarobkowania i zwraca szczególną uwagę Redakcja PHP Solutions
ul. Bokserska 1
na ich opłacalność. Dowiesz się, w co warto za-
02-682 Warszawa
inwestować.

Listingi wszystkich opisywanych programów zostały zamieszczone na naszej stronie


RECENZJE 72 internetowej www.phpsolmag.org/pl.

Łukasz Skowroński, Marcin Stefaniak

TESTY KONSUMENCKIE PHP Solutions jest wydawany przez Software-Wydawnictwo Sp. z o.o.

Redaktor naczelny: Sylwia Pogroszewska


Kolokacja serwerów (hoteling) 74 Redaktor prowadzący: Patrycja Wądołowska patrycja.wadolowska@software.com.pl
Asystent redaktora: Dorota Pączka dorota.paczka@software.com.pl
Stali współpracownicy: Paweł Grzesiak pgrzesiak@phpsolmag.org
Testujemy firmy: Korekta: Krzysztof Trynkiewicz chris.trynkiewicz@gmail.com
l Supermedia Internet Provider Kierownik produkcji: Marta Kurpiewska marta@software.com.pl

(testują CodeLine, Warszawskie Centrum Projekt okładki: Agnieszka Marchocka


Numizmatyczne, QPrint) Skład i łamanie: Sławomir Zadrożny slawomir.zadrozny@software.com.pl
Dział reklamy: adv@software.com.pl
l Warsaw Data Center
Prenumerata: Marzena Dmowska pren@software.com.pl
(serwis biznes.net, shooters.pl). Nakład: 6 000 egz.

Adres korespondencyjny: Software-Wydawnictwo Sp. z o.o.,


ul. Bokserska 1, 02-682 Warszawa, Polska

FELIETON tel. +48 22 887 13 35, fax +48 22 887 10 11


www.phpsolmag.org cooperation@software.com.pl

Cyber rzeczywistość Dołączoną do magazynu płytę CD przetestowano programem AntiVirenKit firmy G DATA Software Sp. z o.o.
– cyber uzależnienie 79
Redakcja dokłada wszelkich starań, by publikowane w piśmie i na towarzyszących mu nośnikach informacje
i programy były poprawne, jednakże nie bierze odpowiedzialności za efekty wykorzystania ich; nie gwarantuje
Łukasz Skowroński także poprawnego działania programów shareware, freeware i public domain.
Uszkodzone podczas wysyłki płyty wymienia redakcja.
Wszystkie znaki firmowe zawarte w piśmie są własnością odpowiednich firm
i zostały użyte wyłącznie w celach informacyjnych.
ZAPOWIEDZI 82 Redakcja używa systemu automatycznego składu
Do tworzenia wykresów i diagramów wykorzystano program firmy
Zapowiedzi artykułów, które planujemy w na- Osoby zainteresowane współpracą prosimy o kontakt: cooperation@software.com.pl
stępnym wydaniu naszego pisma.
Druk: ArtDruk

Wysokość nakładu obejmuje również dodruki. Redakcja nie udziela pomocy technicznej w instalowaniu
i użytkowaniu programów zamieszczonych na płytach CD-ROM dostarczonych razem z pismem.
Sprzedaż aktualnych lub archiwalnych numerów pisma po innej cenie niż wydrukowana na okładce
– bez zgody wydawcy – jest działaniem na jego szkodę i skutkuje odpowiedzialnością sądową.

Pismo ukazuje się w następujących wersjach językowych:


polskiej , francuskiej

PHP Solutions Nr 2/2007 www.phpsolmag.org 5


Aktualności

PEAR::HTML_CSS Suhosin – zabezpieczenia dla PHP


Od początku roku wydano już kilka poprawek
i dodatków do pakietu HTML_CSS działają-
cego w ramach repozytorium PEAR. Pakiet
ten umożliwia tworzenie arkuszy stylów CSS
S uhosin to zaawansowany system za-
bezpieczeń dla PHP. Został zaprojek-
towany, by uchronić użytkowników tej plat-
strzeżonych (np. GLOBALS, _ COOKIE, _ ENV,
_ FILES, _ GET, _ POST, _ REQUEST, _ SERVER ,
_ SESSION, HTTP _ COOKIE _ VARS, HTTP _
zgodnych ze standardami W3C przy pomocy
klas PHP. Projekt rozwijany jest od 2003 ro- formy przed znanymi i nietypowymi błę- ENV _ VARS, HTTP _ GET _ VARS, HTTP _
ku, pozwala na parsowanie plików lub ciągów
z wielu źródeł jednocześnie. Wyniki naszej dami, zagnieżdżonymi tak w skryptach, POST _ VARS, HTTP _ POST _ FILES, HTTP _
pracy możemy „wyeksportować” jako elemen- jak i w samym silniku PHP. Suhosin skła- RAW _ POST _ DATA , HTTP _ SERVER _ VARS,
ty “inline” kodu HTML, wewnętrzne lub ze-
wnętrzne deklaracje na stronie, tablice dekla-
da się więc z dwóch części, z których moż- HTTP _ SESSION _ VARS). Do danych prze-
racji, ciąg znakowy lub zapisać do pliku. na stosować każdą z osobna, lub razem. kazywanych przez powyższe metody mo-
W nowej wersji 1.1.0 dodano możliwość wy-
Pierwsza część pakietu, to patch dla silni- żemy zastosować filtrowanie wyklucza-
szukiwania selektorów i właściwości za po-
mocą wyrażeń regularnych typu Perl. Pakiet ka PHP, który implementuje kilka niskopo- jące zbyt dużą ilość zmiennych lub jedy-
działa pod PHP 4 oraz 5. Jest także rozpo- ziomowych zabezpieczeń przeciwko prze- nie te, które zawierają zbyt zagnieżdżo-
wszechniany na licencji PHP 3.01.
http://pear.php.net/package/HTML_CSS pełnieniom buforów, czy błędów w for- ne tablice, zbyt duże tablice, których na-
http://www.laurent-laville.org/index.php? matach ciągów znakowych. Druga część zwy bądź wartości są zbyt długie. Może-
module=pear&desc=css
to rozszerzenie do PHP, wprowadzają- my także kontrolować ilość plików uplo-
PHP6 nadchodzi ce wiele innych zabezpieczeń. Dostaje- adowanych na serwer, zaś te wrzucone
Wraz z końcem roku, na wielu blogach osób my więc opcje symulacji zabezpieczeń, poddawać sprawdzeniu przez zewnętrz-
pracujących nad PHP6 pojawiły się zapo-
wiedzi nadchodzącej wersji. Zgodnie z tym, funkcje sha256() oraz sha256 _ file() do ny skrypt. Pliki będące binariami są auto-
co pisaliśmy o nowej wersji (PHP Solutions silnika PHP, obsługę CRYPT _ BLOWFISH w matycznie odrzucane, wycinane są tak-
3/2006 (14)), będzie to raczej ewolucja, niż
rewolucja. Wiadomo już, że ponad połowa crypt() dla wszystkich platform, zabezpie- że wykonywalne fragmenty wewnątrz in-
pracy nad wsparciem dla Unicode została za- czenia dla otwartych stron z wywołaniami nych plików. W przypadku zablokowania
kończona. Funkcjonalność ta będzie głów-
phpinfo(), zabezpieczenia użytkowników lub odrzucenia zmiennej bądź pliku, mo-
nym atutem PHP6, możemy więc spodziewać
się pierwszych wersji testowych w ciągu naj- baz danych SQL, enkrypcję ciastek, możli- żemy przekierować użytkownika na inną
bliższych miesięcy. wość wyłączenia funkcji eval(), modyfika- stronę, pokazać błąd lub uruchomić inny
http://blog.libssh2.org/index.php?/archives/48-
PHP-2006-A-look-back.html tora /e funkcji preg _ replace. skrypt PHP. Wszystkie działania pakietu
http://www.gravitonic.com/blog/archives/ Możemy także określić maksymal- są monitorowane i logowane do dzienni-
000305.html
ną ilość rekursji, zapobiegając nieskoń- ka systemowego lub zewnętrznego skryp-
script.aculo.us 1.7.0 czonej ilości wywołań funkcji, otrzymu- tu, są opisane adresem IP Internauty, na-
Wielkimi krokami nadchodzi stabilna wersja jemy także zabezpieczenie przeciw- zwy i linii pliku, w którym wystąpił błąd.
1.7.0 pakietu script.aculo.us, zawierającego
wiele przydatnych efektów stosowanych na ko atakom używającym pustych linii To tylko niektóre z wielu możliwości, jakie
stronach opartych o AJAX. przekazywanych do mail(), czy “\0” do oferuje pakiet Suhosin. Dodatkowo, pro-
W nowej wersji podniesiono ilość klatek na
sekundę dla efektów z 25 do 60, całość po- preg _ replace(). Możemy zablokować jekt współdziała z innymi aplikacjami, np.
winna więc działać zauważalnie szybciej. eksportowanie zmiennych superglobal- Zend Optimizer. Na witrynie projektu znaj-
Nowością są efekty morphingu, które możemy
zastosować dla dowolnych klas CSS. Przy-
nych PHP za pomocą funkcji extract() dziemy bardzo obszerną dokumentację,
kłady morphingu możemy zobaczyć pod ad- oraz import _ request _ vars(). Ochronie forum dyskusyjne, oraz informacje o od-
resem http://mir.aculo.us/demos/script-acu- poddane są także zmienne sesyjne: da- krytych niedawno błędach krytycznych w
lo-us-1-7-beta-demos.
http://mir.aculo.us ne są poddawane enkrypcji, identyfikato- popularnych aplikacjach PHP. Pakiet udo-
http://script.aculo.us ry sesji są sprawdzane pod kątem długo- stępniany jest na darmowej licencji PHP
Dokumentacja Prototype ści i typów znaków, ze wskazaniem na te License 3.01.
Już w poprzednim numerze informowaliśmy o zastrzeżone. Z formularzy filtrowane są
innowacyjnym frameworku Prototype dla Java- znaki ASCIIZ oraz ignorowane są zmien- http://www.hardened-php.net/
Script oraz możliwościach, które daje dewelo-
perom PHP przez AJAX. Dokumentacji do te- ne typu GET, POST i COOKIE o nazwach za- suhosin.127.html
go projektu jednak zawsze brakowało – dostęp-
ne były jedynie tutoriale, nie dające pełnego ob-
razu możliwości, drzemiących w Prototype. Au-
torzy pakietu wciąż zbierają informacje krążące
po Internecie, by zebrać je w całość. Chociaż
oficjalna dokumentacja nie została jeszcze opu-
blikowana, wiele informacji można znaleźć na
stronach polecanych w komentarzach do wpisu
na blogu autorów.
http://encytemedia.com/blog/articles/2006/10/
31/prototype-a-call-for-documentation
http://prototype.conio.net/

Piąta doroczna
konferencja eZ Systems
Wiele razy na łamach PHP Solutions poruszali-
śmy zagadnienia związane z rozwiązaniami fir-
my eZ Systems. Obecnie trwają przygotowania
do piątej już konferencji, która odbędzie się w
Skien, w Norwegii w dniach 6-8 czerwca 2007.
PHP Solutions patronowało także poprzednim
edycjom konferencji. Serdecznie zapraszamy!
http://ez.no/community

6 www.phpsolmag.org PHP Solutions Nr 2/2007


Aktualności

Suhosin – zabezpieczenia dla PHP Heurystyczna


ochrona przeciwko
atakom SQL Injection
SQL Injection to znany problem dla więk-
szości deweloperów PHP – wszyscy zabez-
pieczamy nasze skrypty, by do danych prze-
syłanych metodami POST i GET intruz nie
wkleił swojego kodu SQL, który, nieprze-
filtrowany, mógłby ujawnić zawartość na-
szej bazy danych. Stefan Esser wprowadził
niedawno w swoim projekcie heurystycz-
ną ochronę przeciwko takimi atakami. Po-
lega ona na logowaniu i/lub blokowaniu za-
pytań SQL zawierających komentarze (za-
mknięte lub otwarte), zapytania UNION lub

P
zagnieżdżone zapytania SELECT. Tego typu
HP Unit w wersji 3 wprowadziło za- Dokumentacja projektu jest obszerna i
zapytania nie są często stosowane, jednak
awansowaną obsługę pakietu XDe- czytelna, znajdziemy w niej informacje o wykorzystuje je się przy znacznej ilości ata-
bug. Umożliwia on śledzenie błędów, implementowaniu XDebug do PHP Unit. ków SQL Injection. Zabezpieczenie zostało
wprowadzone do projektu Suhosin, opisane-
wyświetlając informacje o funkcji zawie- Podobne treści znajdziemy także na go szerzej w tym wydaniu aktualności, war-
rającej błąd, parametry do niej przesy- stronach PHP Unit. W efekcie otrzyma- to jednak zastanowić się, czy podobne roz-
wiązanie nie znajdzie zastosowania i w na-
łane (także do funkcji własnych), nazwę my potężne narzędzie, pomocne w de- szych projektach.
pliku, w której rezyduje, oraz numery bugowaniu naszych projektów. XDebug http://blog.php-security.org/archives/67-Heuri-
stic-SQL-Injection-Detection-for-Suhosin.html
wierszów. Dodatkowo, otrzymamy infor- jest rozwijany od 2002. Aktualizacje nie
macje o alokacji pamięci, możliwych nie- są częste, jednak zawsze wnoszą no- Seagull Framework 0.6.1
skończonych rekursjach, będziemy tak- we funkcjonalności. Na temat PHP Unit Po kilku miesiącach przerwy, nowej wersji do-
czekał się słynny framework Seagull. Uspraw-
że mogli wyprofilować swój skrypt. XDe- pisaliśmy obszernie w PHP Solutions niono system raportowania błędów, doda-
bug jest dostępny dla platformy Linux, 1/2006 (12). no możliwość podawania argumentów do za-
pytań CLI, wprowadzono prefixy dla baz da-
posiada także binaria dla Windows. Ist-
nych, dodano element CAPTCHA dla komenta-
nieją osobne pakiety dla PHP 4 i 5. Li- http://xdebug.org rzy i wiele innych funkcjonalności. W PHP Solu-
cencja jest oparta o PHP License 3.0. http://phpunit.de tions 4/2005 (10) zamieściliśmy obszerny arty-
kuł na temat tworzenia portalu opartego na tym
rozwiązaniu.
http://seagullproject.org

PEAR dla każdego


pMachine – gotowe pakiety Repozytorium PEAR z każdym dniem rośnie,
jednak wciąż poszukiwane są opracowania do
projektów tworzonych w jego ramach. PHP Kit-

J eśli szukasz zbioru projektów,


których można używać za darmo
w zastosowaniach nie komercyjnych,
chen (http://www.phpkitchen.com) opracowa-
ło zbiór linków pomocnych w poznawaniu PE-
AR oraz jego pakietów. Dowiemy się wiele na
temat instalacji, konfiguracji, a także pakietów
to pMachine jest właśnie dla Ciebie. PECL. Dodatkowo, znajdziemy kilkadziesiąt
odnośników do tutoriali na temat najprzydat-
Sama strona projektu jest schludna i niejszych narzędzi: Cache, Cache_Lite, Config,
prezentuje jakość, której możemy spo- Console, Crypt_HMAC, DB, DB_DataObject,
dziewać się po każdym z modułów. Archive_Tar, Error, HTML_AJAX, HTML_Pro-
gress, HTML_QuickForm, HTML_Table,
Zaznaczyć należy, że każdy z modu- HTTP_Upload, LiveUser, Mail, Mail_Mime, Ma-
łów może działać niezależnie od innych, il_Queue, Log, PHP_Documentor, PHP_Unit,
Services_Google, SOAP, Spreadsheet_Excel_
mogą one jednak być także połączone, Writer, Structures_DataGrid, Structures_Graph,
tworząc potężny CMS. Autorzy przygo- Text_Captcha, Tree, XML_Parser, XML_Seria-
lizer, XML_Tree, czy XML_RSS.
towali dla nas bardzo eleganckie forum interesowani tworzeniem systemów klasy http://www.phpkitchen.com/index.php?/
dyskusyjne, sklep internetowy, funkcjo- Enterprise. Już teraz możemy bowiem archives/668-PEAR-Tutorials.html
nalną galerię obrazów, system wiki do zobaczyć, co na jego podstawie moż-
Zend Framework
tworzenia własnych encyklopedii oraz na zbudować – każdy z wyżej wymienio- Średnio co miesiąc autorzy Zend Frame-
system do tworzenia blogów – pMachi- nych modułów działa w oparciu o ten fra- work uraczają nas nowymi wersjami pakie-
tu ułatwiającego tworzenie aplikacji PHP.
ne Pro. mework, i trzeba przyznać, że całość pre- W wersji 0.6.0 dodano nowe komponen-
Głównym jednak atutem firmy jest ich zentuje się bardzo dobrze. ty (m.in. Zend_Auth, Zend_Console_GetOpt,
ExpressionEngine. Jest to bardzo ela- Produkty z tej firmy są tworzone już Zend_TimeSync), przepisano na nowo kod
kluczowych komponentów (Zend_Session,
styczny system publikacji treści, który od 6 lat, możemy więc być pewni, że są Zend_Http_Client) i poszerzono dokumenta-
potrafi połączyć wszystkie inne produk- pisane przez doświadczonych progra- cję. Dodatkowo zlikwidowano ponad 100 błę-
dów. Zend Framework wyrasta więc na lide-
ty w całość. Już na stronie głównej pro- mistów. Deweloperzy powinni przyjrzeć ra w zakresie frameworków dla PHP. Szerzej
jektu ujrzymy odnośniki do ponad 200 się bliżej rozwiązaniom zastosowanym o nowym rozwiązaniu pisaliśmy w PHP Solu-
tions 04/2006 (15) – z pewnością warto przyj-
przykładowych witryn, które używają te- w projektach tej firmy – kilka pomysłów rzeć się ponownie temu projektowi, ponieważ
go oprogramowania – jest na co popa- można bowiem sukcesywnie zaimple- od czasu publikacji artykułu zyskał wiele funk-
trzeć. Firma pMachine opracowała także mentować i w swoich dziełach. cjonalności i rzesze zwolenników.
Licencja: własna, darmowa.
własny framework – Code Igniter, które- http://framework.zend.com
mu powinni przyjrzeć się programiści za- http://www.pmachine.com

PHP Solutions Nr 2/2007 www.phpsolmag.org 7


Aktualności

Spamowi mówimy STOP


W dobie Internetu, niemal każdy użytkownik (a
zwłaszcza programista aplikacji webowych) po- CAPTCHA przeciwko spamowi
siada swój blog. Wspólną inicjatywą bloggerów
z całego świata było powstrzymanie automa-
tów spamujących w komentarzach do ich wpi-
sów. Efektem prac jest Akismet, darmowy pa-
C APTCHA to akronim od “Comple-
tely Automated Public Turing Test
to Tell Computers and Humans Apart.
jąc jako alternatywy zagadki, czy pliki
audio. Ostatnie rozwiązanie ma w za-
sadzie jeszcze więcej mankamentów:
kiet, który w kilka minut możemy zaimplemen-
tować do swojej witryny. Domyślnie, jest to do- Innymi słowy, są to obrazki, z których nie każdy ma bowiem możliwość odsłu-
datek do aplikacji WordPress, jednak można
go zaimplementować także w autorskich roz- musimy często przepisywać kod, by chania nagrania. Wydaje się więc, że
wiązaniach. Akismet zidentyfikował dotychczas nasz wpis, komentarz, czy temat na najlepszym wyjściem jest stworzenie
ponad 500 milionów spamerskich wiadomo-
forum został opublikowany. CAPTCHA systemu dającego wybór użytkowniko-
ści, każdego dnia wynik powiększa się o ponad
milion wiadomości. Nie trudno wyobrazić so- jest stosowany w celu wyeliminowa- wi, jakim sposobem chce się “zauto-
bie, ile miejsca i transferu zostało oszczędzone- nia automatów spamujących, próbują- ryzować”. Do podobnego wniosku do-
go dzięki temu projektowi. Statystyki wykazują,
że aż 94% wszystkich wiadomości filtrowanych cych ataków typu bruteforce, zakłada- szedł autor klasy PhpCaptcha. Oferuje
przez Akismet to spam. Obecnie, pakiet jest jącym masowo konta itp... Dewelope- ona rozwiązania tak graficzne, jak au-
jednym z najskuteczniejszych rozwiązań anty-
spamerskich. Polecamy jego implementację na rzy aplikacji mają ostatnio wiele nie- dio, jest rozpowszechniana na zasa-
własnych witrynach! przespanych nocy, właśnie ze wzglę- dach określonych w licencji Free BSD
http://akismet.com
du na rozwiązanie doraźne, jakim jest License. Klasa potrafi generować lo-
Bad Behaviour CAPTCHA. Stosując bowiem obrazki sowe teksty na obrazach w zadanych
Bad Behavioru to zestaw skryptów PHP, który w celu odróżnienia człowieka od ma- czcionkach TrueType, z opcjonalny-
analizuje nagłówki HTTP wysyłane przez oso-
by (lub automaty) odwiedzające naszą witry- szyny, stwarzamy kłopot w przegląda- mi cieniami, losowymi tłami, o różnych
nę. Na podstawie ustalonej czarnej listy i pew- niu witryny osobom niewidomym. Ma- wielkościach czcionek dla możliwych
nych heurystycznych metod, potrafi skutecznie
odróżnić spamerskiego bota od przeglądarki
ło tego, niektórzy wciąż używają prze- do wyświetlenia, zdeklarowanych zna-
lub robota wyszukiwarki. Użytkownicy tego pa- glądarek tekstowych, np. Lynx, inni z ków. Do działania wymaga przynajm-
kietu chwalą go sobie nie mniej niż rozwiązanie kolei mają wyłączone wyświetlanie ob- niej PHP 4 z biblioteką GD 1 lub GD 2
opisane powyżej. Obydwa te systemy, w połą-
czeniu, zapewniają niemal całkowitą ochronę razów. Stosując CAPTCHA, tworzymy oraz obsługę czcionek FreeType.
przed spamem na naszej witrynie. Dodatkowo, bariery – jeden problem znika, poja-
Bad Behaviour filtruje popularne roboty, próbu-
jące przeprowadzać ataki na naszą stronę. Pa- wiają się inne. Internauci od dłuższego http://www.ejeliot.com/pages/2
kiet jest darmowy, prosty w użyciu i łatwo mo- czasu zwracają na to uwagę, proponu- http://www.w3.org/TR/turingtest/
dyfikowalny.
http://www.homelandstupidity.us/software/bad-
behavior/
PAT – PHP Application Tools
Geeklog CMS
Geeklog to nowy, szybki CMS, posiadający
wiele udogodnień. Standardem są oczywiście
moduły takie jak kalendarz, repozytorium pli-
P HP Application Tools to pakiet róż-
nych skryptów dla deweloperów
PHP. Idea stworzenia zestawu narzędzi
ków, systemy ankiet, zintegrowane forum, za-
awansowane statystyki, wyszukiwarka, czy darmowych (większość z nich jest na li-
nowości. Dodatkowo mamy do dyspozycji cencji LGPL, niektóre na GPL) powstała
wielojęzykowość, katalog witryn oraz syste-
my CAPTCHA dla komentarzy i na forum. Ja- już kilka lat temu. Dopiero teraz jednak,
ko edytor WYSIWYG zastosowano popularny czterech programistów, wzięło sprawy w
i skuteczny FCKeditor. Jeśli jeszcze nie znala-
złeś odpowiedniego dla siebie CMSa, wypró- swoje ręce. Efektem jest 10 modułów, któ-
buj Geeklog! re możemy implementować na własne wi-
http://www.geeklog.net
tryny. Na stronie projektu znajdziemy więc
Nucleus CMS opis: patBBCode – pakietu do tworzenia
Z kolei Nucleus, to CMS mający już swoją hi- własnych kodów BBCode, podobnych do ny do Smarty, jednak szybszy i prostszy;
storię i całą gamę pluginów. Obsługuje wie-
le systemów blogowych jednocześnie, wie- tych znanych z for dyskusyjnych; patCon- patUser – system autentykacji użytkowni-
lu autorów, kategorie wpisów, oferuje system figuration – pakiet, dzięki któremu może- ków, który możemy szybko zaimplemen-
komentarzy, przyjazne URLe, skórki, szablo-
ny, archiwa, wyszukiwarkę, wątki RSS i Atom
my stworzyć konfigurację jako plik XML, tować na naszą stronę; patXMLRenderer
dla różnego typu treści, interfejs XML-RPC, który następnie eksportujemy np. jako plik – pakiet pozwalający na transformację pli-
posiada możliwość uploadowania plików gra-
konfiguracyjny PHP; patError – klasa słu- ków XML do łatwych w przeglądaniu wi-
ficznych do galerii. Jest dostępny w 16 wer-
sjach językowych, posiada także system żąca do obsługi błędów; patForms – uła- tryn HTML (lub innego formatu zgodnego
backupowania. Jest także, rzecz jasna, dar- twiające tworzenie formularzy na naszych z ASCII, generuje kod zgodny z szablona-
mowy.
http://nucleuscms.org witrynach; patSession – warstwa abstrak- mi patTemplate). Dodatkowo, mamy moż-
cji służąca do obsługi sesji w PHP; patSpi- liwość skorzystania z siedmiu innych pro-
Analizer plików audio w PHP derizer – narzędzie pomagające w decy- jektów: patDbc, patGuestbook, patNew-
PHPAudioFile to wprawdzie już nie rozwija-
na klasa, ale oferująca bardzo ciekawe możli- dowaniu i konfigurowaniu, które z elemen- sletter, patServer, patRSS, patSHMC, pat-
wości analizy plików WAV, OGG, MP3 i AIFF. tów naszej witryny powinny być zindekso- Messenger. Aplikacje PAT to coś więcej
Skrypt podaje długość ścieżki, typ kompre-
sji, jakość próbkowania, ilość bitów przypada- wane przez roboty wyszukiwarek; patSy- niż framework – to gotowe rozwiązania,
jących na każdy kanał oraz udziela informa- sinfo – wyświetlające wiele informacji o które są bardzo przydatne i funkcjonalne,
cji zawartych w tagach ID3. Dodatkowo ge-
nerowane są pliki PNG wizualizujące prze- zasobach systemu, na którym działa na- a także łatwe w implementacji.
bieg utworu. sza witryna (w tym także jego obciążenie);
http://freshmeat.net/projects/phpaudiofile
patTemplate – system szablonów podob- http://www.php-tools.de

8 www.phpsolmag.org PHP Solutions Nr 2/2007


Opis CD

DzPHP 4.1. PHPmyvisits (wersja 2.3)

P HPmyvisits pozwala sprawdzić


dokładną statystykę odwiedzin
strony interentowej. Jest programem,
który dostarcza informacji na temat
liczby odsłon oraz danych odwie-
dzających. Praktyczny interfejs spra-
wia, że korzystanie z programu nie
przysparza wielu kłopotów. Statysty-
ka jest kompletna i ukazuje się w po-
staci przejrzystej i łatwej w odczyta-

D zPHP 4.1. jest wygodnym i efek-


tywnym narzędziem do pisania
i testowania stron napisanych języ-
wszystkich programistów, zarówno po-
czątkujących, jak i doświadczonych.
Dzięki niemu tworzenie stron przy uży-
niu grafiki.

kiem PHP i HTML. Przystępny inter- ciu PHP i HTML nie jest już tak skom- PhpGroupWare
fejs sprawia, że staje się on łatwy dla plikowane.

PHP/Java Bridge Eclipse-SDK (wesja 3.2.1)


(wersja 3.2.1) (wersja 3.1.2), PHPEclipse
(wersja 1.1.8)
M oduł Java dla języka PHP. Pre-
zentowana wersja stanowi ulep-
szenie poprzedniej – 3.1.8., obie
wersje mogą być używane razem. Za-
wiera podstawowe pliki: java dla PHP/
Apache HTTP, a ponadto funkcję pro-
stego zamykania, która automatycznie
rozpoczyna i kończy sesję, kiedy ser-
P hpGroupWare jest pakietem do pra-
cy zaspołowej, rozwijanym w ramach
projektu DotGNU. Jest stosowany jako
wer HTTP odpowiednio zaczyna lub zbiór komponentów usług sieciowych. Mo-
kończy pracę. gą one być wykorzystywane również (po-
przez XML-RPC) w innych aplikacjach w
pracy w sieci, pod warunkiem, że aplika-

E clipse to rozbudowane środowisko


programistyczne napisane w Javie.
Największą jego zaletą jest to, że daje
cje te zostały stworzone z zastosowaniem
DotGNU.

możliwość korzystania z wielu wtyczek,


co w konsekwencji rozszerza jego fun-
Ebooki
kjonalność. Eclipse można nazwać uni- Ponadto nowe e-booki
wersalnym środowiskiem, a świadczy
o tym fakt, że posiada wtyczkę CDT • Introduction to Programming Using Java,
obsługującą popularne języki C i C++, • The Java Language Specification,
a nie wyłącznie Javę. • Thinking in Java.

10 www.phpsolmag.org PHP Solutions Nr 2/2007


Na CD

HITY
PONADTO Programy komercyjne:
- DzPHP Editor 4.1 o wartości 49$
- PHP/Java Bridge 3.2.1 - Captcha Magic 1.0 o wartości 19.95$
- Eclipse-SDK 3.1.2 oraz 3.2.1 - PHP Magic (Trial)
- PHPEclipse 1.1.8
- PHPmyvisits 2.3 E-BOOKS
- Stato 0.7
- phpGroupWare - Introduction to Programming Using Java
- The Java Language Specification
- Thinking in Java
na naszej stronie internetowej pod adresem www.phpsolmag.org/pl

na naszej stronie internetowej pod adresem www.phpsolmag.org/pl


Wszystkie listingi z artykułów zostały zamieszczone

Wszystkie listingi z artykułów zostały zamieszczone


Dla początkujących

Szybkie i przyjemne
programowanie z Code Igniter
Stopień trudności: lll
Piotr Maliński

Wzorzec MVC jest dość popularny i charakte-


ryzuje się rozdzieleniem komponentów aplika-
cji, tj. modelu danych, interfejsu użytkownika i
logiki sterowania w taki sposób, aby modyfika-
cje jednego komponentu minimalnie wpływały
na pozostałe. O sile MVC przekonamy się, gdy
rozpoczniemy pracę z Code Igniterem.

B
y szybko i bezboleśnie opano- }
wać obsługę prezentowanego tu- $obiekt = new Klasa();
taj frameworka musisz znać pod- echo $obiekt->funkcja();
stawy programowania obiektowego. Mu-
sisz wiedzieć, co to jest klasa, metoda i Klasę definiujemy stosując słowo "class"
obiekt oraz oczywiście musisz znać pod- i podając po nim nazwę klasy. Nawiasy
stawy samego języka. Pomocne mogą klamrowe określają zawartość klasy. Klasa
być artykuły poświęcone PHP na wikibo- zawiera "funkcje", które nazywa się meto-
oks, które dokładnie opisują zagadnienia dami. Metody definiuje się jak funkcje.
programowania obiektowego. Klasy to w Klasy natomiast wywoływane są ina-
W SIECI bardzo dużym uproszczeniu zbiór funkcji. czej niż funkcje. Pierwszym etapem jest
Oto przykładowa klasa: stworzenie obiektu klasy:

• http://www.codeigniter.com class Klasa <?php


– strona frameworka
{ $obiekt = new NAZWAKLASY();
• http://www.php.rk.edu.pl
– kurs CI po polsku function funkcja()
• http://www.todlaciebie.pl {
– przykładowa strona
wykonana w oparciu o Code return 'a'; Co należy wiedzieć...
Igniter } Powinieneś znać podstawy PHP i HTML.
• http://pl.wikibooks.org/
wiki/PHP/Wstęp_ function inna($a)
do_programowania_ { Co obiecujemy...
obiektowego Nauczysz się tworzenia profesjonalnych
return trim($a);
– wprowadzenie do aplikacji internetowych wg wzorca MVC.
programowania obiektowego }

12 www.phpsolmag.org PHP Solutions Nr 2/2007


Code Igniter Dla początkujących

Rysunek 1. Efekt działania naszej wyszukiwarki Flickr

Nowy obiekt tworzy się stosując słowo (np. operacje na bazie danych), (np. sza- • wykorzystuje wzorzec MVC Model-
"new", po którym podajemy nazwę kla- blony) interfejsu użytkownika i logiki ste- Widok-Kontroler przy tworzeniu apli-
sy (tak jakby była to funkcja). Zmienna rowania („pozostały” kod aplikacji) w taki kacji, lecz nie narzuca go,
($obiekt w przykładzie), do której przy- sposób, aby modyfikacje jednego kompo- • lekki i wydajny; komponenty frame-
piszemy stworzony obiekt, będzie miała nentu minimalnie wpływały na pozostałe. worka mają postać wtyczek, które
dostęp do wszystkich metod, które wy- O sile MVC przekonamy się, gdy rozpocz- można ładować w razie potrzeby,
wołujemy: $obiekt->NAZWAMETODY();. niemy pracę z Code Igniterem. • automatycznie generuje przyjazne
W funkcjach zmienne wewnątrz nie wyszukiwarkom URLe dla stworzo-
są dostępne na zewnątrz i na odwrót, Co to jest Code Igniter? nych kontrolerów,
chyba że daną zmienną określi się ja- Code Igniter to framework PHP rozwija- • jest bardzo dobrze udokumentowany
ko globalną, podobnie w klasach. Sto- ny przez firmę pMachine i rozprowadza- i posiada liczne grono użytkowników.
sowanie zmiennych globalnych nie jest ny na liberalnej licencji zbliżonej do licen-
zalecane, szczegóły podam przy oma- cji Apache/BSD. Code Igniter, w skrócie CI nie jest narzędziem tak rozbudowanym
wianiu wzorca MVC. Klasy mają dodat- CI, jest bardzo prostym lecz funkcjonal- jak np. Prado. Nie oferuje takich opcji jak:
kową zmienną wewnętrzną - $this-> nym narzędziem. Oto jego krótka charak-
określa ona zmienne dostępne global- terystyka: • pełna abstrakcja baz danych (wspiera
nie wewnątrz klasy. Zazwyczaj takie tylko podstawowe operacje),
zmienne ustawiane są w konstruktorze • wymaga PHP w wersji nie starszej niż • rozbudowane moduły takie jak system
(automatycznie wykonywanej przy two- 4.3.2, działa również pod PHP 5, uprawnień i użytkowników,
rzeniu obiektu metodzie), a potem wy-
korzystywane przez poszczególne me-
Listing 1. Przykładowy model nowości
tody.
class News extends Model
Co to jest {
function News()
Framework MVC? {
Mianem frameworka określa narzędzie parent::Model();
stanowiące podstawę do tworzenia apli- }
kacji. Framework zawiera elementy uła- function get_news()
twiające i przyśpieszające tworzenie apli- {
// Wszystkie newsy sortowane malejąco po news_id
kacji. W przypadku PHP framework za-
$this->db->orderby("news_id", "desc");
pewni nam obsługę szablonów, połączeń return $this->db->get('news');
z bazami danych, obsługę formularzy i }
wiele więcej. Naszą aplikacją może być function add_news($data)
galeria czy system artykułów. Tworzenie {
// dodanie newsa
takiego skryptu od zera wiązałoby się z
return $this->db->insert('news', $data);
napisaniem kodu odpowiedzialnego za }
wymienione powyżej czynności, a dopie- function update_news($id, $data)
ro w drugiej kolejności z napisaniem kodu {
samej aplikacji. // zmiana newsa o podanym numerze news_id
$this->db->where('news_id', $id);
MVC (ang. Model-View-Controller) to
return $this->db->update('news', $data);
wzorzec programistyczny – pewien sche- }
mat, wg którego tworzy się aplikacje. Ce- function delete_news($id)
lem takich wzorców jest uporządkowanie {
kodu w jasny i klarowny sposób, zapew- // skasowanie newsa o podanym news_od
$this->db->where('news_id', $id);
niając jego czytelność, nie tylko dla auto-
return $this->db->delete('news');
ra kodu. Wzorzec MVC jest dość popu- }
larny i charakteryzuje się rozdzieleniem }
komponentów aplikacji, tj. modelu danych

PHP Solutions Nr 2/2007 www.phpsolmag.org 13


Dla początkujących Code Igniter

Mimo to jest to bardzo dobry produkt ze ne dotyczące bazy danych, routes.php ko drugi parametr podać tablicę z dany-
względu na łatwość i przyjemność pracy, określa m. in. domyślny kontroler. mi. By przypisać widok do zmiennej, a nie
a braki można uzupełnić własnymi biblio- wyświetlić go, wystarczy jako trzeci argu-
tekami i pomocnikami. Odnośniki ment podać wartość True:
CI używa przyjaznego wyszukiwarkom
Instalacja i konfiguracja i ludziom mapowania adresów URL i $widok = $this->load->view(
Pobieramy archiwum z frameworkiem ze zmiennych. Oto przykładowe odnośni- 'nazwa_widoku', array('dane' =>
strony projektu i rozpakowujemy go do ki: http://www.strona.pl/index.php/klasa/ $zmienna), True);
pustego katalogu i przesyłamy na ser- metoda/; http://www.strona.pl/index.php/
wer. Jeżeli teraz otworzymy w przeglą- klasa/metoda/parametr/ .... Witaj Świecie w CI
darce URL prowadzący do katalogu z Gdzie klasa oznacza klasę kontro- W katalogu controllers stwórz plik
frameworkiem to zobaczymy powitalną lera jaka ma być wywołana, metoda – test.php o kodzie:
wiadomość. Możemy przystąpić do two- nazwę wybranej metody tejże klasy,
rzenia własnej aplikacji. a parametry, których może być wiele, <?php
przekazywane są do metody. class Test extends Controller
Struktura frameworka {
Główny katalog Code Igniter zawiera Kontrolery function index()
plik index.php odpowiedzialny za wy- Kontroler to klasa umieszczona w pli- {
świetlanie kontrolerów naszej aplikacji. ku o nazwie takiej jak nazwa klasy, echo 'Test CI';
W katalogu system znajdziemy katalo- umieszczonym w katalogu controllers. }
gi: application, cache, codeigniter, dri- Nazwa zawierać możne znaki alfanu- }
vers fonts, helpers, init, language, libra- meryczne (cyfry i litery) oraz znaki pod- ?>
ries, logs, plugins, scaffolding. W kata- kreślenia. Nazwa klasy jest używana w
logu language umieszcza się pliki z tłu- linkach URL do jej wywoływania. Przy- Otwórz plik config/routes.php i zmień
maczeniami interfejsu frameworka. Nas kładowy odnośnik: http://localhost/html/ wartość
głównie będzie interesował katalog ap- ci/index.php/form
plication jako, że to w nim zawarty bę- Wywoła klasę o nazwie "Form". Kla- $route['default_controller']
dzie cały kod naszych aplikacji. W kata- sa ta powinna znajdować się w pliku
logu tym znajdziemy: "form.php". na nazwę kontrolera - „test”. Teraz głów-
Nazwa pliku musi zaczynać się z na strona frameworka wyświetli tekst
• config - katalog zawierający pliki kon- małej litery, nazwa klasy - z dużej. Me- „Test CI”. Stworzyliśmy pierwszą prostą
figuracyjne, tody klasy kontrolera są automatycznie aplikację. Stworzyliśmy prosty kontroler
• controllers – katalog przechowujący dostępne poprzez system odnośników i ustawiliśmy go jako domyślny. Metoda
kontrolery, CI, za wyjątkiem metod zaczynających index jest domyślnie wywoływaną meto-
• errors – obsługa błędów (np. 404 – się od znaku podkreślenia. dą kontrolera i jak każda inna dostępna
brak strony), jest również pod odnośnikami:
• models – katalog zawierający modele Widoki
• views – katalog z widokami. Widok to niejako szablon strony lub jej index.php/test/index
elementu (np. nagłówek, szablon newsa index.php/test
Konfiguracja itp.). Widok wywoływany jest przez kon-
Podstawowa konfiguracja ogranicza się troler, który wypełnia go danymi i wysyła Modele
do edycji pliku config/config.php i poda- do przeglądarki. Widoki umieszczamy w Modele to klasy PHP zawierające meto-
nia ścieżki URL do naszej instalacji fra- katalogu views. W kontrolerach dany sza- dy operujące na danych w bazie danych.
meworka jako wartość $config['base _ blon ładujemy poleceniem: Przykładowo model "Artykuły" posiadał-
url']. Pozostałe pliki konfiguracyjne bę- by metody typu "dodaj", "zmień", "usuń".
dą interesować nas w dalszej części ar- $this->load->view('nazwa_widoku'); Modele zapisuje się w katalogu models.
tykułu. autoload.php określa, jakie biblio- Nazwy modeli muszą zaczynać się z
teki i pomocniki mają być automatycznie Co wyświetli zawartość widoku. By prze- Dużej litery, nazwy plików - z małej. Co-
ładowane, database.php zawiera da- kazać wartości do widoku wystarczy ja- de Igniter nie wymusza stosowania mo-
deli, można operować na bazie danych
Listing 2. Tabela dla modelu nowości również w kontrolerach, lecz warto z
nich korzystać. Szkielet modelu:
CREATE TABLE `news` (
`news_id` smallint(5) unsigned NOT NULL auto_increment,
class Nazwa_modelu extends Model {
`news_title` varchar(255) default NULL,
function Nazwa_modelu()
`news_text` text,
`news_date` int(10) unsigned NOT NULL, {
PRIMARY KEY (`news_id`) parent::Model();
) ENGINE=MyISAM AUTO_INCREMENT=1 ; }
}

14 www.phpsolmag.org PHP Solutions Nr 2/2007


Code Igniter Dla początkujących

Mamy zwykłą klasę dziedziczącą z kla- Metoda ta pobierze wszystkie wpisy z po- Pobieranie określonych kolumn
sy "Model". Tworząc konstruktor musi- danej tabeli. Można też, jako drugi para-
my dodać: metr, podać limit wyników (LIMIT) lub też $this->db->select('pole, pole2, pole3');
Limit i Ofset (np. pobierze 10 wyników,
parent::Model(); ale nie 10 pierwszych tylko zaczynając od Pozwala na pobranie wartości tylko z
5 (ofset to 5). określonych pól podanych jako argument.
By załadować w Kontrolerze model sto- Podajemy nazwy pól oddzielone przecin-
sujemy: Warunek WHERE kami.

$this->load->model('Nazwa modelu'); $this->db->where('nazwa kolumny', LIKE - pobieranie


wartość); wierszy zawierający
Po załadowaniu modelu uzyskujemy do- podany podłańcuch
stęp do jego metod: Określi warunek "WHERE" limitujący wy-
niki – pobrane zostaną tylko te rekordy $this->db->like('pole', 'wartość');
$this->Nazwa_modelu->metoda(); (wpisy z bazy danych), które spełniają ten
warunek. Można kilka razy zastosować tą Operator LIKE w SQL pozwala na wy-
Bazy Danych w CI metodą dla uzyskania łączonego warun- branie wpisów, zawierających w okre-
Połączenie z bazą danych ustawiamy ku where. Lub też można zastosować ta- ślonym polu podany "podłańcuch". Me-
w pliku config/database.php. Znajdzie- blicę asocjacyjną: toda like ma takie same opcje z argu-
my w nim: mentami (tablice też może być), jak
$array = array('pole' => $wartosc, where. Istnieje też metoda orlike łączą-
$db['default']['hostname'] = "localhost"; 'pole2' => $wartosc2, 'pole' => ca warunki przez "lub".
$db['default']['username'] = $wartosc);
"użytkownik"; $this->db->where($array); Sortowanie wyników
$db['default']['password'] = "hasło";
$db['default']['database'] = By uzyskać warunki łączone przez "lub" $this->db->orderby('pole',
"nazwa bazy"; wystarczy użyć metody "orwhere": 'desc lub asc');
// sterownik: mssql, mysql, mysqli, "desc" posortuje malejąco a "asc"
// odbc, postgre, sqlite $this->db->orwhere(takie same parametry); rosnąco.
$db['default']['dbdriver'] = "mysql";
// prefiks
Listing 3. Kontroler z formularzem i kontrolą danych
$db['default']['dbprefix'] = "";
// Czy używać trwałych połączeń class Formularz extends Controller
{
$db['default']['pconnect'] = FALSE;
// czy pokazywać komunikaty błędów
function index()
$db['default']['db_debug'] = FALSE; {
// czy załadować klasę Active Records // dane poszczególnych pól w postaci tablicy
$db['default']['active_r'] = TRUE; $data["tytul"] = array('name' => 'tytul');
$data['tresc'] = array('name' => 'tresc', 'rows' => 3, 'cols' => 40);

Podajemy dane naszej bazy, a następ- // określenie warunków walidacji


nie przechodzimy do pliku autoload.php $rules['tytul'] = "required|min_length[5]|max_length[12]";
i dodajemy "database" do automatycz- $rules['tresc'] = "required";
nego ładowania: $autoload['libraries'] $this->validation->set_rules($rules);
= array('database');. Code Igniter udo-
if ($this->validation->run() == FALSE)
stępnia nam Active Records – bibliotekę {
mapującą obiekty na kod SQL. Za jego $data['tytul']['value'] = $this->input->post('tytul');
pomocą możemy tworzyć niezależne od $data['tresc']['value'] = $this->input->post('tresc');
typu bazy danych aplikacje, lecz w przy- $this->load->view('form', $data);
}
padku bardziej złożonych zapytań bę-
dziemy zmuszeni do zastosowania suro- else
wego kodu SQL. Oto przegląd możliwo- {
ści mapera: // przypisanie danych z formularza
// wyświetlenie wyników
$news['tytul'] = $this->input->post('tytul');
Pobranie danych
$news['tresc'] = $this->input->post('tresc');
$this->load->view('wynik', $news);
$this->db->get('nazwa tabeli'); }
$this->db->get('nazwa tabeli', LIMIT); }
$this->db->get('nazwa tabeli', LIMIT, }
OFSET);

PHP Solutions Nr 2/2007 www.phpsolmag.org 15


Dla początkujących Code Igniter

Ograniczanie ilości wyników Łączenie tabel – JOIN mać wyniki musimy wykonać na uchwy-
cie metodę result() zwracającą wyniki
$this->db->limit(Limit); $this->db->select('*'); w postaci obiektu lub result _ array() w
$this->db->from('tabela1'); postaci tablicy.
Dodawanie wpisu $this->db->join('tabela2',
'tabela2.pole = tabela1.pole'); Formularze
$dane = array('pole' => wartość, $query = $this->db->get(); Code Igniter posiada pomocnik (ang.
'pole2' => wartość); helper) do obsługi formularzy. By za-
$this->db->insert('tabela', $dane); Pozwala połączyć wyniki z dwóch zależ- ładować go w autoload.php dodajemy
nych tabel. Przykładowy model dla modu- „form” do tablicy $autoload['helper']
Metoda insert dodaje wpis do bazy da- łu nowości przedstawia Listing 1. lub też ładujemy go bezpośrednio w
nych. Przyjmuje ona jako parametr nazwę kontrolerze:
tabeli oraz tablicę asocjacyjną lub obiekt Wykonywanie zapytań SQL
z danymi. Tablica jako klucze musi za- $this->load->helper('form');
wierać nazwy pól, a jako ich wartości – te $query = $this->db->query(
wartości, które mają być dodane do bazy. 'Zapytanie SQL'); Otwarcie Formularza

Zmiana wpisu Metoda "query" wykonuje zapyta- form_open('kontroler/metoda');


nie i zwraca do niego uchwyt. Dodat-
$this->db->update('tabela', $dane); kowo do dyspozycji mamy: $this->db-> Zwraca tag form z atrybutem „action”
escape('łańcuch'); Odpowiednio zabez- ustawionym na podany odnośnik. Dodat-
Parametry jak dla "insert". Modyfikuje piecza znaki specjalne języka SQL. kowo jako drugi parametr można prze-
wpisy nowymi danymi, zazwyczaj towa- kazać tablicę asocjacyjną, której klucze i
rzyszy jej warunek WHERE do modyfika- $this->db->dbprefix wartości staną się atrybutami i ich warto-
cji określonego wpisu. ściami taga form.
Zwraca prefiks do tabel ustawiony w kon-
Kasowanie wpisów figuracji. Pola ukryte

$this->db->delete('tabela', array('pole' Wyświetlanie pobranych danych form_hidden('nazwa', 'wartość');


=> wartość, 'pole' => wartość)); Wykonanie własnego zapytania SELECT
czy też skorzystanie z "get" w Activer Zwróci kod pola ukrytego z podanymi da-
Kasuje wpisu, dla których podane pola w Records nie daje nam od razu wyników. nymi.
tablicy spełniają warunek Dostajemy uchwyt do nich. By otrzy-
Pole Input/text
Listing 4. Implementacja wyszukiwarki Flickr w kodzie strony
form_input('nazwa', 'wartość');
<h1>Wyszukiwarka Flickr</h1>
<?PHP
Można także zastosować tablicę:
echo $content;
?>
Widok flickr_form.php wygląda następująco: $data = array(
<center> 'name' => 'username',
<?=$this->validation->error_string; ?> 'id' => 'username',
</center>
'value' => 'johndoe',
<?php
'maxlength' => '100',
echo form_open('flickr/index');
?> 'size' => '50',
<table width="90%" border="0" cellspacing="3" cellpadding="3"> 'style' => 'width:50%',
<tr><td width="180"><B>Fraza</B></td><td> );
<?php echo form_input($query); ?></td></tr>
echo form_input($data);
<tr><td> </td><td><?php echo form_submit('submit', 'Szukaj'); ?></td></tr>
// wynik:
</table>
<?php <input type="text" name="username"
echo form_close(); id="username" value="johndoe"
?> maxlength="100" size="50"
Natomiast flickr_result.php:
style="width:50%" />
<?PHP
Lista Select
foreach($flickr['img'] as $val) {
echo '<a href="http://www.flickr.com/photos/'.$val['owner'].'/'.$val['id']. $options = array(
'/"><img src="http://static.flickr.com/'.$val['server'].'/'.$val['id']. 'small' => 'Small Shirt',
'_'.$val['secret'].'_s.jpg" style="margin:5px;" alt="" /></a>'; 'med' => 'Medium Shirt',
}
'large' => 'Large Shirt',
'xlarge' => 'Extra Large Shirt',

16 www.phpsolmag.org PHP Solutions Nr 2/2007


Code Igniter Dla początkujących

); Biblioteka „validation” oferuje kilkana- tość pola musi mieć maksymalnie/


echo form_dropdown('nazwa', $options); ście warunków: minimalnie * znaków.

Otrzymamy: • required: pole jest wymagane, musi Opcje można łączyć za pomocą znaku |
mieć jakąś wartość,
<select name="nazwa"> • valid _ email: pole musi zawierać po- $rules['username'] = "required|
<option value="small">Small Shirt prawny adres email, min_length[5]|max_length[12]";
</option> • numeric: pole musi zawierać same
<option value="med">Medium Shirt liczby, Możemy dodać dodatkowo do parametrów :
</option> • alpha _ dash: pole może zawierać je-
<option value="large">Large Shirt dynie znaki alfanumeryczne, podkre- • xss _ clean: oczyszcza dane ze "zło-
</option> ślenia i myślniki, śliwego" kodu (ataki XSS),
<option value="xlarge">Extra Large Shirt • alpha _ numeric: pole może zawierać • prep _ for _ form : zamienia znaki
</option> jedynie znaki alfanumeryczne, HTML na znaki specjalne przez co
</select> • alpha: pole może zawierać jedynie li- można je wyświetlać bez problemu w
tery, formularzach,
Checkbox • exact _ length[*]: wartość pola mu- • prep _ url: doda http:// do linków jeże-
si mieć określoną długość exact_ li brakuje,
form_checkbox('nazwa', 'wartość') length[6] - 6 znaków, • strip _ image _ tags: usunie tagi IMG
• max _ length[*], min_length[*]: war- zostawiając czyste linki URI.
Co zwróci kod checkboxa. By był zazna-
czony, jako trzeci parametr wystarczy Listing 5. Zmodyfikowany kontroler wyszukiwarki Flickr
ustawić wartość logiczną True.
<?PHP
Radio
class Flickr extends Controller
{
form_radio('nazwa', 'wartość') private $api_key;

Obsługa taka sama jak checkboxa. public function __construct()


{
parent::Controller();
Przycisk Submit $this->api_key = 'TWÓJ KLUCZ API';
}
form_submit('nazwa', 'wartość')
public function index()
{
Zwraca kod przycisku submit, gdzie "war-
$ar = Flickr::_search('kubica');
tość" to tekst jaki pokaże się na przycisku. foreach($ar['img'] as $val)
{
Zakończenie formularza echo '<a href="http://www.flickr.com/photos/'.$val['owner'].
'/'.$val['id'].'/"><img src="http://static.flickr.com/'.
$val['server'].'/'.$val['id'].'_'.$val['secret'].
form_close()
'_s.jpg" style="margin:5px;" alt="" /></a>';
}
Zwróci tag zamykający „form”. Można ja- }
ko argument przekazać łańcuch - zosta-
nie od dodany za tagiem zamykającym private function _search($query)
{
formularz.
$x = simplexml_load_file('http://www.flickr.com/services/rest/?method=flickr.
By w kontrolerze uzyskać dostęp do photos.search&text='.$query.'&per_page=20&api_key='.$this->api_key);
pola z wysłanego formularza wystarczy $ret['total'] = (int)$x->photos['total'];
skorzystać z metody input: $r = array();

foreach($x->photos->photo as $res)
$this->input->post('nazwa Pola');
{
$r[] = array('id' => (int)$res['id'], 'title' =>(string)$res['title'],
Walidacja Formularzy 'owner' => (string)$res['owner'], 'secret' =>
Code Igniter oferuje również bibliotekę (string)$res['secret'], 'server' => (int)$res['server']);
do walidacji m.in. formularzy. Wystar- }
$ret['img'] = $r;
czy w autoload.php dodać dla tablicy
return $ret;
libraries wartość „validation”. Listing 3 }
przedstawia przykładowy kontroler wy- }
korzystujący pomocnik form i bibliote-
kę validation.

PHP Solutions Nr 2/2007 www.phpsolmag.org 17


Dla początkujących Code Igniter

• upraszcza aktualizacje kodu,


Listing 6. Ciało klasy Flickr • dla kontrolerów nie jest ważne jak
model zdobywa dane, ważne jest
<?PHP
class Flickr extends Controller { jedynie w jakiej postaci je zwra-
private $api_key; ca. Zachowując tą samą struktu-
rę danych możemy zmienić typ ba-
public function __construct() {
zy danych bez edycji całego kodu
parent::Controller();
aplikacji.
$this->response = array();
$this->api_key = 'KLUCZ API';
} Niektórzy mogą spytać, czy nie war-
to wybrać jakiś gotowy CMS i nauczyć
public function index() {
się go rozszerzać. Otóż jest to jedna
$data["query"] = array('name' => 'query');
możliwość, ale tworzenie nowych mo-
$rules['query'] = "required|max_length[20]|min_length[3]|xss_clean";
$this->validation->set_rules($rules); dułów do CMS nie jest ani przyjemne
ani proste jak we frameworkach. Doku-
if ($this->validation->run() == FALSE) { mentacja API dla modułów jest mniej
$data['query']['value'] = $this->input->post('query');
lub bardziej kompletna, ale co ważniej-
$this->response['content'] = $this->load->view('flickr_form', $data, True);
sze – każdy CMS narzuca różne ogra-
}
niczenia, które mogą bardzo utrudnić
else { tworzenie specyficznych aplikacji. Dla
$ar = Flickr::_search($this->input->post('query')); przykładu – duże i dojrzałe CMSy ta-
$this->response['content'] = $this->load->view(
kie, jak postnuke czy mambo nie ma-
'flickr_result', array('flickr' => $ar), True);
ją natywnych modułów for dyskusyj-
}
$this->load->view('index', $this->response); nych. Istnieją np. zintegrowane modu-
} ły phpBB, ale nie jest to natywny mo-
duł, jak np. w php-fusion czy Drupalu.
private function _search($query) {
Wspomniany Drupal, o coraz bardziej
$x = simplexml_load_file('http://www.flickr.com/services/rest/?method=flickr.
rosnącej popularności, to nie zwykły
photos.search&text='.$query.'&per_page=20&api_key='.$this->api_key);
$ret['total'] = (int)$x->photos['total']; CMS lecz połączenie CMSa z prostym
$r = array(); frameworkiem, dzięki czemu zmodyfi-
kowane i rozbudowane instalacje Dru-
foreach($x->photos->photo as $res) {
pala działają na wielu serwisach.
$r[] = array('id' => (int)$res['id'], 'title' =>(string)$res['title'],
'owner' => (string)$res['owner'], 'secret' =>
(string)$res['secret'], 'server' => (int)$res['server']); Na zakończenie
} Powyższy artykuł miał za zadania za-
$ret['img'] = $r; prezentowanie możliwości prostego w
return $ret;
budowie frameworka bazującego na
}
modelu MVC i ułatwień jakie oferuje
} podczas tworzenia aplikacji interne-
towych. Nauka nie powinna przyspa-
rzać problemów, a opanowanie pracy
Wyszukiwarka Flickr Kontroler korzysta z trzech widoków. z tym narzędziem umożliwi ci szybkie
Stworzymy teraz prostą wyszukiwarkę Pierwszy – index.php jest dość prosty. i sprawne tworzenie CMSów jak i in-
Flickr.com wykorzystując udostępnione Otrzymaliśmy prostą wyszukiwarkę nych skryptów. n
API serwisu. Tworzymy prosty kontro- zdjęć z serwisu flickr.com
ler: Po wstawieniu własnego Klucza API
kontroler będzie w pełni sprawny i wy- Siła MVC
świetli 20 pierwszych grafik znalezionych Stworzyliśmy prostą aplikację według
dla frazy „kubica”. Metoda _ search jest wzorca MVC. Prawdziwe aplikacje jak np.
niedostępna poprzez odnośniki, gdyż za- forum dyskusyjne to kilka tysięcy lub wię- O autorze
czyna się od znaku podkreślenia. Metoda cej linii kodu, który musimy w stanie roz-
Piotr Maliński jest studentem Politech-
index wykorzystuje ją i wyświetla zawar- wijać. Jakie są zalety MVC?
niki Warszawskiej na kierunku Techno-
tość zwróconej tablicy. Efekt przedstawio- logia Chemiczna. Od czterech lat zajmu-
no na Rysunku 1. • każdym elementem (logika, interfejs i je sie tworzeniem aplikacji w PHP, jak
Teraz rozszerzymy istniejący kon- model aplikacji) mogą zajmować się też od niedawna o Pythonie. Jest rów-
nież autorem serwisów o nazwie Biblio-
troler o formularz na poszukiwaną frazę inne osoby,
teka Riklaunima.
oraz skorzystamy z widoków. Kod zmo- • można stosować dopasowane do ele-
dyfikowanego kontrolera widzimy na Li- mentu programy (np. edytory xhtml do Kontakt: riklaunim@gmail.com
stingu 3. szablonów),

18 www.phpsolmag.org PHP Solutions Nr 2/2007


Projekty

Wsparcie SEO w systemach


zgodnych ze standardami W3C
na przykładzie eZ Publish
Stopień trudności: lll
Juliusz Całyniuk

Przestrzeganie standardów kreowanych przez


W3C jest sprawą pierwszorzędnej wagi dla
witryn WWW – o tym nie trzeba przekonywać
nikogo. Strony zgodne ze wskazaniami tej
organizacji zapewniają długoterminowe
bezpieczeństwo związane z możliwymi zmianami
technologii.

W
ebmaster, projektant i progra- SEO i standardy W3C
mista WWW odpowiedzą, że Search Engine Optimization (SEO), czyli
standardy służą każdemu in- optymalizacja stron WWW dla wyszukiwa-
ternaucie. Dokładniej służą temu, aby rek internetowych, jest jednym z elementów
wszystkie przeglądarki poprawnie wyświe- pozwalających promować serwisy WWW.
tlały stronę spełniającą wytyczne W3C. Optymalizacja może stanowić część szer-
Standardy mają zapewnić długoterminowe szej strategii marketingowej w internecie
bezpieczeństwo. Nowa wersja przeglądar- – Search Engine Maketing (SEM). Dla ko-
ki lub nowa technologia nie powinny spo- mercyjnych przedsięwzięć kwestia optyma-
wodować konieczności zmiany witryny. lizacji dla wyszukiwarek jest bezsporna, po-
Wcześniej zwróciłem jednak uwagę, że zwala bowiem skutecznie dotrzeć do poten-
„czytelnikami” stron WWW nie są jedynie in- cjalnych zainteresowanych z informacją o
ternauci korzystający z przeglądarek interne-
towych. Innym ważnym odbiorcą treści pu- Co należy wiedzieć...
blikowanych w internecie są wyszukiwarki. Czym są standardy i technologie WWW:
Systemy wyszukiwawcze starają się prze- XHTML, CSS, WCAG, RSS; podstawy
czytać jak najwięcej stron WWW, a następ- XHTML; znajomość podstaw budowy
serwisów WWW.
nie zindeksować i uporządkować ze wzglę-
du na ich treść. Takie zadanie wymaga bar-
Co obiecujemy...
dzo dobrego zrozumienia struktury danych. Optymalizacja stron WWW dla wyszuki-
Zgodnie z powyższym można posta- warek (SEO). Dowiesz się, jaki jest zwią-
wić tezę, że wspierając standardy W3C, zek pomiędzy standardami W3C i SEO.
optymalizujemy strony dla wyszukiwarek Nauczysz się też podstaw optymalizacji
dla wyszukiwarek.
internetowych.

20 www.phpsolmag.org PHP Solutions Nr 2/2007


SEO Projekty

produktach lub usługach. SEO ma ogrom- cy pełną wbudowaną funkcjonalność po- Uzyskujemy dzięki temu adres postaci:
ne znaczenie dla witryn WWW, a zwłasz- trzebną do zarządzania informacją z bar- http://www.domena.com/content/view/
cza przedsięwzięć komercyjnych. Świadomi dzo elastycznym systemem szablonów, full/66 w miejsce przykładowego ad-
tego faktu projektanci potrafili zaimplemen- • Content Management Framework (CMF) resu pozbawionego translacji: http://
tować wsparcie dla SEO w budowanych – wzorzec projektowy dla różnorodnych www.domena.com/index.php?id_kat=
przez siebie systemach zarządzania treścią. systemów informacyjnych; jest otwarty, news&art=123&SessID=123jkls8je3k-
Standardy W3C zapewniają wsparcie SEO, elastyczny, rozszerzalny, skalowalny, a s905lpswas23we89d9ei.
ponieważ promują: przede wszystkim wspiera standardy. • Translacja z adresowania systemo-
wego do “nice urls” (automatyczna),
• oddzielenie treści od formy jej prezen- eZ Publish wykorzystuje takie standardy i czyli zamiana parametrów systemo-
tacji (wykorzystanie XHTML dla opisu protokoły jak: XHTML, CSS, WCAG, RSS, wych na czytelne dla człowieka fra-
treści, CSS dla formatowania), Open Document, SOAP, WebDav. zy. Translacja odbywa się na podsta-
• właściwe wykorzystanie języka opisu Najbardziej istotne z punktu widze- wie nazw kolejnych obiektów w ścież-
strony (brak błędów składni w XHTML nia systemu WCM są standardy kreowa- ce do przeglądanego dokumentu.
ułatwia systemom wyszukiwawczym po- ne przez W3C, czyli XHTML, CSS oraz Przykładowo, zamiana adresu: http://
prawnie interpretować treść dokumentu), WCAG. Zgodność z nimi zapewnia rów- www.domena.com/content/view/full/66
• stosowanie właściwej struktury doku- nież pomoc w optymalizowaniu serwisów na “nice url”: http://www.domena.com/
mentu (XHTML udostępnia znaczni- dla systemów wyszukiwawczych. oferta/uslugi/seo. W efekcie takiej zamia-
ki dla podstawowych jednostek infor- ny systemy wyszukiwawcze otrzymują
macyjnych dokumentu: nagłówki, listy, Wbudowane dodatkową informację (słowa kluczowe)
paragrafy, odnośniki, grafiki itd.), wsparcie dla SEO na temat zawartości dokumentu.
• wykorzystanie metainformacji (XHTML eZ Publish posiada mechanizm “przyja- • Translacja manualna dokonywana
pozwala na zdefiniowanie: tytułu, opi- znego adresowania”, który podzielić moż- przez administratora serwisu. Dzięki
su zawartości, słów kluczowych, usta- na na 3 poziomy: odpowiedniej funkcjonalności eZ Pu-
wień języka itp.), blish administrator może samodziel-
• dostępność treści stron (wskazania • Adresowanie systemowe (automa- nie dokonać konwersji adresu. Taka
Web Content Accessibility Guidlines tyczne), czyli zapisywanie adresów funkcja nie jest wykonywana często,
– WCAG – promują np. dodawanie URL pozbawionych znaków innych niż jednak może znacznie skrócić adres
alternatywnych opisów dla obiektów alfanumeryczne oraz znaków podkre- oraz podkreślić słowa kluczowe. Funk-
osadzanych, typu obrazki i multime- ślenia. Podstawową zaletą tej transla- cja jest również przydatna w sytuacji,
dia oraz alternatywnych bloków <no- cji jest pozbycie się znaków charakte- kiedy adres URL powinien być łatwy
script> i <noframes>). rystycznych dla przesyłania parame- do zapamiętania (np. trzeba go podać
trów w żądaniu GET protokołu HTTP. słownie lub zamieścić na plakacie).
Dla systemu Web Content Management
(WCM) wspieranie standardów siecio-
wych oraz SEO to podstawowe wymaga-
nia. W jaki sposób system może wspie-
rać optymalizację? Jest przynajmniej kil-
ka możliwości:

• czytelne adresowanie URL,


• poprawne formatowanie dokumen-
tów poprzez odpowiednie stosowa-
nie znaczników: tytuł strony, nagłówki,
opisy odnośników i grafik,
• informacja o języku dokumentu,
• dynamiczne mapy stron.

W dalszej części postaram się przedsta-


wić przykłady wsparcia SEO przez system
eZ Publish.

eZ Publish i standardy
eZ Publish przedstawiany jest jako:

• Content Management System (CMS) Rysunek 1. Narzędzie translacji adresów URL dostępne z poziomu panelu administra-
– system zarządzania treścią zawierają- cyjnego eZ Publish

PHP Solutions Nr 2/2007 www.phpsolmag.org 21


Projekty SEO

Przykładowo, ważną informację o promo- "http://www.w3.org/TR/xhtml1/ <!DOCTYPE html PUBLIC "-//W3C//


cji przedstawianą na stronie zamieszczo- DTD/xhtml1-transitional.dtd"> DTD XHTML 1.0 Transitional//EN"
nej głęboko w strukturze serwisu WWW "http://www.w3.org/TR/xhtml1/
i adresowaną: http://www.domena.com/ Język dokumentu oraz DTD/xhtml1-transitional.dtd">
firma/aktualnosci/promocje/promocja_zima_ kodowanie znaków. <html xmlns="http://www.w3.org/1999/
2006_2007, możemy uprościć do: http:// xhtml" xml:lang="{$site.
www.domena.com/promocja <html xmlns="http://www.w3.org/1999/ http_equiv.Content-language|wash}"
xhtml" xml:lang="en" lang="en"> lang="{$site.http_equiv.
Poprawne formatowanie <meta http-equiv="Content-Language" Content-language|wash}">

dokumentów content="en-GB" /> <head>


Jak wspomniałem wyżej, standardy siecio- <meta http-equiv="Content-Type" {include uri="design:page_head.tpl"}
we są sprzymierzeńcem SEO. Podstawo- content="text/html; </head>
wym zadaniem wyszukiwarek jest indek- charset=iso-8859-1" /> <body>
sowanie treści tekstowych. Aby przepro- <!-- tresc dokumentu -->
wadzić ten proces, system wyszukiwaw- Tytuł dokumentu. </body></html>
czy musi rozumieć czytane dokumenty.
Nie trudno się zatem domyśleć, że zgod- <title>Tytuł przeglądanej strony</title> Ustawienia językowe:
ność dokumentów ze standardami W3C,
a przede wszystkim HTML i XHTML jest Dodatkowe metainformacje {$site.http_equiv.Content-language|wash}
bardzo istotna dla tego procesu. Najczęściej wykorzystywane znaczniki
System WCM powinien zatem wspierać <meta> zawierają opis zawartości doku- czytane są z pliku konfiguracyjnego syste-
standardy, aby sprawić, by dokumenty były mentu oraz słowa kluczowe: mu site.ini:
czytelne nie tylko dla ludzi (korzystających z
interfejsu przeglądarek WWW), ale również l <meta name="description" conten- [RegionalSettings]
robotów wyszukiwarek. System powinien t="eZ Publish Documentation" />, Locale=eng-GB
zapewnić przesłanie metainformacji charak- l <meta name="keywords" content="eZ
teryzujących dany dokument: Publish, documentation, manual, refe- W szablonie page_head.tpl włączanym do
rence, eZ systems" />. głównego układu strony (pagelayout.tpl),
Format dokumentu. ustawiane są między innymi znaczni-
Przykładowo dla XHTML 1.0 Transitional: Wszystkie z wymienionych wytycznych ki <meta> czytane z konfiguracji zawartej
wspierane są przez wbudowane szablony również w pliku site.ini:
<!DOCTYPE html PUBLIC "-//W3C//DTD eZ Publish. Oto przykładowy szablon ukła-
XHTML 1.0 Transitional//EN" du strony pagelayout.tpl: [SiteSettings]
MetaDataArray[author]=eZ systems
MetaDataArray[copyright]=eZ systems
MetaDataArray[description]=Content
Management System
Rysunek 2. Zawartość znacznika <title> wyświetlona przez przeglądarkę
MetaDataArray[keywords]=cms, publish,
e-commerce, content management,
development framework

Dodatkowo generowany jest znacznik <title>


składający się z nazw kolejnych obiektów,
poczynając od aktualnego, przez kolejnych
przodków, aż do głównej strony serwisu.

Szablony oparte
na blokach <div>
W przeszłości układ strony WWW two-
rzony był przy użyciu zagnieżdżonych ta-
bel, co pozwalało na bardzo wygodne roz-
mieszczanie elementów na stronie, jednak
powodowało kilka istotnych problemów.
Oto najważniejsze z nich:

• niejasna konstrukcja dokumentu (np.


nagłówek mógł znajdować się w innej
komórce, wierszu, czy nawet tabeli w
Rysunek 3. Formatowanie treści w eZ Publish Online Editor stosunku do treści kolejnych akapitów),

22 www.phpsolmag.org PHP Solutions Nr 2/2007


SEO Projekty

• elementy formatowania pomieszane z wiedniego interpretowania jego zawarto- Dynamiczna mapa nie jest już nowo-
treścią strony (np. wstawienie instruk- ści przez wyszukiwarki. Format zapisane- ścią w systemach typu WCM. Jest ona
cji dla CSS bezpośrednio w znaczniku go dokumentu XHTML 2.0 jest następnie cenna, ponieważ wiarygodnie odzwier-
HTML lub „tworzenie nagłówka” z ko- konwertowany na zgodny z XHTML 1.0 ciedla strukturę serwisu, a przez to do-
mórki tabeli przez odwołanie do odpo- przy wykorzystaniu szablonów systemu. brze opisuje jego zawartość. Dodatkowo,
wiedniej klasy zdefiniowanej w CSS), Wysokiej jakości formatowanie zgod- nazwy działów i dokumentów są wysoko
• skomplikowana interpretacja – kod ne z XHTML jest kluczowe dla SEO. Po- oceniane, ponieważ mają formę nagłów-
źródłowy HTML był zwykle dużo więk- zwalając redaktorom serwisu na dowol- ków i odnośników.
szy i często składał się z wielokrotnie ność (wstawianie niepoprawnego kodu eZ publish umożliwia generowanie ma-
zagnieżdżonych tabel. HTML) niszczy się efekt pracy włożonej w py serwisu lub jego dowolnej gałęzi. Jeżeli
tworzenie zgodnych ze standardami sza- zatem tworzymy stronę z kilkoma rozbudo-
Ponieważ podstawowym celem stawia- blonów stron. wanymi działami lub nawet kilka serwisów
nym CMS jest oddzielenie warstw: treści i WWW opartych na jednej instancji systemu
prezentacji, szablony wzorcowe w eZ Pu- Dostępność CMS, możliwe jest niezależne generowanie
blish skonstruowane są bez użycia tabel, Wskazówki WCAG służą dostosowa- map dla działów lub serwisów.
a oparte na blokach <div>. Taka konstruk- niu treści dostępnych na stronach WWW Mapa strony generuje się automa-
cja pozwala zamknąć stronę WWW w czy- użytkownikom starszym, niepełnospraw- tycznie po odwołaniu do adresu: http://
stej formie dokumentu XML. nym oraz interpretację przez urządze- www.domena.pl/content/view/sitemap/x,
Zalety takiego rozwiązania są istotne, nia mobilne. Podobnie, jak inne standar- gdzie “x” oznacza numer węzła w drze-
ponieważ niwelują wady stylu tabelarycz- dy kreowane przez W3C, daje on również wie struktury zawartości. Przykładowy kod
nego, oferując w zamian: silny oręż do optymalizacji dla wyszukiwa- strony związany bezpośrednio z mapą
rek. Jedną z reguł, którą powinny spełniać może posiadać następującą formę:
• oddzielenie treści (zamkniętej w for- witryny zgodne z WCAG, jest konieczność
macie XHTML) od formy (formatowa- opisywania grafik. <h1><a href=”/”>Mapa strony Domena.com
nie w CSS), Mówi się, że jeden obraz znaczy wię- </a></h1>
• czystą konstrukcję dokumentu (widać, cej niż tysiąc słów. Prawdopodobnie dla- <h2><a href=”/dzial_pierwszy”>
gdzie jest tytuł, nagłówki listy i paragrafy) tego wyszukiwarki traktują opisy alterna- Dział pierwszy</a></h2>
• możliwość prostej integracji – importu tywne bardzo poważnie. Nie są w stanie <ul>
lub eksportu danych, zinterpretować treści ilustracji inaczej niż <li><h3><a href="/
• lekką stronę z treścią – mniejszy roz- przez opis, który został do niego dodany. dzial_pierwszy/folder_x">
miar dokumentu, Także w tym zakresie eZ publish udo- Folder X</a></li>
• przenośność pomiędzy przeglądarka- stępnia wygodne narzędzia redaktorskie. <li><h3><a href="/
mi (również urządzeń mobilnych z ma- Dodanie obrazka i opisanie go pozwoli dzial_pierwszy/
łymi ekranami). wygenerować kod XHTML z opisem alter- folder_y">Folder Y</a></li>
natywnym, czyli znacznik postaci: </ul>
Znaczniki treści formatowanych <h2><a href=”/dzial_drugi”>
Większość nowoczesnych systemów <img src="ilustracja.png" Dział drugi</a></h2>
WCM udostępnia redaktorowi wbudowa- alt="Alternatywny opis dla ilustracji" /> <ul>
ną aplikację – edytor online, który pozwa- <li><h3><a href="/
la formatować treść stron WWW. Ważne Mapa strony dzial_drugi/folder_a">
jest, aby zapisywana po sformatowaniu Dla procesu indeksowania stron WWW Folder A</a></li>
treść była również zgodna ze standarda- niezwykle istotne jest wewnętrzne linko- <li><h3><a href="/
mi W3C. Generowanie kodu zawierające- wanie, czyli powiązania pomiędzy strona- dzial_drugi/folder_b">
go wpisane formatowanie CSS lub znacz- mi serwisu. Stąd dla wyszukiwarek klu- Folder B</a></li>
niki <FONT> jest niedopuszczalne. czową rolę odgrywają strony-bramy, czy- <li><h3><a href="/
eZ Publish posiada własne dedykowa- li strony zawierające dużą liczbę odnośni- dzial_drugi/folder_c">
ne rozwiązanie wyróżniające się zgodno- ków wewnętrznych. Najpopularniejszym Folder C</a></li>
ścią ze standardem, za który obrano kre- przykładem takiej strony jest „Mapa ser- </ul>
owany przez W3C XHTML 2. Z pozoru wisu”.
podstawowe formatowanie tekstu jako na-
główków, paragrafów, list punktów stano-
wi jeden z kluczowych elementów odpo-

Rysunek 6. Efekt wyświetlenia tekstu al-


Rysunek 4. Kod wygenerowany przez Rysunek 5. Efekt wyświetlenia tekstu al- ternatywnego grafiki przez przeglądarkę
eZ Publish Online Editor ternatywnego grafiki przez przeglądarkę z zablokowaną opcją pobierania obrazów

PHP Solutions Nr 2/2007 www.phpsolmag.org 23


Projekty SEO

RSS dostarczonymi przez eZ Publish „w pu- Dla systemu WCM, którego głównym
Nowoczesne systemy wyszukiwawcze dełku”, można wzbogacić go o nową zadaniem jest oddzielenie treści od pre-
cenią wysoko aktualne treści, dlatego dla funkcjonalność. Rozszerzalność syste- zentacji, generowanie dowolnego formatu
procesu SEO ważna jest częsta aktuali- mu oraz możliwość modyfikacji to rów- dokumentu nie powinno stanowić proble-
zacja zawartości. Blogi oraz wszelkiego nież cechy ważne dla programistów roz- mu. System eZ Publish pozwala budować
typu serwisy dostępne w formie RSS sta- wiązań bazujących na WWW. Dzięki szablony w dowolnym standardzie zgod-
nowią cenne źródło bieżącej informacji. nim można zaimplementować ulepszo- nym z XML. W domyślnej wersji system
Dodatkową zaletą witryn WWW, udo- ną obsługę znaczników <meta>, albo pracuje z XHTML 1.0 Transitional. Można
stępniających subskrypcję RSS, jest moż- Google Sitemaps. jednak opracować własny format.
liwość publikowania skrótów wiadomości w Specjalnie dla potrzeb Google Site-
innych serwisach. W takich sytuacjach stro- Metatagi maps udostępniona została wtyczka do
na otrzymuje to, co w przypadku rankingu Google jasno informuje o całkowi- systemu, pozwalająca generować doku-
Google jest najważniejsze – odnośniki do tym ignorowaniu zawartości tagów me- menty w takim właśnie formacie.
własnej treści z zewnętrznych witryn. ta “keywords”. Musimy jednak pamię- Rozszerzenie można pobrać ze stro-
Możliwość importu i eksportu kana- tać, że inne mechanizmy wyszukiwaw- ny społeczności: http://ez.no/community/
łów RSS jest jedną z podstawowych funk- cze niekoniecznie postępują w ten sam contribs/template_plugins/googlesite-
cjonalności eZ Publish. Wykorzystując na- sposób. Jeśli nawet metatagi nie stano- maps_extension
rzędzia dostępne w panelu administracyj- wią podstawy opisu informacji zawartych
nym, automatyzujemy generowanie RSS na stronie, to stanowią część opisu jego Podsumowanie
dla eksportu oraz importu. zawartość. Jednym z celów, jaki chcemy osiągnąć przy
Import, czyli pobieranie informacji z Warto zatem w przypadku, gdy SEO budowie strony WWW, jest dotarcie do sze-
obcej lokalizacji, pozwala wzbogacić ser- jest dla nas bardzo ważne, skonstruować rokiego grona zainteresowanych prezento-
wis o: mechanizm obsługi dla osób redagują- waną tematyką odbiorców. Pragniemy, aby
cych treść. W przypadku eZ Publish zada- planowana grupa docelowa wiedziała o je-
• częstą aktualizację, nie jest proste i polega na: go istnieniu. Często nie możemy sobie po-
• wartościowe treści związane z tema- zwolić, żeby było inaczej. Najlepszym przy-
tem witryny (wzmocnienie słów klu- • rozszerzeniu klasy Artykuł, czyli do- kładem jest sklep internetowy.
czowych), daniu nowych atrybutów – pól teksto- SEO to nie pozycjonowanie, ale opty-
• odnośniki zewnętrzne do cennych źró- wych o nazwach: „Słowa kluczowe” malizacja – pomaganie wyszukiwarce
deł informacji (wartościowe źródła mo- oraz “Description”, w odpowiedniej interpretacji zawartości
gą wzmacniać wiarygodność strony). • dodaniu krótkiego skryptu szablo- wszystkich stron serwisu WWW.
nowego, który wyświetli zawartość Mając zamiar wykorzystać system
Eksport, czyli udostępnianie własnych treści: wypełnionych pól w znacznikach CMS, gotowe narzędzie zapewniają-
<meta name=”description”> i <meta ce podstawową funkcjonalność zarzą-
• wzbogaca rozwiązanie o nowy kanał name=”keywords”> niezależnie dla każ- dzania treścią, należy zwrócić uwagę,
komunikacyjny, dej strony. czy respektowane są w nim standar-
• pozwala uzyskać odnośniki do naszej dy W3C. Jeśli tak jest, uzyskamy także
strony, które pochodzą z innych witryn. Google Sitemap wsparcie dla procesu SEO.
W Google opracowano technikę wspie- Wbudowana konwersja adresów URL
Samodzielne rającą proces indeksowania witryn. Go- pozwalająca uzyskać przyjazne odnośni-
rozszerzenie wsparcia SEO ogle Sitemaps to dokumenty XML o spe- ki, staje się normą. Należy jednak zwró-
Poza wymienionymi wyżej przykładami cyficznej składni, odzwierciedlające struk- cić uwagę na inne elementy optymalizacji,
wsparcia SEO przez systemy WCM, a turę serwisu. a przede wszystkim odpowiednie dostoso-
wanie do standardów sieciowych. Czytelny
dokument jest sprzymierzeńcem SEO. n

O autorze
Juliusz Całyniuk zajmuje się zarządze-
niem projektami oraz relacjami z klienta-
mi i partnerami WebStyle Systems. Od
siedmiu lat jest związany z oprogramo-
waniem dla platformy LAMP. Współtwo-
rzy serwis polskiej grupy użytkowników
systemu eZ Publish.

Kontakt:
Rysunek 7. Funkcjonalność eksportu i importu RSS w panelu administracyjnym juliusz.calyniuk@ws-webstyle.com
eZ Publish

24 www.phpsolmag.org PHP Solutions Nr 2/2007


Strona poświęcona językowi PHP. Skierowa- Strona zawierająca skrypty, newsy i artykuły Strona poświęcona językowi php. Można tu
na głównie do webmasterów i twórców opro- dotyczące aplikacji CMS oraz forum poświęco- znaleźć m.in. artykuły oraz dział “download”
gramowania. ne temu zagadnieniu. oraz wypowiedzieć się na forum.
www.strefaphp.net www.trycms.org www.php.org.pl

Główna strona firmy gdaq.pl multimedia zajmu- Strona zajmująca się różnymi zagadnieniami z Strona jest polską bazą tutoriali, zawierającą
jącej się kreowaniem wizerunku firm poprzez działu IT. Prezentuje m.in. newsy, artykuły oraz różnorodne teksty o tematyce informatycznej.
projektowanie stron, hosting, e-marketing etc. pliki do ściągnięcia i forum. www.webtutorials.pl
www.gdaq.pl www.huntersq2.boo.pl

Misją serwisu jest dostarczanie rzetelnych in- Portal w całości poświęcony językowi PHP. Strona, na której znajdziesz profesjonalne sza-
formacji z zakresu szeroko pojętej informatyki. Można tu znaleźć m.in. recenzje, artykuły oraz blony stron www. Ponadto prezentuje tutoriale,
Strona zawiera newsy m.in. z działów: progra- newsy poświęcone temu zagdnieniu. artykuły i porady dla webmasterów.
mowania, bezpieczeństwa oraz Internetu. www.php.pl www.d4u.pl
www.itnews.icx.pl

To serwis branży IT, oferujący m.in. newsy, ar- Serwis dla początkujących, jak i zaawansowa- Główna strona studentów Politechniki War-
tykuły, recenzje książek i magazynów oraz fo- nych webmasterów. Zawiera gotowe szablony szawskiej.
rum. Strona obejmuje również patronat nad stron oraz posegregowane skrypty PHP i Ja- www.polibuda.info
projektami IT. vaScript.
www.webhat.pl www.szablonypro.com
Dla zaawansowanych

Ankiety w stylu rankingowym


z użyciem AJAX-a
Stopień trudności: lll
Krzysztof Trynkiewicz

PHP od początku swojego istnienia był wyko-


rzystywany do tworzenia różnego rodzaju ankiet
i rankingów. Specyfika formularzy w HTML nie
pozwalała jednak nigdy na stworzenie prostego
w obsłudze systemu, w którym oceny przyzna-
wane są hierarchicznie. Dzięki technologii AJAX,
wreszcie możemy stworzyć obiektywne systemy
rankingowe z przyjemnym dla oka interfejsem,
opartym na CSS i JavaScript.

W
dobie społeczności Inter- osobne pole na wybór oceny, jednak
netu istotne jest, by znać wynik będzie uzyskany kosztem wielu
opinie jego użytkowników kliknięć Internauty – a więc często je-
na wszelkie tematy. Na wielu witry- go frustracji. Takiej sytuacji nie ryzyku-
nach spotykamy więc ankiety, w któ- ją webmasterzy, tworząc ankiety z jed-
rych oceniamy pewne zachowania, sy- ną możliwą odpowiedzią. Od 2005 ro-
tuacje, zdarzenia, czy też informuje- ku, kiedy to rozpowszechniła się tech-
my o naszych upodobaniach. Na pew- nologia AJAX, zadanie to stało się nie-
no jednak każdy z nas trafił na ankie- mal trywialnie proste. Nieznajomość
tę, która zmusiła go do refleksji – jeże- nowej technologii, niechęć do języka
li bowiem mamy do wyboru dwie nie- JavaScript i obawy o niekompatybil-
mal równoważne możliwości, wybranie ności przeglądarek powodują jednak,
W SIECI jednej, oznacza dyskredytację drugiej. że w Internecie niemal niemożliwe jest
Ten mankament powoduje, że ankiety spotkanie ankiet hierarchicznych. Re-
w Internecie nie odzwierciedlają ide-
• http://prototype.conio.net/ alnie gustów ankietowanych. Idealna
– framework AJAX-owy,
• http://script.aculo.us/
ankieta powinna więc pozwalać nam Co należy wiedzieć…
– pakiet Script.Aculo.Us, na udzielenie kredytu nie tylko jednej Przydatna będzie znajomość podstaw
• http://www.sergiopereira. technologii AJAX.
opcji. Jakkolwiek taki stan rzeczy wy-
com/articles/prototype.js.
html – obszerny opis daje się oczywisty w życiu codzien-
Prototype, nym. Tak, jest to trudne zadanie do Co obiecujemy…
• http://ajax.eldoras.com Dowiesz się, jak tworzyć ankiety w sty-
– witryna projektu ankiet
zrealizowania przy pomocy formularzy
lu rankingowym przy pomocy technolo-
AJAX-owych Autora. dostępnych w HTML. Możemy wpraw-
gii AJAX.
dzie obok każdej z pozycji umieścić

26 www.phpsolmag.org PHP Solutions Nr 2/2007


Ankiety AJAX-owe Dla zaawansowanych

wolucja nadeszła jednak wraz z opra- ny jest banalnie proste i skuteczne. Na języka CSS (reprezentowanym przez
cowanym przez Sama Stephensona bazie tego wspaniałego skryptu stwo- identyfikatory) efektów pojawiania się,
frameworkiem Prototype dla języka Ja- rzono także zestaw graficznych udo- ukrywania, przenoszenia i wielu in-
vaScript. Dzięki niemu, tworzenie po- godnień w języku JavaScript – Scrip- nych, kompatybilnych z większością
łączeń AJAX-owych ze skryptem PHP taculous. Stosując ten pakiet, otrzyma- nowoczesnych przeglądarek. Stosując
bez konieczności przeładowania stro- my możliwość nadawania elementom wszystkie te udogodnienia, możemy
stworzyć efektowny oraz efektywny
system rankingowy.
Listing 1. Wygląd ogólny ankiety w kodzie HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" Niezbędne


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> przygotowania
<html xmlns="http://www.w3.org/1999/xhtml"> Do pełni szczęścia będzie nam po-
<head> trzebny, oprócz PHP, framework Proto-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
type oraz pakiet Scriptaculous. Zestaw
<title>AJAXowe ankiety</title>
<script src="js/prototype.js" type="text/javascript"></script> Scriptaculous pobierzemy z adresu wi-
<script src="js/scriptaculous.js" type="text/javascript"></script> docznego w ramce W Sieci. Zawiera on
<script type="text/javascript" language="javascript"> także framework Prototype, jednak jeśli
<style> chcemy – możemy sprawdzić, czy jest
#categories {
to wersja aktualna na stronie projektu,
list-style-image:none;
list-style-type:none; ewentualnie zamieniając plik prototy-
margin:0px; pe.js na odpowiedni. Powinniśmy roz-
padding:0px; pakować pliki o rozszerzeniu js z ka-
} talogu lib pakietu Scriptaculous oraz
#categories li {
plik prototype.js do wspólnego folderu,
background-color: #ECF3E1;
border:1px solid #C5DEA1; np. javascript. Nasz kod zamieścimy w
cursor: move; dwóch plikach PHP: index.php oraz ra-
width: 130px; te.php. Pierwszy z nich będzie odpo-
margin-top:5px; wiedzialny za prezentację ankiety oraz
}
wyników, drugi – za zliczanie głosów
#submit {
background-color: #C5DEA1; oraz ich pobieranie z bazy. Kod CSS
border:1px solid #ECF3E1; jest w tym wypadku istotny, znajdziecie
padding: 2px; go w pliku index.php.
width: 80px;
cursor: pointer;
text-align: center;
Wygląd zewnętrzny
} Zacznijmy od stworzenia treści ankie-
</style> ty. Przykładowa ankieta, wraz z kodem
</head> CSS, została zamieszczona na Listin-
<? gu 1. Pobrane biblioteki JavaScript zo-
$options=array('Rock', 'Pop', 'House', 'Techno', 'Chillout', 'HipHop', 'Other');
stały włączone do kodu strony, style
?>
<body>
<div id="container">
Jaką muzykę lubisz?
<ul id="categories">
<?
$i=1;
foreach($options as $option){
print '<li id="item_'.$i.'">'.$option.'</li>';
$i++;
}
?>
</ul>
<br />
<div id="submit" onclick="SubmitForm('categories');">
Submit
</div>
</div>
</body>
</html>

Rysunek 1. Gotowa ankieta AJAX-owa

PHP Solutions Nr 2/2007 www.phpsolmag.org 27


Dla zaawansowanych Ankiety AJAX-owe

CSS zostały zdefiniowane tak, by an- nić witryna po pobraniu wyników zapy- Zliczamy głosy
kieta wyglądała odpowiednio, mimo że tania AJAX. Nam wystarczy jednak ta Nasz system ankiet jest już niemal goto-
użyjemy do jej prezentacji listy HTML. jedna – jeśli zależy nam na transferze, wy. Musimy jeszcze dopisać kod odpo-
Biorąc pod uwagę dostępność, nale- możemy pokusić się o wycięcie nieuży- wiedzialny za zliczanie głosów i ich wy-
żałoby stworzyć formularz HTML dla wanych fragmentów kodu z pliku proto- świetlanie. Zadanie może sprawić trudno-
osób z wyłączoną obsługą JavaScript, type.js. Do wyjaśnienia pozostała jesz- ści jedynie przy zagadnieniu rozkodowy-
który dzięki niemu byłby ukrywany, cze zmienna pars. Wiąże się ona z pa- wania przesłanego w zmiennej rates łań-
jednak nie jest to w gestii tego artyku- kietem Scriptaculous, którego funkcja cucha. Listing 5. pokazuje, jak tego doko-
łu. Możliwości wyboru zostały wpisane Sortable.serialize() zwraca ciąg zna- namy. Najpierw, zamienimy go na tablicę,
do tablicy, a następnie wyświetlone za ków w stylu tego z zapytań GET, które- z której pozbędziemy się zbędnego wy-
pomocą pętli. Wygląd ankiety został go składowymi są numery pozycji z na- miaru (categories). Następnie przetwo-
przedstawiony na Rysunku 1. szej listy, przypisane jako kolejne ele- rzymy ją w pętli, przypisując kolejnym po-
menty tablicy, o nazwie będącej iden- zycjom (istotna jest tu kolejność w tablicy
Prototype w praktyce tyfikatorem listy. W naszym przypad- $options) ich kolejność ustaloną przez
Po kodzie naszego przycisku można ku, dla niezmienionej kolejności pól, użytkownika (przy czym niższa liczba
poznać, że aktywuje on funkcję Sub- funkcja ta zwróci następujący ciąg: oznacza wyższą pozycję). Wszystko, co
mitForm z parametrem będącym iden- categories[]=1&categories[]=2&catego pozostało do zrobienia, to wpisanie wyni-
tyfikatorem listy naszej ankiety. Funk- ries[]=3&... itd. Kłopot w tym, że jeżeli ków do bazy danych (zapewne będziemy
cja ta (Listing 2.) będzie zdefiniowa- prześlemy taki ciąg znaków bezpośred- odejmować wybraną kolejność od ilości
na wewnątrz znacznika head. Będzie nio jako zbiór parametrów, otrzymamy wyborów, by uzyskać wyższą notę dla po-
to główny silnik naszej aplikacji: jej za- w PHP tablicę z jedynie jednym – ostat- zycji wyżej notowanej w hierarchii) przez
daniem będzie połączenie się z pli- nim – elementem. Musimy więc cały sumowanie oraz wypisanie aktualnych wy-
kiem rate.php z parametrami określo- ciąg znaków eskejpować i przypisać do ników. Tę część pracy pozostawiamy czy-
nymi w zmiennej pars (o nich za chwi- jednej zmiennej (rates), którą będziemy telnikowi, wymaga bowiem jedynie użycia
lę). Do wykonania połączenia wykorzy- rozkodowywać na właściwą tablicę po prostych zapytań do bazy oraz kilku lini-
stamy klasę AjaxUpdater frameworka stronie serwera. Pozostało nam jesz- jek kodu CSS odpowiednio formatujące-
Prototype. Jak można się spodziewać, cze przypisanie odpowiednich efektów go wyniki (nie zapomnijmy go uwzględnić
wywołuje ona witrynę z danymi para- wizualnych do naszej listy. Uzyskamy już w pliku index.php!). By otrzymać wy-
metrami, przekazując je przy pomo- to, stosując funkcję Sortable.create() niki własnego głosowania względem po-
cy określonej metody, zaś to, co zosta- pakietu Scriptaculous. Jej kod, widocz- zycji w tablicy $options, wystarczy użyć
nie odesłane, trafi do znacznika o iden- ny na Listingu 3, musimy umieścić po kodu zaprezentowanego na Listingu 5.
tyfikatorze target, zastępując już obec- kodzie listy, bowiem będzie on ją mo- Porównując wartości $item['order _ id']
ny tam kod (w naszym wypadku ankie- dyfikował – musi więc być już widocz- z indeksami tablicy $options, otrzymamy
ta zostanie zastąpiona jej wynikami). na. Najlepiej kod ten wkleić zaraz przed listę dostępnych wyborów.
Prototype oferuje także szereg innych znacznikiem kończącym body. Pełen
klas i funkcji, które pomagają w pre- kod pliku index.php, w odpowiedniej ko- Co dalej?
cyzyjnym określeniu, jak ma się zmie- lejności, widoczny jest na Listingu 4. Jak pokazaliśmy, stworzenie efektownej
i efektywnej ankiety przy pomocy frame-
Listing 2. Funkcja wysyłająca ankietę worka Prototype, zestawu Scriptaculous
oraz PHP jest łatwe i intuicyjne. Jako za-
<script type="text/javascript" language="javascript"> danie domowe pozostawiamy połączenie
// <![CDATA[
wyników z bazą danych. Czytelnicy, któ-
function SubmitForm(someid){
var url = 'rate.php';
rzy gustują w rozwiązaniach AJAX-owych,
var pars = 'rates='+escape(Sortable.serialize(someid)); zapewne zechcą użyć dodatku Behavio-
var target = 'container'; ur (http://www.bennolan.com/behaviour/).
var myAjax = new Ajax.Updater(target, url, {method: 'post', Został on stworzony przez Bena Nolana,
parameters: pars});
który słusznie zauważył, że wprowadzając
}
dodatkowe parametry do znaczników (np.
// ]]> onClick w naszym "przycisku"), ponow-
</script> nie zanieczyszczamy kod, który powinien
być zgodny z wytycznymi XML. Behavio-
Listing 3. Funkcja przypisująca efekty wizualne do listy ur pozwala na przypisanie elementom za-
<script type="text/javascript" language="javascript"> chowań JavaScript za pomocą ich identy-
// <![CDATA[ fikatorów. W ten sposób dołączamy kolejny
Sortable.create('categories',{dropOnEmpty:true,handle:'handle', plik w nagłówku witryny, jednak oczyszcza-
constraint:false}); my sam kod HTML. Czytelnicy pragnący
zastosować ten typ ankiety powinni pamię-
// ]]>
tać, by wartości głosów były odpowiednio
sprawdzane pod kątem zgodności w pliku

28 www.phpsolmag.org PHP Solutions Nr 2/2007


Ankiety AJAX-owe Dla zaawansowanych

Listing 4. Kompletny plik index.php

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>AJAXowe ankiety</title>
<script src="js/prototype.js" type="text/javascript"></script>
<script src="js/scriptaculous.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
<script type="text/javascript" language="javascript"> Rysunek 2. Główna witryna
// <![CDATA[ script.aculo.us zawiera wiele prezentacji
function SubmitForm(someid){ wizualnych pakietu
var url = 'rate.php';
var pars = 'rates='+escape(Sortable.serialize(someid));
var target = 'container'; Listing 5. Funkcja przypisująca
var myAjax = new Ajax.Updater(target, url, { efekty wizualne do listy
method: 'post', parameters: pars});
} <?
// ]]> parse_str($_POST['rates'],
</script><style> $ratesArray);
#categories { $ratesArray = $ratesArray[
list-style-image:none; 'categories'];
list-style-type:none; for($i=0;$i<count($ratesArray);
margin:0px; $i++) {
padding:0px; $finalArray[] = array(
} 'order_id' =>
#categories li { $ratesArray[$i], 'rate' =>
background-color: #ECF3E1; $i +1);
border:1px solid #C5DEA1; }
cursor: move;
width: 130px; foreach($finalArray as $item) {
margin-top:5px; print($item['order_id'].' =
} '.$item['rate'].'<br />');
#submit { }
background-color: #C5DEA1; ?>
border:1px solid #ECF3E1;
padding: 2px;
width: 80px; rate.php, przed wpisaniem ich do bazy. Pa-
cursor: pointer; miętać także należy o zablokowaniu moż-
text-align: center; liwości wielokrotnego głosowania przez te-
}
go samego użytkownika naszego serwisu.
</style>
</head> Z pewnością warto także przyjrzeć się bli-
<? żej pakietowi Scriptaculous, bowiem w ar-
$options=array('Rock', 'Pop', 'House', 'Techno', 'Chillout', 'HipHop', 'Other'); tykule wykorzystaliśmy zaledwie mały pro-
?> cent jego możliwości, podobnie zresztą,
<body><div id="container">
jak samego frameworka Prototype. W koń-
Jaką muzykę lubisz?
<ul id="categories"> cu, polecamy obejrzeć witrynę projektu an-
<? kiet hierarchicznych autora (patrz ramka
$i=1; W Sieci). n
foreach($options as $option){
print '<li id="item_'.$i.'">'.$option.'</li>';
$i++;
}
?>
</ul><br /> O autorze
<div id="submit" onclick="SubmitForm('categories');">Submit</div>
</div> Krzysztof Trynkiewicz od wielu lat zaj-
<script type="text/javascript" language="javascript"> muje się tworzeniem witryn w technolo-
// <![CDATA[ gii PHP oraz Flash. Ściśle współpracu-
Sortable.create('categories',{dropOnEmpty:true, je z magazynem PHPSolutions. Obec-
handle:'handle',constraint:false}); nie rozwija kilka równoległych projektów
// ]]> autorskich, dostępnych na witrynie http:
</script> //eldoras.com.
</body></html>
Kontakt: chris.trynkiewicz@gmail.com

PHP Solutions Nr 2/2007 www.phpsolmag.org 29


Dla zaawansowanych

ASwing + AMFPHP,
czyli przepis na szybkie GUI
Stopień trudności: lll
Rafał Malinowski

Masz już aplikację napisaną w PHP, ale chcesz


ulepszyć jej działanie? Możesz łatwo
stworzyć aplikacje Flash-owe w oparciu
o darmowe narzędzia. Prosto i bez trudu
przejdziesz trudną drogę, która doprowadzi do
powstania serwera aplikacji, który będzie mógł
komunikować się z Flash-em. Dodatkowo,
pokazujemy zastosowania ASwing.

C
elem artykułu jest przedsta- • część druga wprowadza do podstaw
wienie zalet tworzenia inter- OOP w ActionScript 2.0,
fejsu użytkownika we Flash-u. • część trzecia przedstawia ASwing
Chcemy pokazać, jak łatwo i przyjem- – narzędzie do tworzenia GUI z do-
nie da się tworzyć GUI dla aplikacji na- stępnych graficznych komponentów,
pisanych w PHP. Będziemy do tego ce- • część czwarta zaznajamia z AMFPHP
lu używać biblioteki ASwing, która po- – zapewniającym wydajną komunika-
zwala na budowę aplikacji z gotowych cję Flash-a z PHP-em.
graficznych komponentów. Przekaże-
my wiedzę, która każdemu początkują- Na samym końcu, w oparciu o to, co zo-
cemu programiście pozwoli na zbudo- stało przedstawione, napiszemy bardziej
wanie RIA, wykorzystując w zaawan- zaawansowaną aplikację typu klient-ser-
sowany sposób PHP-owy serwer apli-
kacji. Artykuł podzieliliśmy na cztery
tematyczne części. W każdej Czytelnik Co należy wiedzieć...
znajdzie konkretny, bardzo uproszczo- Przydatna będzie znajomość zasad pro-
gramowania obiektowego.
ny, ale działający przykład, zgodnie z
formułą HelloWorld, czyli bez dodatko-
wych upiększaczy. Co obiecujemy...
I tak: Dowiesz się, jak szybko i łatwo stworzyć
w GUI dla Twojej PHP-owej aplikacji, jak
w prosty sposób przesyłać dane między
• część pierwsza dotyczy procesu two- PHP a Flash-em. Nauczysz się też pod-
rzenia aplikacji Flash-owych w opar- staw programowania w ActionScript 2.0.
ciu o darmowe narzędzia,

30 www.phpsolmag.org PHP Solutions Nr 2/2007


GUI Dla zaawansowanych

wer, która będzie już wymagała od Czy- nym programem zapewniającym kompa- skompiluje program do postaci Hello-
telnika nieco samodzielnej pracy. tybilność z Flash Player-em, w wersjach World.swf. Tak przygotowany plik mo-
do 8 włącznie i do tego jest to jeszcze żemy otworzyć w przeglądarce interne-
Hello World – MTASC program pisany w konwencji opensour- towej z zainstalowanym FlashPlayer-em.
Na początek, prosty przykład pokazujący ce. Jak widać, same plusy. Przeglądarka, otwierając plik o rozsze-
podstawy działania kompilatora MTASC, Przyjrzymy się podstawowej składni rzeniu .swf, przekaże jego obsługę do
którego będziemy używać do tworze- kompilującej kod programu do pliku .swf: FlashPlayer-a, który powinien pokazać
nia aplikacji Flash-owych. MTASC (http:// nam w przeglądarce napis Hello World !
www.mtasc.org/) jest kompilatorem pli- mtasc (pliki .as z kodem programu) -swf Jeśli mamy problemy z kompilacją
ków .as wywoływanym z linii poleceń. (nazwa pliku swf) programu, znaczy to, że popełniliśmy ja-
Jego zadaniem jest zamiana kodu kiś błąd podczas pisania.
zrozumiałego dla człowieka na kod ma- W celu przetestowania MTASC na- Możliwe błędy podczas kompilacji to
szynowy, dający się uruchomić w prze- piszemy prosty program w języku przede wszystkim błędy występujące w
glądarce przy pomocy Flash Player-a, ActionScript 2.0. Tworzymy nowy plik w składni kodu. W takim przypadku kompi-
czyli popularnie nazywanego SWF lub naszym ulubionym edytorze tekstowym lator zwraca dokładne informacje na te-
MovieClip. MTASC wywoływany jest z li- i nazywamy go HelloWorld.as, a na- mat umiejscowienia błędu:
nii poleceń, można go więc zintegrować stępnie wpisujemy kawałek kodu przed-
z różnymi edytorami plików tekstowych stawiony na Listingu 1. nazwa pliku : numer linii : numer znaku
czy programów automatyzujących pro- Po zapisaniu pliku, komenda: w linii : komunikat błędu.
ces kompilacji (np.: Ant) – my w dalszej
części artykułu pokażemy, jak zintegro- mtasc HelloWorld.as -swf HelloWorld.swf Kod, w którym nie zamknęlibyśmy klam-
wać go z Eclipse 3.1. MTASC jest potęż- -main -header 800:600:20 ry kończącej definicję klasy HelloWorld
spowodowałby komunikat błędu nastę-
pującej postaci:
Listing 1. Plik HelloWorld.as

class HelloWorld { HelloWorld.as:15: character 0 : parse


error Unexpected <end of file>
public static function main (mc:MovieClip) : Void
{
Nie zawsze więc widać na pierwszy rzut
mc.createTextField("myText", 1, 100, 200, 300, 400);
mc.myText.text = "Hello World !"; oka, o co chodzi, ale po kilku literówkach
} i dokładnej analizie pliku we wskazanym
} miejscu będziemy w stanie szybko roz-
wiązywać napotkane problemy.
Przyjrzyjmy się dokładniej parame-
trom, które użyliśmy do kompilacji pro-
gramu:

• parametr pierwszy to nazwa pliku


kompilowanego, czyli źródło progra-
mu,
• parametr -swf HelloWorld.swf wska-
zuje, jak ma nazywać się plik wyniko-
wy kompilacji,
• Parametr -main mówi kompilatorowi,
aby program po uruchomieniu roz-
począł pracę od wywołania meto-
dy statycznej main, której prawidło-
wa definicja to public static function
main (mc:MovieClip): Void. Oznacza
to, że w tym miejscu będzie zaczy-
nał prace program wynikowy,
• parametr ostatni -header 800:600:20,
ustala rozmiar pliku .swf na 800x600
pixeli i FPS na 20.

Teraz kilka słów na temat naszego


Rysunek 1. Konfiguracja wtyczek Eclipse – FDT i ASDT programu. Wiemy już, że program roz-

PHP Solutions Nr 2/2007 www.phpsolmag.org 31


Dla zaawansowanych GUI

poczyna swoje działanie od wywoła- MovieClip-ów. MovieClip-y tworzą struk- da np. po dwie kropki i kreskę. Wszyst-
nia metody statycznej main(mc:Movie- turę drzewiastą, czyli każdy MC ma swo- kie akcje, które wywołamy na wskaza-
Clip), (parametr -main). MovieClip (MC) jego rodzica i może mieć wiele dzieci. W nym MovieClip-ie dotyczyć będą rów-
to pojedynczy obiekt widziany na sce- uproszczeniu, wygląda to więc tak, że nież elementów, które on posiada. Czyli,
nie (czyli w przeglądarce), który jest mamy np. niebieskie tło, które posiada jeśli teraz sprawimy, by jedno kółko prze-
jednocześnie pojemnikiem dla innych na sobie dwa kółka, a każde kółko posia- stało być widzialne, to elementy, które są
do niego przyczepione (dwie kropki i kre-
seczka) też przestaną być widzialne. Jak
Listing 2. Plik ASBasic.as – podstawy składni w ActionScript każde drzewo, tak i to posiada swój ko-
// do skompilowania klasy potrzebne są : rzeń, czyli MovieClip leżący najniżej.
// definicje klas z pakietu mx.data W metodzie main jako parametr mc prze-
import mx.data.*; kazywana jest referencja do _ root, czyli
//definicja klasy mx.controls.Button głównego MovieClip-a na scenie.
import mx.controls.Button;
Dostając referencje do _ root – Movie-
// definicja klasy ASBasic rozszerza def. klasy MovieClip
// ASBasic należeć bedzie do pakietu(ang.:package) : „org.me” Clipa leżącego na samym dole sceny, mo-
class org.me.ASBasic extends MovieClip { żemy osadzić na scenie dowolny obiekt i
// zmienna w AS poprzedzona musi byc słowem kluczowym "var" będzie on widzialny. W naszym przypad-
// AS pozwala na określenie typu zmiennych „:Button” ku jest to TextField, czyli pole tekstowe.
public var button:Button;
Metoda createTextField tworzy nową in-
// kwalifikatora dostępu protected w AS nie występuje
// protected var pProtected; stancję TextField, nadając jej nazwę „my-
// typowanie zmiennych nie jest konieczne Text” i ustawiając głębokość osadzenia na
public var object; poziomie 1. Głębokość osadzenia Movie-
/** Clip-a na scenie to poprostu kolejność, w
* Konstructor – nazwa methody musi być taka jak nazwa klasy
jakiej będą rysowane elementy na ekra-
*/
public function ASBasic(name:String) { nie. Jeśli więc jeden obiekt rysowany bę-
// wywołanie konstruktora klasy dziedziczonej dzie wczesniej, a drugi później, to ten dru-
super(); gi może zasłonić pierwszy. Sytuacja taka
// $this->param zamieniamy na this.param pojawia się, gdy więcej MovieClip-ów na-
this.button = new Button();
leży do jednego MovieClip-a i ważna sta-
// try, catch, finally działa identycznie jak w PHP
try { je się ich kolejność. Kolejne parametry
this.setName(name); metody createTextField to współrzędne
} x i y (100, 200) oraz wysokość i szerokość
catch (e:Error){ pola tekstowego (300,400). Nazwa jaką
this.setName("Basic example");
ustaliliśmy dla tworzonego obiektu („my-
}
finally { Text”), jest potrzebna, by w kolejnych kro-
} kach operować na jego właściwościach,
} czyli między innymi przypisać do para-
// metoda w AS tak jak w PHP poprzedzona musi być metru text wartość HelloWorld (mc.my-
// słowem kluczowym „function”
Text.text = "Hello World !";), co jest
public function add(p1:Number,p2:Number) : Number {
var sum : Number = p1 + p2; równoznaczne z wypełnieniem pola tek-
return sum; stowego tekstem HelloWorld.
}
private var name:String; Przygotowujemy
public function getName() : String {
return this.name;
narzędzia do pracy
} Oczywiste jest, że na dłuższą metę pro-
public function setName(name:String) : Void { gramowanie w notatniku staje się meczą-
if (name !== null) { ce. Nawet, jeśli używamy edytora teksto-
this.name = name; wego, który koloruje nam kod, to podpo-
}
wiadanie składni i wykrywanie błędów
else {
throw new Error("Name can not be null!"); semantycznych jest niezastąpioną po-
} mocą dla każdego, a zwłaszcza począt-
} kującego programisty. Skupimy się te-
public function addStrings(s1:String,s2:String) : String { raz na przygotowaniu środowiska pra-
// dodawanie String-ow w AS
cy tak, aby programowanie w Action-
// używamy operatora „+”
var sum:String = " " + s1 + s2; Script-cie stało się naprawdę przyjemne.
return sum; Do tego celu użyjemy IDE Eclipse (http:/
} /www.eclipse.org). Dostępne są jeszcze
} inne edytory wspomagające pracę z Ac-
tionScript-em. Wartym wspomnienia jest

32 www.phpsolmag.org PHP Solutions Nr 2/2007


Dla zaawansowanych GUI

przykład Se|Py (http://www.sephiroth.it/ na liście FDT (lub/i ASDT) i klikamy „Windows” -> „Preferences”
python/sepy.php), ale Eclipse jest na- „Finish”.
rzędziem znanym większości programi- Aby zainstalować Flashout (który po- Rysunek 1. przedstawia to, co powin-
stów PHP, stąd nasz wybór padł właśnie trzebny będzie dla tych, którzy wybrali niśmy zobaczyć. Powinniśmy usta-
na niego. Eclipse wymaga zainstalowanej ASDT), ściągamy ze strony projektu pa- wić tu ścieżkę do kompilatora MTASC
wirtualnej machiny Java. Mamy tu dowol- kiet instalacyjny. Po rozpakowaniu, prze- (parametr MTASC dla obu wtyczek),
ność w wyborze wersji Javy, ale propo- grywamy znajdujący się w środku kata- oraz ścieżkę do bibliotek Action-
nujemy zainstalować wersję 5, którą bę- log plugin do odpowiedniego (też plugin) Script-a (FDT – „Core Libraries”, ASDT
dzie w przyszłości wymagana przez roz- w folderze macierzystym Eclipse. „Core path”). Core Libraries to zbiór
szerzenie Flashout. Po ściągnięciu Ec- podstawowych dla Flash-a bibliotek,
lipse, koniecznie w wersji 3.1.x (my bę- Konfiguracja Eclipse które dostajemy wraz z MTASC w ka-
dziemy pracować na 3.1.2) przechodzi- Po zainstalowaniu, FDT (czy ASDT) wy- talogu /std.
my do instalacji rozszerzeń wspomagają- maga skonfigurowania. Z menu Eclipse Wtyczki Flashout nie trzeba konfigu-
cych pracę w języku ActionScript. Do wy- wybieramy: rować.
boru mamy:

• FDT (Development Tool for Flash –


http://fdt.powerflasher.com/) – spraw-
dza poprawności składni, podpowia-
da i automatycznie kompiluje pro-
gram. Jest w tej chwili najlepszą do-
stępną wtyczką dla Eclipsa wspoma-
gająca AS, ale niestety płatną,
• ASDT (AS Development Tool – http://
aseclipseplugin.sourceforge.net /
wordpress/) – podpowiada ale nie
wykrywa błędów składni. Jest to jesz-
cze niedopracowana wtyczka (wersja
0.0.8beta5), ale dostępna za darmo,
• FlashOut (http://www.potapenko.com/
flashout/) – umożliwia automatyczne
kompilowanie programu. Współpracu-
jąc z ASDT zapewnia funkcjonalność
FDT, posiadając dodatkowo funkcjo-
nalność pomagającą w debugowaniu
kodu.
Rysunek 2. Eclipse i FDT – nowy projekt
Ze względu na to, że rozpoczynamy do-
piero pracę z ActionScript-em, proponuje-
my rozpocząć pracę z trial-ową, trzydzie-
stodniową wersją FDT.
Aby zainstalować FDT, (lub ASDT –
dla bardziej zaawansowanych) urucha-
miamy Eclipse, a następnie z menu wy-
bieramy kolejno:

„Help”->”Software Updates”->
”Find and install...”

Następnie:

„Search for new features to install” ->


”Next”->„New Remote Site”

i odpowiednio w polach Name i URL


wpisujemy „FDT” i „http://fdt.power-
flasher.com/update” (lub „ASDT” i „http://
aseclipseplugin.sourceforge.net /
updates/„). Zaznaczamy nowy element Rysunek 3. Eclipse i FDT – konfiguracja parametrów kompilacji

34 www.phpsolmag.org PHP Solutions Nr 2/2007


GUI Dla zaawansowanych

ActionScript 2.0 (AS2) nizować kod zgodnie z zasadami OOP Niestety, możliwości, jakie daje nam AS2
– podstawy (Obiect Oriented Programming), czyli w nie są duże i polegają w głównej mie-
ActionScript 2.0 należy do rodziny ję- postaci klas zapisywanych w oddzielnych rze na wyświetlaniu komunikatów o sta-
zyków skryptowych implementujących plikach. nie wykonywania algorytmu w miejscach
standard ECMA-262. Do rodziny tej W AS2 definicja klasy i nazwa pliku, w uznanych przez nas za krytyczne dla pi-
należy między innymi JavaScript czy którym definicja jest zapisana muszą się sanej aplikacji. Czyli, nie różni się to w ni-
JScript, stąd też osoby znające JS do- pokrywać, czyli klasę ASBasic zapisujemy czym od metody stosowanej w progra-
strzegą na pewno duże podobieństwo w pliku ASBasic.as. Dodatkowo w AS2 mowaniu w PHP, prócz tego, że w AS2
AS2 do tego języka. Porównując AS2 pojawia się nowe dla programistów PHP zamiast funkcji echo() stosujemy trace()
do JS zauważyć należy jedną podsta- pojęcie tzw. pakietu (ang. Package). Pa- (print _ r() nie posiada swojego odpo-
wową różnicę, jaka występuję pomię- kage określa przestrzeń nazw, w obrę- wiednika w AS2 – ale istnieją metody,
dzy tymi językami. JS (w dużym uprosz- bie której nazwa klasy musi być unikalna. aby uzyskać podobny efekt. Stosowa-
czeniu) operuje na danych odzwiercie- Od strony systemu plików struktura pakie- nie metody trace() jest utrudnione, gdy
dlających strukturę znaczników XML- tów zapisywana jest w postaci drzewa ka- programujemy używając MTASC: jej ko-
owych opisujących wygląd strony – do- talogów. Definicja klasy org.me.ASBasic munikaty bowiem nie są wtedy widziane,
brym przykładem będzie tu znacznik zapisana jest więc w pliku ASBasic.as w wyrzuca ona bowiem tekst do wydzielo-
<DIV>. W AS2 występuje podobna struk- katalogu org/me/. Dzięki takiemu podej- nego okna dialogowego jedynie, gdy pro-
tura danych, odzwierciedla ona jednak ściu, nie musimy stosować instrukcji inc- gramujemy używając Adobe Flash IDE.
drzewo MovieClip-ów – czyli np. anima- lude(file _ path); a wystarczy nam import Okno dostępne jest tylko podczas uru-
cji. Tu i tu mamy więc warstwy, przezro- my.package.ClassName; który jednoznacz- chamiania MovieClip-a z poziomu Flash
czystości, współrzędne, ale w AS2 do- nie wskaże definicję klasy ClassName w IDE i jest niedostępne dla programistów
tyczą one innego typu obiektów. Innymi pliku o nazwie ClassName.as w katalogu używających MTASC. Dlatego, aby zo-
słowy MovieClipy to coś takiego jak war- my/package/. baczyć prosty wynik działania meto-
stwy <div> w JS. Dla tych, którzy znają podstawy pro- dy trace() trzeba trochę gimnastyki, co
Dla programistów PHP naukę Action- gramowania obiektowego, definicja kla- zniechęca wielu początkujących. Same-
Script najlepiej rozpocząć od przedstawie- sy ASBasic przedstawiona na Listingu 2. mu należy bowiem zadbać o to, gdzie i w
nia przykładowego kodu. Listing 2 przed- powinna być zrozumiała. Dodatkowe ko- jaki sposób wyświetlane będą przez nią
stawia definicję klasy ASBasic. AS2 jest mentarze powinny wyjaśnić pozostałe komunikaty. Przedstawimy teraz scena-
językiem obiektowym. Istnieje możliwość niejasności. riusz, jak szybko zobaczyć wynik dzia-
programowania w AS2 metodą procedu- łania metody trace(). Jeśli pracujemy z
ralną – program zapisany jest w postaci Debugowanie MTASC, służy do tego następujący para-
luźno rozsianych funkcji czyli procedury, Gdy chcemy nauczyć się jeździć na nar- metr kompilacji:
ale metoda ta wykorzystywana jest głów- tach, czeka nas lekcja wstawania i upa-
nie w pracy z Flash IDE, gdzie graficz- dania. Tak też jest i w programowaniu. - trace nazwa_metody_statycznej
ny interfejs pozwala na zarządzanie po- Zanim więc zaczniemy tworzyć większe
szczególnymi grupami procedur. Przy du- programy, przyjrzymy się możliwościom Sprawia on, że każde wywołanie me-
żych projektach wskazane jest, aby orga- debugowania kodu napisanego w AS2. tody trace() napotkane przez kompila-
tor zostanie zamienione na wywołanie
wskazanej przez nas metody. Zaletą te-
go rozwiązania jest nie tylko to, że z po-
ziomu samego kompilatora możemy ste-
rować, czy i gdzie powinny pojawić sie
generowane komunikaty, ale także to,
że MTASC wzbogaca wywołanie funkcji
zastępującej trace() dodatkowymi trze-
ma parametrami, które określają dokład-
nie miejsce wywołania metody trace():

• pełna nazwa klasy i metody,


• nazwa pliku,
• numer lini.

Dzięki temu, automatycznie nasz log


wzbogacony jest o bardzo ważne in-
formacje, pozwalające na zidentyfiko-
wanie miejsca wystąpienia błędu. Aby
wykorzystać te parametry definicja
metody zastępującej trace() powinna
Rysunek 4. Eclipse i FDT – konfiguracja dodatkowych parametrów kompilacji wyglądać tak:

PHP Solutions Nr 2/2007 www.phpsolmag.org 35


Dla zaawansowanych GUI

class Tracer() { kie komunikaty dostępne w interne- Eclipse i FDT


public static function cie to: – tworzymy projekt
log(msg:String,clazz:String,file: Nowy projekt stworzymy używając per-
String,line:Number); • http://osflash.org/xray – polecamy dla spektywy Flash, która dodana została do
} bardziej zaawansowanych, Eclipse po zainstalowaniu FDT. Aby użyć
• http://sos.powerflasher.de/english/ perspektywy Flash w Eclipse z menu, wy-
Dla tak przygotowanej metody obsługu- english.html – bardzo prosty, wyma- bieramy: Windows -> Open Perspective
jącej logi parametr -trace powinien wy- ga Windows, -> Flash.
glądać tak: • http:/ /sock4log.sourceforge.net / Teraz w oknie Flash Explorer klika-
– bardzo prosty, wymaga Java 5 my prawym przyciskiem myszki i z otwo-
-trace Tracer.log – niezależny od OS. rzonego menu wybieramy: New -> New
project.
Co do samego miejsca, gdzie komuni- Najszybciej i prościej będzie nam W otwartym oknie New project ko-
katy powinny być prezentowane, moż- rozpocząć pracę używając Sock4Log, lejno wykonujemy: Flash -> „New Flash
liwości jest dużo i zależą one tylko od który jest małym serwerem nasłuchu- Project, Project name -> wpisujemy na-
tego, co wstawimy w ciało naszej me- jącym na wskazanym porcie komunika- zwę, np.: HelloWorld.
tody Trace.log(). Wszystko jednak tów wysyłanych ze specjalnie napisa- W oknie konfiguracji źródeł folde-
sprowadza się do wysyłania komuni- nej dla niego metody trace(). Program ru powinniśmy mieć zaznaczone źródło
katów do zewnętrznego programu lub jest niezależny od systemu operacyj- „MtascSTD”, które dodaliśmy wcześniej.
innego MovieClip-a, który to dopiero nego, dlatego też następne przykłady Teraz Finish i w oknie Flash Explorer po-
zajmuje się wypisaniem ich na ekran. opierać się będą właśnie o współpra- winna pokazać się nowa pozycja Hello-
Ciekawsze narzędzia odbierające ta- ce z nim. World.
Teraz dodamy katalog, w którym
przechowywać będziemy źródła nasze-
go programu.
Klikamy prawym przyciskiem myszki
na pozycje HelloWorld, następnie: New ->
Source Folder. Nowy folder proponuję
nazwać src.

Dodajemy pierwszą klasę


Klikamy prawym przyciskiem myszki na
pozycję src, następnie:
New -> Class, Package -> nazwij-
my np.: org.me, Class Name -> nazwijmy
np.: HelloWorld i klikamy „Finish”.
Jeśli w nowym pliku wpiszemy to, co
zostało już pokazane na Listingu 1, to
na ekranie powinniśmy zobaczyć to, co
Rysunek 5. Sock4log – test funkcji trace() przedstawia Rysunek 2.
Teraz pozostaje nam tylko skompilo-
wać i uruchomić program.
Listing 3. Program demonstrujący działania Sock4Log
Z menu wybieramy: Run” -> Run...
import org.webservicesware.sock4log.Tracer; W lewej części okna klikamy prawym
class org.me.HelloWorld { przyciskiem myszy na FDT-MTASC Sup-
public static function main (mc:MovieClip) : Void
port -> New
{
// Inicjacja połączenia socketowego z Sock4Log Następnie w prawej części okna wy-
Tracer.init(); pełniamy w zakładce „Main” kolejno:
trace("Start");
mc.createTextField("myText",1,100,200,100,100); • Name -> helloword – to nazwa, jaka
mc.myText.text = "Hello World !";
będzie wyświetlać się w menu run,
mc.myText.border = true;
mc.myText.type = "input"; • Project -> HelloWord – wybieramy,
// implementujemy metodę wywoływana w reakcji na klikając na przycisk Browse... i wska-
// zdarzenie onChanged – czyli na zmianę treści zując nasz projekt,
mc.myText.onChanged = function () { • Main Class -> org.me.HelloWord – to
trace("onChanged Event : " + this.text);
tzw. entry point aplikacji – czyli klasa,
};
} w której zdefiniowana jest publiczna
} metoda statyczna main() , od której
wywołania rozpoczynać będzie pracę

36 www.phpsolmag.org PHP Solutions Nr 2/2007


GUI Dla zaawansowanych

program. Finalnie, powinniśmy zoba-


czyć to, co na Rysunku 3, a po przej- Listing 4. Plik HelloWorldASwing.as – wprowadzenie do ASwing
ściu do zakładki „MTASC Arguments”
import org.aswing.JFrame;
– to, co na Rysunku 4. import org.aswing.JLabel;
class org.aswing.me.HelloWorldASwing {
Uruchomienie kompilacji rozpoczyna /**
kliknięcie na przycisk Run. Po wyko- * Create the GUI and show it.
*/
naniu tej akcji, w naszym oknie Flash
Explorer pojawić powinien się nowy private static function createAndShowGUI() : Void {
plik default_mtasc.swf. //Tworzymy okno zatutułowane HelloWordlAswing
Zanim przejdziemy do dalszej części var frame:JFrame = new Jframe("HelloWorldASwing");
artykułu, należałoby przetestować jeszcze // ustawiamy jak okno ma zareagować gdy chcemy je zamknąć
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
możliwość debugowania naszego progra-
//dodajemy "Hello World" label.
mu. My do tego celu wybraliśmy program var label:JLabel = new JLabel("Hello World");
Sock4Log, jako najprostszy i niezależny // dodajemy label do okna
od systemu operacyjnego. Zachęcamy frame.getContentPane().append(label);
jednak do zapoznania się w miarę możli- // ustawiamy rozmiar okna
frame.setSize(200,100);
wości z pozostałymi dwoma programami,
//Display the window.
jako ciekawymi alternatywami. frame.setVisible(true);
Po ściągnięciu Sock4Log ze strony }
projektu (http://sock4log.sourceforge.net/),
należy przegrać plik org/webservicesware/ /**
* Entry point for aplication
sock4log/Tracer.as do odpowiedniego
*/
katalogu naszego projektu (src/org/web- public static function main(mc:MovieClip):Void {
servicesware/sock4log/Tracer.as). Te- createAndShowGUI();
raz dodajemy dodatkowy parametr kon- }
figurujący proces kompilacji w zakładce }

z Rysunku 4.

������������� ���������������
����������������

������

������� ��������� �����������

�������������
������

�������������
���� �������������� �������� ��������� �������������� ������

�������������
������
�������������
������������� �������

���������� ���������

������������ ���������

������ ������� ������� ���������� �����������

������� ����������� ������������


������

Rysunek 6. ASwing class diagram – poglądowa struktura komponentów

PHP Solutions Nr 2/2007 www.phpsolmag.org 37


Dla zaawansowanych GUI

-trace org.webservicesware.sock4log. Przed uruchomieniem MovieClipa na- Wynik działania kodu widoczny jest na
Tracer.log leży jeszcze uruchomić program na- Rysunku 5. Każda zmiana pola teksto-
słuchujący komunikaty wysyłane przez wego wywołuje akcję onChange() i w
Zmieniamy odpowiednio kod naszego naszą aplikację. Robimy to komendą: efekcie wysyła komunikat do programu
programu tak, by inicjował nowy me- Sock4Log, który prezentuje go nam na
chanizm logowania i wywoływał po- java -jar „Sock4Log.jar” ekranie.
jedynczą metodę trace(); (Listing 3).

Listing 5. Plik CelsiusConverter.as – programowanie zdarzeń ASwing – wprowadzenie


ASwing to prawie wierna kopia bibliote-
import org.aswing.*;
ki Swing napisanej w Java, dlatego też w
class org.aswing.me.CelsiusConverter {
var converterFrame : Jframe;
dużej ilości miejsc dokumentacja ASwing
var converterPanel : Jpanel; sprowadza się do odesłania czytelnika
var tempCelsius : JtextField; na strony bardzo dobrze udokumentowa-
var celsiusLabel, fahrenheitLabel : Jlabel; nej biblioteki Swing. My też radzimy, aby
var convertTemp : Jbutton;
w razie problemów szukać tam pomocy :
public function CelsiusConverter() {
(http://java.sun.com/docs/books/tutorial/
var frame:JFrame = new JFrame("Convert Celsius to Fahrenheit"); uiswing/index.html http://java.sun.com/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); j2se/1.5.0/docs/api/javax/swing/package-
frame.setSize(250,90); summary.html)
converterPanel = new JPanel(new GridLayout(2, 2));
Ponieważ kopiowanie dokumentacji
addWidgets();
//Add the panel to the window.
powszechnie dostępnej w internecie nie
frame.getContentPane().append(converterPanel, BorderLayout.CENTER); jest celem tego artykułu, postaramy się
//frame.pack(); tylko wprowadzić do filozofii tworzenia
//Display the window. okienek w ASwing, opisując podstawowe
frame.setVisible(true);
jego elementy. Rysunek 6. przedstawia
}
poglądową strukturę komponentów do-
/** stępnych w ASwing. Jak widać, wszystkie
* Create and add the widgets. one dziedziczą po klasie Component, która
*/ implementuje takie podstawowe mecha-
private function addWidgets() : Void {
nizmy, jak pokazywanie i ukrywanie kom-
//Create widgets.
tempCelsius = new JtextField("2");
ponentu, ustalanie rozmiarów, położe-
celsiusLabel = new Jlabel("Celsius",null,JLabel.LEFT); nia itd. Drugim podstawowym elementem
convertTemp = new Jbutton("Convert"); ASwing-a jest klasa Container, która jest
fahrenheitLabel = new Jlabel("Fahrenheit",null,JLabel.LEFT); pojemnikiem dla komponentów. Contain-
//Listen to events from the Convert button.
er implementuje mechanizmy, jakie po-
convertTemp.addEventListener(Component.ON_RELEASE,
actionPerformed, this);
trzebne są do tego, by mógł on opisać re-
//Add the widgets to the container. lacje, jakie panują między poszczególny-
converterPanel.append(tempCelsius); mi komponentami, a w szczególności ich
converterPanel.append(celsiusLabel); ułożenie względem siebie (tzw. Layout).
converterPanel.append(convertTemp);
Jak widać na diagramie Container dzie-
converterPanel.append(fahrenheitLabel);
}
dziczy po klasie Component, czyli mo-
public function actionPerformed():Void { że przechowywać sam siebie. Wszyst-
//Parse degrees Celsius as a double and convert to Fahrenheit. kie komponenty, które pozwalają na in-
var tempFahr:Number = (Number(tempCelsius.getText()) * 1.8 + 32); terakcję z otoczeniem dziedziczą po kla-
fahrenheitLabel.setText(tempFahr + " Fahrenheit");
sie EventDispatcher. Każdy komponent
}
ma swój zbiór zdarzań (ang. Events), któ-
/** re może wywoływać, dla przykładu JBut-
* Create the GUI and show it. ton wywołuje zdarzenie ON_PRESS – w
*/ chwili, gdy zostanie naciśnięty, a JWin-
private static function createAndShowGUI() : Void {
dow ON_WINDOW_CLOSING – gdy zo-
var converter:CelsiusConverter = new CelsiusConverter();
}
staje zamykane. Zdarzenia te zostają wy-
/** słane do wszystkich obiektów, które zgło-
* Entry point for aplication siły się, jako nasłuchujące.
*/ Jak widać, zasady działania ASwing
public static function main(mc:MovieClip):Void {
są bardzo logiczne: mamy elementy, któ-
createAndShowGUI();
}
re możemy układać na scenie i które się
} ze sobą komunikują. To, co pozostaje
nam do zrobienia, to oprogramować re-

38 www.phpsolmag.org PHP Solutions Nr 2/2007


Dla zaawansowanych GUI

śnie takim komponentem. Używamy me- wchodzące w jej skład komponenty. War-
tody append, aby dodać Component do to przejrzeć, jakie jeszcze możliwości da-
naszego okna. je nam ASwing.
Na Listingu 5 przedstawiamy już nieco
bardziej skomplikowany przykład. Na po- Komunikacja Flash
czątku tworzymy kolejno dwa pola JLabel, z otoczeniem
jeden JButton i jedno pole typu Jtext- Twórcy technologii Flash położyli bardzo
Field, w którym można będzie wpisywać duży nacisk na to, by ich produkt był w
tekst z klawiatury. Po dodaniu wszystkich stanie komunikować się ze światem ze-
elementów do tworzonego okna, należy wnętrznym w sposób prosty i ustanda-
ustalić, jak ma reagować nasz program na ryzowany. Firma Macromedia (a teraz
zdarzenie naciśnięcia przycisku: służy do Adobe – będziemy używać obu nazw
Rysunek 7. ASwing – okna programów tego metoda, jaką posiada klasa JButton : firm, ponieważ w Internecie wciąż wię-
akcje na te wysyłane przez otoczenie ko- addEventListener(); cej informacji na temat Flash-a znajdzie-
munikaty. Metoda ta dodaje słuchacza (ang. my wyszukując po nazwie Macromedia
Aby rozpocząć pracę z ASwing, na- Listener), czyli referencję do obiektu, Flash) wyposażyła ActionScript w sze-
leży ściągnąć ostatnie wydanie biblio- który będzie powiadamiany o zdarze- reg bibliotek, pozwalających na komuni-
tek ASwing ze strony www.aswing.org (w niach, jakie wywołuje nasz JButton. W kację z otoczeniem w ustandaryzowany
czasie pisania artykułu była to wersja ba- naszym przypadku, interesuje nas zda- sposób. I tak, do komunikacji ze świa-
ta 1). Następnie musimy dodać biblioteki rzenie kliknięcia, czyli Component.ON _ tem zewnętrznym do wyboru mamy:
do naszego projektu. W tym celu klikamy RELEASE . Dodatkowo, ustawiamy jesz-
prawym przyciskiem myszki na nazwę cze, jaką metodę chcemy, by urucho- • FlashRemoting – pozwala na komu-
projektu w oknie Flash Explorer i wybie- mił JButton na naszym obiekcie, gdy zo- nikację Flash-a z serwerem aplikacji
ramy z listy Properties. Następnie w uka- stanie wywołane zdarzenie, ustawiamy używając do tego standardu Action
zującym się oknie wybieramy: Flash więc actionPerformed. Całość ostatecz- Message Format (AMF), który po-
Properties -> Add Linked Libraries... -> nie ma postać: zwala na serializację i deserializację
Add... i, jeśli wykonujemy tę operację po obiektów przesyłanych między ma-
raz pierwszy, klikamy na New.... Wypeł- convertTemp.addEventListener szynami,
niamy parametry wymagane do stworze- (Component.ON_RELEASE, • XMLSocket – pozwala na komunika-
nia nowej pozycji na liście bibliotek: Na- actionPerformed, this); cję z serwerem używając do tego po-
me -> ASwing – beta1, Location -> ścież- łączenia socketowego,
ka do katalogu ze źródłami ASwing. Teraz wystarczy wykonać operację na • LoadVars – odpowiednik AJAX-owe-
Klikamy na przycisk OK i nowa biblio- własnościach text obiektów JTextField i go XMLHttpRequest. Pozwala na po-
teka powinna pojawić się na naszej liście. udało się nam stworzyć program konwer- bieranie z serwera danych używając
Wybieramy ją, klikamy przycisk OK i mo- tujący temperaturę w stopniach Celsjusza do tego protokołu HTTP. Ten typ ko-
żemy zacząć kodować. na Fahrenheita. munikacji wykorzystywany jest, gdy
Przykłady, które wybraliśmy do za- Wraz z biblioteką ASwing dostajemy chcemy porozumieć się z serwerem
prezentowana działania podstaw ASwing szereg przykładów tego jak wykorzystać przy pomocy standardu XML-RPC,
zostały oparte o tutorial Swing na stronie
http://java.sun.com/docs/books/tutorial/
Listing 6. HelloWorld AmfPHP – przykładowy serwis
uiswing/, tak, aby przedstawić wspólne
części obu bibliotek i jeszcze raz zapro- <?php
ponować naukę ASwing w oparciu o do- class HelloWorldService
kumentację Swing-a. {
function __construct()
Najlepiej będzie rozpocząć naukę od
{
kompilacji i uruchomienia programów (Li- $this->methodTable = array
sting 4 i 5, Rysunek 7). Są one bardzo (
proste i właściwie wystarczy spojrzeć na "say" => array
kod, by wiedzieć, co się w nich dzieje. (
"access" => "remote",
W pierwszym przykładzie (Listing nr 4),
"description" => "Pings back a message"
tworzymy pojedyncze okno z tekstem )
„Hello World”. To, co w tym przykładzie );
jest istotne to fakt, że nie wystarczy stwo- }
rzyć instancji klasy JFrame – odpowiedni- function say($sMessage)
{
ka okna – ale trzeba jeszcze ustawić jego
return 'You said: ' . $sMessage;
visiblity na true. (frame.setVisible(true);). }
Jframe jest klasą dziedziczącą klasę }
Container, oznacza to, że można do niej ?>
dodawać Componenty. Jlabel jest wła-

40 www.phpsolmag.org PHP Solutions Nr 2/2007


GUI Dla zaawansowanych

„amfphp and this gateway are installed


correctly ”. To wystarczy, by rozpocząć
pracę z AMFPHP. Warto jeszcze zazna-
jomić się z treścią plików:

• gateway.php – który będzie wywoły-


wany przez Flash-a. Przez niego bę-
dą szły wszystkie zapytania do na-
szego serwera aplikacji. Tu możemy
dokonać pewnych zmian w konfigura-
cji np. ustawić zmienną środowiskową
PRODUCTION _ SERVER na true, co spra-
wi, że zmniejszy się poziom logowa-
nia błędów i informowania o nich.
Warto zapoznać się z treścią komen-
tarzy występujących w tym pliku,
• debuggateway.php – to plik, któ-
ry przydaje się, gdy powstają pro-
blemy we współpracy Flash-a z ser-
werem aplikacji. Korzysta on z gate-
way.php, obudowując go i dodając
Rysunek 8. Serwis eksplorer dla AMFPHP większą ilość sprawdzeń dla komu-
nikatów przychodzących i wychodzą-
• FSCommand – umożliwia komu- Flash Remoting cych (głównie skupia się na popraw-
nikowanie się z odtwarzaczem Flash Remoting to określenie używa- ności formatowania zapytań).
Flash-a, lub programem, w którym ne przezMacromedia (a teraz Adobe) do
FlashPlayer jest osadzony. Połą- zdefiniowania technologii, która używa- My będziemy korzystać ze standardo-
czenie takie wykorzystać można na jest do komunikacji serwera aplikacji z wych ustawień AMFPHP, dlatego naszą
do komunikacji np. z przeglądarką Flash-em w oparciu o protokół AMF. Mó- prace rozpoczniemy w katalogu amfphp/
lub w szczególności z JavaScript- wiąc o Flash Remoting, mamy na myśli services/, gdzie umieścimy pierwszy Hello-
em osadzonym na stronie, dwie strony komunikacji : WorldService (Listing 6) w pliku helloworld-
• LocalConnection – umożliwia ko- service.php.
munikowanie się z innymi uru- • serwer – tą część implementują me- Na początek prześledzimy proces
chomionymi w środowisku klien- chanizmy potrzebne dla korzystania przetwarzania zapytania serwera apli-
ta MovieClip-ami. Komunikacja ta- z AMF przez serwery aplikacji. Adobe kacji.
ka pozwala na porozumiewanie się wspiera tu jedynie dwie technologie:
między odgrywanymi przez Flash- Java iMicrosoft .Net. My będziemy • Krok 1. AmfPhp (gateway.php) odbiera
Player, różnymi MovieClip-ami, ale korzystać z trzeciej, darmowej imple- zapytanie w formacie AMF z Flash-a,
tylko w obrębie jednej aplikacji, tj. mentacji AMF dla PHP – AMFPHP, • Krok 2. Dane komunikatu zostają de-
np. uruchomionych w jednej prze- • klient – część implementująca AMF w serializowane i zamienione na obiekty/
glądarce, języku ActionScript od strony klienta, typy PHP-owe. AMFPHP uzyskuje
• WebService – pozwala na używanie czyli Flash-a – tzw. Flash Remoting w tym miejscu informacje o tym, jaka
WebService-ów (protokoły SOAP Component. Jest to darmowy kompo- metoda jakiego serwisu ma być wyko-
i WSDL) przez Flash, jest to w tej nent, który musimy pobrać ze strony nana i z jakimi parametrami,
chwili jeden z najczęściej używa- Adobe. • Krok 3. Jeśli nie zostało ustawione in-
nych standardów komunikacji mię- aczej, AMFPHP przeszukuje katalog
dzy maszynami. AMFPHP – wprowadzenie services/ w poszukiwaniu pliku, któ-
AMFPHP (http://www.amfphp.org) – to rego nazwa pokrywa się z nazwą wy-
Ponieważ ramy tego artykułu nie po- projekt, który wychodzi na przeciw ocze- woływanego serwisu,
zwalają na opisanie wszystkich metod kiwaniom środowiska opensource co do • Krok 4. AMFPHP powołuje do życia
komunikacji, co byłoby niewątpliwie darmowego wykorzystania technologii instancję obiektu klasy, która została
bardzo ciekawe, skupimy się na roz- Flash w architekturze klient-serwer. In- znaleziona w szukanym pliku i urucho-
wiązaniu, jakie daje Flash Remoting. stalacja i konfiguracja sprowadza się tu miony zostaje jej konstruktor. W kon-
Jest to bowiem rozwiązanie, które za- do ściągnięcia źródeł programu i umiesz- struktorze następuje zainicjowanie ta-
pewnia najwyższą wydajność, z racji czenia ich na serwerze np. w katalogu blicy methodTable, w której to zosta-
tego, że serializuje i deserializuje dane amfphp/. Aby sprawdzić, czy wszystko ją zapisane informacje, o możliwych
do plików binarnych, czyli maksymal- działa poprawnie, należy otworzyć stro- do wywołania metodach, jakie wystę-
nie zmniejsza wielkość przesyłanych nę: http://localhost/amfphp/gateway.php, pują w danej klasie oraz informacje o
danych między klientem a serwerem. na której powinien pojawić się komunikat tym, jakie są ewentualne wymagania/

PHP Solutions Nr 2/2007 www.phpsolmag.org 41


Dla zaawansowanych GUI

dodatkowe parametry wywołania me-


Listing 7. Prosty przykład wykorzystujący HelloWorldService tody,
• Krok 5. Jeśli wszystko się zgadza, na-
import mx.remoting.*;
import mx.rpc.*; stępuje wywołanie wskazanej przez
import mx.remoting.debug.NetDebug; klienta metody i serializacja tego, co
import mx.services.Log; zostało zwrócone,
import org.webservicesware.sock4log.Tracer;
• Krok 6. AmfPHP wysyła odpowiedź
class org.me.test.AmfPhpClient {
do Flash-a w formacie zgodnym z
private var tfReq:TextField;
private var tfResp:TextField; AMF.
var myLogger:Log;
// Tu rozpoczyna prace program Listing 6. przedstawia prosty serwis,
public static function main(mc:MovieClip) {
który posiada tylko jedną metodę
Tracer.init();
say($sMessage), która do przekazywa-
var amf:AmfPhpClient = new AmfPhpClient(mc);
} nej w parametrze wiadomości docze-
public function AmfPhpClient(mc:MovieClip) { pia ciąg znaków i zwraca go w postacji
// Tworzymy nowe pole tekstowe – tekst wysylany 'You said : ' .$sMessage;
mc.createTextField("tfReq", 0, 10, 10, 200, 50);
W konstruktorze mamy inicjację ta-
this.tfReq = mc.tfReq;
blicy asocjacyjnej $this->methodTable,
// niech obramowanie pola będzie widoczne
this.tfReq.border = true; w której kluczem jest nazwa metody, a
this.tfReq.text = "Hello AmfPHP"; ciałem – opis jej parametrów wywołania:
// niech pole będzie edytowalne
this.tfReq.type = "input";
• access – ustawiamy na remote jeśli,
// Tworzymy nowe pole tekstowe – tekst odbierany
chcemy, by metoda była dostępna dla
mc.createTextField("tfResp", 1, 10, 60, 400, 100);
this.tfResp = mc.tfResp; Flash-a,
this.tfResp.text = "Waiting for response"; • description – opis metody widoczny
// inicjujemy NetConnection Debugger podczas przeglądania metod serwe-
mx.remoting.debug.NetDebug.initialize();
ra aplikacji.
this.myLogger = new Log( Log.DEBUG, "AmfPhp" );
// piszemy wlasna funkcje obsługi zdarzenia onLog
this.myLogger.onLog = function( message:String ):Void { Gdy już mamy stworzony serwer, może-
trace( "AmfPhpClient-Logger => "+message ); my przejść do jego przetestowania. Naj-
}; prościej będzie uruchomić przeglądarkę
var thiz:AmfPhp = this;
serwera aplikacji: http://localhost/amfphp/
// piszemy wlasna funkcje obsługi zdarzenia onChange
browser/index.html. Powinniśmy móc zo-
this.tfReq.onChanged = function() {
thiz.say(this.text); baczyć w niej, po lewej stronie, listę do-
}; stępnych serwisów, jakie udostępniamy
} i po wybraniu jednego z nich – po prawej
var gatewayUrl:String = "http://localhost/amfphp/gateway.php";
stronie listę metod, które możemy w ramach
public function say(s:String):Void{
serwisu wywołać. Jeśli klikniemy na jedną z
// inicjacja nowego servisu (url,logHandler,nazwa serisu)
var _service:Service = new Service(this.gatewayUrl, metod, będziemy mogli przetestować wysła-
this.myLogger, 'HelloWorldService', null , null); nie zapytania i odebranie odpowiedzi, co zo-
// wywołujemy zdalnie metodę say() stało przedstawione na Rysunku 8.
var pc:PendingCall = _service.say(s);
Mamy działający serwis, możemy te-
// ustawiamy reakcję na odpowiedź – referencje do funkcji
raz przejść do programowania Flash-
pc.responder = new RelayResponder(this, "say_result", "say_error");
} owego klienta.
// funkcja obsługująca odpowiedz metody say
function say_result(re:ResultEvent) Flash Remoting
{
var resp:String = 'The result is: ' + re.result;
Component
Jeszcze do niedawna Flash był techno-
trace(resp);
this.tfResp.text =resp; logią, z którą pracować można było tyl-
} ko przy pomocy Flash IDE. Jest to narzę-
// funkcja obsługująca błąd w wywołaniu metody say dzie dostępne dla rodziny Windowsi Mac
function say_error(fe:FaultEvent) {
OS. Dla posiadaczy Flash IDE, przygoto-
var resp:String = 'There has been an error.'+
wanie Flash-a do pracy z AMFPHP spro-
'\n Fault code : ' + fe.fault.faultcode +
'\n Fault message : '+fe.fault.faultstring; wadza się do zainstalowania darmowego
trace(resp); komponentu Flash Remoting Component,
this.tfResp.text =resp; który jest do ściągnięcia ze strony http://
}
www.adobe.com/products/flashremoting/
}
downloads/components/, a następnie
przekopiowania plików *.as z katalogu mx,

42 www.phpsolmag.org PHP Solutions Nr 2/2007


GUI Dla zaawansowanych

który powinien znaleźć się gdzieś w oko- Ściągamy plik Gdispatcher.as z http:// • Krok 3: Wywołujemy metodę say()
licach: \Documents and Settings\user_ www.gskinner.com/blog/archives/2003/ serwera aplikacji. Ponieważ wywo-
name\Ustawienia lokalne\Dane aplikacji\ 09/code_gdispatche.html i przegrywamy łanie jest asynchroniczne, czyli nie
Macromedia\Flash 8\en\Configuration\ go do katalogu std/ w macierzystym fol- wiemy, kiedy przyjdzie i czy w ogó-
Classes\ do katalogu MTASC_ROOT/ derze MTASC. le przyjdzie odpowiedź serwera,
std/mx/, gdzie MTASC_ROOT to katalog wywołanie zdalnej metody zwraca je-
domowy naszego kompilatora MTASC. • Krok 3. Przegrać katalog mx/, w którym dynie tzw. PendingCall – obiekt, któ-
Unix-owych użytkowników (lub tych, któ- poprawialiśmy pliki, do katalogu std/ . ry przechowuje informację o toczącej
rzy nie posiadają Flash IDE) czeka trochę się, wywołanej akcji,
dłuższa droga. Należy bowiem: Dopiero teraz możemy przejść do próby • Krok 4: Ustalamy, jaka ma być reakcja
połączenia z serwerem aplikacji. na odpowiedź serwera aplikacji. Two-
• Krok 1. Ściągnąć plik flashremoting _ rząc nowy obiekt RelayResponder
comp_sourcecode.zip – który zawie- Amf-AS – wprowadzenie ustalamy, że przy zakończeniu po-
ra kod źródłowy (dostępny w tym sa- Tworzymy nowy projekt i nową klasę, naz- myślnym akcji należy wywołać meto-
mym miejscu, co Flash Remoting – wijmy ją AmfPhpClient, w pliku AmfPhp- dę say_result na obiekcie this, a przy
patrz wyżej), Client.as. Listing 7. przedstawia przykład zakończeniu błędnym – metodę say _
• Krok 2. Dokonać poprawek w kodzie klasy komunikującej się z naszym serwisem. result, również na obiekcie this,
tak, by można było go kompilować W konstruktorze klasy tworzymy dwa po- • Krok 5: W chwili, gdy serwer aplikacji
przy pomocy MTASC: la tekstowe tfReq i tfResp, które odpowied- przekaże odpowiedź wywołanej przez
nio przechowują tekst do wysłania i pokazu- nas metody, Service przekazuje infor-
plik: mx.remoting.debug.GlobalLocalCon- ją tekst odebrany z serwera. Typ pierwsze- macje o zakończeniu oczekiwania na
nection go pola ustawiamy na „input” tak, by mogło odpowiedź do ustawionego przez nas
linia 93 – zmieniamy z : var suc:Boolean być edytowane. Inicjujemy też obiekt klasy PendingCall, który to, w zależności od
= true; na : var suc = true; Log, który będzie informował nas o szcze- tego, jaki był wynik operacji, przekaże
plik: mx.remoting.NetServiceProxy.as gółach operacji na poziomie Log.DEBUG – odpowiedź do odpowiednio wcześniej
linia 60 – zmieniamy z : client czyli najniższym. Metoda onChange(), którą ustawionych metod naszej klasy.
na : this.client nadpisujemy w obiekcie tfReq, będzie roz-
linia 72 – zmieniamy z : serviceName poczynała proces komunikacji z serwerem W ten sposób możemy przejąć odpo-
na : this.servicename aplikacji po każdej zmianie treści pola tek- wiedź z serwera i wyświetlić ją na ekra-
linia 73 – zmieniamy z : nc stowego, wysyłając do serwera aktualną je- nie. Listing 8. przedstawia wykaz komu-
na : this.nc (w obu miejsach) go wartość. Sam proces komunikacji z ser- nikatów, jakie dostaliśmy podczas wyko-
linia 74 – dodaj średnik : ; za klamrą za- werem aplikacji wygląda tak: nywania tej operacji: komunikaty rozpo-
mykającą funkcję var f=function... czynające się od AmfPhpClient-Logger->>
plik: mx.remoting.debug.commands. • Krok 1: Metoda OnChange rozpoczyna zostały wygenerowane przez instancję
GetConfig działanie w momencie zmiany treści klasy Log.
dodaj konstruktor: public function pola i wywołuje metodę naszej kla-
GetConfig() {super();} sy say(s:String), gdzie s = wartość Podsumowanie
usuń wywołanie : super(); z metody tekstu pola, Doprowadziliśmy do powstania serwera
GetConfigCommand() • Krok 2: Inicjowana jest instancja kla- aplikacji, zdolnego do komunikacji z Flash-
plik: mx.remoting.RecordSet.as sy Serwice, która będzie obsługiwać em oraz tzw. grubego klienta (ang. fat
wszystkie wywołania konkretnego ser- client), czyli aplikacji Flash-owej, w której
linia 51 – zmieniamy z : „ mx.events.Event- wisu serwera aplikacji. Kolejne para- ASwing jest w stanie przedstawić w dowol-
Dispatcher.initialize( this );” na : metry konstruktora określają adres ser- ny sposób dane odebrane z serwera. Przy
„GDispatcher.initialize( this );” wera, ewentualny loger, nazwę serwi- odrobinie chęci, przedstawiony szkielet
linia 404 – zmieniamy z : return na : re- su. O pozostałych dwóch parametrach można rozbudować i stworzyć okienkową
turn null na razie nie będziemy nic pisać, aplikację prezentowaną po stronie klienta
w dowolnej przeglądarce internetowej. n
Listing 8. Odpowiedź z serwera aplikacji

AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:


Creating Service for HelloWorldService O autorze
AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:
Creating gateway connection for http://localhost/amfphp/gateway.php
Rafał Malinowski jest programistą Ac-
tionScript, Java i PHP. W wolnych chwi-
AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:
lach tworzy framework dla Flash-a/Flex-
Successfully created Service
a i udziela się w kilku projektach Open
AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:
Source. Obecnie pracuje w Superme-
Invoking say on HelloWorldService
dia Interactive jeko projektant / programi-
The result is: You said: Hello AmfPHP!
sta Java.
AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:
HelloWorldService.say() returned "You said: Hello AmfPHP!" Kontakt: malinr@wp.pl

PHP Solutions Nr 2/2007 www.phpsolmag.org 43


Dla zaawansowanych

Przeglądarka bazy danych


przy użyciu PHP-Gtk2
Stopień trudności: lll
Christian Weiske

Bardzo mocną stroną PHP są wbudowane funk-


cje obsługi baz danych. Z kolei aplikacje okien-
kowe wiodą prym dzięki intuicyjnym interfej-
som, doskonale reagującym na działania użyt-
kownika. W tym artykule opiszemy, jak połączyć
zalety tych dwóch aspektów programistycznych,
budując przeglądarkę bazy danych, którą łatwo
będzie można udoskonalać oraz dostosowywać
do różnych systemów bazodanowych.

S
łysząc kombinację słów „ba- wraz z ich reprezentacją koloru w wido-
za danych” oraz “przeglądarka”, ku strukturalnym (patrz Rysunek 1):
na myśl przychodzi nam zazwy-
czaj phpMyAdmin lub podobne jemu na- • możliwość wyboru bazy danych z me-
W SIECI rzędzie. Wygląd (ang. layout) tych apli- nu rozwijanego (pomarańczowy),
kacji jest w większości przypadków bar- • wyświetlanie nazw i ilości wierszy
dzo do siebie zbliżony: w górnym lewym tabel w zaznaczonej bazie danych
• http://www.gnope.org
– pakiet PHP5 + Gtk2 dla
rogu mamy menu rozwijane z możliwo- (zielony),
Windows, ścią wyboru bazy danych, na której bę- • wyświetlanie zawartości (wierszy) za-
• http://gtk.php.net dziemy pracować, zaś poniżej wyświetla- znaczonej tabeli (fioletowy),
– strona główna projektu
PHP-Gtk2 wraz ne są jej tabele. • numeracja i sortowanie, nawigacja
z repozytorium, Cała zawartość prawej części apli- wierszy za pomocą przycisków w to-
• http://cweiske.de/files/
download/phpgtk2/ kacji jest przeznaczona na wyświetla- olbarze (niebieski).
DatabaseBrowser.tar.bz2 nie zawartości i struktury aktualnie za-
– pełen kod aplikacji
zbudowanej w tym artykule,
znaczonej tabeli. Często zawiera także
• http://pear.php.net/package/ elementy nawigacyjne, pozwalające na Co należy wiedzieć...
MDB2 zmianę struktury, właściwości czy za- Przydatna będzie znajomość podstaw
– pakiet MDB2 dla PEAR, PHP-Gtk oraz podstawowych zapytań
• http://pear.php.net/package/ wartości tabeli.
SQL.
Gtk2_ExceptionDump Ponieważ takie rozmieszczenie jest
– pakiet Gtk_ExceptionDump
dla PEAR, popularne i dobrze znane większości Co obiecujemy...
• http://pear.php.net/package/ użytkowników, nasza przeglądarka ba- Dowiesz się, jakie nowe funkcje przynosi
Structures_Form_Gtk2 druga wersja PHP-Gtk. Zbudujesz prze-
zy danych będzie także miała taki wy-
– pakiet Structures_Form_Gtk2 glądarkę baz danych z funkcją sortowa-
dla PEAR. gląd. Oto lista wszystkich funkcjonalno- nia i podziału na strony.
ści, które omówimy w ramach artykułu,

44 www.phpsolmag.org PHP Solutions Nr 2/2007


PHP-Gtk2 Dla zaawansowanych

Na Rysunku 1. pokazaliśmy, jakie wid- Prawa strona naszej aplikacji jest aczej szybko zgubimy się we własnym
gety GTK+ zostaną użyte oraz, w jaki podobnie zamknięta w GtkVBox. Prze- kodzie. Ta metoda pozwala także na
sposób będą zagnieżdżone. trzymujący element GtkTreeView, będzie łatwe przystosowanie kodu do ponow-
Ponieważ GtkWindow może mieć pokazywał wszystkie wiersze. Będzie nego użycia, ponieważ wystarczy za-
jedynie jeden element potomny, a my on także zawierał element GtkToolbar z łączyć klasę i zainicjować ją komendą
potrzebujemy użyć kilku widgetów, sko- przyciskami nawigacyjnymi, usprawnia- new MyClassName() – bez porówna-
rzystamy z GtkContainer. GtkHPaned jącymi poruszanie się po liście: pierw- nia jest to mniej kodu, niż w przypad-
z kolei idealnie będzie pasował do na- sza i ostatnia strona, odśwież, następna ku wycinania i kopiowania kodu każdej
szych wymagań: dzieli bowiem okno i ostatnia strona. funkcji (co z kolei utrudnia znalezienie
na dwie sekcje, których rozmiar może Kilka słów na temat stylu kodo- i korektę błędów).
zmieniać użytkownik. wania i używania klas: z doświadcze-
Dla lewego panelu użyjemy kla- nia wiem, że bardzo pomocne okazu- Podłączamy się do bazy
sycznego GtkVBox, w którym zagnieź- je się rozszerzanie klas głównych wid- Wykonanie połączenia do bazy danych,
dzimy nasze rozwijane menu (Gtk- getów Gtk, tworząc własne klasy i osa- używając MDB2 jest relatywnie proste:
ComboBox ze specjalnym GtkListStore dzając je według kolejności zagnież- wystarczy stworzyć cią DSN (ang. Data
funkcjonującym jako jego model), oraz dżenia. To może powiększyć ilość linii Source Name), który odpowiada nasze-
dla listy tabel – także GtkTreeView kodu przy małych projektach, jednak mu środowisku, i wywołać metodę sin-
z odpowiednim GtkListStore jako mo- jest absolutnie niezbędne przy budo- gleton klasy MDB2:
delem. waniu wielkoskalowych projektów – in-
require_once 'MDB2.php';
$dsn = 'mysql://username:
password@hostname/databasename';
$mdb2 = MDB2::singleton($dsn, array());

Jeśli otrzymujesz błąd podobny do


"MDB2 Error: not found", prawdopo-
dobnie nie masz zainstalowanych odpo-
wiednich sterowników MDB2. Wystarczy
wykonać polecenie pear install MDB2_
Driver_mysql, by całość zaczęła działać
(należy zamienić “mysql” na nazwę na-
szego systemu bazodanowego).

Rozprawiamy się z błędami


W przypadku dużego projektu, zaprzęgli-
byśmy do pracy wyjątki, sprawdzając, czy
zwracany obiekt w $mdb2 to PEAR_Error
i rzucalibyśmy wyjątek w przypadku praw-
dy. Ponieważ tego typu zabiegi są bardzo
Rysunek 1. Struktura przeglądarki bazy danych kosztowne pod kątem np. czasu wykony-
wania, czy pisania aplikacji, użyjemy za-
let pakietu PEAR : Gtk2_ExceptionDump.
Wymagania Tworzy on graficzny zrzut wszelkiego ro-
Przygotujmy najpierw nasze stanowisko. Niezbędne będą: dzaju błędów: wyjątków, obiektów PEAR_
Error, kiedy zostaną utworzone oraz błę-
• PHP 5.1.x
dów PHP, w przypadku ich pojawienia się
• zainstalowany moduł PHP-Gtk2
• zainstalowany PEAR z pakietami MDB2 i Gtk2_ExceptionDump (patrz ramka W Sieci) (patrz Rysunek 2).
• dostęp do bazy danych Dobrą wiadomością jest, że ten skom-
plikowany z pozoru proces reprezentują w
Ja wybrałem MDB2, ponieważ oferuje najłatwiejszy sposób dostępu do różnych typów baz kodzie zaledwie dwie linijki:
danych, w tym Oracle, DB2 i MySQL. Jeśli pracujesz w systemie Windows, polecam uży-
cie pakietu Gnope (patrz ramka “W Sieci”), który zawiera wszystkie niezbędne składniki, require_once 'Gtk2/ExceptionDump.php';
pozwalające rozpocząć pracę z PHP5 i Gtk2. Jeśli używasz Linuxa lub Macintosha, powi-
Gtk2_ExceptionDump::setupAllHandlers();
nieneś pobrać PHP-Gtk2 Alpha (patrz ramka “W Sieci”) i skompilować go samodzielnie. W
manualu załączonym do pakietu znajdziesz instrukcję, jak przeprowadzić kompilację dla
Nie musimy już martwić się o błędy i
obu systemów. Mamy już zainstalowane narzędzia pracy, możemy więc przejść do właści-
wego rzemiosła. możemy skupić się na programowaniu
funkcjonalności naszej aplikacji. Taki

PHP Solutions Nr 2/2007 www.phpsolmag.org 45


Dla zaawansowanych PHP-Gtk2

zabieg jest bardzo przydatny przy two-


Listing 1. Kod klas wyświetlających bazy danych rzeniu prototypu aplikacji, jednak je-
śli zamierzasz rozprzestrzeniać swój
class DatabaseBrowser_DatabaseList extends GtkListStore
kod, powinieneś zaimplementować wła-
{
sny system obsługi błędów, by klient
public function __construct() otrzymywał bardziej przydatne i bar-
{ dziej czytelne informacje o ewentual-
parent::__construct(Gtk::TYPE_STRING); nych błędach.
$this->loadDatabases();
}
Wyświetlamy tabele
protected function loadDatabases() Pierwsze zapytanie SQL, jakiego bę-
{ dziemy używać, to naturalnie "SHOW
$res = DatabaseBrowser::$mdb2->query('SHOW DATABASES'); DATABASES ". Jego wynikiem wypeł-
while (($row = $res->fetchRow())) {
nimy GtkComboBox. By być przygoto-
$this->append(array($row[0]));
} wanym na wprowadzanie zmian i udo-
} skonaleń w przyszłości, skorzystamy
} z naszej własnej klasy, która będzie
rozszerzała GtkListStore. Widget ten
$cmbDatabase = GtkComboBox::new_text();
posiada jedynie jedną kolumnę typu
$cmbDatabase->set_model(new DatabaseBrowser_DatabaseList());
Gtk::TYPE_STRING, która przechowu-
Listing 2. Wyświetlamy dostępne tabele je nazwy dostępnych baz danych. Kod
klas zamieściliśmy na Listingu 1, wynik
class DatabaseBrowser_TableList extends GtkListStore
jego działania widać na Rysunku 3.
{
GtkListStore oferuje kilka metod do-
public function __construct() dawania wierszy. W tym przypadku za-
{ stosujemy append(), ponieważ jest dla
parent::__construct(Gtk::TYPE_STRING, Gtk::TYPE_LONG); nas najłatwiejsza w użyciu. Pobiera
}
ona jako parametr tablicę, która powin-
public function loadTables($strDatabase) na mieć tyle wartości, ile nasza lista ma
{ kolumn.
$this->clear(); Zauważmy, że stosujemy obiekt pu-
DatabaseBrowser::$mdb2->setDatabase($strDatabase); bliczny $mdb2 typu static naszej głów-
$res = DatabaseBrowser::$mdb2->query('SHOW TABLES');
nej klasy, DatabaseBrowser, do wykony-
while (($row = $res->fetchRow())) { wania zapytań do bazy danych...
$strTable = $row[0]; W połączeniu z dwoma kolejnymi
$nRows = DatabaseBrowser::$mdb2->queryOne( linijkami, otrzymujemy działające me-
t'SELECT COUNT(*) FROM ' . $strTable); nu rozwijane z listą dostępnych baz da-
$this->append(array($strTable, $nRows));
nych.
}
} Kiedy użytkownik wybierze bazę
} danych, powinniśmy wyświetlić mu Gtk-
TreeView (Listing 2). Element ten bę-
$lstTables = new GtkTreeView(new DatabaseBrowser_TableList()); dzie zawierał nazwy tabel oraz ilość
$renderer = new GtkCellRendererText();
wierszy w nich dostępnych. Podobnie,
$col = new GtkTreeViewColumn('Table', $renderer, 'text', 0);
$lstTables->append_column($col); jak poprzednio, stworzymy własną kla-
sę rozszerzając GtkListStore. Tym ra-
$numberRenderer = new GtkCellRendererText(); zem musimy pamiętać, że lista musi
$col->pack_end($numberRenderer, false); być czyszczona i ponownie uzupełnia-
$col->add_attribute($numberRenderer, 'text', 1);
na przy każdym kolejnym wyborze ba-
$cmbDatabase->connect('changed', array($this, 'onSelectDatabase'), $lstTables); zy danych przez użytkownika. Tym sa-
mym, klasa otrzyma własną metodę lo-
public function onSelectDatabase($cmbDatabase, $lstTables) adTables(), która będzie wymagała ja-
{ ko jedynego parametru, nazwy bazy
$strDatabase = $cmbDatabase->get_active_text();
danych. Wynik jej działania będziemy
$lstTables->get_model()->loadTables($strDatabase);
} wyświetlać w dwóch kolumnach: jednej
dla nazwy tabeli, drugiej dla ilości re-
$scrTables = new GtkScrolledWindow(); kordów w niej istniejących.
$scrTables->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); Wypełnienie elementu GtkTreeView
$scrTables->add($lstTables);
będzie wymagało tym razem więcej
pracy, niż w przypadku baz danych w

46 www.phpsolmag.org PHP Solutions Nr 2/2007


Kei.pl Ciao GmbH
Kei.pl działa na rynku usług hostingowych od Ciao GmbH jest właścicielem wiodącego porta-
2000 roku. Do naszych zadowolonych Klientów lu konsumenckiego w Europie – Ciao.com. Do
z dumą możemy zaliczyć wiele przedsiębiorstw nowo powstałego centrum rozwoju oprogramo-
sektora MSP, instytucji oraz osób prywatnych. wania we Wrocławiu poszukujemy doświadczo-
W ofercie Kei.pl znajdują się pakiety hostingowe, nych programistów PHP. Chcesz dobrze zara-
a także usługi dla wymagających Użytkowników biać, pracować w międzynarodowym środowi-
– platformy e-Biznes oraz serwery fizyczne. sku i w przyjaznej atmosferze – dołącz do nas.
http://www.kei.pl www.ciao-group.com/careers_wroclaw.php

Agencja Interaktywna

Prenumerata PRO
– br-design.pl
Kreowanie oraz obsługa serwisów interne-
towych, programowanie aplikacji interneto-
wych według indywidualnych potrzeb klienta,
realizacja projektów graficznych i prezentacji
multimedialnych.
www.br-design.pl

Więcej informacji: patrycja.wadolowska@software.com.pl tel.: 022 887-13-45


Firma Informatyczna
„Saulewicz”
Wdrażamy technologie internetowe w opar-
ciu o serwery linuxowe i rozwiązania „Open
Source”. Oferujemy aplikacje bazodaniowe
pracujące w środowisku PHP. Prowadzimy
konsultacje dotyczące bezpieczeństwa sys-
temów sieciowych.
www.saulewicz.com.pl.

Masz ciekawy e-pomysł?


Potrzebujesz pomocy!
Zapewniamy profesjonalną i kompleksową
obsługę w zakresie: stron internetowych
– systemów zarządzania treścią; sklepów
internetowych – projektów graficznych;
aplikacji internetowych – drukowania off-
setowego.
www.intersum.pl

protHOST
Rewelacyjny hosting o12 już od 49 zł netto/rok
(w tym cPanel PL). Rejestracja domen od 1 zł
netto. Webdesign i pozycjonowanie. Wszystko
czego potrzebujesz.
http://o12.pl

Hosting
Elastyczny dobór pakietów, pakiet POCZTA
– 40 zł, pakiet START (www, email, 10 domen,
php 5, mysql, pgsql) – 150 zł, pakiety KOM-
FORT, PROFIT, PROFITSSL, zarządzanie przez
cPanel. Rejestracja domen globalnych, krajowych,
funkcjonalnych i regionalnych. Ceny od 50 zł.
www: http://www.lubman.pl,
e-mail: biuro@lubman.pl,

Dzsoft Agnat Sp. z o.o.


Siedziba firmy znajduje się na Ukrainie. Naszą Dostarcza pełen wachlarz usług związanych ze
ofertę kierujemy szczególnie do osób, które zaj- stronami WWW. Serwis www.agnat.eu obsłu-
mują się językiem PHP, gdyż sami specjalizuje- guje kilkanaście tysięcy Klientów z całej Polski
my się w tym, pisząc nasz własny kod. Posia- oraz Unii Europejskiej, wyposażając je w do-
damy również edytor Perl oraz inne przydatne meny internetowe, hosting, pozycjonowanie,
oprogramowania. Nasi pracownicy to specjaliści, kreację stron WWW, kampanie reklamowo-pro-
zajmujący się optymalizacją specyficznych po- mocyjne, oprogramowanie i aplikacje niezbędne
trzeb języka PHP i Perl. do prowadzenia biznesu w sieci.
http://www.dzsoft.com
PHP-Gtk2 Dla zaawansowanych

cjalizować widgetu GtkListStore z usta- zodanowego. Wszystko więc, co musi- DESCRIBE, otrzymamy w wyniku na-
loną odgórnie ilością elementów Gtk:: my zrobić, to ustalić ilość kolumn w ta- zwy kolumn i ich liczbę.
TYPE_STRING, lecz musimy robić to dy- beli, ich tytuły, zaś później stworzymy Problem pierwszy został już wielo-
namicznie. Poza tym, kolumny baz da- odpowiednią ilość widgetów GtkTree- krotnie dostrzeżony przez dewelope-
nych SQL nie posiadają typów STRING, ViewColumns, by wyświetlić nasze da- rów PHP-Gtk2, czego skutkiem jest im-
lecz szeroki zakres innych typów: INT o ne. Używając oświadczenia SQL-owego plementacja metody set_column_types()
różnych długościach, a także VARCHAR,
SHORT/MEDIUM/LONG TEXT, ENUM Listing 4. Model przechowujący nasze dane
oraz inne.
Mimo, że nie jest to optymalne roz- class DatabaseBrowser_TableModel extends GtkListStore
{
wiązanie, możemy użyć Gtk::TYPE_
protected $nPageSize = 20;
STRING dla każdej kolumny, nieza- public function __construct($strDatabase, $strTable, $arTypes)
leżnie od typu danych, które zawiera- {
ła będąc w bazie danych. Takie podej- $this->strDatabase = $strDatabase;
ście ma jednak pewne poważne wady: $this->strTable = $strTable;
parent::__construct();
nasz model zużywa więcej pamięci, niż
$this->set_column_types($arTypes);
jest to konieczne, przechowując przy $this->update('refresh');
tym wszystkie dane w jednym modelu, }
włącznie z wielkimi BLOBami, które za- public function navigate($strAction)
pewne nie powinny mieć takiego prze- {
switch ($strAction) {
znaczenia. Przeglądanie tabeli z takimi
case 'first':
elementami może być bardzo powolne. $this->nCurrentPage = 0;
Z drugiej strony, mapowanie bazy break;
danych w taki sposób ma – w celach case 'back':
demonstracyjnych artykułu – niepod- if ($this->nCurrentPage > 0) {
--$this->nCurrentPage;
ważalną zaletę: jest bardzo łatwe w im-
}
plementacji, bowiem omija nas koniecz- break;
ność mapowania typów z SQL do Gtk, ...
które dodatkowo różniłoby się w zależ- }
ności od typu używanego systemu ba- $this->update();
}
...
public function update()
{
$this->clear();
$this->nRows = DatabaseBrowser::$mdb2->queryOne(
Rysunek 3. Pole wyboru bazy danych
'SELECT COUNT(*) FROM ' . $this->strTable);
DatabaseBrowser::$mdb2->setLimit($this->nPageSize,
$this->nCurrentPage * $this->nPageSize);
$arData = DatabaseBrowser::$mdb2->queryAll(
'SELECT * FROM ' . $this->strTable . $this->strOrder);
foreach ($arData as $arRow) {
$this->append($arRow);
}
}

...
public static function getTableStructure($strDatabase, $strTable)
{
$arData = DatabaseBrowser::$mdb2->queryAll('DESCRIBE ' .
$strDatabase . '.' . $strTable);
$arStructure = array();
foreach ($arData as $arColumnDef) {
$strColumnName = $arColumnDef[0];
$arStructure[$strColumnName] = Gtk::TYPE_STRING;
}
return $arStructure;
}
}

Listing 5. Przypisanie handlera dla efektu kliknięcia

$col->set_clickable(true);
$col->connect('clicked', array($this, 'onClickedHeader'), $strColumnName);
Rysunek 4. Tabele w bazie danych

PHP Solutions Nr 2/2007 www.phpsolmag.org 49


Dla zaawansowanych PHP-Gtk2

widgetu GtkListStore, która pobiera tabli- mięci, czasu na przekazanie danych ny rezultat w około dziesięciu liniach ko-
cę typów Gtk. z serwera do aplikacji, zaś sam użyt- du, widocznych na Listingu 3.
By zaimplementować solucje obu pro- kownik na pewno nie będzie zachwy- Następnie, jak widać na Listingu 4,
blemów, najpierw musimy stworzyć sta- cony, widząc miliony wierszy. Dewelo- tworzymy klasę DatabaseBrowser_Table,
tyczną metodę getTableStructure, któ- perzy GTK+ zauważyli potrzebę wpro- rozszerzając GtkTreeView oraz klasę Da-
ra wykonuje zapytanie "DESCRIBE $ta- wadzenia przycisków nawigacyjnych, tabaseBrowser_TableModel, będącą roz-
blename" do bazy danych i zwraca tabli- dodali więc kilka elementów zwanych szerzeniem GtkListStore, ponieważ jest
cę asocjacyjną. Nazwy kolumn są uży- Stock Items, które wykonują pożąda- to nasz główny silnik przeglądarki, któ-
wane jako klucze, zaś typy Gtk::TYPE_ ne przez nas zadania: Gtk::STOCK_ ry powinien umieć wypełniać się dany-
STRING jako wartości. Dzięki temu, mo- GOTO_FIRST, Gtk::STOCK_GO_BACK, mi, gdy zajdzie taka potrzeba. Kieruje-
żemy używać tej tablicy tak dla tworzenia Gtk::STOCK_REFRESH, Gtk::STOCK_ my komendy nawigacyjne, przekazywa-
GtkTreeViewColumn, jak przekazywać ją GO_FORWARD i Gtk::STOCK_GOTO_ ne przez przyciski, do metody navigate(),
do set_column_types() bez dodatkowych LAST. Przekazanie każdego z tych ele- po prostu zmieniając wewnętrzną zmien-
modyfikacji. mentów do konstruktora new_from_ ną nCurrentPage klasy i wywołując funk-
Kolejnym dobrym pomysłem jest po- stock() widgetu GtkToolButton's powo- cję update().
dział wyników na strony. Mimo, że GtkLi- duje, że otrzymamy menu z przyciskami update() używa naszego obiektu
stStore może przechowywać dowolną oznaczonymi odpowiednim tekstem i iko- MDB2 do wykonania zapytania SELECT
ilość wierszy, przetrzymywanie wszyst- nami. Używając metody insert($btn, -1) po użyciu setLimit(), który precyzuje,
kich danych może zająć za dużo pa- widgetu GtkToolbar, otrzymamy pożąda- które rekordy chcemy pobrać dla aktu-
alnie wyświetlanej strony. Następnie, ta-
blice zwrócone przez metodę queryAll()
są przekazywane bezpośrednio do me-
tody append() modelu. Efekt naszej pra-
cy jest widoczny na Rysunku 5.

Dodajemy sortowanie
Jedna z funkcjonalności, oferowanych
przez tabele i często oczekiwanych, to
możliwość sortowania wierszy przez
kliknięcie na nazwę określonej kolum-
ny. GtkTreeViewColumn posiada wbu-
dowane funkcje wspomagające sorto-
wanie. Nagłówki mogą zostać skonfi-
gurowane jako klikalne, zaś dodatkowo
automatycznie będą dodawane strzał-
ki, sygnalizujące aktualny układ, we-

Rysunek 5. Nasza przeglądarka wyświetlająca rekordy

Listing 6. Wykonujemy sortowanie w zależności od klikniętej kolumny

public function onClickedHeader($column, $strColumnName)


{
if ($column !== $this->sortColumn) {
if ($this->sortColumn !== null) {
$this->sortColumn->set_sort_indicator(false);
}
$this->sortColumn = $column;
$this->sortColumn->set_sort_indicator(true);
}

if ($column->get_sort_order() == Gtk::SORT_ASCENDING) {
$column->set_sort_order(Gtk::SORT_DESCENDING);
$strOrder = 'DESC';
} else {
$column->set_sort_order(Gtk::SORT_ASCENDING);
$strOrder = 'ASC';
}
$this->model->setOrder($strColumnName . ' ' . $strOrder);
$this->model->update();
}
Rysunek 6. Sortowanie tabeli wg ilości
pobrań

50 www.phpsolmag.org PHP Solutions Nr 2/2007


PHP-Gtk2 Dla zaawansowanych

dług którego posortowana jest tabe- pie sortowania do zapytania SQL wy- Do aplikacji można dodać wiele przydat-
la. Łącznikiem, między modelem da- korzystywanego przez metodę update(). nych funkcjonalności:
nych obecnych w aplikacji z przedsta- Osiągniemy to, używając prostej meto-
wianymi użytkownikowi, jest GtkTree- dy setOrder(). Rezultaty widać na Ry- • obsługa zakładek, by umożliwić prze-
ModelSort. sunku 6. glądanie wielu tabel jednocześnie,
Sortowanie danych jest tym, czego • wyświetlanie widoku struktury tabeli,
zazwyczaj potrzebują użytkownicy. Nam Konkluzja • używanie różnych typów danych w
jednak zwykłe sortowanie nie wystarczy, Stworzyliśmy prosty, intuicyjny i niezależ- modelu, w celu usprawnienia prędko-
bowiem objęte by nim były jedynie aktu- ny system przeglądania bazy danych w ści i efektywności działania aplikacji,
alnie wczytane wiersze. Użytkownik bę- 300 liniach kodu używając Gtk2 oraz pa- • dodanie pola tekstowego, pozwalają-
dzie oczekiwał, że kliknięcie na nagłówek kietu MDB2 z repozytorium PEAR. Ob- cego na wprowadzenie własnych za-
reprezentujący nazwy kolumn spowoduje sługuje on podział danych na strony i sor- pytań SQL z możliwością wyszukiwa-
wyświetlenie wszystkich nazw zaczyna- towanie, będąc bardzo łatwym w rozsze- nia wartości,
jących się na “A” na pierwszych stronach, rzaniu. • możliwość edycji wierszy dzięki wyświe-
czego nie osiągnęlibyśmy stosując sorto- Przeglądarki można użyć jako pod- tlaniu danych rekordów w innym oknie,
wanie lokalne. stawy do budowy własnego edytora baz przy użyciu Structures_Form_Gtk2.
Bazy danych mają wbudowane funk- danych, do którego zapewne przydatny
cje sortujące, więc najłatwiej będzie nam okaże się pakiet Structures_Form_Gtk2 Zapraszamy do wypróbowania nowych
z tych dogodności skorzystać. Musimy dostępny w repozytorium PEAR (patrz możliwości PHP-Gtk2! n
zidentyfikować kliknięcia na nagłówkach ramka “W Sieci”), idealnie nadający się
kolumn i wygenerować odpowiednie za- do manipulacji danymi, o dynamicznie
pytanie SQL z “ORDER BY ” dla danej określanej liczbie pól.
kolumny. Pełny kod przeglądarki bazy danych, O autorze
Przy tworzeniu naszych kolumn Gtk- którą zbudowaliśmy, jest zamieszczo-
TreeViewColumn, każda z nich otrzyma ny na CD oraz w Internecie (patrz ramka Christian Weiske jest studentem infor-
dwa nowe wiersze widoczne na Listingu “W Sieci”). matyki na uniwersytecie w Leipzigu, w
Niemczech. Jest członkiem zespołu roz-
5. W funkcji onClickedHeader() wykona-
wijającego i dokumentującego projekt
my sortowanie (Listing 6). Co dalej? PHP-Gtk2, jak również autorem wielu
Wszystko, czego jeszcze potrze- W tym artykule omówiliśmy jedynie pod- pakietów PEAR.
bujemy, to przekazanie informacji o ty- stawy wyświetlania danych z bazy SQL.

R E K L A M A

PHP Solutions Nr 2/2007 www.phpsolmag.org 51


Dla zaawansowanych PHP-Gtk2

GtkComboBox, ponieważ nie posiada Ostatnie zadanie, to umożliwie- Po połączeniu kodu, otrzymujemy
on odpowiedniego konstruktora, który nie przewijania listy, co staje się trywial- aplikację widoczną na Rysunku 4.
mógłby ustawić wszystkie kolumny. ne przy użyciu widgeta GtkScrolledWin-
Użyjemy więc następujących kompo- dow. Miejmy na uwadze, że GtkTreeView, Pokazujemy dane
nentów: w odróżnieniu od wielu innych widge- Zmapowanie zawartości całej tabeli z ba-
tów, posiada swój własny system wido- zy danych do jednego widgetu GtkList-
• GtkTreeView jako główny widget, ma- ku. Oznacza to, że jeśli będziemy przewi- Store jest możliwe, acz nie trywialne.
jący dostęp do modelu Database- jać zawartość widgetu, tytuły kolumn bę- Będziemy musieli zmierzyć się z dwoma
Browser_TableList, dą zawsze widoczne. Dodatkowo, upew- problemami:
• GtkTreeViewColumn, wyświetlający nijmy się, że paski przewijania nie będą Po pierwsze, lista kolumn każdej ta-
zawartość kolumn, widoczne, jeśli nie są konieczne. To za- beli nie jest znana podczas progra-
• GtkCellRendererText, by narysować danie spełni proste odwołanie do set_ mowania naszej przeglądarki baz da-
nazwy tabel w wierszach, policy. nych. Oznacza to, że nie możemy zaini-
• GtkScrolledWindow, by wyświetlone
zostały suwaki na wypadek, gdyby li- Listing 3. Tworzymy menu nawigacyjne
sta tabel nie mieściła się w oknie.
$this->tbl = new DatabaseBrowser_Table($strDatabase, $strTable);

Konstruktor GtkTreeView potrzebuje, $scrwnd = new GtkScrolledWindow();


jako pierwszego i jedynego parame- $scrwnd->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
tru modelu, podajemy więc mu instan- $scrwnd->add($this->tbl);
cję naszej klasy DatabaseBrowser_
$this->pack_start($scrwnd);
TableList.
GtkTreeViewColumn potrzebuje z $tb = new GtkToolbar();
kolei czterech parametrów: jako pierw- $arButtons = array(
szego, tytułu nagłówka kolumny. Ja- Gtk::STOCK_GOTO_FIRST => 'first',
ko drugiego – obiektu GtkCellRenderer, Gtk::STOCK_GO_BACK => 'back',
Gtk::STOCK_REFRESH => 'refresh',
który zajmuje się rysowaniem danych
Gtk::STOCK_GO_FORWARD => 'forward',
modelu. Trzeci parametr determinuje, Gtk::STOCK_GOTO_LAST => 'last'
który atrybut GtkCellRenderer zostanie );
ustawiony (np. GtkCellRendererText ja- foreach ($arButtons as $nStockItem => $strAction) {
ko atrybut “text”, ale już GtkCellRende- $btn = GtkToolButton::new_from_stock($nStockItem);
$btn->connect_simple('clicked', array($this->tbl, 'navigate'), $strAction);
rerPixbuf jako "pixbuf", bowiem determi-
$tb->insert($btn, -1);
nuje obraz). Czwarty i ostatni, parametr, $this->arButtons[$strAction] = $btn;
to numer kolumny modelu, który prze- }
trzymuje dane zawarte w atrybucie.
Moglibyśmy teraz po prostu dodać
drugą kolumnę, by wyświetlać ilości
wierszy, lecz istnieje także inna metoda:
dodanie drugiego elementu GtkCellRen-
dererText do tej samej kolumny. Ponie-
waż klasa GtkTreeViewColumn imple-
mentuje interfejs GtkCellLayout, może-
my użyć jej podobnie, jak w przypadku
GtkBox, używającego pack_start() oraz
pack_end(), w celu dodania większej ilo-
ści rendererów.
Jeśli uważnie śledziłeś dotychcza-
sową treść artykułu, zapewne zastana-
wiasz się, skąd lista tabel “wie”, kiedy
zachodzą zmiany w liście baz danych.
Odpowiedź jest prosta: jeszcze nie wie.
Musimy więc uzupełnić kod, dodając
uchwyt (ang. handler) do sygnału Gtk-
ComboBox changed (reakcja na zmia-
nę). Przekazujemy objekt tabeli do funk-
cji pełniącej rolę callbacka (połączenie
zmiany z jej efektem), bowiem będziemy
odnosili się do metody loadTables() mo- Rysunek 2. Wynik działania Gtk2_ExceptionDump po stworzeniu obiektu PEAR_Error
delu, który wcześniej zdefiniowaliśmy. przez MDB2

48 www.phpsolmag.org PHP Solutions Nr 2/2007


Narzędzia

PHP5 WebServices vs MS .NET


vs Java vs Java Mobile
Stopień trudności: lll
Łukasz Budnik

W tym artykule pokażemy, jak stworzyć prostą


usługę w PHP5, jak się z nią połączyć. Następnie
pokażemy, jak należy łączyć się z usługami
sieciowymi MS .NET, Jakarta AXIS (Java). Pokażemy
też jak zaimplementować usługę z Security
Extension udostępnianą po HTTPS w PHP5, jak
napisać klienta PHP5, który będzie się łączył z taką
usługą i weryfikował oraz zabezpieczał połączenie
własnym certyfikatem i kluczem. Pokażemy
również, jak połączyć się z usługą PHP5 z komórki
(Java, w dodatku Java mobile), a także, jak
mapować obiekty złożone z PHP5 do MS .NET.

W
PHP5 pojawił się bardzo inte- Można powiedzieć, że Web Services to
resujący moduł SOAP. SOAP nowa wersja CORBA.
(ang. Simple Object Access SOAP jest to protokół, poprzez który
Protocol) zapewnia nam możliwość two- realizowane są wszystkie operacje Web
rzenia własnych oraz wywoływania zdal- Services. SOAP bazuje na XML, jest
nych usług sieciowych, rozsianych po więc bardzo prostym protokołem, do któ-
całym Internecie. Implementacja SOAP rego obsługi wystarczy nam zwykły par-
w PHP5 nie zawiera wszystkich rozsze-
rzeń protokołu SOAP, ale sami możemy
Co należy wiedzieć...
je dopisać, ponieważ zarówno klasy ser- Powinieneś posiadać dobrą znajomość
werów, jak i klientów, możemy rozsze- PHP5, znać ogólne zasady współpracy i
rzyć (klasy nie są typu final). projektowania systemów rozproszonych
na różnych systemach. Mile widziana
znajomość podstaw SOAP i WSDL.
Web Services,
protokół SOAP Co obiecujemy...
Ale zacznijmy od początku. Web Servi- Nauczysz się pisać własne usługi siecio-
ces to systemy, które są projektowane we, dowiesz się, jak rozszerzyć domyśl-
tak, aby komputery o różnych architek- ne klasy PHP5 klienta i serwera SAOP.
Nauczysz się zabezpieczać swoje usługi
turach, różnych systemach operacyj-
z rozszerzeniem WS Security Enhance-
nych działające w rozproszonym środo- ments i HTTPS. Nauczysz się, jak mapo-
wisku mogły wywoływać zdalnie swoje wać złożone obiekty i przesyłać je pomię-
pewne operacje poprzez sieć Internet. dzy różnymi platformami technologiczny-
mi. Dowiesz się, jak połączyć się z usłu-
Najczęściej wykorzystują one jako war-
gami sieciowym MS .NET, Jakarta AXIS.
stwę transportową HTTP (lub HTTPS).

52 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

ser dokumentów XML. SOAP jest stan-


dardem opracowanym przez W3C. Je-
go implementacje znajdziemy na każdej
platformie technologicznej, w tym takich
gigantów jak MS .NET, Java czy Java w
wersji na urządzenia przenośne.
Jak działa SOAP? Klient podczas
zdalnego wywoływania metod wymie-
nia z serwerem dokumenty XML o ści-
śle zdefiniowanej strukturze, tak zwane
koperty. Koperta z kolei zawiera dwa ele-
menty: Header (nieobowiązkowy) oraz
Body (obowiązkowy). W Header można
wstawiać dodatkowe informacje typu da-
Rysunek 1. Rozbudowana koperta SAOP – WS Security Enhancements ta, miejsce skąd wywołujemy usługę, lo-
gin, hasło. W Body klient umieszcza in-
formacje o metodzie, którą chce wywołać
Listing 1. Koperta SOAP służąca do wywołania zdalnej usługi PobierzArtykul
oraz ewentualne jej parametry. Serwer
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle= odpowiada również kopertą, w której mo-
"http://schemas.xmlsoap.org/soap/encoding/"> że być nagłówek (Header) i zawsze mu-
<SOAP-ENV:Body> si być ciało (Body), w której znajdują się
<!-- nazwa metody --> dane, które są wynikiem wykonania zdal-
<ns1:PobierzArtykul>
nej procedury.
<!-- parametry... tutaj parametr o nazwie id, typu xsd:int o wartości 1212 -->
<id xsi:type="xsd:int">1212</id> Podstawowy schemat żądania został
</ns1:PobierzArtykul> przedstawiony na Listingu 1.
</SOAP-ENV:Body> Natomiast odpowiedź została przed-
</SOAP-ENV:Envelope> stawiona na Listingu 2.
Nie musimy znać dokładnych struktur
Listing 2. Koperta SOAP będąca odpowiedzią na wywołanie usługi
PobierzArtykul kopert wymienianych pomiędzy klientem a
serwerem, ponieważ są one tworzone au-
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/ tomatycznie i nie potrzebujemy w nie inge-
encoding/">
rować, jeśli nie chcemy np. rozszerzać do-
<SOAP-ENV:Body>
<!-- wynik działania PobierzArtykul -->
myślnych implementacji SOAP w PHP5.
<ns1:PobierzArtykulResponse> W późniejszej części artykułu, pokażę, jak
<!-- typem zwracanym jest xsd:string o podanej zawartości --> rozszerzać klasy PHP5 i modyfikować ta-
<PobierzArtykulReturn xsi:type="xsd:string"> kie koperty. Przykład koperty SOAP żąda-
zalozmy, ze przeszukalismy baze i to jest ten jedyny artykul
nia klienta z security extension możemy
</PobierzArtykulReturn>
</ns1:PobierzArtykulResponse>
zobaczyć na Rysunku 1.
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> WSDL – Web Services
Definition Language
Listing 3. Wiązanie ProsteOperacjeSoapBinding WSDL to najtrudniejsza część związana
<wsdl:binding name="ProsteOperacjeSoapBinding" type="impl:ProsteOperacje"> z Web Services. WSDL to język, w któ-
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> rym definiujemy naszą usługę tak, aby in-
<wsdl:operation name="PobierzArtykul"> ne systemy mogły z niej korzystać. WSDL
<wsdlsoap:operation soapAction=""/> składa się z 5 najważniejszych części:
<wsdl:input name="PobierzArtykulRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/
encoding/" namespace="http://t:81/soap/article/ • <types> – definicje typów złożonych,
ProsteOperacjeWS.php" use="encoded"/> które nie są obsługiwane przez XSD,
</wsdl:input> jeśli nie używamy tablic, czy własnych
<wsdl:output name="PobierzArtykulResponse"> klas kopertowych, nie musimy definio-
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/
wać nic,
encoding/" namespace="http://t:81/soap/article/
ProsteOperacjeWS.php" use="encoded"/> • <message> – definicje wiadomości, de-
</wsdl:output> finiujemy tu z jakich typów składają się
</wsdl:operation> dana wiadomość, jeśli z typów złożo-
</wsdl:binding> nych, muszą one być wcześniej zdefi-
niowane w <types>,

PHP Solutions Nr 2/2007 www.phpsolmag.org 53


Narzędzia SOAP w PHP5

Listing 4. WSDL definiujący przykładową operację PobierzArtykul Listing 6. Plik


ProsteOperacjeWS.php
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://t:81/soap/article/ProsteOperacjeWS.php" // plik z naszą klasą ProsteOperacje
xmlns:impl="http://t:81/soap/article/ProsteOperacjeWS.php" require_once 'ProsteOperacje.
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" inc.php';
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" // parametrem konstruktora
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> // SoapServer jest adres do pliku
<wsdl:message name="PobierzArtykulResponse"> // WSDL
<wsdl:part name="PobierzArtykulReturn" type="xsd:string"/> $server = new SoapServer
</wsdl:message> ('ProsteOperacje.wsdl');
<wsdl:message name="PobierzArtykulRequest">
<wsdl:part name="id" type="xsd:int"/> // klasa implementująca portType
</wsdl:message> $server->setClass('ProsteOperacje');
<wsdl:portType name="ProsteOperacje">
<wsdl:operation name="PobierzArtykul" parameterOrder="id"> // przekazujemy sterowanie do PHP5
<wsdl:input message="impl:PobierzArtykulRequest" name="PobierzArtykulRequest"/> // – to wszystko
<wsdl:output message="impl:PobierzArtykulResponse" name="PobierzArtykulResponse"/> $server->handle();
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ProsteOperacjeSoapBinding" type="impl:ProsteOperacje">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> • <portType> – definiuje zbiór operacji
<wsdl:operation name="PobierzArtykul"> udostępnianych na zewnątrz, jest od-
<wsdlsoap:operation soapAction=""/> powiednikiem interfejsu klas, opera-
<wsdl:input name="PobierzArtykulRequest">
cje definiuje w dzieciach <operation>,
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/
encoding/" namespace="http://DefaultNamespace" use="encoded"/> które definiują operacje, pobierają na
</wsdl:input> wejściu pewną wiadomość i zwraca-
<wsdl:output name="PobierzArtykulResponse"> ją wiadomość; wiadomości muszą być
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/ definiowane w <message>,
encoding/" namespace="http://t:81/soap/article/
• <binding> – wiążę operacje zdefinio-
ProsteOperacjeWS.php" use="encoded"/>
</wsdl:output> wane w portType z konkretnym pro-
</wsdl:operation> tokołem (najczęściej HTTP/HTTPS)
</wsdl:binding> oraz zawiera informacje na temat ko-
<wsdl:service name="ProsteOperacjeService"> dowania parametrów/odpowiedzi kon-
<wsdl:port binding="impl:ProsteOperacjeSoapBinding" name="ProsteOperacje">
kretnych operacji,
<wsdlsoap:address location="http://t:81/soap/article/
ProsteOperacjeWS.php"/> • <service> – wiąże wcześniej zdefinio-
</wsdl:port> wany binding z konkretnym adresem,
</wsdl:service> pod którym dostępna będzie nasza
</wsdl:definitions> usługa.
Listing 5. Kod klasy implementującej interfejs naszej usługi sieciowej
Z tak opisanej usługi klient może dowiedzieć
// w normalnych warunkach klasa ProsteOperacje się wszystkiego, czego potrzebuje, aby wy-
// łączyła by się z bazą danych i pobierała artykułu wołać dowolną metodę. Istnieje wiele pakie-
// dodatkowo ciągi znaków przesyłane SOAP muszą być
tów typu WSDL2Java, które generują kody
// zakodowane w UTF-8, używam do tego prostych funkcji konwertujących
require_once ('Strings.inc.php');
klientów w Java-ie, gotowe do użycia i wy-
wołania zdalnego serwisu, MS .NET sam
class ProsteOperacje { tworzy referencje i wiązania obiektów, rów-
function PobierzNajnowszyArtykul() { nież w PHP5 w kliencie SOAP wystarczy
return Strings::ConvertFromISOToUTF("załóżmy, że to jest ten artykuł");
podać adres do pliku WSDL, aby można by-
}
function PobierzArtykul($id) {
ło korzystać ze wszystkich usług zdefiniowa-
return Strings::ConvertFromISOToUTF("zalozmy, ze przeszukalismy baze i to nych w Web Services.
jest ten jedyny artykul"); WSDL może na pierwszy rzut oka wy-
} dawać się bardzo trudnym. Nic jednak bar-
function Pobierz10Najnowszych($kategoria) {
dziej mylnego, jest wręcz dziecinnie prosty.
return array (
Strings::ConvertFromISOToUTF('pierwszy artykuł'),
Zobrazuje to nasz pierwszy przykład.
Strings::ConvertFromISOToUTF('drugi artykuł'),
Strings::ConvertFromISOToUTF('kolejny artykuł') Pierwsza usługa Web
); Service PHP5 – WSDL
}
Zdefiniujmy klasę, której publiczne me-
}
tody będą operacjami udostępnianymi
przez naszą usługę. Poniżej pokazuję,

54 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

jak krok po kroku zdefiniować operację,


której sygnaturę można zapisać jako:
String PobierzArtykul(int id).
Jak widzimy używamy tu typów xsd:
string oraz xsd:int – nie potrzebujemy
więc tworzyć żadnych innych typów.
Przechodzimy od razu do elemen-
tów <message>, zwyczajowo przyję-
ło się aby nazwy wiadomości składa-
ły się z nazwy operacji, plus Request
dla wiadomości wysyłanej przez klien-
ta (żądania), oraz Response dla wiado-
mości wysyłanej przez serwer. Pisze-
my zatem:

Rysunek 2. Jeśli przeglądając usługę przez przeglądarkę zobaczymy błąd przewrot- <wsdl:message name="Pobierz
nie znaczy to, że usługa działa, tylko nie ma danych POST ArtykulResponse">
<wsdl:part name="Pobierz
ArtykulReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="Pobierz
ArtykulRequest">
<wsdl:part name="id" type="xsd:int"/>
</wsdl:message>

Następnym krokiem jest definicja ele-


mentu <portType> i <operation> a w niej
elementy input oraz output, które wska-
zują na zdefiniowane przed chwilą wia-
domości. Nazywamy portType jako
ProsteOperacje, oraz operation jako
PobierzArtykuł. Jako atrybut message
elementów input oraz output podajemy
odpowiednie wiadomości z przedrost-
kiem impl: (namespace impl).

Rysunek 3. Każda usługa powinna przedstawić się podając swój WSDL po doda- <wsdl:portType name="Proste Operacje">
niu ?wsdl do adresu usługi <wsdl:operation name="PobierzArtykul">
<wsdl:input message="impl:Pobierz
ArtykulRequest" name="PobierzArtykul
Request"/>
<wsdl:output message="impl:Pobierz
ArtykulResponse"name="PobierzArtykul
Response"/>
</wsdl:operation>
</wsdl:portType>

Mając już zdefiniowany interfejs o


nazwie ProsteOperacje musimy zwią-
zać go z protokołem, stylem wywoły-
wania zdalnych metod, oraz określić,
czy i jak kodowane mają być wiado-
mości. Definiuję warstwę transportową
jako HTTP, styl RPC (ang. remote pro-
cedure call) oraz definiuję kodowanie
encoded dla wiadomości. Jako atrybut
type podaję nazwę portType (wartość
atrybutu name dla elementu portType
Rysunek 4. Pierwsze zdalne wywołanie naszej usługi sieciowej z przedrostkiem impl:). Wiązanie na-

PHP Solutions Nr 2/2007 www.phpsolmag.org 55


Narzędzia SOAP w PHP5

Listing 7. Pełny kod klienta PHP5 łączącego się z usługą sieciową, wraz ze śle-
dzeniem wywołań i obsługą zdalnych wyjątków

require_once ('Strings.inc.php');
$client = new SoapClient(
'http://t:81/soap/article/ProsteOperacjeWS.php?wsdl',
array('trace' => 1, 'exceptions' => 1)
);
try {
echo '<pre>';
var_dump(Strings::ConvertFromUTFToISO($client->
PobierzNajnowszyArtykul()));
$id = 1212;
var_dump(Strings::ConvertFromUTFToISO($client->PobierzArtykul($id)));
$artykuly = $client->Pobierz10Najnowszych();
for($i = 0; $i < count($artykuly); $i++) {
$artykuly[$i] = Strings::ConvertFromUTFToIso($artykuly[$i]);
}
var_dump($artykuly);
} catch (SoapFault $e) {
echo $e->getMessage();
// wyswietlmy zawartosc XML po ludzku
echo wordwrap(htmlentities($client->__getLastRequest()));
echo wordwrap(htmlentities($client->__getLastResponse()));
}
echo '</pre>';

Rysunek 5. Dodanie Web Reference do Listing 8. Tworzenie Thread t = new Thread()


projektu C# .NET
public void run() {
String url = "http://t:81/soap/article/ProsteOperacjeWS.php";
zywam “ProsteOperacjeSoapBinding”,
HttpTransport transport = new HttpTransport(url, "ProsteOperacje");
które przedstawia Listing 3. SoapObject request = new SoapObject(url, "PobierzArtykul");
Ostatnim elementem jest powiązanie request.addProperty("id", Integer.valueOf(idArtykulu.getString()));
wiązania o nazwie ProsteOperacjeSoap- try {
Binding z adresem pod którym będzie do- odpowiedz.setText("\n" + ((String)transport.call(request)));
} catch (IOException ex) {
stępna usługa. W elemencie <port> dla
ex.printStackTrace();
atrybutu binding przypisuję nazwę wiąza- }
nia z prefiksem impl:. }
};
<wsdl:service name="ProsteOperacjeService"> t.start();

<wsdl:port binding="impl:
ProsteOperacjeSoapBinding"
name="ProsteOperacje">
<wsdlsoap:address location=
"http://t:81/soap/article/
ProsteOperacjeWS.php"/>
</wsdl:port>
</wsdl:service>

Pełny WSDL jaki przed chwilką stworzyli-


śmy możemy zobaczyć na Listingu 4.

Pierwsza usługa Web


Service PHP5 – serwer
Jeśli mamy już WSDL, teraz pójdzie
nam już tylko z górki. Implementacja SO-
AP w PHP5 jest bardzo prosta w użyciu.
Jak pokazałem na Listingu 5, usługa jest
dostępna pod adresem: http://t:81/soap/
article/ProsteOperacjeWS.php (oczywiście
zmieniając serwer, port i lokację skryptu na-
leży pamiętać o modyfikacji WSDL – ele-
ment <address> i parametr location). Rysunek 6. Usługa sieciowa napisana w PHP5 wywołana z poziomu Java SE

56 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

Załóżmy, że mamy klasę Proste- readfile('ProsteOperacje.wsdl'); Jak widzimy, użyłem tu ponownie funk-
Operacje, taką jak pokazana na Listingu 4, die(); cji konwertującej. Wszystko, co jest wy-
którą chcemy udostępnić jako usługę sie- } syłane SOAP musi być w UTF-8, więk-
ciową. Normalnie, wszystkie artykuły po- szość stron polskojęzycznych używa jed-
winny być wyciągane z bazy danych, ale Teraz jeśli w przeglądarce podamy adres: nak kodowania ISO-8859-2, użyłem więc
my w przykładzie użyjemy danych wpro- http://t:81/soap/article/ProsteOperacjeWS. prostej funkcji konwertującej polskie zna-
wadzonych na sztywno. Listing 6 prezen- php?wsdl zobaczymy definicję WSDL na- ki diakrytyczne z UTF-8 do ISO.
tuje jak powinien wyglądać plik ProsteOpe- szej usługi tak, jak jest to pokazane na Ry- Jeśli spojrzymy na Listing 5, za-
racjeWS.php. W tym momencie, jeśli połą- sunku 3. uważymy, że SoapClient posiada rów-
czymy się z naszą usługą np. przez prze- nież drugi argument, który domyślnie jest
glądarkę WWW, dostaniemy komunikat, Pierwsza usługa Web NULL. Są to opcje, bardzo przydatne np.
że nie znaleziono danych POST (wiado- Service PHP5 – klient podczas testowania. Jeśli włączymy fla-
mości SOAP wrzucane są w ciało wiado- Aby przetestować naszą usługę, należy na- gę trace, będziemy mieli do dyspozycji
mości HTTP a zatem muszą używać meto- pisać klienta. Napisać klienta podobnie jak dwie metody:
dy POST) – zobacz Rysunek 2. Wiele silni- serwer jest bardzo prosto, a nawet prościej,
ków Web Services próbuje w momencie łą- bo nie musimy tworzyć żadnego WSDL. Aby $client->__getLastRequest();
czenia się do usługi pobrać WSDL automa- wykonać dowolną metodę zdalną w wersji $client->__getLastResponse();
tycznie. Przyjęło się, że WSDL powinien być minimalistycznej potrzebujemy 2 linii:
zwracany zawsze, jeśli QUERY_STRING jest które zwracają odpowiednio: ostatnie żą-
równy '?wsdl', zatem dopiszmy na samym $client = new SoapClient('http:// danie wysłane do serwera i ostatnią odpo-
początku pliku ProsteOperacjeWS.php: t:81/soap/article/ProsteOperacjeWS. wiedź. Jeśli włączymy flagę exceptions,
php?wsdl'); PHP5 będzie reagował na wyjątki, które zo-
if (0 == strcmp($_SERVER var_dump(Strings::ConvertFromUTFToISO stały wyrzucone na zdalnej maszynie, dlate-
['QUERY_STRING'], '?wsdl')) { ($client->PobierzNajnowszyArtykul()) go też na Listingu dodałem blok try/catch
header('Content-type: text/xml'); ); wokół wywołania metod na obiekcie $client.
Wynik naszego pierwszego zdalnego wywo-
Listing 9. Przykładowa usługa sieciowa napisana w C# łania przedstawiony jest na Rysunku 4.

namespace WebServiceTest Web Service PHP5 serwer


{
– klient w MS .NET
Mamy już działającą usługę sieciową. Na-
public class WebService : System.Web.Services.WebService {
[WebMethod] pisaliśmy do niej klienta w PHP5. To nic
public string getString(){ nadzwyczajnego. Połączmy się do niej z
return "Jestem łańcuchem"; innej platformy technologicznej.
} Dodanie usługi sieciowej jest dziecin-
[WebMethod]
nie proste. Będąc w oknie Solution, wy-
public double getDouble() { starczy prawym przyciskiem myszki klik-
return -123123.23123d; nąć na Project, następnie wybrać Add
}
[WebMethod]

public long getLong() {


return Int64.MaxValue;
}
[WebMethod]

public int getInt() {


return Int32.MaxValue;
}
[WebMethod]

public bool[] getBooleanArray() {


return new bool[] { true, false, false, true };
}
[WebMethod]

public object[] makeItArray(int i, double d, string s, bool b) {


Object[] o = new Object[] {i, d, s, b};
return o;
}
}
} Rysunek 7. Usługa sieciowa napisana w
PHP5 wywołana z poziomu Java Mobile

PHP Solutions Nr 2/2007 www.phpsolmag.org 57


Narzędzia SOAP w PHP5

Web Reference (Zobacz Rysunek 6) i po-


Listing 10. Klient PHP5 łączący się do usługi MS .NET dać adres definicji WSDL. U nas będzie
to: http://t:81/soap/article/ProsteOperacj
require_once ('Strings.inc.php');
$client = new SoapClient( eWS.php?wsdl. Wszystkie typy zdalne i
'http://localhost/WebServiceTest/WebService.asmx?wsdl', obiekty służące do połączeń są domyśl-
array('trace' => 1) nie wrzucane do przestrzeni nazw takiej,
); jak ma nasz projekt z rozszerzeniem na-
$functions = $client->__getFunctions();
zwy hosta z jakiego pochodzą. Czyli, wy-
echo '<pre>';
var_dump($functions); wołanie zdalne będziemy zapisywali tak
$string = $client->getString(); (mój testowy host to t od słówka test):
var_dump(Strings::ConvertFromUTFToISO($string->getStringResult));
$double = $client->getDouble(); t.ProsteOperacjeService proxy =
var_dump($double->getDoubleResult);
t.ProsteOperacjeService();
$int = $client->getInt();
var_dump($int->getIntResult); int id = 1212;
string artykul = proxy.PobierzArtykul(id);
// UWAGA!!
// MS Int64.MAX_VALUE Web Service PHP5
// jest w PHP jako float!
serwer – klient w Java SE
$long = $client->getLong(); Posłużę się tutaj środowiskiem NetBeans.
var_dump($long->getLongResult); Stwórzmy nowy projekt. Po utworzeniu klik-
$booleanArray = $client->getBooleanArray(); nijmy na nim prawym przyciskiem o okienku
var_dump($booleanArray->getBooleanArrayResult->boolean); Navigator i wybierzmy opcję: New -> Web
Service Client. Następnie podajemy adres
// nie zadziała!
//$response = $client->makeItArray(123, -123.0, "string", true); WSDL usługi i klikamy OK. Po kilku sekun-
dach będziemy mieli utworzone wszystkie
class MakeItArray { niezbędne pliki do połączeń z usługą. Mo-
public $i; żemy też skorzystać z narzędzia do testo-
public $d;
wania zdalnych wywołań, za pomcą klik-
public $s;
public $b; nięć w NB możemy wywołać dowolną meto-
public function __construct($i, $d, $s, $b) { dę z dowolnymi parametrami. Jeszcze tylko
$this->i = $i; jedna mała uwaga: kody źródłowe klas NB
$this->d = $d; generuje dość niestandardowo do katalogu
$this->s = $s;
bin. Należy je ręcznie skopiować do katalo-
$this->b = $b;
} gu src! Następnie, w obsłudze konkretnej
} akcji piszemy:
$response = $client->makeItArray(new MakeItArray(123, "-123.0", "string", true));
var_dump($response->makeItArrayResult->anyType); ProsteOperacjeService po =
echo '</pre>';
new ProsteOperacjeService_Impl();
this.wywolanaUsluga.setText((String)this.
listaUslug.getSelectedItem());
try {
this.wynikUslugi.setText
(po.getProsteOperacje().
pobierzNajnowszyArtykul());
} catch (RemoteException ex) {
ex.printStackTrace();
} catch (ServiceException ex) {
ex.printStackTrace();
}

Wynik działania graficznego klienta Java


SE możemy zaobserwować na Rysunku 7.

Web Service PHP5


serwer – klient w Java
Mobile
Aby połączyć się z usługą sieciową w
J2ME mamy do wyboru: natywny JSR
Rysunek 8. Klient PHP5 łączący się z usługą MS .NET, rezultat 175 (dość ograniczony, w dodatku ofe-

58 www.phpsolmag.org PHP Solutions Nr 2/2007


Narzędzia SOAP w PHP5

rujący tylko tryby DOCUMENT/literal)


Listing 11. Przykładowa usługa sieciowa napisana w Java'ie lub skorzystać z darmowych biblio-
tek typu kSOAP czy WingFoot. Ja uży-
public class WebServiceTest {
ję kSOAP.
public String getString() { Aby połączyć się z usługą należy
return "Jestem łańcuchem ąśź"; utworzyć obiekt HttpTransport podać
} adres URL do usługi (nie do WSDL,
kSOAP sam pobierze WSDL dodając
public double getDouble() {
return -123123.23123d; ?wsdl do adresu). Tworzymy żąda-
} nie jako SoapObject – drugim parame-
trem jest nazwa zdalnej metody. Je-
public long getLong() { śli metoda ma parametry dodajemy
return Long.MAX_VALUE;
je jako property. Służy do tego meto-
}
da addProperty – pierwszym argumen-
public int getInt() { tem jest nazwa parametru, drugim – je-
return Integer.MAX_VALUE; go wartość (jako obiekt, dlatego użyłem
} Integer, a nie int).
Samo łączenie się do usługi musi być
public boolean[] getBooleanArray() {
return new boolean[] { true, false, false, true }; wykonane w odrębnym wątku, inaczej
} emulator generuje ostrzeżenie o możli-
wym dead-locku podczas prawdziwych
public Object[] makeItArray(int i, double d, String s, boolean b) { połączeń z komórki, tworzę więc
Object[] o = new Object[] {new Integer(i), new Double(d), s,
new Boolean(b)
}; Thread t = new Thread() {. Przedstawia
to Listing 8.
return o;
} PHP5 jako klient
}
Jak zauważyliśmy Java, Java mobile czy
Listing 12. Klient PHP5 łączący się do usługi AXIS (Java)
.NET komunikuje się bez problemu z na-
require_once ('Strings.inc.php'); szym serwerem SOAP. Java pracuje na
Unicode, .NET zazwyczaj na WinCp1250,
$client = new SoapClient(
a jak zauważyliśmy, wszystkie znaki są
'http://localhost:8080/axis/WebServiceTest.jws?wsdl', array('trace' => 1)
);
poprawnie przedstawiane, nie ma także
problemów z przesyłaniem różnych ty-
$functions = $client->__getFunctions(); pów danych.
echo '<pre>'; Ale to tylko i wyłącznie dlatego,
var_dump($functions);
że to Java czy .NET biorą na siebie
// UWAGA!
wszystkie rzeczy związane z przekształ-
// AXIS zwraca odpowiedź w formacie: ceniem odpowiedzi na swoją wewnętrz-
// Jestem &#x139;&#x201A;a&#x139;&#x201E;cuchem ną reprezentację.
// &#xC4;&#x2026;&#x139;&#x203A;&#x139;&#x15F; Co będzie, jeśli to my z poziomu
// jest ona błędna - polskie znaki nie są kodowane w UTF-8
PHP5 będziemy wołali metody z .NET
// tylko zamieniane na encje, stąd problem ponieważ PHP
// próbuje najpierw rozkodować UTF-8
czy z Jakarta AXIS?

var_dump($client->getString()); Web Service PHP5 klient


var_dump($client->getDouble());
var_dump($client->getInt());
– serwer MS. NET
Stwórzmy testową usługę sieciową napi-
// UWAGA!!
saną w C#. Jej kod przedstawiony jest na
// Java Long.MAX_VALUE Listingu 9. Dla skrócenia listingu, usuną-
// jest w PHP jako float! łem automatycznie wygenerowane meto-
dy typu: InitializeComponent, oraz usu-
var_dump($client->getLong());
nąłem dyrektywy using.
var_dump($client->getBooleanArray());
Widzimy, że mamy zdefiniowane ope-
// działa bez problemu! racje, które mają nam zwrócić różne ty-
// nie trzeba niczego pakować w obiekty py danych, począwszy od int, double,
string po tablice typów prostych a skoń-
var_dump($client->makeItArray(123, -123.0, "string", true));
czywszy na tablicach obiektów. (w .NET
echo '</pre>';
int, double, string czy bool są równoznacz-
ne z obiektami).

60 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

Bardzo pożyteczną funkcją, z ja-


kiej skorzystamy, jest __getFunctions, Listing 13. Definicja WSDL typów złożonych: autor, ksiazka oraz tablica książek
która jest wywoływana na obiekcie
<wsdl:types>
SoapClient, a która zwraca nam sygna- <schema targetNamespace="http://t:81/soap/article/ComplexTypeWS.php"
tury zdalnych metod. Z nich dowiemy się xmlns="http://www.w3.org/2001/XMLSchema">
np. że MS .NET opakowuje wszystkie <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
wiadomości zarówno input jak i output. <xsd:complexType name="autor">
<xsd:all>
I tak np. $client->getString() zwraca
<xsd:element name="nazwisko" type="xsd:string"/>
nam obiekt, w którym znajduje się pole <xsd:element name="ksiazki" type="impl:ArrayOf_impl_ksiazka"/>
getStringResult. Aby wywołać metody </xsd:all>
z parametrami, musimy utworzyć obiekt, </xsd:complexType>
którego nazwy pól są takie same jak na- <xsd:complexType name="ksiazka">
<xsd:all>
zwy parametrów usługi MS .NET. Listing
<xsd:element name="tytul" type="xsd:string"/>
7 wyjaśni wszelkie wątpliwości, a Rysu- <xsd:element name="isbn" type="xsd:int"/>
nek 8 potwierdzi poprawne działanie na- </xsd:all>
szego kodu. </xsd:complexType>
<complexType name="ArrayOf_impl_ksiazka">

Klient Web Service <complexContent>


<restriction base="soapenc:Array">
PHP5 – Serwer Jakarta <attribute ref="soapenc:arrayType" wsdl:arrayType="impl:
AXIS (Java) ksiazka[]"/>
Stwórzmy teraz analogiczny kod usłu- </restriction>
gi sieciowej AXIS. Jest on pokazany na </complexContent>
</complexType>
Listingu 11. Usługi sieciowe JWS to nor-
</schema>
malne kody źródłowe Java'y z rozsze- </wsdl:types>
rzeniem nie java, a właśnie jws, które
kopiujemy (tak, tylko kopiujemy!) bez- Listing 14. Definicja WSDL typów złożonych: autor, ksiazka oraz tablica książek
pośrednio do $CATALINA_HOME/web
if (0 == strcmp($_SERVER['QUERY_STRING'], '?wsdl')) {
apps/axis/. header('Content-type: text/xml');
Znów skorzystamy z funkcji __get- readfile('ComplexType.wsdl');
Functions, która zwróci nam sygnatu- die();
ry zdalnych metod. Z nich dowiemy się }
class Autor {
np. że Jakarta AXIS w przeciwieństwie
private $ksiazki = array();
do MS .NET nie opakowuje wszystkich function __construct($nazwisko) {
wiadomości. Możemy z nich korzystać $this->nazwisko = $nazwisko;
wprost tak, jakby były lokalnie wywoły- }
wanymi funkcjami. Ale zauważymy, że function dodajKsiazke(Ksiazka $ksiazka) {
$this->ksiazki[] = $ksiazka;
coś jest nie tak. Polskie kodowanie! Tak,
}
jeśli podejrzymy koperty SOAP wymie- }
niane z usługą AXIS okaże się, że pol- class Ksiazka {
skie znaki nie są kodowane w UTF-8, private $tytul;
tylko są zamieniane na kody znaków ty- private $isbn;
function __construct($tytul, $isbn) {
pu &#1111;. Jest to niewątpliwie błąd
$this->tytul = $tytul;
AXISa, można oczywiście z tego wybrnąć $this->isbn = $isbn;
na co najmniej kilka sposobów, ale nale- }
ży o tym pamiętać pisząc własny system }
– AXIS nie spełnia standardu! Listing 12 // klasa usługi sieciowej
class ComplexType {
pokazuje jak wywoływać usługi sieciowe
function PobierzAutora($id) {
Java'y w PHP5, a Rysunek 9 potwierdzi // załóżmy, że szukamy w bazie autora o id = $id i znaleźliśmy
poprawne działanie naszego kodu. $autor = new Autor('Budnik');
$autor->dodajKsiazke(new Ksiazka('PHP vs .NET vs Java vs J2ME', 1212));
Typy złożone i mapowania $autor->dodajKsiazke(new Ksiazka('PHP LIZ DB', 1313));
return $autor;
Nie jest sztuką przesłać obiekt ty-
}
pu string czy int, sztuką jest przesłanie }
obiektu PHP do np. MS .NET czy do Ja- // mapowanie klas! TypZłożonyWSDL => NazwaKlasyPHP
va'y. Załóżmy, że mamy usługę siecio- $classmap = array('autor' => 'Autor', 'ksiazka' => 'Ksiazka');
wą z metodą, która zwraca klasę Autor, $server = new SoapServer("ComplexType.wsdl");
$server->setClass("ComplexType");
z polami nazwisko – typu string oraz po-
$server->handle();
lem ksiazki, które jest tablicą obiektów
Ksiazka. W WSDL będziemy musieli zde-

PHP Solutions Nr 2/2007 www.phpsolmag.org 61


Narzędzia SOAP w PHP5

finiować trzy typy złożone: autor, książka


Listing 15. Kod klasy C# Ksiazka, z publicznymi property i metodą konwertującą oraz tablicę książek. WSDL przedstawio-
obiekty
ny jest na Listingu 13.
class Ksiazka { Klasa PHP implementująca np. typy
private xh.ksiazka ksiazka; autor czy ksiazka, wcale nie musi mieć
public string Tytul { publicznych pól. Mogą one być ukryte
get { we wnętrzu jako pola private. Wystar-
return ksiazka.tytul;
czy, że jest pewien mechanizm za po-
}
} mocą, którego możemy te pola ustawić.
public int ISBN { W naszym prostym przykładzie posta-
get { nowiłem przypisywać pola w konstrukto-
return ksiazka.isbn; rach. Spójrzmy na implementację i kod
}
usługi sieciowej zamieszczonej na Li-
}
public Ksiazka(xh.ksiazka ksiazka) { stingu 14.
this.ksiazka = ksiazka; Połączmy się z nią w MS .NET. Plat-
} forma Microsoft wykonuje mapowanie
public static Ksiazka[] Convert(xh.ksiazka[] ksiazki) { praktycznie za nas, ja napisałem dodat-
Ksiazka[] dotNetKsiazki = new Ksiazka[ksiazki.Length];
kowo klasę Ksiazka ze statyczną meto-
for (int i = 0; i < ksiazki.Length; i++) {
dotNetKsiazki[i] = new Ksiazka(ksiazki[i]); dą Convert. Aby móc dodać do Data-
} Source tablice klas, klasy muszą mieć
return dotNetKsiazki; stworzone publiczne property, które au-
} tomatycznie będą mapowane na kolum-
}
ny. Kod łączenia się z usługą wygląda
Listing 16. Wgranie usługi na serwer z obsługą SSL i zmienienie w WSDL ele- jak poniżej, kod klasy Książka zamiesz-
mentu <address> atrybutu location czony jest na Listingu 15, a wynik dzia-
łania z kolei na Rysunku nr 10.
<wsdl:service name="ProsteOperacjeService">
<wsdl:port binding="impl:ProsteOperacjeSoapBinding" name="ProsteOperacje">
t.ComplexTypeService proxy =
<wsdlsoap:address location="https://ers:4433/soap/article/
ProsteOperacjeWSSecExt.php"/> new t.ComplexTypeService();
</wsdl:port> t.autor autor = proxy.PobierzAutora
</wsdl:service> (Int32.Parse(this.idAutora.Text));
nazwiskoAutora.Text = autor.nazwisko;
Listing 17. Szkielet nowej klasy serwera
ksiazkiDataGrid.DataSource = Ksiazka.
class SecExtSoapServer extends SoapServer { Convert(autor.ksiazki);
public function __construct($wsdl) {
parent::__construct($wsdl); Implementujemy SOAP
}
public function handle($rawData) {
Security Enhancements
// sprawdź dane użytkownika plus HTTPS – serwer
$this->CheckCredentials($dom); Implementacja SOAP w PHP5 zawie-
// zapisz zmodyfikowane żądanie i prześlij do klasy rodzica ra jedynie podstawowe operacje. Jeśli
parent::handle($dom->saveXML()); chcemy skorzystać z jakiegoś rozsze-
}
rzenia musimy sami je zaimplemento-
private function CheckCredentials(&$dom) { wać. Spróbujemy teraz udostępnić na-
// tu napiszemy własną obsługę WS-SE szą usługę w sposób w pełni bezpiecz-
} ny – z uwierzytelnianiem oraz z przesy-
} łaniem żądań i odpowiedzi po szyfrowa-
nych łączach. Najprostsze jest oczywi-
Listing 18. Częściowy kod serwera
ście udostępnienie naszej usługi przez
$nodes = $dom->getElementsByTagNameNS ('http://docs.oasis-open.org/wss/ HTTPS, wymaga to jedynie wgrania na-
2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd', 'UsernameToken'); szej usługi na serwer z obsługą SSL i
if ($nodes->length == 0) { zmienienie w WSDL elementu <address>
$valid = false;
atrybutu location tak, jak przedstawia
} else {
// użytkownik jest tu: to Listing 16.
$nodes->item(0)->firstChild->textContent; Stwórzmy zatem na naszą nową klasę
// hasło tu: serwera, szkielet będzie wyglądał tak, jak
$nodes->item(0)->firstChild->nextSibling->textContent; na Listingu 17.
$valid = true;
Widzimy w nim, że rozszerzamy podsta-
}
wową klasę SoapServer, nadpisujemy tylko
metodę handle, w której z $rawData wczy-

62 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

Listing 19. Kod serwera SOAP wspierającego WS Security Enhancements

if (0 == strcmp($_SERVER['QUERY_STRING'], 'wsdl')) { } else {


header('Content-type: text/xml'); // użytkownik jest tu:
readfile('ProsteOperacjeSecExt.wsdl'); $nodes->item(0)->firstChild->textContent;
die(); // hasło tu:
} $nodes->item(0)->firstChild->nextSibling
->textContent;
class SecExtSoapServer extends SoapServer {
public function __construct($wsdl) { // załóżmy, że tu połączymy się z bazą i to sprawdzimy
parent::__construct($wsdl); $valid = true;
} }

public function handle($rawData) { // wyrzuć zdalny wyjątek jeśli jest błąd


if (false == $valid) {
if (true == empty($rawData)) { $this->fault('SOAP-ENV:Client', 'Invalid credentials');
$this->fault('SOAP-ENV:Server', }
'Bad Request. Can\'t find HTTP_RAW_POST_DATA');
} // teraz muszę usunąć nagłówki, które już przetworzyłem
$dom = new DOMDocument('1.0'); // domyślna implementacja PHP5 SOAP nie obsłuży nam
try { // WS Security, a element Security ma podany atrybut
// ładuję dokument danymi z POST // mustUnderstand="1" wtedy przesłane do parent::handle
$dom->loadXML($rawData); // wyrzuci wyjątek, że nie zrozumiał
} catch (DOMException $e) { $header = $dom->getElementsByTagNameNS (
$this->fault('SOAP-ENV:Client', 'Bad Request.'); 'http://schemas.xmlsoap.org/soap/envelope/',
} 'Header')->item(0);
// weryfikuję dane użytkowników
$this->CheckCredentials($dom); // cały węzeł Security
// zapisz zmodyfikowane żądanie i $security = $dom->
// prześlij do klasy rodzica getElementsByTagNameNS ( 'http://docs.oasis-open.org/
parent::handle($dom->saveXML()); wss/2004/01/oasis-200401-wss-wssecurity-secext-
} 1.0.xsd', 'Security')->item(0);
$header->removeChild($security);
private function CheckCredentials(&$dom) { }
$valid = true; }
$nodes = $dom->getElements ByTagNameNS(
'http://docs.oasis-open.org/wss/2004/01/ require_once ('Strings.inc.php');
oasis-200401-wss-wssecurity-secext-1.0.xsd', require_once ('ProsteOperacje .inc.php');
'UsernameToken' $server = new SecExtSoapServer ('ProsteOperacjeSecExt.wsdl');
); $server->setClass('ProsteOperacje');
if ($nodes->length == 0) { // trzeba jawnie podać: $HTTP_RAW_POST_DATA
$valid = false; $server->handle($HTTP_RAW_POST_DATA);v

R E K L A M A
Narzędzia SOAP w PHP5

Listing 20. Łączenie z usługą Listing 21. Szkielet klienta przy zastosowaniu metody
AddWSSEHeader
ers.ProsteOperacjeServiceWse proxy=
new ers.ProsteOperacjeServiceWse(); class ExtendedSoapClient extends SoapClient {

string pw = "I love Jessica Simpson"; function __construct($wsdl, $options = null) {


parent::__construct($wsdl, $options);
proxy.RequestSoapContext.Security.Tokens.Add ( }
new UsernameToken(
"xh", pw, PasswordOption.SendPlainText function __doRequest($request, $location, $action,
) $version) {
); $this->AddWSSEHeader($dom);
// doRequest do rodzica
try {
textBox1.Text = proxy.PobierzNajnowszyArtykul(); return parent::__doRequest (
} $request, $location, $action, $version);
}
catch (Exception ex)
{ public function SetUsername($username) { }
System.Console.WriteLine( public function SetPassword($password) { }
"Wyjątek: " + ex.GetType() + "\n" + ex.Message private function AddWSSEHeader($domDocument) {
+ "\n" +ex.StackTrace // tutaj wygenerujemy nagłówek
); }
}
}

tamy dokument DOM XML (nie ma tego niej, za pomocą API DOM XML, pobrać od- stępnie do katalogu Web References i po-
w powyższym szkielecie, nie ma także po- powiednie wartości. Praktyczna uwaga: dla prawmy MS, dopisując do każdego http://
kazanej weryfikacji, czy dane POST wpro- hasła należy sprawdzić jeszcze atrybut Ty- kluczowe 's' czyli https://. Używam testowe-
wadzone nie są puste, czy żądanie jest po- pe, aby dowiedzieć się, czy hasło jet skró- go certyfikatu serwera, który sam stworzy-
prawnym dokumentem XML), przekażemy tem SHA1 czy PlainText. Sam kod jest pro- łem, muszę więc przekonać MS, że jest on
później przez referencję dokument do meto- sty i przedstawia go Listing 18. Pełny kod wartościowy (inaczej nie będę mógł się po-
dy prywatnej CheckCredentials. W tej meto- serwera umieściłem na Listingu 19. łączyć z serwerem SOAP): najprościej jest
dzie pobierzemy elementy <Username> oraz Aby mieć pewność, że poprawnie zaim- otworzyć w IE stronę: https://ers:4433/soap/
<Password> elementu <UsernameToken> we- plementowaliśmy to rozszerzenie, stwórz- article/ProsteOperacjeWSSecExt.php?wsdl
wnątrz <Security> w nagłówku koperty. Ko- my projekt np. w MS .NET. W przypadku lub dowolną z serwera ers:4433 i po prostu
perta ta została przedstawiona na Rysunku VS 2003 musimy mieć doinstalowany pakiet zainstalować certyfikat. Po zainstalowaniu i
1. Samo pobranie użytkownika i jego hasła WS Security Enhancements 2.0 w wersji dla włączeniu WS SE 2.0, po wygenerowaniu
jest sprawą banalną, wystarczy wyszukać developerów. Dodajemy Web Reference referencji do usługi sieciowej będziemy mie-
element Username z przestrzeni nazw http: jak poprzednio, podajemy adres do WSDL li do dyspozycji dwa obiekty służące do wy-
//docs.oasis-open.org/wss/2004/01/oasis- czyli: https://ers:4433/soap/article/ProsteOp woływania zdalnych usług. Pierwszy z nich
200401-wss-wssecurity-secext-1.0.xsd, póź- eracjeWSSecExt.php?wsdl, przejdźmy na- o nazwie usługi z końcówką 'Service', jak
dotychczas, oraz drugi obiekt – z końców-
ką 'ServiceWse', który posiada dodatkowe,
rozszerzające bezpieczeństwo, metody. To
wszystko. Możemy już bez problemu połą-
czyć się z naszą usługą pisząc to co prezen-
tuje Listing 20. Efekt pokazany jest na Ry-
sunku 11.

Implementujemy SOAP
Security Enhancements
plus HTTPS – klient
Napisanie klienta w PHP5 łączącego się z
naszą usługą jest proste. Musimy udostęp-
nić publiczne metody, służące do ustawienia
użytkownika i jego hasła, następnie musi-
my nadpisać metodę __doRequest i napisać
własną prywatną metodę AddWSSEHeader,
która będzie generowała odpowiednie na-
Rysunek 11. Klient MS .NET łączący się po HTTPS do naszej usługi WS Security główki WS SE. Szkielet klienta wygląda tak
Enhancements jak na Listingu 21. Pełny kod klienta umie-

64 www.phpsolmag.org PHP Solutions Nr 2/2007


SOAP w PHP5 Narzędzia

Listing 22. Kod klienta SOAP wspierającego WS Security Enhancements i łączącego się z usługą po HTTPS
class ExtendedSoapClient extends SoapClient { envelope/', 'Body');
private $Username; $body = $body->item(0);
private $Password; $header = $soapEnvelope->
function __construct($wsdl, $options = null) { insertBefore($header, $body);
parent::__construct($wsdl, $options); }
} else {
function __doRequest $header = $nodes->item(0);
($request, $location, $action, $version) { }
$dom = new DOMDocument('1.0'); // tworzę właściwy element Security
try { $security = $domDocument->createElementNS
$dom->loadXML($request); ('http://docs.oasis-open.org/wss/2004/01/
} catch (DOMException $e) { oasis-200401-wss-wssecurity-
die('Dokument nie jest prawidłowy: secext-1.0.xsd', 'wsse:Security');
' . $e->code); // w nim element UsernameToken
} $usernameToken = $domDocument->createElementNS('http://
// dodaję nagłowek WSSE Security Header docs.oasis-open.org/wss/2004/01/oasis-200401-
$this->AddWSSEHeader($dom); wss-wssecurity-secext-1.0.xsd', 'UsernameToken');
// musimy recznie dodac https, bo inaczej nici... // w nim Username
// PHP tez sobie do konca nie radzi z HTTPS $username = $domDocument->createElementNS
$location = 'https://vega.eti.pg.gda.pl/~xh/soap_ssl/ ('http://docs.oasis-open.org/wss/2004/01/
ProsteOperacjeWSSecExt.php'; oasis-200401-wss-wssecurity-secext-1.0.xsd',
// doRequest do klasy nadrzędnej SoapClient 'Username');
return parent::__doRequest($dom->saveXML(), $usernameText = $domDocument->createTextNode
$location, $action, $version); ($this->Username);
} // załóżmy, że Password zawsze będzie PlainText
public function SetUsername ($username) { $password = $domDocument->createElementNS
$this->Username = $username; ('http://docs.oasis-open.org/wss/2004/01/
} oasis-200401-wss-wssecurity-secext-1.0.xsd',
public function SetPassword ($password) { 'Password');
$this->Password = $password; $passwordText = $domDocument->
} createTextNode($this->Password);
private function AddWSSEHeader ($domDocument) { $type = $domDocument->createAttribute('Type');
$soapEnvelope = $domDocument-> $type->value = 'http://docs.oasis-open.org/wss/2004/01/
documentElement; oasis-200401-wss-username-token-profile-
// pobieram nagłówek 1.0#PasswordText';
$nodes = $domDocument->getElementsByTagNameNS // podpinam wszystkie elementy do dokumentu żądania
('http://schemas.xmlsoap.org/ $username->appendChild($usernameText);
soap/envelope/', 'Header'); $password->appendChild($type);
// jeśli go nie ma muszę go stworzyć $password->appendChild($passwordText);
if ($nodes->length == 0) { $usernameToken->appendChild($username);
$header = $domDocument-> $usernameToken->appendChild($password);
createElementNS $security->appendChild($usernameToken);
('http://schemas.xmlsoap.org/ $header->appendChild($security);
soap/envelope/', 'Header'); }
$body = $domDocument->
getElementsByTagNameNS ('http://schemas.xmlsoap.org/soap/ }

ściłem na Listingu 22. Aby jednak wywołać 'https://ers:4433/soap/article/ cej, możemy korzystać z różnych rozsze-
taką zdalną zabezpieczoną usługę, musi- ProsteOperacjeWSSecExt.php?wsdl', rzeń standardu WS Security Enhance-
my stworzyć odpowiedni certyfikat. Konia z array('trace' => 1, 'exceptions' ments, które możemy z łatwością w kilka
rzędem temu, kto wyczyta w dokumentacji => 1, 'local_cert' => 'cert.pem' chwil zaimplementować. n
PHP5, jak to zrobić. Certyfikat, jaki jest po- )
trzebny, aby móc łączyć się po HTTPS do );
usług sieciowych to połączenie klucza pry- $artykuly = $client->
watnego i certyfikatu w jednym! Wystarczy Pobierz10Najnowszych();
O autorze
połączyć oba te pliki w jeden i zapisać jako Łukasz Budnik jest studentem V ro-
np. cert.pem Wywołanie takiej metody jest Podsumowanie ku Informatyki na Politechnice Gdańskiej,
uczestniczy w projektach nad rozwijaniem
już banalne, sprowadza się jedynie to 3 lo- Nauczyliśmy się dziś, jak współpracować
systemów zbierania i analizy danych w po-
gicznych linii: z innymi platformami technologicznymi. staci XML, jest rówież administratorem
Teraz śmiało możemy współtworzyć sys- serwisu www.komputery-internet.net.
require_once ( temy rozproszone na bazie Web Servi-
Kontakt:
'ExtendedSoapClient.inc.php'); ces komunikujących się z takimi giganta-
lukasz.budnik@komputery-internet.net
$client = new ExtendedSoapClient( mi jak MS .NET, J2EE, Java Mobile. Wię-

PHP Solutions Nr 2/2007 www.phpsolmag.org 65


Kasa dla
Webmastera

Jak zarobić na stronie www?


Poradnik dla przedsiębiorczych
webmasterów
Stopień trudności: lll
Paweł Grzesiak

Istnieje wiele źródeł, z których właściciel strony


może czerpać zyski. W artykule przyglądamy się
dostępnym metodom zarobkowania, zwracając
szczególną uwagę na opłacalność każdej z nich.

P
rzez kilka ostatnich lat zaszło w które oferują przede wszystkim intere-
sieci wiele pozytywnych zmian. sujące treści lub usługi internetowe. Fi-
Nie boimy się już płacić za to- nansowe możliwości wielu tych serwi-
W SIECI wary i usługi. Coraz chętniej korzysta- sów zmieniły się odkąd użytkownicy są
my więc ze sklepów internetowych. Ich bardziej skorzy do płacenia za warto-
korzyści odkrywa coraz więcej osób, nie ściową treść. W polskiej sieci trend pła-
• Ad.net, http://www.adnet.pl/ tylko dlatego, że są szybszą metodą na cenia za korzystanie ze stron interne-
• AdClick, http://www.adclick.pl/
• ARBOmedia,
zakupienie dokładnie tego, co potrzebu- towych stał się masowy i nieunikniony.
http://www.arbomedia.pl/ jemy. Zakupy w sieci są także tańszą al- Wszystko to za sprawą fatalnej kondy-
• IDMnet, http://www.idmnet.pl/
ternatywą pozyskiwania dóbr, bo kosz- cji rynku reklamowego nastawionego ra-
• phpAdsNew,
http://www.phpadsnew.com/ ty prowadzenia sprzedaży przez Inter- czej na duże przedsięwzięcia, typu por-
• phpPgAds, net są znacząco niższe. Niewątpliwie, tale, niż pojedyncze serwisy. W dodatku
http://www.phppgads.com/
• http://www.google.pl/adsense/ istotny wpływ na popularność płacenia portale prowadzą sprzedaż reklam sa-
• OnetKontekst, http:// przez internet miały serwisy aukcyjne. modzielnie, stąd brak tu prowizji należ-
kontekst.onet.pl/
• Adkontekst, http://adkontekst.wp.pl/
Zaufanie, jakim darzymy najpopularniej- nych sieciom reklamowym. Choć i we-
• AdPortal, http://www.adportal.pl/ szy serwis aukcyjny, Allegro.pl świadczy wnętrzna sprzedaż reklam przez portale
• AllPay.pl, http://www.allpay.pl/
dobitnie o ogromnym postępie, jaki do- to tylko kropla w morzu ich potrzeb. Ta
• CashBill, http://www.cashbill.pl/
• Ebill.pl, http://www.ebill.pl/ konał się w świadomości użytkowników forma aktywności może być jedynie do-
• Wapacz, http://www.wapacz.pl/ sieci. Omawiane zjawisko, niczym na- datkiem w ogólnym rozrachunku rodzi-
• Wapster.pl, http://www.wapster.pl/
mobilepay/ czynia połączone odbija się na byt wła- mych portali. Zarabia się w najróżniej-
• AllPay.pl, http://www.allpay.pl/ ścicieli wszelkiego rodzaju serwisów in- szy sposób, np. wprowadzając opłaty
• Platnosci.pl, http://www.platnosci.pl/
• Przelewy24.pl, http://
ternetowych. Mowa tu oczywiście o ser- za szybszą indeksację witryny w porta-
www.przelewy24.pl/ wisach nie nastawionych bezpośred- lowym katalogu, czy wyszukiwarce. Są
nio na sprzedaż towarów, czyli o takich, to usługi mocno wątpliwe, bo ideą po-

66 www.phpsolmag.org PHP Solutions Nr 2/2007


Kasa dla
Zarabianie
Webmastera

wstania katalogu stron www, czy wyszu- nowego. Użytkownik płaci za rekla- • Partner – firma (rzadko osoba fi-
kiwarki jest rzetelne i równorzędne trak- mę pośrednio, ponieważ koszt rekla- zyczna) dysponująca serwisem
towanie wszystkich stron www. my zawarty jest w cenie towaru lub lub serwisami internetowymi o
W ciągu ostatniego roku stał się bar- usługi. określonej powierzchni reklamo-
dzo zauważalny rozwój reklamy kontek- wej. Partner przyłącza się do sieci
stowej, która nie dość, że nie jest na- Sieci reklamowe reklamowej podpisując stosowną
chalna, to jeszcze okazuje się klikalna. W myśl zasady „reklama dźwignią han- umowę na wyłączność. Sieć rekla-
Dzieje się tak nie z nieudanej próby za- dlu” powstały pierwsze sieci reklamo- mowa zapewnia partnerowi pro-
mknięcia reklamy, a z faktycznej warto- we. Najstarsza polska sieć, IDMnet za- cent od dochodów uzyskanych w
ści przekazu reklamowego. wiązała się już w 1997 roku. Podstawo- wyniku realizacji kampanii na jego
Wszystkie do tej pory omówione wym zadaniem sieci reklamowej jest po- stronach. Partnerowi może przy-
czynniki rodzą sobą pytanie: czy nasta- średnictwo w sprzedaży powierzchni re- sługiwać tzw. gwarancja – o ne-
ły dobre czasy dla tych, którzy utrzymu- klamowej należącej do partnerów sieci gocjowanej wartości. Gwarancją
ją się z prowadzenia serwisów w sieci? oraz obsługa w ten sposób powstałych określamy minimalną miesięcz-
Spróbujmy odpowiedzieć na to pytanie kampanii. ną kwotę, którą partner otrzymuje
podsumowując możliwości zarobkowe Możemy zatem wyróżnić trzy strony biorą- bez względu na wyniki sprzedaży
właściciela strony www. ce udział w transakcjach: w danym okresie rozliczeniowym,
Pierwszym podziałem, który rysu- • Sieć reklamowa – odpowiada za
je się, gdy mowa o płatnościach jest fi- • Reklamodawca – dom mediowy, fir- pozyskiwanie klientów oraz ich ob-
zyczne źródło dochodu. Wyróżniamy ma, agencja reklamowa dysponują- sługę. Sieć realizuje kampanie re-
więc metody, które: ca określonym budżetem na reali- klamowe, kierując je do serwisów
zację kampanii marketingowej wła- wybranych partnerów w oparciu o
• Pozyskują środki bezpośrednio od snego produktu. Część środków ich oglądalność oraz tematykę. To
użytkownika. By skorzystać z usłu- kierowana jest do realizacji w sie- sieć reklamowa najczęściej decy-
gi, użytkownik musi dokonać płat- ci. W ten sposób w/w zleca realiza- duje o tym, komu przydzielić da-
ności na stronie www. Jego rachu- cję kampanii sieci reklamowej. Na ną kampanię, a komu nie. Jest to
nek telefoniczny lub bankowy ob- podstawie grupy docelowej, sta- jak najbardziej stronnicza decy-
ciążany jest należną kwotą, nowiącej przedmiot zainteresowa- zja, stąd partner nie ma wpływu na
• Pozyskują środki od reklamodaw- nia reklamodawcy, dobierani są ci ilość realizowanych u niego kam-
ców, czy pośrednio od użytkownika. partnerzy sieci reklamowej, którzy panii. Sieć reklamowa dostarcza
Reklamodawca zainteresowany pro- spełniają założenia. Reklama trafia tzw. technologię adserverową, czy-
mowaniem swoich towarów i usług do internautów, którzy mogliby być li oprogramowanie zdolne do rota-
decyduje się na uiszczenie opłaty najbardziej zainteresowani przeka- cji reklamami oraz zbierania i ana-
na podstawie ustalonego modelu ce- zem danej kampanii, lizy wyników kampanii. Dostarcza,
zarówno dla partnera, jak i dla re-
klamodawcy, odpowiednie panele
administracyjne przydatne w śle-
dzeniu postępów kampanii.

Pomimo obiecujących zapewnień sieci


reklamowych, rzeczywistość pokazuje,
iż uzyskanie wystarczających do prowa-
dzenia serwisu dochodów z tytułu reali-
zacji kampanii jest zadaniem trudnym.
Polski rynek reklamy jest podzielony po-
między największych na rynku graczy i
to pomiędzy nimi rozgrywa się dzielenie
reklamowego tortu. Trudno więc liczyć
na dochody bez osiągania bardzo du-
żej oglądalności idącej minimum w set-
kach tysięcy unikalnych użytkowników
miesięcznie.
Należy również pamiętać o wysokich
prowizjach naliczanych przez sieci rekla-
mowe, które obniżają znacznie zarobek
partnera od kosztu reklamy, jaką przezna-
Rysunek 1. Ad.net to największa sieć reklamowa w Polsce czył na nią reklamodawca.

PHP Solutions Nr 2/2007 www.phpsolmag.org 67


Kasa dla Webmastera Zarabianie

instalacji i końcowego wdrożenia. Przy-


kładem takiej aplikacji jest phpAdsNew,
gdzie od serwera wymagana jest obsłu-
ga PHP i MySQL. Istnieje także alterna-
tywa w postaci phpPgAds przygotowa-
na do obsługi wraz z bazą danych Post-
greSQL.

Płatne odnośniki
Pewnym pomysłem ułatwiającym pozy-
skiwanie klientów jest stworzenie usłu-
gi sprzedaży płatnych linków. Pole-
ga ona na wyświetlaniu listy odnośni-
ków reklamowych w określonych miej-
scach, np. na stronie głównej serwisu.
Treść reklam tekstowych (odnośników)
reklamodawcy ustalają samodzielnie,
bezpośrednio na odpowiedniej stronie
serwisu. Po uzupełnieniu formularza z
propozycją treści płatnego odnośnika,
dokonują oni płatności przy użyciu jed-
Rysunek 2. phpAdsNew to bezpłatne oprogramowanie do obsługi kampanii rekla- nej z dostępnych metod (mikropłatno-
mowych ści sms, płatność bankowa – przelew
z..., kartą kredytową).
Sieci reklamowe to nie tylko wyświe- Ustalanie cen na usługi w zakresie
tlenie różnego rodzaju i formatu reklam sprzedaży powierzchni reklamowej jest Reklama kontekstowa
na stronach www. To także realizacja zadaniem niezmiernie trudnym. Należy Głównym zarzutem wobec reklamy
kampanii opartych o mailing, czyli wy- pamiętać, że nie tylko zbyt wysokie, lecz bannerowej jest jej mała skuteczność.
syłkę internetowych przesyłek poczto- także i zbyt niskie ceny mogą odstraszyć Przy użyciu coraz większej siły raże-
wych o treści reklamowej do dużej gru- reklamodawcę. nia (coraz większe reklamy, w dodatku
py odbiorców. Stworzenie rozległej listy Problem technologii służącej do ob- w postaci filmów wyświetlanych na peł-
osób zainteresowanych treściami po- sługi tej formy reklamy jest łatwy do roz- ny ekran) sieci reklamowe starają się
chodzącymi z danego serwisu owocu- wiązania. Wystarczy skorzystać z jednej możliwe zwiększyć zasięg i skutecz-
je możliwością zaoferowania sieci rekla- z bezpłatnych aplikacji. Oprogramowa- ność reklamy. Z marnym skutkiem.
mowej tego typu usługi. W przypadku, nie na otwartym źródle, służące do rota- Reklama kontekstowa powsta-
gdy znajdzie się reklamodawca skłonny cji bannerów, jest nieskomplikowane do ła, by odmienić los rynku reklamowe-
zrealizować kampanię mailingową, mo-
żemy liczyć na jednorazowe zwiększe-
nie dochodu.

Sprzedaż reklam
na własną rękę
Alternatywą dla włączenia w szeregi jed-
nej z sieci reklamowych, jest sprzedaż
reklam na własną rękę. O ile wydaje się
to sensowne z ekonomicznego punktu
widzenia, to realizacja w praktyce jest
zadaniem wymagającym bardzo dużego
wysiłku. Z pewnością na reklamę sprze-
dawaną na własną rękę nie zdecydu-
ją się duże agencje, czy domy medio-
we. Możemy zatem liczyć wyłącznie na
mniejsze firmy, które z braku wystarcza-
jącego budżetu skupiają w niskobudże-
towych kampaniach. Tego typu klient naj-
częściej jednak trudno podejmuje decy-
zje i nie jest przekonany do reklamy in-
ternetowej. Ta w dodatku, jak wiadomo,
nie należy do najefektywniejszych. Rysunek 3. Reklama kontekstowa w wynikach wyszukiwania to dziś żadne novum

68 www.phpsolmag.org PHP Solutions Nr 2/2007


Zarabianie Kasa dla Webmastera

stowa nie zainteresuje odwiedzających


dany serwis, będzie skutkowało to bra-
kiem kliknięć, a co za tym idzie mar-
nym przychodem. Dlatego też niektóre
branże, gdzie reklam jest znacznie wię-
cej, mogą poszczycić się znacznie lep-
szymi wynikami. Słyszy się wiele gło-
sów na temat możliwości zwiększania
własnego zysku z AdSense. Problem
polega jak zwykle na poprawnej opty-
malizacji kodu źródłowego strony, tak,
by Google przyznawało lepsze, tzn.
droższe reklamy. Choć cena jaką otrzy-
mujemy za jedno kliknięcie w reklamy
jest niejawna, wiadomo, iż zależy ona
od popularności danego słowa kluczo-
wego. Im dla tego słowa istnieje więk-
sza ilość reklamodawców, tym stawki
za jedno kliknięcie są wyższe. Znacze-
nie przy zarobkowaniu odgrywa także
kolor reklamy, jej umiejscowienie oraz
Rysunek 4. Z Google AdSense można bardzo szybko zacząć zarabiać wymiary.
Google nawiązuje współprace nie-
go w sieci. Pomysł, który wdrożyła na Reklamy dobierane są na podsta- mal z każdym serwisem internetowym.
świat jako pierwsza wyszukiwarka Go- wie treści strony. Roboty indeksują- Wadą takiego rozwiązania są bardzo
ogle jest stosunkowo prosty. Dostar- ce analizują każdą ze stron, na której niskie stawki, ponieważ system może
czyć użytkownikom reklamę, która bę- znajduje się reklama, tak, by zaofero- pobierać dla siebie prowizję dochodzą-
dzie dostosowana treścią do wyników wać reklamy, które są możliwie zbliżo- cą nawet do 80%. Informacje te są jed-
wyszukiwania. ne do tematyki serwisu. nak niejawne. Wielu właścicieli kont Ad-
Google AdWords był pierwszym na W praktyce zysk osiągany z tego Sense zostało posądzonych o zjawisko
świecie programem skierowanym do re- tytułu może być bardzo zróżnicowany. kradnięcia kliknięć (ang. Click Fraud).
klamodawców na całym świecie. Po re- Głównym tego powodem jest brak inte- Mieli oni jakoby dokonywać kliknięć na
jestracji, reklamodawca zyskuje możli- resujących reklam. Jeżeli reklama tek- własne reklamy. Taki proceder jak za-
wość publikacji reklam w wynikach wy-
szukiwania Google. Ponieważ reklamo-
dawca samodzielnie ustala słowa klu-
czowe, które pozostają w korelacji te-
matycznej z jego reklamą, ukazuje się
ona tylko dla interesujących go słów
wprowadzanych do wyszukiwarki. Idea
płatnych odnośników reklamowych w
wynikach wyszukiwania i gigantyczny
sukces komercyjny zarazem skłonił Go-
ogle do otwarcia programu Google Ad-
Sense.

Google AdSense
Google AdSense skierowano do właści-
cieli stron www. Dzieląc się zyskami z
reklam, Google umożliwia właścicielom
stron www publikację reklamy kontek-
stowej i płaci za każde kliknięcie w tą
reklamę. Dołączenie do programu jest
bezpłatne, a wypłaty dokonywane ter-
minowo przelewem na rachunek banku
(dostępne w Polsce). Warunkiem wy-
płaty zgromadzonych środków jest uzy-
skanie po danym okresie rozliczenio- Rysunek 5. OnetKontekst to próba stworzenia polskiej alternatywy dla Google
wym $100 ogólnego zarobku. AdSense

PHP Solutions Nr 2/2007 www.phpsolmag.org 69


Kasa dla Webmastera Zarabianie

kod dostępu, który następnie wpisuje na


stronie www, która zachęciła go do za-
mówienia usługi. Użytkownik wprowa-
dza kod na stronie, otrzymując dostęp
do usługi.
Mechanizm taki jest zatem bardzo
prosty od strony użytkownika i wła-
śnie to zadecydowało o rozpowszech-
nieniu się tej usługi w tak znacznym
stopniu.
Tworzenie od zera własnego sys-
temu do obsługi mikropłatności SMS
mija się z celem. Oznaczałoby to bo-
wiem konieczność postawienia osob-
nej maszyny do obsługi przychodzą-
cych SMSów, a przede wszystkimi wią-
załoby się z podpisywaniem umów ze
wszystkimi polskimi sieciami komórko-
wymi. Dlatego powstali partnerzy, któ-
rzy dostarczają potrzebnej do realizacji
usługi technologii.
Rysunek 6. Zarabianie na mikropłatnościach SMS jest łatwe dzięki pośrednikom, ta- Po utworzeniu nowej usługi w ser-
kim jak Wapacz wisie partnera, generujemy listę kilku
tysięcy kodów, które następnie umiesz-
broniony i grozi za niego utrata zgro- zań oferowanych przez Google. Brak tu- czamy w bazie danych. Gdy użytkow-
madzonych środków oraz usunięcie z taj mechanizmu przydzielającego rekla- nik naszej strony wyśle wiadomość
programu. Wiele serwisów broniło się my na podstawie zawartości strony. To SMS, kolejny kod z listy zostanie do
przed takimi oskarżeniami, lecz Google webmaster ustala tematykę serwisu, ko- niego wysłany. Wystarczy teraz spraw-
pozostało nieugięte. To jeden z proble- rzystając przy tym ze specjalnego kata- dzić, czy na naszej liście kodów istnie-
mów AdSense, trudny do rozwiązania, logu. je ten, wprowadzony na stronie przez
bo tym sposobem można w bardzo ła- użytkownika. Po jego wykorzystaniu,
twy sposób pozbawić konkurencję tego Mikropłatności SMS następuje usunięcie kodu. Algorytm
źródła dochodu. Dotychczas wszystkie zaprezentowa- wydaje się więc bardzo łatwy do imple-
ne metody oscylowały wokół zarabiania mentacji i taki też jest w praktyce.
Reklama kontekstowa na publikacji reklam. Przejdźmy teraz Oto lista partnerów obsługujących mi-
po polsku do formy bardziej inwazyjnej, to znaczy kropłantości SMS:
Sukces AdSense wiąże się z ogromnym mikropłatności SMS. Inwazyjność ozna- Zarobki z tytułu wprowadzenia mi-
odpływem polskiego kapitału za granicę. cza tu konieczność wprowadzenia opłat kropłatności SMS mogą być bardzo
Powstały więc polskie odpowiedniki, któ- za pewien rodzaj usługi. Wiele witryn za- znaczące, o ile dobrze zostanie prze-
re wyraziły chęć podzielenia rynku stwo- blokuje tutaj powszechny dostęp do arty- myślana strategia odnośnie sprzeda-
rzonego przez AdSense. kułów lub do działu z plikami. Użytkow- ży. Stawki oferowane przez partne-
Systemy reklamy kontekstowej pol- nik otrzyma dostęp do pobierania plików rów są stosunkowo niskie w porówna-
skich portali powstały w drugiej połowie lub możliwość obejrzenia artykułów do- niu do wartości jednostkowej wiadomo-
2005 roku, natomiast AdPortal (w mo- piero wówczas, gdy uiści opłatę. Formy ści SMS. Przykładowo za SMS wysła-
mencie przygotowywania tekstu w prze- dostępu, to znaczy ilość plików, czy ilość ny przez użytkownika o wartości 6 zł +
budowie) – w połowie roku 2006. Ponie- artykułów, które można objerzeć po jed- vat otrzymamy nieco ponad 2 zł netto.
waż żadna z tych firm nie prezentuje in- nym zakupie, różnią się w zależności od Stawki są negocjowalne, gdzie większa
formacji na temat osiąganych zysków, serwisu. sprzedaż oznacza nieco wyższe zyski.
trudno wyrokować o skuteczności dzia- Odwiecznym problemem, przed któ- Nie można jednak liczyć na zbyt wyso-
łania tych programów. Można stwierdzić, rym stawali posiadacze stron www, by- kie stawki. Znaczną część prowizji po-
iż z pewnością ich zasięg jest znacznie ła obsługa płatności. Brakowało środ- bierają przede wszystkim sieci komór-
mniejszy od Google AdSense. Prowizje ka płatniczego, który byłby dostępny kowe i to one powodują, że usługi SMS
utrzymywane na ok. 50% nie są w sta- dla większości użytkowników Interne- są drogie i przynoszą zyski jedynie na
nie skłonić większości webmasterów do tu, a przy tym nie wymagał zbyt wiele masową skalę. Najdroższy SMS to wia-
przejścia na rozwiązania polskie. Powo- wysiłku. Wiadomości SMS o podwyż- domość o wartości 9 zł + vat, najtańszy
dem jest przede wszystkim zauważalnie szonej wartości spełniły te oczekiwania – 1 zł + vat, stąd usługi muszą opero-
mniejsza ilość reklamodawców. Tech- więcej niż dobrze. Po wysłaniu wiado- wać właśnie w tych granicach ceno-
nologia oferowana przez polskie syste- mości o podwyższonej wartości (np. 2 zł wych. Warto wybierać dużych partne-
my kontekstowe odbiega też od rozwią- + vat, 5 zł + vat), użytkownik otrzymuje rów, ponieważ mają oni największy ob-

70 www.phpsolmag.org PHP Solutions Nr 2/2007


Zarabianie Kasa dla Webmastera

rót, a zatem i dużą siłę przebicia w sie-


ciach komórkowych. Wypłaty następują
tu cyklicznie co miesiąc w formie wpła-
ty na konto, z opóźnieniem trzy mie-
sięcznym (tak rozliczają się sieci ko-
mórkowe).

Mikropłatności bankowe
Dla usług o większej wartości stosuje
się mikropłatności kartą lub przelewem.
Pozwalają one dokonywać płatności je-
dynie posiadaczom kart wypukłych (ok.
20% ogółu kart) oraz klientom banków
elektronicznych. W tym ostatnim przy-
padku korzysta się ze specjalnej for-
my zapłaty nazywanej przelew z....
W ten sposób można płacić korzysta-
jąc z usług:

• mTransfer – przelew z mBanku,


• Płacę z Inteligo – przelew z Inteligo, Rysunek 7. Platnosci.pl w znaczący sposób ułatwiają wdrożenie usług elektronicznych
• MultiTransfer – przelew z MultiBanku, płatności bankowych
• Przelew z BPH,
• Przelew z ING BankOnLine, właściciel rozpoczyna reklamowanie ser- Podsumowanie
• Przelewy24 – przelew z BZWBK, wisu oferującego program. W zależności W artykule przyjrzeliśmy się dostępnym
• Płać z Nordea – przelew z Nordea od programu, właściciel zarabia np. uzy- metodom zarobkowania. Warto teraz wy-
Bank Polska, skując procent od sprzedaży będący wy- brać zestaw metod najbardziej pasują-
• Przelew z PKO Inteligo. nikiem przejścia z serwisu reklamującego. cych do przedmiotu działalności danego
Technologia stosowana w tym przypadku serwisu internetowego. Wdrożenie więk-
Także i w przypadku płatności kartą ogranicza się do plików cookies oraz sto- szości z powyżej zaprezentowanych me-
zalecane jest korzystanie z pośredni- sowania specjalnych parametrów wejścio- tod zarobkowania nie powinno sprawić
ków. Oferują oni znacznie korzystniej- wych przesyłanych metodą get (poprzez większych trudności programistycznych.
sze stawki niż przy mikropłatnościach wpisanie adresu URL z parametrem). Jako że rejestracja, czy nawiązanie
SMS, ponieważ prowizje krążą w oko- Swoje programy partnerskie oferuje współpracy jest bezpłatne, do zarabia-
licy kilku procent. ogromna ilość firm, głównie sklepy in- nia, oprócz wartościowej strony www, nie
Implementacja tego typu płatności ternetowe. Programy oferują witryny z potrzebne są już żadne dodatkowe środ-
jest znacznie trudniejsza i uwzględnia bardzo różnych sektorów rynku. Warto ki finansowe. Zainteresowanych szer-
sporą dawkę programowania. Właściciel wybrać programy należące do sklepów szym ujęciem tematu zachęcamy do za-
serwisu musi bowiem upewnić się, iż pie- internetowych skorelowanych z tematy- głębienia się w pozycję książkową auto-
niądze zostały poprawnie przelane, co ką danego serwisu. Powodzenie znaj- ra tegoż artykułu. Szersze podejście do
niestety trwa. Zazwyczaj do ok. 15 minut dą także programy niszowe, oferują- problematyki oraz zestaw przykładowych
(i tak ta sytuacja uległa znaczącej popra- ce unikalne programy. Idea programów wdrożeń mogą okazać się przydatne w
wie). Ta metoda płatności nie jest już tak partnerskich, choć stara, bardzo rzad- podejmowaniu dalszych decyzji. n
dostępna, jak mikropłatności SMS, stąd ko oferuje przyzwoite zyski. Rzadko też
skorzysta z niej znacznie mniej użytkow- dochodzi do wypłaty środków, które w
ników. Mikropłatności kartą lub przele- dodatku mogą po pewnym okresie cza-
wem należy stosować wszędzie tam, su bezpowrotnie przepaść.
gdzie grupę docelową stanowi pokole- Przykładem korzystnej sieci rekla- O autorze
nie 30-40 latków, gdzie poczucie bezpie- mowej jest pośrednictwo w sprzedaży
Paweł Grzesiak jest projektantem witryn
czeństwa płatnościami kartą jest wyso- logo i dzwonków na telefony komórko-
internetowych z sześcioletnim doświad-
kie, a samodzielność podejmowania de- we. Wszelkiego rodzaju dodatki tego ty- czeniem. Zajmuje się tworzeniem rozbu-
cyzji i posiadanie tego środka płatnicze- pu cieszą się nieustającą popularnością dowanych witryn w oparciu o rozwiązania
go najczęstsze (w porównaniu do prze- i przynoszą duże zyski, jako że stanowią własnego autorstwa. Jest autorem ponad
50 publikacji w Magazynie Internet, Inter-
ważającego pokolenia 15-30 latków). produkt czysto usługowy. Przykłady ser-
net Maker oraz phpSolutions. W styczniu
wisów oferujących takie programy: br. nakładem wyd. Helion ukazała się je-
Programy partnerskie go książka pt. „Jak zarabiać w Internecie.
Jedną z najstarszych metod zarobkowa- • PP Wapacz.pl, Witryna, która przynosi zysk.”
nia na stronach www są programy part- http://partner.wapacz.pl/
Kontakt: pawel@grzesiak.com.pl
nerskie. Po przyłączeniu do programu, • PP WapSter, http://partner.wapster.pl/

PHP Solutions Nr 2/2007 www.phpsolmag.org 71


Recenzje

Tworzenie sklepów internetowych.


PHP i MySQL. Wydanie II. «««««
Autor: Marc Wandschneider

Jesienią 2006 roku pojawiło się na rynku II wydanie książki “Tworzenie sklepów internetowych. PHP i MySQL”. Reklamowa-
no ją jako poradnik, z którego można nauczyć się jak stworzyć własny sklep internetowy. Reklama, reklamą, a jak jest na-
prawdę? Pierwsze, co rzuca się w oczy przy pierwszym kontakcie z książką, to bardzo staranne wykonanie oraz spis treści
obfitujący w interesujące tematy. Ze spisu treści wynika, że znajdziemy w niej wiedzę na temat szablonów Smarty, biblioteki
PEAR, mechanizmów autoryzacji i bezpieczeństwa oraz dowiemy się jak napisać nasz sklep. Wszystko wygląda pięknie do-
póki nie zaczniemy czytać. Książka liczy sobie około 500 stron, z czego 250 to wstęp do właściwego tematu. Z pierwszej po-
łowy naprawdę możemy się czegoś nauczyć np. trochę XML-u, obsługi wyjątków czy też poznać pakiety z biblioteki PEAR.
Natomiast w drugiej połowie zaczyna się dziać coraz gorzej. “Naukę” na temat sklepu podzielono na fragmenty np. katalog
produktów czy też koszyk, ale gdy zajrzymy do tych działów nie zobaczymy porad z typu “jak pisać”, ale napotkamy od razu
na klasy i obiekty, z których dajmy na to koszyk jest zbudowany. Przez takie podejście do sprawy mamy wrażenie, że tak na-
prawdę czytamy dokumentację sklepu internetowego. Przeglądamy spis elementów i listingi wraz z ich lakonicznym
opisem. Bardzo często zdarza się też umieszczanie niepełnych listingów, pod którymi dowiadujemy się, że braku-
jące elementy znajdziemy na dołączonej do książki płycie. Zasadniczo więc mamy marne szanse na zrozumienie
przekazywanej treści, jeżeli nie będziemy podczas lektury korzystać z komputera. Podsycając negatywne odczucia
należy zwrócić uwagę na tytuł i treść. W tytule mamy PHP i MySQL. Ale, gdzie podział się ten MySQL ?? W całej
książce nie ma ani fragmentu wyjaśniającego formę zwrotów do bazy danych. Autorów możemy za to bardzo po-
chwalić za ostatni dział - “Obsługa zamówień”. Jest naprawdę ciekawy i dowiemy się z niego, jak uruchomić w na-
szym sklepie płatności za pośrednictwem banków internetowych czy tez kart płatniczych. Dobrym aspektem jest
też wykorzystywanie w pełnym zakresie programowania obiektowego. Podsumowując można stwierdzić, że nie
jest to książka dla początkujących. Aby zrozumieć treści przez nią przekazywane, trzeba znać zasady programo-
wania obiektowego, język PHP i MySQL.
Zrecenzował: Łukasz Skowroński

MySQL «««««
Autor: Paul Dubois

Drugie wydanie „MySQL” Paul’a Dubois jest swoistym kompedium wiedzy na temat tego popularnego silnika bazodanowego
i całej otoczki, która mu towarzyszy. Na ponad tysiącu stron znajdziemy niemal wszystko odnośnie MySQL - od składni SQL,
poprzez optymalizację zapytań, po zaawansowaną administrację serwerem bazodanowym oraz omówienie API MySQL za-
implementowanych w popularnych językach programowania (C, PHP, Perl). Ale zacznijmy po kolei.
Książka wydana w oryginale w roku 2003, a w Polsce rok później, może się wydawać nieco nieaktualna i tak jest w rze-
czywistości. Poruszane zagadnienia dotyczą MySQL w wersji 3 i 4, co może wywołać pewien niesmak u osób starających
się być na bieżąco. Dzisiaj na wielu serwerach panuje już przecież MySQL 5. Z drugiej strony trzon systemu pozostaje nie-
zmieniony, więc większość zagadnień pokrywa się z jego najnowszą wersją.
Sama książka napisana jest bardzo czytelnie. Jej lektura nie powinna sprawić problemów nawet mniej zaawansowanym
użytkownikom. Autor bardzo dokładnie opisuje wszystkie zagadnienia, unikając stosowania języka typowo technicznego
i popierając wszystko stosownymi przykładami. Całość podzielona jest na trzy części: „Sposób używania MySQL”,
„Interfejsy programowania do systemu MySQL”, „Administrowanie MySQL” oraz „Dodatki”. Mogłoby się wydawać,
że każda z nich kierowana jest do innego odbiorcy, ale po chwili przemyślenia dochodzimy do wniosku, że przecież
o każdą z nich zahaczamy choć trochę w swojej codziennej pracy.
Podsumowując, „MySQL” Paul’a Dubois to wartościowa książka, którą warto mieć w swojej podręcznej biblio-
teczce. Trzecia edycja otrzymałaby ode mnie najwyższą ocenę, druga dostaje oczko niżej, ze względu na pewne
braki w stosunku do najnowszych wersji MySQL.
Wszystkim, którzy czują się mocno w języku angielskim, mogę polecić trzecią edycję „MySQL”. Wierzę, że nie
ustępuje ona merytorycznie swojej poprzedniczce, a zawiera informacje o nowych mechanizmach zaimplemento-
wanych w MySQL 5 (widoki, wyzwalacze, procedury przechowywane). Więcej o książce na stronie autora: http://
www.kitebird.com/mysql-book/.
Zrecenzował: Marcin Stefaniak
Testy

Marcin Kowalczyk
Kierownik Działu Systemów i Serwerowni

Oczywiście zdajemy sobie spra-


wę, że nawet najlepsza i ciągle roz-
wijana infrastruktura nie stanowi
100% gwarancji sukcesu oraz pełnej
satysfakcji Klientów. Nie mniej waż-
nym a być może nawet ważniejszym
jest czynnik ludzki, czyli odpowiednio
dobrany i kompetentny zespół admi-
nistratorów.
Myślę, że warto w tym momencie
pokusić się o nieskromność i zapewnić
wszystkich obecnych jak i potencjal-
nych Klientów, że zespół doświadczo-
nych inżynierów stanowiących obsadę
Data Center Supermedia to gwarancja,
że każde z „goszczonych” urządzeń
jest w dobrych rękach. Wiadomo, że
nawet najbardziej niezawodne syste-
my mogą czasem odmówić posłuszeń-
stwa – tak jak np.: klimatyzacja, któ-
ra zgodnie z prawami Murphy’ego od-

N owoczesne społeczeństwo informa-


tyczne, z uwagi na ostatnie trendy
w rozwoju usług internetowych skupiają-
duje się w siedzibie firmy: w Pałacu Pry-
masowskim przy ulicy Senatorskiej, w sa-
mym centrum miasta. Taka lokalizacja za-
mówiła posłuszeństwa w gorący letni
dzień. Wtedy właśnie okazało się jak
szybko i jak skutecznie nasi specjaliści
cych się na interaktywności, współtwo- pewnia Klientom łatwy dostęp do powie- potrafią radzić sobie z kłopotami. Tak
rzeniu przez internautów zawartości por- rzonego nam sprzętu, z drugiej daje pew- doświadczony zespół jest zresztą nie-
tali oraz przesyłania dużych plików multi- ność stałego nad nim nadzoru. Paradok- zbędnie potrzebny na miejscu, ponie-
medialnych stawia coraz większe wyma- salnie historyczne wnętrza doskonale na- waż jako centrum usług internetowych
gania firmom prowadzącym działalność dają się dla nowoczesnych technologii – Supermedia świadczy Klientom usłu-
w oparciu o nowoczesne technologie in- chronione przez grube mury pałacu oraz gi daleko bardziej kompleksowe, wy-
ternetowe oraz globalną sieć jako platfor- system zamków elektronicznych i dodat- kraczające niejednokrotnie poza stan-
mę komunikacji. Podmioty takie zmuszo- kowej ochrony komputery naszych Klien- dardowe ramy usług kolokacji. Dlatego
ne są do ciągłego rozwijania własnej in- tów są bezpieczne jak nigdzie indziej. Do- część z naszych kolokacji to przypadki
frastruktury informatycznej, co nierzad- datkowo Kolokacja w Supermedia zapew- nietypowe, połączone z szeregiem in-
ko łączy się z koniecznością ponoszenia nia wszystkie wysokie standardy jakie nych usług.
wysokich nakładów inwestycyjnych. Taka przewidziano dla tej usługi: klimatyzowa- Potrafimy również sprostać często
sytuacja może stanąć na drodze rozwoju ne pomieszczenia, wydajny system pod- nietypowym wymaganiom Klientów na-
lub stanowić poważną barierę wejścia dla trzymywania napięcia, odcięcie od „brud- szej agencji interaktywnej Superme-
wielu firm chcących zaistnieć na poważ- nego” prądu, ochrona i opieka administra- dia Interactive – i właśnie dlatego pro-
nie w środowisku internetu. torów. Jednak nasi Klienci wybierają nas fesjonalna obsługa oraz indywidualne
Takim właśnie firmom proponuje- również dlatego, że zapewniamy ich sys- podejście do każdego Klienta to głów-
my współpracę polegającą na możliwo- temom doskonałą łączność z internetem ne atuty kolokacji w Supermedia. Naj-
ści umieszczenia ich serwerów w na- dzięki własnym łączom światłowodowym lepszym dowodem skuteczności oraz
szym Centrum Hostingu i Kolokacji w Su- oraz łączom do najważniejszych operato- jakości naszej pracy i naszych usług
permedia (Data Center Supermedia). Jest rów i dostawców internetu. Niejednokrot- jest duża popularność kolokacji w na-
to propozycja dająca możliwości wykorzy- nie zdarza nam się słyszeć opinie, że pod szym Data Center oraz stale rosnąca
stania zaawansowanej i stale rozbudo- tym względem nasze usługi są nieco „na liczba Klientów. Cieszymy się również,
wywanej infrastruktury firmy Supermedia wyrost” w stosunku do potrzeb naszych że nasi obecni Klienci zaczynając od
oraz przy okazji zapewniająca najlepsze z Klientów. Wiemy jednak, że wraz z roz- jednej usługi, często zaczynają korzy-
możliwych warunki pracy serwerów. Ofer- wojem internetu oraz rozwojem naszych stać z szerokiej oferty usług Superme-
ta usług Kolokacji (hotelingu) serwerów w Klientów te potrzeby mogą rosnąć – dla- dia zamawiając i aktywując kolejne z
Supermedia Internet Provider jest rozwija- tego staramy się uprzedzać fakty i rozbu- nich. Dzięki temu mamy powody i mo-
na właściwie od początku 10-letniej dzia- dowywać strukturę by móc rosnąć wraz tywację, aby dbać o nich jak najlepiej.
łalności firmy. Nasze Data Center znaj- z nimi. No i ciągle się rozwijać:).

74 www.phpsolmag.org PHP Solutions Nr 2/2007


Testy konsumenckie Testy

Marek Berkan, Project Manager,


CodeLine

waż możliwość fizycznego dostępu do


serwera kilka razy umożliwiła nam roz-
wiązanie różnych problemów. Jesteśmy
także zadowoleni z wyboru usługodaw-
cy i nie mamy zastrzeżeń do poziomu
świadczonej usługi – prawdopodobnie
częściowo wynika to również z faktu, że
nie mamy wygórowanych wymagań. Nie-
zawodność usługi na przestrzeni tych lat
niemal stuprocentowa, kontakt z przed-
stawicielami firmy – bezproblemowy.
Naszym zdaniem na pochwałę
zasługują również administratorzy SU-
PERMEDIA. W sytuacjach, gdy docho-
dziło do awarii naszego serwera szyb-
ko kontaktowali się z nami telefonicz-
nie i sugerowali możliwe rozwiązania.
Również w przypadku odwiedzin ser-
werowni można było liczyć na ich po-
moc i miłą atmosferę, co niestety nie
zawsze jest standardem.
Jedyne czego moglibyśmy jeszcze
oczekiwać to obniżenie ceny usługi oraz
podwyższenie parametrów, ponieważ
mamy wrażenie, że usługi tego typu na
przestrzeni tych kilku lat trochę stania-

W 2002 roku szukaliśmy miejsca, w


którym moglibyśmy umieścić nasz
serwer internetowy. W tym czasie wybór
ma ta miała jedną z najkorzystniejszych
ofert cenowych, ponadto nie stosowała
dopłat z tytułu użycia serwera w obudo-
ły, prawdopodobnie dzięki konkurencji
zagranicznej. Podsumowując, jesteśmy
zadowoleni ze współpracy z firmą SU-
usługodawców krajowych był bardzo wie wolnostojącej, jaką my wtedy dyspo- PERMEDIA, ponieważ za rozsądną ce-
ograniczony, ponadto nie było takiego nowaliśmy – pozostałe firmy preferowa- nę gwarantuje ona dobrą jakość świad-
dostępu do tanich usług firm zagranicz- ły obudowy do montażu w szafie rack i czonej usługi i bezpośredni dostęp do
nych jak w chwili obecnej. O usłudze ko- dopłaty innych obudów były stosunko- serwera.
lokacji firmy SUPERMEDIA dowiedzieli- wo wysokie. Z perspektywy tych kilku lat W skali ocen od 1 do 5 ocenił-
śmy się od jednego z naszych klientów, współpracy uznaliśmy, że decyzja wybo- bym firmę i usługi przez nią oferowa-
który wtedy także z niej korzystał. Fir- ru kolokacji w kraju była słuszna, ponie- ne na 5.

R E K L A M A

PHP Solutions Nr 2/2007 www.phpsolmag.org 75


Testy Testy konsumenckie

Daniel Maksymiuk,
Warszawskie Centrum Numizmatyczne

W obecnych
czasach suk-
ces firmy oraz jej
tą były w wersji off-line. Z biegiem cza-
su okazało się, że ilość przechowywa-
nych danych była tak duża, że usługa
lizację – znajduje się niedaleko Starego
Miasta, firma ma profesjonalną obsługę,
a także może poszczycić się korzystną
przetrwanie na rynku dzierżawienia pamięci dyskowej okaza- ofertą cenową. Podczas całego okresu
zależne jest od wielu ła się nieefektywna. Postanowiliśmy za- współpracy nie pojawiły się żadne pro-
czynników. tem zakupić własny serwer, który w peł- blemy z działaniem naszego serwera,
Do niektórych z ni miałby spełnić nasze oczekiwania i z czego jesteśmy niezwykle zadowole-
nich na pewno zali- kolokować go w profesjonalnej firmie w ni. Dzięki temu możemy całkowicie sku-
czymy profesjona- Warszawie. Firma, którą wybrano z po- pić się na działalności firmy i nie myśleć
lizm i doświadczenie, a także postęp i śród wielu innych konkurencyjnych firm o ciągłym kontrolowaniu poprawności
szybkość wdrażania nowych technolo- to Supermedia Internet Provider. Oka- działania naszego serwera. Biorąc pod
gii. Wychodząc na przeciw swoim klien- zało się, że spełnia ona wszystkie nasze uwagę usługę, która jest nam świadczo-
tom nasza firma zdecydowała się uru- podstawowe ustalenia. Do kryterium wy- na przez firmę Supermedia można jej z
chomić sprzedaż poprzez internet. W boru, które miały być spełnione należa- całą pewnością dać maksymalną oce-
przyszłości planuje także uruchomienie ły: profesjonalizm, dogodna lokalizacja, nę, jeśli chodzi o jakość hotelingu. Jeśli
aukcji on-line. Do tej pory wydzierża- całodobowy dostęp do serwera i konku- miałbym ponownie wybrać firmę do ko-
wialiśmy jedynie miejsce na serwerze, rencyjne ceny. Siedziba firmy Superme- lokacji serwera zdecydowanie byłaby to
a strony internetowe z całą naszą ofer- dia Internet Provider ma doskonałą loka- Supermedia Internet Provider.

Jakub Kuran,
QPrint

S zybki rozwój technologiczny gospo-


darki wymusza na większości firm
konieczność dostosowania się do sytu-
ruch w sensie ilości spływających za-
pytań czy obsługiwanych jednocześnie
Klientów. Dokonując wyboru odpowied-
siadaniu jest firma Supermedia bez ko-
nieczności ponoszenia kosztów budo-
wy własnych specjalnie zaprojektowa-
acji i dokonywanie licznych inwestycji w niego dostawcy musieliśmy skupić się nych pomieszczeń utrzymujących od-
nowe technologie. Internet jest jedną z na możliwości ciągłego przekazywania powiednie warunki do pracy nasze-
inwestycji, której patrząca w przyszłość informacji oraz zapewnienia ciągłości go systemu oraz tworzenia kosztownej
firma nie może zignorować. Dlatego od obsługi on-line wielu Klientów naszej fir- infrastruktury. Nie bez znaczenia po-
samego początku działalności inwesto- my jednocześnie. Tak więc ważna była zostaje fakt, że firma Supermedia za-
waliśmy w budowę własnego systemu nie tylko przepustowość łącza, ale rów- pewniła nam jednocześnie bezpośred-
informatycznego, który pozwalałby na nież gwarancja ciągłości działania sys- nie stałe łącza internetowe do naszych
optymalizację procesu realizacji i przyj- temów. Wybierając firmę Supermedia lokalizacji w Warszawie, co pozwa-
mowania zleceń. Po wdrożeniu modułów Internet Provider kierowaliśmy się po- la na optymalne wykorzystanie posia-
pozwalających na przyjmowanie zleceń ziomem obsługi oferowanej przez firmę danego pasma na komunikację pomię-
przez Internet niezbędne okazało się za- oraz dostępnością do naszych serwe- dzy wszystkimi systemami i serwera-
pewnienie dobrego łącza o dużej przepu- rów ulokowanych w centrum Hostingu mi QPrint. Pozwoliło to na zbudowanie
stowości oraz cechującego się dużą nie- i Kolokacji Supermedia w Warszawie. wydajnej infrastruktury opartej o dodat-
zawodnością – klienci nasi razem ze zle- Centrum mieści się w dogodnym punk- kowe lokalne serwery, które pełnią jed-
ceniami dostarczają najczęściej pliki gra- cie niedaleko warszawskiej starówki a nocześnie funkcje mirrora systemu cen-
ficzne, których rozmiar znacznie przekra- sama firma zaoferowała bardzo dobre tralnego, dzięki czemu pracownicy ma-
cza 10MB. Szybko okazało się, że łącze warunki umożliwiające zarówno zdalną ją bezpośredni i szybki dostęp do ma-
indywidualne do którego podłączony był konfigurację systemów jak i bezpośred- teriałów nadesłanych przez klientów w
nasz system jest niewystarczające, dlate- ni dostęp do własnych maszyn uloko- ramach sieci lokalnej danego punktu
go byliśmy zmuszeni do znalezienia roz- wanych w Supermedia. Zespół wykwa- usługowego – jest to rozwiązanie nie-
wiązania, które zapewniałoby odpowied- lifikowanych inżynierów pracujących w zbędne do zapewnienia optymalnego
nie parametry łącza. Dziale Technicznym bez żadnych pro- przepływu zadań i związanych z nimi
Nasze rozwiązanie od obsługi Klien- blemów radzi sobie z obsługą koloko- materiałów graficznych. Dodatkowym
tów on-line pozwala na wybór właściwej wanych urządzeń oraz konfiguracją atutem takiego rozwiązania okazała się
technologii druku, ustawienie wszyst- urządzeń do backupu. możliwość konfiguracji systemu tele-
kich niezbędnych do tego parametrów Zastosowanie tego rozwiązania po- komunikacyjnego na bazie VoIP i inte-
oraz co ważniejsze przesłanie goto- zwoliło na czerpanie korzyści wynikają- gracji wszystkich linii telefonicznych ze-
wych do druku przy wykorzystaniu sie- cych z posiadania specjalnie przygoto- wnętrznych jak i wewnętrznych w jeden
ci internet. Niweluje to również koniecz- wanego systemu informatycznego, od- system telekomunikacyjny. Dzięki temu
ność bezpośredniego kontaktu w celu powiednio wydajnej infrastruktury tech- klienci dzwoniący do pod jeden nr te-
uzyskania wyceny czy złożenia zamó- nicznej oraz bezpośredniego dostępu lefonu mogą zostać przełączeni do do-
wienia ale w rezultacie generuje duży do łącz światłowodowych w jakich po- wolnej lokalizacji firmy Qprint.

76 www.phpsolmag.org PHP Solutions Nr 2/2007


Testy konsumenckie Testy

Grzegorz Pilarski
Warsaw Data Center
w przypadku wykrycia jakichkolwiek nie-
prawidłowości. Kolokowanie serwerów
i urządzeń w Warsaw Data Center jest
nie tylko ekonomicznym rozwiązaniem
ale także zwiększa jakość i niezawod-
ność świadczonych usług. W szczegól-
ności:

• obniża koszty utrzymania więcej niż


jednego łącza do internetu bez potrze-
by inwestycji w drogie routery umieją-
ce obsłużyć protkół dynamicznego ro-
utingu BGP4,
• obniża koszty utrzymania personelu
wyszkolonego do utrzymania własnej
sieci rozległej,
• obniża koszty bezpiecznego zasilania
bez potrzeby inwestycji w urządzenia
podtrzymujące napięcie przez wiele
godzin,
• obniża koszty archiwizacji danych bez

K olokacja serwerów lub innych urzą-


dzeń w wyspecjalizowanym ośrod-
ku jest najlepszym sposobem uzyskania
Klienci mogą instalować własne syste-
my lub skorzystać z wynajmu serwerów
lub innych urządzeń. Lokalizacja siedzi- •
potrzeby inwestycji w urządzenia archi-
wizujące, oprogramowanie i nośniki,
zapewnia monitoring i obsługę przez
warunków niezbędnych w prowadzeniu e- by WDC gwarantuje najwyższy stopień 24 godziny na dobę 7 dni w tygodniu
biznesu: bezpiecznej i stale monitorowa- bezpieczeństwa, zapewnia przestrzeń bez zatrudnienia działu technicznego
nej lokalizacji serwera, niezawodnych łącz umożliwiającą nieskrępowany rozwój pracującego całą dobę,
oraz sprzętu elastycznie dostosowane- oraz infrastrukturę stworzoną specjal- • umożliwia prostą rozbudowę i dostęp
go do aktualnych potrzeb. Usługi Warsaw nie dla potrzeb serwerów. Ponadto na do usług wedle narastających potrzeb,
Data Center stanowią idealne rozwiązanie miejscu przebywają wysokokwalifiko- • zdecydowanie skraca czas dostępno-
dla każdej firmy, która opiera swój rozwój wani inżynierowie i technicy WDC, któ- ści usług (większość usług dostępna
na wykorzystaniu aplikacji internetowych. rzy przez 24 godziny na dobę 7 dni w ty- w przeciągu 24 godzin),
Oferta WDC zaspokaja wszelkie po- godniu dbają o utrzymanie wszystkich • zapewnia Gwarancję Jakości Usług
trzeby związane z kolokacją serwerów. urządzeń w ruchu i reagują natychmiast (SLA).

R E K L A M A

PHP Solutions Nr 2/2007 www.phpsolmag.org 77


Testy Testy konsumenckie

Michał Faber
serwis biznes.net

P rowadzę rozmaite serwisy interneto-


we od 1999 r. Pierwszy z nich dzia-
łał na zwykłym PC-cie, który stał podob-
no w jakiejś kawiarence internetowej na-
leżącej do mojego wspólnika. Nigdy tam
nie byłem, nie znałem konfiguracji sprzę-
towej, ani przepustowości łącza, ale wiem
że serwis ładował się strasznie wolno.
Dodatkowo po każdym długim weeken-
dzie, albo świętach przez kilkanaście go-
dzin serwis nie działał w ogóle, prawdopo-
dobnie na skutek awarii zasilania, braku
miejsca na dysku, czy błędów konfiguracji
systemu. Wtedy po raz pierwszy zetkną-
łem się z firmą Warsaw Data Center.
Na jednym ze spotkań First Tuesday
otrzymałem od WDC propozycję prefe-
rencyjnych warunków wynajmu serwe- mieć swobodę w kształtowaniu całego roz- Warsaw Data Center, a kilka lat w tej bran-
ra dedykowanego. Długo się nie zasta- wiązania składającego się z aplikacji porta- ży to wieczność. Zmieniają się technologie,
nawiałem. Później okazało się, że była to lowej, określonej struktury dość dużej ba- zmienia się rynek usług telekomunikacyj-
słuszna koncepcja. Po migracji aplikacji i zy danych i konfiguracji sprzętowej serwe- nych. Na szczęście nie muszę znać szcze-
danych serwis ładował się znacznie szyb- rów. Chciałem po prostu eksperymentować gółów tych przemian.
ciej, a co najważniejsze, po raz pierw- z różnymi ilościami pamięci dostępnymi dla Jestem zadowolony z usług WDC.
szy od dłuższego czasu mogłem spokoj- PHP i MySQL, dostepną przestrzenią dys- Wszystko działa jak należy, ale co waż-
nie spędzać weekendy i święta. W cią- kową, czy sprzętowym rozdzielaniem ser- niejsze w praktyce poznałem ich procedu-
gu kilku lat które od tego czasu upłynę- wera bazy danych, aplikacji i webserwera. ry i organizację działania. Właśnie po pro-
ły aplikacja obsługująca portal interneto- Przy wykorzystaniu serwerów dedykowa- cedurach poznaje się doświadczenie zdo-
wy się rozwijała, zarejestrowanych użyt- nych nie zawsze było to możliwe, ze wzglę- byte w walce z materią teleinformatyczną,
kowników przybywało, wysyłaliśmy coraz du na ich standaryzację: ograniczenia która złośliwa jest i skrupulatnie przestrze-
więcej codziennych newsletterów, a w do- maksymalnej wielkości pamięci, czy rodza- ga praw Murphy'ego.
datku około roku 2003 pojawił się znaczą- ju dysków. Poza tym chyba dojrzałem do Korzystałem z usług WDC zarówno
cy ruch przychodzący z wyszukiwarki Go- posiadania własnego sprzętu, co w przy- jako osoba prywatna, jako przedstawi-
ogle. Wszystkie te czynniki uświadomiły padku biznesu portalowego daje poczucie, ciel kilku firm, polecałem także ich usługi
nam zapotrzebowanie rozmaitych usług że jest się właścicielem czegoś więcej niż swoim klientom. Można powiedzieć, że je-
internetowych na pasmo, przestrzeń dys- tylko domeny, bazy danych i aplikacji we- stem stałym klientem co przekłada się na
kową, szybkość procesora, czy wielkość bowej. Kolokacja okazała się dla mnie do- pewien rodzaj zażyłości i zaufania między
pamięci. Uruchamiając kolejny portal zde- brym kompromisem bo daje swobodę dzia- dostawcą, a odbiorca usługi. Tego rodzaju
cydowałem się na usługę kolokacji serwe- łania, a jednocześnie nie wymaga budo- relacja pozwala spokojnie i profesjonalnie
ra. Oczywiście w Warsaw Data Center. wania własnej serwerowni i utrzymywa- przezwyciężać trudności, które miewają
Alternatywą do kolokacji był wyna- nia rozbudowanej infrastruktury. Od kilku obie strony. Wystawiam WDC ocenę pię-
jem serwera dedykowanego, ale chciałem lat jestem zadowolony z usług kolokacji w ciu gwiazdek.

Magdalena Stec,
shooters.pl

W pewnym momencie działalności


naszej firmy stwierdziliśmy, że po-
trzebujemy skorzystać z usługi kolokacji
tywnego pomieszczenia dla naszych ser-
werów, zaczęliśmy szukać kolejnej firmy i
tak trafiliśmy do Warsaw Data Center. Fir-
firmy, u której moglibyśmy kolokować na-
sze serwery, były brane pod uwagę roz-
wiązania konkurencyjne. Jednakże w po-
serwerów. Wybraliśmy tę usługę, ponie- ma zapewniła nam najbardziej elastycz- równaniu z innymi, Warsaw Data Center
waż posiadamy własne zasoby sprzęto- ną usługę tego typu w kraju, dotyczą- zapewniało nam największą elastyczność
we – farma 40 serwerów. Nie mamy też cą zarówno oferowanego pasma inter- rozwojową oraz dostępność. Na pytanie,
potrzeby dzierzawić ich od innych provi- netowego, jak również samego dostepu czy skorzystalibyśmy z usług kolokacji fir-
derow, tylko sami, we własnym zakresie do urzadzeń. Możemy liczyć na pomoc my Warsaw Data Center, odpowiedzia-
je dostarczamy i wykorzystujemy. o dowolnej porze dnia i nocy. Zdecydo- łabym zdecydowanie tak. Nie żałujemy
Generalnie w kraju korzystaliśmy już waliśmy się na Warsaw Data Center, po- naszego wyboru i jesteśmy zadowoleni z
z paru firm kolokacyjnych i dalej z nich nieważ ich oferta wydała nam się najbar- jakości usługi, którą oferuje nam ta firma.
korzystamy. Jednak potrzebując alterna- dziej korzystna. W momencie poszukiwań W skali 1-5 gwiazdek oceniamy ją na 5.

78 www.phpsolmag.org PHP Solutions Nr 2/2007


Cyber rzeczywistość – Cyber uzależnienie Felieton

Cyber rzeczywistość
– Cyber uzależnienie
Łukasz Skowroński

takie życie, to jest przecież nasze życie. musi przerwać. To jest jak wirus, który
To jest nasza rzeczywistość. I tu właśnie atakuje nieświadomych zagrożenia. Ist-
zaczyna się problem. nieją też już przypadki rozwodów, właśnie
Powstają nowe określenia typu: sie- z powodu nadużywania komputera przez
cioholizm, cybernałóg. Uzależnienie od jednego z małżonków. Zarażony człowiek
komputera staje się problemem, takim jak z każdym dniem oddala się od innych
alkoholizm czy każdy inny nałóg. Specja- ludzi, otaczając się murem, w którym jedy-
liści coraz głośniej nas przed tym ostrze- nym wyjściem jest jego komputer.
gają. Ale przecież nas to nie dotyczy. Dla dobra swojego i otaczających
Jesteśmy pewni, że panujemy nad kom- nas ludzi, sprawdźmy się. W sieci mnó-
puterem. Tkwimy w przekonaniu, że każdy stwo jest testów sprawdzających nasz
normalny człowiek korzysta z komputera stan uzależnienia lub od razu wybierz-
przez 20 godzin dziennie. Bo przecież, my lepszą drogę. Postawmy sprawę ja-
po co mi jakaś inna forma aktywności. Je- sno – komputer jest urządzeniem, któ-

P
opatrzmy na nasz współczesny stem najlepszy w grę sieciową, zostałem re ma nam umożliwić sprawną pracę i
świat. I zastanówmy się, co wi- doceniony przez użytkowników mojego naukę oraz rozrywkę w rozsądnych ilo-
dzimy – widzimy samych siebie, ulubionego forum, jestem na bieżąco, bo ściach. Zamiast poświęcać czas na bez-
widzimy innych ludzi i oczywiście widzi- internet jest moim źródłem informacji – to produktywne siedzenie przed monitorem
my nieodłączny element naszej cywilizacji jest rzeczywistość. Rzeczywistość, w któ- wybierzmy się na spacer, spotkajmy ze
– komputery. Maszyny, które służą nam do rej znajduję akceptację. znajomymi, poczytajmy książkę lub Wasz
pracy i nauki, bo przecież do tego zostały Niestety, takie myślenie jest nagmin- ulubiony magazyn. Ocalimy dzięki temu
stworzone. Ale z biegiem czasu te narzę- ne i bardzo szkodliwe. Najczęściej taka zdrowie psychiczne jak i fizyczne, któ-
dzia zaczęły umożliwiać nam też rozryw- osoba nie zdaje sobie sprawy ze skali pro- re przy dłuższym nadużywaniu kompute-
kę, robienie zakupów, kontakt z przyjaciół- blemu. W naszym skomputeryzowanym ra na pewno by ucierpiało. Otyłość, pro-
mi. Mało tego, komputery stają się naszy- społeczeństwie, coraz częściej możemy blemy z kręgosłupem i układem krążenia,
mi przyjaciółmi. Wracając do domu, pierw- zauważyć młodych ludzi, nie tylko w wieku słabszy wzrok, to tylko nieliczne “atrak-
sze, co robimy, to pędzimy do niego – że- szkolnym, którzy już nie widzą niczego cje” nadmiernego poświecenia się takie-
by biedaczek nie był sam – z myślą : sią- poza komputerem. W Polsce nie jest to mu “hobby”. Dodatkowym atutem powro-
dę na chwilkę i sprawdzę czy nie ma no- jeszcze tak widoczne jak, np. w Stanach tu do normalności niech będzie fakt, że w
wych wiadomości. Po chwili, co najczę- Zjednoczonych, ale warto zwrócić na to dzisiejszym realnym świecie, każdy chce
ściej oznacza godzinę, wygrywa fizjologia. uwagę już teraz. Nie jest to tylko problem osiągnąć sukces. Każdy chce być KIMŚ.
Kiedyś przecież trzeba coś zjeść. Szyb- ludzi młodych. Uzależniony i nieświadomy Żeby to osiągnąć musimy dokonać wybo-
ka przekąska i znowu wracamy do naszej rodzic przekazuje ten model życia swoim ru. Poświęćmy się rodzinie, pracy, nauce.
maszyny. Godzina za godziną, dzień za dzieciom, które z kolei przekazują ten Zdecydujmy się na prawdziwe życie, do
dniem – po chwili – rok za rokiem, przy- styl swoim rówieśnikom. Tak powstaje którego zostaliśmy stworzeni, a nie na cy-
zwyczajamy się do takiego życia. Lubimy pewnego rodzaju pętla, którą ktoś kiedyś ber namiastkę świata. n

PHP Solutions Nr 2/2007 www.phpsolmag.org 79


www.buyitpress.com

Zaprenumeruj swoje ulubione magazyny


i zamów archiwalne numery!

Już teraz w kilka minut możesz zaprenumerować swoje ulubione pismo.


Gwarantujemy:
- preferencyjne ceny
- bezpieczną płatność on-line
- szybką realizację Twojego zamówienia
Bezpieczna prenumerata on-line wszystkich tytułów Wydawnictwa Software!
zamówienie prenumeraty

Prosimy wypełnić czytelnie i przesłać faksem na numer: (22) 887 10 11 lub listownie na adres: Software-Wydawnictwo Sp. z o.o.,
Bokserska 1, 02-682 Warszawa, e-mail: pren@software.com.pl. Przyjmujemy też zamówienia telefoniczne: (22) 887 14 44

Imię i nazwisko............................................................................................ ID kontrahenta..........................................................................................

Nazwa firmy................................................................................................. Numer NIP firmy.......................................................................................

Dokładny adres....................................................................................................................................................................................................................

Telefon (wraz z numerem kierunkowym)................................................... Faks (wraz z numerem kierunkowym) ....................................................

E-mail (niezbędny do wysłania faktury)............................................................................................................................................................................


automatyczne przedłużenie prenumeraty

Tytuł
Ilość Od numeru Opłata
Ilość
zamawianych pisma lub w zł
numerów
prenumerat miesiąca z VAT
Software Developer’s Journal (1 płyta CD)
– dawniej Software 2.0 12 250/1801
Miesięcznik profesjonalnych programistów
SDJ Extra (od 1 do 4 płyt CD lub DVD)
– dawniej Software 2.0 Extra! 6 150/1352
Numery tematyczne dla programistów

Linux+DVD (2 płyty DVD)


Miesięcznik o systemie Linux
12 199/1791

Linux+Extra! (od 1 do 7 płyt CD lub DVD)


Numery specjalne z najpopularniejszymi dystrybucjami Linuksa
8 232/1982

PHP Solutions (1 płyta CD)


Dwumiesięcznik o zastosowaniach języka PHP
6 135

Hakin9, jak się obronić (1 płyta CD)


Miesięcznik o bezpieczeństwie i hakingu
12 1991/219

.psd (1 płyta CD + film instruktażowy)


Dwumiesięcznik użytkowników programu Adobe Photoshop
6 140

.psd numery specjalne


(.psd Extra + .psd Starter Kit)
6 140

Suma

Jeżeli chcesz zapłacić kartą kredytową, wejdź na


stronę naszego sklepu internetowego:
1
Cena prenumeraty rocznej dla osób prywatnych
2
Cena prenumeraty rocznej dla osób prenumerujących już Software Developer’s Journal lub Linux+
3
Cena prenumeraty dwuletniej Aurox Linux
www.buyitpress.com
W następnym numerze PHP Solutions 3/2007 (20)

W sprzedaży od kwietnia

BEZPIECZEŃSTWO UWAGA KOLEJNY TEST KONSUMENCKI


n Bezpieczeństwo Sesji n Sprzęt: Serwery

NARZĘDZIA
NOWE ARTYKUŁY W DZIAŁACH:
n ImageMagick i PHP
graficzny kombajn n dla początkujących

n Agavi n dla zaawansowanych


pokażemy jak szybciej, prościej i wydajniej budować aplikacje
internetowe przy użyciu frameworka Agavi n kasa dla webmastera

I wiele innych artykułów, których nie możesz przeoczyć!

Redakcja zastrzega sobie możliwość zmiany zawartości pisma.

You might also like