PHP Solutions 02 2007 PL

84

description

* Szybkie i przyjemne programowanie z Code Igniter* Wsparcie SEO w systemach zgodnych ze standardami W3C na przykładzie eZ Publish* Ankiety w stylu rankingowym z użyciem AJAX-a* ASwing + AMFPHP, czyli przepis na szybkie GUI* Przeglądarka bazy danych przy użyciu PHP-Gtk2* PHP5 WebServices vs MS .NET vs Java vs Java Mobile – interoperability pełną parą!* Jak zarobić na stronie www? Poradnik dla przedsiębiorczych webmasterów.* Kolokacja serwerów (hoteling)* Cyber rzeczywistość – cyber uzależnienie

Transcript of PHP Solutions 02 2007 PL

Page 1: PHP Solutions 02 2007 PL
Page 2: PHP Solutions 02 2007 PL
Page 3: PHP Solutions 02 2007 PL
Page 4: PHP Solutions 02 2007 PL

Spis treści

www.phpsolmag.org4 PHP Solutions Nr 2/2007

Spis treści

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

AKTUALNOŚCI 6

Krzysztof Trynkiewicz

OPIS CD 10

Dorota Pączka

DLA POCZĄTKUJĄCYCHSzybkie i przyjemne programowanie z Code Igniter 12

Piotr Maliński

Piotr pokazuje jak profesjonalnie stworzyć apli-kacje internetowe wg wzorca MVC. Wzorzec opi-sywany przez autora w jasny i klarowny sposób zapewni Ci uporządkowanie kodu, co zwiększy jego czytelność.

PROJEKTYWsparcie SEO w systemach zgodnych ze standardami W3C na przykładzie eZ Publish 20

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 ZAAWANSOWANYCHAnkiety w stylu rankingowym z użyciem AJAX-a 26

Krzysztof Trynkiewicz

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.

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-let dwóch aspektów programistycznych.

francuskimpolskim

Nasz magazyn ukazuje się w dwóch językach!

Jeśli jesteś zainteresowany zakupem licencji na wydawanie naszych pism prosimy o kontakt:Monika Godlewska [email protected] tel.: 48 22 887 12 66, fax: 48 22 887 10 11

Przyjemne z pożytecznymMówi się, że „pieniądze szczęścia nie dają”, ale na pewno każdy przyzna, że 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 przełożyć sie na niemałe korzyści majątkowe. Możecie zacząć tworzyć wła-sne witryny WWW łącząc przyjemne z pożytecznym.

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-sać inne aplikacje za pomocą Code Igniter.

Zachęcam również do przeczytania ciekawych artykułów, w rozbudo-wanym dziale „Dla zaawansowanych”. Staramy się, aby z numeru na nu-mer umieszczać coraz więcej tekstów właśnie w tym dziale, ponieważ je-steśmy w pełni świadomi, że programujecie coraz bardziej zaawansowa-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 wzieliśmy pod lupę firmy oferujące hoteling. Tematem kolejnego testu bę-dą serwery, jeśli chcecie, aby właśnie Wasza opinia ukazała się na łamach naszego pisma, piszcie!

Gorąco polecam też lekturę numeru extra poświęconego Xoops. Już niedługo w kioskach! Zapraszam do czytania.

Patrycja Wądoł[email protected]

Page 5: PHP Solutions 02 2007 PL

Spis treści

www.phpsolmag.org4 PHP Solutions Nr 2/2007

Spis treści

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

NARZĘDZIAPHP5 WebServices vs MS .NETvs Java vs Java Mobile– interoperability pełną parą! 52

Łukasz Budnik

Łukasz uczy pisania własnych usług sieciowych oraz rozszerzania domyślnych klas PHP5 klien-ta i serwera SOAP. Po przeczytaniu artykułu nie będziesz miał też problemu z zabezpieczaniem swoich usług z rozszerzeniem WS Security En-hancements i HTTPS.

KASA DLA WEBMASTERAJak zarobić na stronie www? Poradnik dla przedsiębiorczych webmasterów. 66

Paweł Grzesiak

W dzisiajszych czasach istnieje wiele źródeł, z których właściciel strony interentowej może czerpać zyski. Autor w artykule prezentuje me-tody zarobkowania i zwraca szczególną uwagę na ich opłacalność. Dowiesz się, w co warto za-inwestować.

RECENZJE 72

Łukasz Skowroński, Marcin Stefaniak

TESTY KONSUMENCKIEKolokacja serwerów (hoteling) 74

Testujemy firmy:l Supermedia Internet Provider (testują CodeLine, Warszawskie Centrum Numizmatyczne, QPrint)l Warsaw Data Center (serwis biznes.net, shooters.pl).

FELIETONCyber rzeczywistość– cyber uzależnienie 79

Łukasz Skowroński

ZAPOWIEDZI 82

Zapowiedzi artykułów, które planujemy w na-stępnym wydaniu naszego pisma.

Listingi wszystkich opisywanych programów zostały zamieszczone na naszej stronieinternetowej www.phpsolmag.org/pl.

Pytania dotycząceprenumeratytel. (22) 887 14 44e-mail: [email protected] Wydawnictwo Sp. z o.o.dział prenumeratyul. Bokserska 102-682 Warszawa

CDtel. (22) 887 14 44e-mail: [email protected] Wydawnictwo Sp. z o.o.Defekty CD/DVDul. Bokserska 102-682 Warszawa

Zamówienia /Numery archiwalnetel. (22) 887 14 44e-mail: [email protected] on-line: www.buyitpress.com

Kontakt z redakcjąe-mail: [email protected] Wydawnictwo Sp. z o.o.Redakcja PHP Solutionsul. Bokserska 102-682 Warszawa

Strona WWW/Forumstrona www: www.phpsolmag.orgTu znajdą Państwo informacjedotyczące aktualnych i przyszłychnumerów magazynu PHP Solutions.

Forum: www.phpsolmag.org/newforumZachęcamy do dyskusji na naszymforum. Czekamy na propozycjetematów, które chcieliby Państwoznaleźć w najbliższym numerze pisma. Zapraszamy także do wymianypoglądów z innymi fanami PHP.

Cena Prenumerata: 135 złPrzelew na konto nr:46 1440 1299 0000 0000 0391 8238 Nordea Bank Polska S.A.II Oddział w Warszawie

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

Redaktor naczelny: Sylwia PogroszewskaRedaktor prowadzący: Patrycja Wądołowska [email protected] redaktora: Dorota Pączka [email protected] współpracownicy: Paweł Grzesiak [email protected]: Krzysztof Trynkiewicz [email protected] produkcji: Marta Kurpiewska [email protected]

Projekt okładki: Agnieszka MarchockaSkład i łamanie: Sławomir Zadrożny [email protected]ł reklamy: [email protected]: Marzena Dmowska [email protected]ład: 6 000 egz.

Adres korespondencyjny: Software-Wydawnictwo Sp. z o.o., ul. Bokserska 1, 02-682 Warszawa, Polskatel. +48 22 887 13 35, fax +48 22 887 10 11www.phpsolmag.org [email protected]

Dołączoną do magazynu płytę CD przetestowano programem AntiVirenKit firmy G DATA Software Sp. z o.o.

Redakcja dokłada wszelkich starań, by publikowane w piśmie i na towarzyszących mu nośnikach informacjei programy były poprawne, jednakże nie bierze odpowiedzialności za efekty wykorzystania ich; nie gwarantujetakż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 firmi zostały użyte wyłącznie w celach informacyjnych.

Redakcja używa systemu automatycznego składu Do tworzenia wykresów i diagramów wykorzystano program firmy

Osoby zainteresowane współpracą prosimy o kontakt: [email protected]

Druk: ArtDruk

Wysokość nakładu obejmuje również dodruki. Redakcja nie udziela pomocy technicznej w instalowaniui 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

Page 6: PHP Solutions 02 2007 PL

Aktualności

PHP Solutions Nr 2/2007www.phpsolmag.org6

PEAR::HTML_CSSOd 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 zgodnych ze standardami W3C przy pomocy klas PHP. Projekt rozwijany jest od 2003 ro-ku, pozwala na parsowanie plików lub ciągów z wielu źródeł jednocześnie. Wyniki naszej pracy możemy „wyeksportować” jako elemen-ty “inline” kodu HTML, wewnętrzne lub ze-wnętrzne deklaracje na stronie, tablice dekla-racji, ciąg znakowy lub zapisać do pliku.W nowej wersji 1.1.0 dodano możliwość wy-szukiwania selektorów i właściwości za po-mocą wyrażeń regularnych typu Perl. Pakiet działa pod PHP 4 oraz 5. Jest także rozpo-wszechniany na licencji PHP 3.01.http://pear.php.net/package/HTML_CSShttp://www.laurent-laville.org/index.php?module=pear&desc=css

PHP6 nadchodziWraz z końcem roku, na wielu blogach osób pracujących nad PHP6 pojawiły się zapo-wiedzi nadchodzącej wersji. Zgodnie z tym, co pisaliśmy o nowej wersji (PHP Solutions 3/2006 (14)), będzie to raczej ewolucja, niż rewolucja. Wiadomo już, że ponad połowa pracy nad wsparciem dla Unicode została za-kończona. Funkcjonalność ta będzie głów-nym atutem PHP6, możemy więc spodziewać się pierwszych wersji testowych w ciągu naj-bliższych miesięcy.http://blog.libssh2.org/index.php?/archives/48-PHP-2006-A-look-back.htmlhttp://www.gravitonic.com/blog/archives/000305.html

script.aculo.us 1.7.0Wielkimi krokami nadchodzi stabilna wersja 1.7.0 pakietu script.aculo.us, zawierającego wiele przydatnych efektów stosowanych na stronach opartych o AJAX.W nowej wersji podniesiono ilość klatek na sekundę dla efektów z 25 do 60, całość po-winna więc działać zauważalnie szybciej.Nowością są efekty morphingu, które możemy zastosować dla dowolnych klas CSS. Przy-kłady morphingu możemy zobaczyć pod ad-resem http://mir.aculo.us/demos/script-acu-lo-us-1-7-beta-demos.http://mir.aculo.ushttp://script.aculo.us

Dokumentacja PrototypeJuż w poprzednim numerze informowaliśmy o innowacyjnym frameworku Prototype dla Java-Script oraz możliwościach, które daje dewelo-perom PHP przez AJAX. Dokumentacji do te-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-documentationhttp://prototype.conio.net/

Piąta doroczna konferencja eZ SystemsWiele 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

Suhosin – zabezpieczenia dla PHP

Suhosin to zaawansowany system za-bezpieczeń dla PHP. Został zaprojek-

towany, by uchronić użytkowników tej plat-formy przed znanymi i nietypowymi błę-dami, zagnieżdżonymi tak w skryptach, jak i w samym silniku PHP. Suhosin skła-da się więc z dwóch części, z których moż-na stosować każdą z osobna, lub razem. Pierwsza część pakietu, to patch dla silni-ka PHP, który implementuje kilka niskopo-ziomowych zabezpieczeń przeciwko prze-pełnieniom buforów, czy błędów w for-matach ciągów znakowych. Druga część to rozszerzenie do PHP, wprowadzają-ce wiele innych zabezpieczeń. Dostaje-my więc opcje symulacji zabezpieczeń, funkcje sha256() oraz sha256 _ file() do silnika PHP, obsługę CRYPT _ BLOWFISH w crypt() dla wszystkich platform, zabezpie-czenia dla otwartych stron z wywołaniami phpinfo(), zabezpieczenia użytkowników baz danych SQL, enkrypcję ciastek, możli-wość wyłączenia funkcji eval(), modyfika-tora /e funkcji preg _ replace.

Możemy także określić maksymal-ną ilość rekursji, zapobiegając nieskoń-czonej ilości wywołań funkcji, otrzymu-jemy także zabezpieczenie przeciw-ko atakom używającym pustych linii przekazywanych do mail(), czy “\0” do preg _ replace(). Możemy zablokować eksportowanie zmiennych superglobal-nych PHP za pomocą funkcji extract() oraz import _ request _ vars(). Ochronie poddane są także zmienne sesyjne: da-ne są poddawane enkrypcji, identyfikato-ry sesji są sprawdzane pod kątem długo-ści i typów znaków, ze wskazaniem na te zastrzeżone. Z formularzy filtrowane są znaki ASCIIZ oraz ignorowane są zmien-ne typu GET, POST i COOKIE o nazwach za-

strzeżonych (np. GLOBALS, _ COOKIE, _ ENV, _ FILES, _ GET, _ POST, _ REQUEST, _ SERVER, _ SESSION, HTTP _ COOKIE _ VARS, HTTP _

ENV _ VARS, HTTP _ GET _ VARS, HTTP _

POST _ VARS, HTTP _ POST _ FILES, HTTP _

RAW _ POST _ DATA, HTTP _ SERVER _ VARS, HTTP _ SESSION _ VARS). Do danych prze-kazywanych przez powyższe metody mo-żemy zastosować filtrowanie wyklucza-jące zbyt dużą ilość zmiennych lub jedy-nie te, które zawierają zbyt zagnieżdżo-ne tablice, zbyt duże tablice, których na-zwy bądź wartości są zbyt długie. Może-my także kontrolować ilość plików uplo-adowanych na serwer, zaś te wrzucone poddawać sprawdzeniu przez zewnętrz-ny skrypt. Pliki będące binariami są auto-matycznie odrzucane, wycinane są tak-że wykonywalne fragmenty wewnątrz in-nych plików. W przypadku zablokowania lub odrzucenia zmiennej bądź pliku, mo-żemy przekierować użytkownika na inną stronę, pokazać błąd lub uruchomić inny skrypt PHP. Wszystkie działania pakietu są monitorowane i logowane do dzienni-ka systemowego lub zewnętrznego skryp-tu, są opisane adresem IP Internauty, na-zwy i linii pliku, w którym wystąpił błąd. To tylko niektóre z wielu możliwości, jakie oferuje pakiet Suhosin. Dodatkowo, pro-jekt współdziała z innymi aplikacjami, np. Zend Optimizer. Na witrynie projektu znaj-dziemy bardzo obszerną dokumentację, forum dyskusyjne, oraz informacje o od-krytych niedawno błędach krytycznych w popularnych aplikacjach PHP. Pakiet udo-stępniany jest na darmowej licencji PHP License 3.01.

http://www.hardened-php.net/suhosin.127.html

Page 7: PHP Solutions 02 2007 PL

Aktualności

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

Heurystyczna ochrona przeciwko atakom SQL InjectionSQL 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 zagnieżdżone zapytania SELECT. Tego typu zapytania nie są często stosowane, jednak wykorzystuje je się przy znacznej ilości ata-ków SQL Injection. Zabezpieczenie zostało wprowadzone do projektu Suhosin, opisane-go szerzej w tym wydaniu aktualności, war-to jednak zastanowić się, czy podobne roz-wiązanie nie znajdzie zastosowania i w na-szych projektach.http://blog.php-security.org/archives/67-Heuri-stic-SQL-Injection-Detection-for-Suhosin.html

Seagull Framework 0.6.1Po kilku miesiącach przerwy, nowej wersji do-czekał się słynny framework Seagull. Uspraw-niono system raportowania błędów, doda-no możliwość podawania argumentów do za-pytań CLI, wprowadzono prefixy dla baz da-nych, dodano element CAPTCHA dla komenta-rzy i wiele innych funkcjonalności. W PHP Solu-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żdegoRepozytorium PEAR z każdym dniem rośnie, jednak wciąż poszukiwane są opracowania do projektów tworzonych w jego ramach. PHP Kit-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 PECL. Dodatkowo, znajdziemy kilkadziesiąt odnośników do tutoriali na temat najprzydat-niejszych narzędzi: Cache, Cache_Lite, Config, Console, Crypt_HMAC, DB, DB_DataObject, Archive_Tar, Error, HTML_AJAX, HTML_Pro-gress, HTML_QuickForm, HTML_Table, HTTP_Upload, LiveUser, Mail, Mail_Mime, Ma-il_Queue, Log, PHP_Documentor, PHP_Unit, Services_Google, SOAP, Spreadsheet_Excel_Writer, Structures_DataGrid, Structures_Graph, Text_Captcha, Tree, XML_Parser, XML_Seria-lizer, XML_Tree, czy XML_RSS.http://www.phpkitchen.com/index.php?/archives/668-PEAR-Tutorials.html

Zend FrameworkŚrednio co miesiąc autorzy Zend Frame-work uraczają nas nowymi wersjami pakie-tu ułatwiającego tworzenie aplikacji PHP. W wersji 0.6.0 dodano nowe komponen-ty (m.in. Zend_Auth, Zend_Console_GetOpt, Zend_TimeSync), przepisano na nowo kod kluczowych komponentów (Zend_Session, Zend_Http_Client) i poszerzono dokumenta-cję. Dodatkowo zlikwidowano ponad 100 błę-dów. Zend Framework wyrasta więc na lide-ra w zakresie frameworków dla PHP. Szerzej o nowym rozwiązaniu pisaliśmy w PHP Solu-tions 04/2006 (15) – z pewnością warto przyj-rzeć się ponownie temu projektowi, ponieważ od czasu publikacji artykułu zyskał wiele funk-cjonalności i rzesze zwolenników.Licencja: własna, darmowa.http://framework.zend.com

PHP Unit w wersji 3 wprowadziło za-awansowaną obsługę pakietu XDe-

bug. Umożliwia on śledzenie błędów, wyświetlając informacje o funkcji zawie-rającej błąd, parametry do niej przesy-łane (także do funkcji własnych), nazwę pliku, w której rezyduje, oraz numery wierszów. Dodatkowo, otrzymamy infor-macje o alokacji pamięci, możliwych nie-skończonych rekursjach, będziemy tak-że mogli wyprofilować swój skrypt. XDe-bug jest dostępny dla platformy Linux, posiada także binaria dla Windows. Ist-nieją osobne pakiety dla PHP 4 i 5. Li-cencja jest oparta o PHP License 3.0.

Dokumentacja projektu jest obszerna i czytelna, znajdziemy w niej informacje o implementowaniu XDebug do PHP Unit. Podobne treści znajdziemy także na stronach PHP Unit. W efekcie otrzyma-my potężne narzędzie, pomocne w de-bugowaniu naszych projektów. XDebug jest rozwijany od 2002. Aktualizacje nie są częste, jednak zawsze wnoszą no-we funkcjonalności. Na temat PHP Unit pisaliśmy obszernie w PHP Solutions 1/2006 (12).

http://xdebug.orghttp://phpunit.de

pMachine – gotowe pakiety

Jeśli szukasz zbioru projektów, których można używać za darmo

w zastosowaniach nie komercyjnych, to pMachine jest właśnie dla Ciebie. Sama strona projektu jest schludna i prezentuje jakość, której możemy spo-dziewać się po każdym z modułów.

Zaznaczyć należy, że każdy z modu-łów może działać niezależnie od innych, mogą one jednak być także połączone, tworząc potężny CMS. Autorzy przygo-towali dla nas bardzo eleganckie forum dyskusyjne, sklep internetowy, funkcjo-nalną galerię obrazów, system wiki do tworzenia własnych encyklopedii oraz system do tworzenia blogów – pMachi-ne Pro.

Głównym jednak atutem firmy jest ich ExpressionEngine. Jest to bardzo ela-styczny system publikacji treści, który potrafi połączyć wszystkie inne produk-ty w całość. Już na stronie głównej pro-jektu ujrzymy odnośniki do ponad 200 przykładowych witryn, które używają te-go oprogramowania – jest na co popa-trzeć. Firma pMachine opracowała także własny framework – Code Igniter, które-mu powinni przyjrzeć się programiści za-

interesowani tworzeniem systemów klasyEnterprise. Już teraz możemy bowiem zobaczyć, co na jego podstawie moż-na zbudować – każdy z wyżej wymienio-nych modułów działa w oparciu o ten fra-mework, i trzeba przyznać, że całość pre-zentuje się bardzo dobrze.

Produkty z tej firmy są tworzone już od 6 lat, możemy więc być pewni, że są pisane przez doświadczonych progra-mistów. Deweloperzy powinni przyjrzeć się bliżej rozwiązaniom zastosowanym w projektach tej firmy – kilka pomysłów można bowiem sukcesywnie zaimple-mentować i w swoich dziełach.

http://www.pmachine.com

Suhosin – zabezpieczenia dla PHP

Page 8: PHP Solutions 02 2007 PL

Aktualności

PHP Solutions Nr 2/2007www.phpsolmag.org8

Spamowi mówimy STOPW dobie Internetu, niemal każdy użytkownik (a zwłaszcza programista aplikacji webowych) po-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-kiet, który w kilka minut możemy zaimplemen-tować do swojej witryny. Domyślnie, jest to do-datek do aplikacji WordPress, jednak można go zaimplementować także w autorskich roz-wiązaniach. Akismet zidentyfikował dotychczas ponad 500 milionów spamerskich wiadomo-ści, każdego dnia wynik powiększa się o ponad milion wiadomości. Nie trudno wyobrazić so-bie, ile miejsca i transferu zostało oszczędzone-go dzięki temu projektowi. Statystyki wykazują, że aż 94% wszystkich wiadomości filtrowanych przez Akismet to spam. Obecnie, pakiet jest jednym z najskuteczniejszych rozwiązań anty-spamerskich. Polecamy jego implementację na własnych witrynach!http://akismet.com

Bad BehaviourBad Behavioru to zestaw skryptów PHP, który analizuje nagłówki HTTP wysyłane przez oso-by (lub automaty) odwiedzające naszą witry-nę. Na podstawie ustalonej czarnej listy i pew-nych heurystycznych metod, potrafi skutecznie odróżnić spamerskiego bota od przeglądarki lub robota wyszukiwarki. Użytkownicy tego pa-kietu chwalą go sobie nie mniej niż rozwiązanie opisane powyżej. Obydwa te systemy, w połą-czeniu, zapewniają niemal całkowitą ochronę przed spamem na naszej witrynie. Dodatkowo, Bad Behaviour filtruje popularne roboty, próbu-jące przeprowadzać ataki na naszą stronę. Pa-kiet jest darmowy, prosty w użyciu i łatwo mo-dyfikowalny.http://www.homelandstupidity.us/software/bad-behavior/

Geeklog CMSGeeklog to nowy, szybki CMS, posiadający wiele udogodnień. Standardem są oczywiście moduły takie jak kalendarz, repozytorium pli-ków, systemy ankiet, zintegrowane forum, za-awansowane statystyki, wyszukiwarka, czy nowości. Dodatkowo mamy do dyspozycji wielojęzykowość, katalog witryn oraz syste-my CAPTCHA dla komentarzy i na forum. Ja-ko edytor WYSIWYG zastosowano popularny i skuteczny FCKeditor. Jeśli jeszcze nie znala-złeś odpowiedniego dla siebie CMSa, wypró-buj Geeklog!http://www.geeklog.net

Nucleus CMSZ kolei Nucleus, to CMS mający już swoją hi-storię i całą gamę pluginów. Obsługuje wie-le systemów blogowych jednocześnie, wie-lu autorów, kategorie wpisów, oferuje system komentarzy, przyjazne URLe, skórki, szablo-ny, archiwa, wyszukiwarkę, wątki RSS i Atom dla różnego typu treści, interfejs XML-RPC, posiada możliwość uploadowania plików gra-ficznych do galerii. Jest dostępny w 16 wer-sjach językowych, posiada także system backupowania. Jest także, rzecz jasna, dar-mowy.http://nucleuscms.org

Analizer plików audio w PHPPHPAudioFile to wprawdzie już nie rozwija-na klasa, ale oferująca bardzo ciekawe możli-wości analizy plików WAV, OGG, MP3 i AIFF. Skrypt podaje długość ścieżki, typ kompre-sji, jakość próbkowania, ilość bitów przypada-jących na każdy kanał oraz udziela informa-cji zawartych w tagach ID3. Dodatkowo ge-nerowane są pliki PNG wizualizujące prze-bieg utworu.http://freshmeat.net/projects/phpaudiofile

CAPTCHA przeciwko spamowi

CAPTCHA to akronim od “Comple-tely Automated Public Turing Test

to Tell Computers and Humans Apart. Innymi słowy, są to obrazki, z których musimy często przepisywać kod, by nasz wpis, komentarz, czy temat na forum został opublikowany. CAPTCHA jest stosowany w celu wyeliminowa-nia automatów spamujących, próbują-cych ataków typu bruteforce, zakłada-jącym masowo konta itp... Dewelope-rzy aplikacji mają ostatnio wiele nie-przespanych nocy, właśnie ze wzglę-du na rozwiązanie doraźne, jakim jest CAPTCHA. Stosując bowiem obrazki w celu odróżnienia człowieka od ma-szyny, stwarzamy kłopot w przegląda-niu witryny osobom niewidomym. Ma-ło tego, niektórzy wciąż używają prze-glądarek tekstowych, np. Lynx, inni z kolei mają wyłączone wyświetlanie ob-razów. Stosując CAPTCHA, tworzymy bariery – jeden problem znika, poja-wiają się inne. Internauci od dłuższego czasu zwracają na to uwagę, proponu-

jąc jako alternatywy zagadki, czy pliki audio. Ostatnie rozwiązanie ma w za-sadzie jeszcze więcej mankamentów: nie każdy ma bowiem możliwość odsłu-chania nagrania. Wydaje się więc, że najlepszym wyjściem jest stworzenie systemu dającego wybór użytkowniko-wi, jakim sposobem chce się “zauto-ryzować”. Do podobnego wniosku do-szedł autor klasy PhpCaptcha. Oferuje ona rozwiązania tak graficzne, jak au-dio, jest rozpowszechniana na zasa-dach określonych w licencji Free BSD License. Klasa potrafi generować lo-sowe teksty na obrazach w zadanych czcionkach TrueType, z opcjonalny-mi cieniami, losowymi tłami, o różnych wielkościach czcionek dla możliwych do wyświetlenia, zdeklarowanych zna-ków. Do działania wymaga przynajm-niej PHP 4 z biblioteką GD 1 lub GD 2 oraz obsługę czcionek FreeType.

http://www.ejeliot.com/pages/2http://www.w3.org/TR/turingtest/

PAT – PHP Application Tools

PHP Application Tools to pakiet róż-nych skryptów dla deweloperów

PHP. Idea stworzenia zestawu narzędzi darmowych (większość z nich jest na li-cencji LGPL, niektóre na GPL) powstała już kilka lat temu. Dopiero teraz jednak, czterech programistów, wzięło sprawy w swoje ręce. Efektem jest 10 modułów, któ-re możemy implementować na własne wi-tryny. Na stronie projektu znajdziemy więc opis: patBBCode – pakietu do tworzenia własnych kodów BBCode, podobnych do tych znanych z for dyskusyjnych; patCon-figuration – pakiet, dzięki któremu może-my stworzyć konfigurację jako plik XML, który następnie eksportujemy np. jako plik konfiguracyjny PHP; patError – klasa słu-żąca do obsługi błędów; patForms – uła-twiające tworzenie formularzy na naszych witrynach; patSession – warstwa abstrak-cji służąca do obsługi sesji w PHP; patSpi-derizer – narzędzie pomagające w decy-dowaniu i konfigurowaniu, które z elemen-tów naszej witryny powinny być zindekso-wane przez roboty wyszukiwarek; patSy-sinfo – wyświetlające wiele informacji o zasobach systemu, na którym działa na-sza witryna (w tym także jego obciążenie); patTemplate – system szablonów podob-

ny do Smarty, jednak szybszy i prostszy; patUser – system autentykacji użytkowni-ków, który możemy szybko zaimplemen-tować na naszą stronę; patXMLRenderer – pakiet pozwalający na transformację pli-ków XML do łatwych w przeglądaniu wi-tryn HTML (lub innego formatu zgodnego z ASCII, generuje kod zgodny z szablona-mi patTemplate). Dodatkowo, mamy moż-liwość skorzystania z siedmiu innych pro-jektów: patDbc, patGuestbook, patNew-sletter, patServer, patRSS, patSHMC, pat-Messenger. Aplikacje PAT to coś więcej niż framework – to gotowe rozwiązania, które są bardzo przydatne i funkcjonalne, a także łatwe w implementacji.

http://www.php-tools.de

Page 9: PHP Solutions 02 2007 PL
Page 10: PHP Solutions 02 2007 PL

www.phpsolmag.org10

Opis CD

PHP Solutions Nr 2/2007

DzPHP 4.1.

DzPHP 4.1. jest wygodnym i efek-tywnym narzędziem do pisania

i testowania stron napisanych języ-kiem PHP i HTML. Przystępny inter-fejs sprawia, że staje się on łatwy dla

PHPmyvisits (wersja 2.3)

PHPmyvisits 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-niu grafiki.

PhpGroupWare

PhpGroupWare jest pakietem do pra-cy zaspołowej, rozwijanym w ramach

projektu DotGNU. Jest stosowany jako zbiór komponentów usług sieciowych. Mo-gą one być wykorzystywane również (po-przez XML-RPC) w innych aplikacjach w pracy w sieci, pod warunkiem, że aplika-cje te zostały stworzone z zastosowaniem DotGNU.

wszystkich programistów, zarówno po-czątkujących, jak i doświadczonych. Dzięki niemu tworzenie stron przy uży-ciu PHP i HTML nie jest już tak skom-plikowane.

EbookiPonadto nowe e-booki

• Introduction to Programming Using Java,• The Java Language Specification,• Thinking in Java.

PHP/Java Bridge(wersja 3.2.1)

Moduł Java dla języka PHP. Pre-zentowana wersja stanowi ulep-

szenie poprzedniej – 3.1.8., obiewersje 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-wer HTTP odpowiednio zaczyna lub kończy pracę.

Eclipse-SDK (wesja 3.2.1) (wersja 3.1.2), PHPEclipse (wersja 1.1.8)

Eclipse to rozbudowane środowisko programistyczne napisane w Javie.

Największą jego zaletą jest to, że daje możliwość korzystania z wielu wtyczek, co w konsekwencji rozszerza jego fun-kjonalność. Eclipse można nazwać uni-wersalnym środowiskiem, a świadczyo tym fakt, że posiada wtyczkę CDTobsługującą popularne języki C i C++,a nie wyłącznie Javę.

Page 11: PHP Solutions 02 2007 PL

Na CDNa CD

HITY

Programy komercyjne:- DzPHP Editor 4.1 o wartości 49$- Captcha Magic 1.0 o wartości 19.95$- PHP Magic (Trial)

Wsz

ystk

ie lis

tingi

z a

rtyku

łów

zos

tały

zam

iesz

czon

ena

nas

zej s

troni

e in

tern

etow

ej p

od a

dres

em www.phpsolmag.org/pl

Wsz

ystk

ie lis

tingi

z a

rtyku

łów

zos

tały

zam

iesz

czon

ena

nas

zej s

troni

e in

tern

etow

ej p

od a

dres

em www.phpsolmag.org/pl

E-BOOKS

- Introduction to Programming Using Java- The Java Language Specifi cation- Thinking in Java

PONADTO

- PHP/Java Bridge 3.2.1- Eclipse-SDK 3.1.2 oraz 3.2.1 - PHPEclipse 1.1.8- PHPmyvisits 2.3- Stato 0.7- phpGroupWare

Page 12: PHP Solutions 02 2007 PL

www.phpsolmag.org12 PHP Solutions Nr 2/2007

Dla początkujących

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

Code Igniter Dla początkujących

By szybko i bezboleśnie opano-wać obsługę prezentowanego tu-taj frameworka musisz znać pod-

stawy programowania obiektowego. Mu-sisz wiedzieć, co to jest klasa, metoda i obiekt oraz oczywiście musisz znać pod-stawy samego języka. Pomocne mogą być artykuły poświęcone PHP na wikibo-oks, które dokładnie opisują zagadnienia programowania obiektowego. Klasy to w bardzo dużym uproszczeniu zbiór funkcji. Oto przykładowa klasa:

class Klasa

{

function funkcja()

{

return 'a';

}

function inna($a)

{

return trim($a);

}

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.

}

$obiekt = new Klasa();

echo $obiekt->funkcja();

Klasę definiujemy stosując słowo "class" i podając po nim nazwę klasy. Nawiasy klamrowe określają zawartość klasy. Klasa zawiera "funkcje", które nazywa się meto-dami. Metody definiuje się jak funkcje.

Klasy natomiast wywoływane są ina-czej niż funkcje. Pierwszym etapem jest stworzenie obiektu klasy:

<?php

$obiekt = new NAZWAKLASY();

Szybkie i przyjemne programowanie z Code IgniterPiotr Maliński

W SIECI

• http://www.codeigniter.com– strona frameworka

• http://www.php.rk.edu.pl– kurs CI po polsku

• http://www.todlaciebie.pl – przykładowa strona wykonana w oparciu o Code Igniter

• http://pl.wikibooks.org/wiki/PHP/Wstęp_do_programowania_obiektowego– wprowadzenie do programowania obiektowego

Stopień trudności: lll

Co należy wiedzieć...Powinieneś znać podstawy PHP i HTML.

Co obiecujemy...Nauczysz się tworzenia profesjonalnych aplikacji internetowych wg wzorca MVC.

Page 13: PHP Solutions 02 2007 PL

www.phpsolmag.org12 PHP Solutions Nr 2/2007

Dla początkujących

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

Code Igniter Dla początkujących

Nowy obiekt tworzy się stosując słowo "new", po którym podajemy nazwę kla-sy (tak jakby była to funkcja). Zmienna ($obiekt w przykładzie), do której przy-piszemy stworzony obiekt, będzie miała dostęp do wszystkich metod, które wy-wołujemy: $obiekt->NAZWAMETODY();.

W funkcjach zmienne wewnątrz nie są dostępne na zewnątrz i na odwrót, chyba że daną zmienną określi się ja-ko globalną, podobnie w klasach. Sto-sowanie zmiennych globalnych nie jest zalecane, szczegóły podam przy oma-wianiu wzorca MVC. Klasy mają dodat-kową zmienną wewnętrzną - $this-> określa ona zmienne dostępne global-nie wewnątrz klasy. Zazwyczaj takie zmienne ustawiane są w konstruktorze (automatycznie wykonywanej przy two-rzeniu obiektu metodzie), a potem wy-korzystywane przez poszczególne me-tody.

Co to jest Framework MVC?Mianem frameworka określa narzędzie stanowiące podstawę do tworzenia apli-kacji. Framework zawiera elementy uła-twiające i przyśpieszające tworzenie apli-kacji. W przypadku PHP framework za-pewni nam obsługę szablonów, połączeń z bazami danych, obsługę formularzy i wiele więcej. Naszą aplikacją może być galeria czy system artykułów. Tworzenie takiego skryptu od zera wiązałoby się z napisaniem kodu odpowiedzialnego za wymienione powyżej czynności, a dopie-ro w drugiej kolejności z napisaniem kodu samej aplikacji.

MVC (ang. Model-View-Controller) to wzorzec programistyczny – pewien sche-mat, wg którego tworzy się aplikacje. Ce-lem takich wzorców jest uporządkowanie kodu w jasny i klarowny sposób, zapew-niając jego czytelność, nie tylko dla auto-ra kodu. Wzorzec MVC jest dość popu-larny i charakteryzuje się rozdzieleniem komponentów aplikacji, tj. modelu danych

(np. operacje na bazie danych), (np. sza-blony) interfejsu użytkownika i logiki ste-rowania („pozostały” kod aplikacji) w taki sposób, aby modyfikacje jednego kompo-nentu minimalnie wpływały na pozostałe. O sile MVC przekonamy się, gdy rozpocz-niemy pracę z Code Igniterem.

Co to jest Code Igniter?Code Igniter to framework PHP rozwija-ny przez firmę pMachine i rozprowadza-ny na liberalnej licencji zbliżonej do licen-cji Apache/BSD. Code Igniter, w skrócie CI, jest bardzo prostym lecz funkcjonal-nym narzędziem. Oto jego krótka charak-terystyka:

• wymaga PHP w wersji nie starszej niż 4.3.2, działa również pod PHP 5,

• wykorzystuje wzorzec MVC Model-Widok-Kontroler przy tworzeniu apli-kacji, lecz nie narzuca go,

• lekki i wydajny; komponenty frame-worka mają postać wtyczek, które można ładować w razie potrzeby,

• automatycznie generuje przyjazne wyszukiwarkom URLe dla stworzo-nych kontrolerów,

• jest bardzo dobrze udokumentowanyi posiada liczne grono użytkowników.

CI nie jest narzędziem tak rozbudowanym jak np. Prado. Nie oferuje takich opcji jak:

• pełna abstrakcja baz danych (wspiera tylko podstawowe operacje),

• rozbudowane moduły takie jak system uprawnień i użytkowników,

Listing 1. Przykładowy model nowości

class News extends Model{

function News() {

parent::Model();

}

function get_news() {

// Wszystkie newsy sortowane malejąco po news_id

$this->db->orderby("news_id", "desc");

return $this->db->get('news'); }

function add_news($data) {

// dodanie newsa

return $this->db->insert('news', $data); }

function update_news($id, $data) {

// zmiana newsa o podanym numerze news_id

$this->db->where('news_id', $id);

return $this->db->update('news', $data); }

function delete_news($id) {

// skasowanie newsa o podanym news_od

$this->db->where('news_id', $id);

return $this->db->delete('news'); }

}

Rysunek 1. Efekt działania naszej wyszukiwarki Flickr

Page 14: PHP Solutions 02 2007 PL

Code Igniter

www.phpsolmag.org14

Dla początkujących

PHP Solutions Nr 2/2007

Mimo to jest to bardzo dobry produkt ze względu na łatwość i przyjemność pracy, a braki można uzupełnić własnymi biblio-tekami i pomocnikami.

Instalacja i konfiguracjaPobieramy archiwum z frameworkiem ze strony projektu i rozpakowujemy go do pustego katalogu i przesyłamy na ser-wer. Jeżeli teraz otworzymy w przeglą-darce URL prowadzący do katalogu z frameworkiem to zobaczymy powitalną wiadomość. Możemy przystąpić do two-rzenia własnej aplikacji.

Struktura frameworkaGłówny katalog Code Igniter zawiera plik index.php odpowiedzialny za wy-świetlanie kontrolerów naszej aplikacji. W katalogu system znajdziemy katalo-gi: application, cache, codeigniter, dri-vers fonts, helpers, init, language, libra-ries, logs, plugins, scaffolding. W kata-logu language umieszcza się pliki z tłu-maczeniami interfejsu frameworka. Nas głównie będzie interesował katalog ap-plication jako, że to w nim zawarty bę-dzie cały kod naszych aplikacji. W kata-logu tym znajdziemy:

• config - katalog zawierający pliki kon-figuracyjne,

• controllers – katalog przechowujący kontrolery,

• errors – obsługa błędów (np. 404 – brak strony),

• models – katalog zawierający modele• views – katalog z widokami.

KonfiguracjaPodstawowa konfiguracja ogranicza się do edycji pliku config/config.php i poda-nia ścieżki URL do naszej instalacji fra-meworka jako wartość $config['base _

url']. Pozostałe pliki konfiguracyjne bę-dą interesować nas w dalszej części ar-tykułu. autoload.php określa, jakie biblio-teki i pomocniki mają być automatycznie ładowane, database.php zawiera da-

ne dotyczące bazy danych, routes.php określa m. in. domyślny kontroler.

OdnośnikiCI używa przyjaznego wyszukiwarkom i ludziom mapowania adresów URL i zmiennych. Oto przykładowe odnośni-ki: http://www.strona.pl/index.php/klasa/metoda/; http://www.strona.pl/index.php/klasa/metoda/parametr/ ....

Gdzie klasa oznacza klasę kontro-lera jaka ma być wywołana, metoda – nazwę wybranej metody tejże klasy, a parametry, których może być wiele, przekazywane są do metody.

KontroleryKontroler to klasa umieszczona w pli-ku o nazwie takiej jak nazwa klasy, umieszczonym w katalogu controllers. Nazwa zawierać możne znaki alfanu-meryczne (cyfry i litery) oraz znaki pod-kreślenia. Nazwa klasy jest używana w linkach URL do jej wywoływania. Przy-kładowy odnośnik: http://localhost/html/ci/index.php/form

Wywoła klasę o nazwie "Form". Kla-sa ta powinna znajdować się w pliku "form.php".

Nazwa pliku musi zaczynać się z małej litery, nazwa klasy - z dużej. Me-tody klasy kontrolera są automatycznie dostępne poprzez system odnośników CI, za wyjątkiem metod zaczynających się od znaku podkreślenia.

WidokiWidok to niejako szablon strony lub jej elementu (np. nagłówek, szablon newsa itp.). Widok wywoływany jest przez kon-troler, który wypełnia go danymi i wysyła do przeglądarki. Widoki umieszczamy w katalogu views. W kontrolerach dany sza-blon ładujemy poleceniem:

$this->load->view('nazwa_widoku');

Co wyświetli zawartość widoku. By prze-kazać wartości do widoku wystarczy ja-

ko drugi parametr podać tablicę z dany-mi. By przypisać widok do zmiennej, a nie wyświetlić go, wystarczy jako trzeci argu-ment podać wartość True:

$widok = $this->load->view(

'nazwa_widoku', array('dane' =>

$zmienna), True);

Witaj Świecie w CIW katalogu controllers stwórz plik test.php o kodzie:

<?php

class Test extends Controller

{

function index()

{

echo 'Test CI';

}

}

?>

Otwórz plik config/routes.php i zmień wartość

$route['default_controller']

na nazwę kontrolera - „test”. Teraz głów-na strona frameworka wyświetli tekst „Test CI”. Stworzyliśmy pierwszą prostą aplikację. Stworzyliśmy prosty kontroler i ustawiliśmy go jako domyślny. Metoda index jest domyślnie wywoływaną meto-dą kontrolera i jak każda inna dostępna jest również pod odnośnikami:

index.php/test/index

index.php/test

ModeleModele to klasy PHP zawierające meto-dy operujące na danych w bazie danych. Przykładowo model "Artykuły" posiadał-by metody typu "dodaj", "zmień", "usuń". Modele zapisuje się w katalogu models. Nazwy modeli muszą zaczynać się z Dużej litery, nazwy plików - z małej. Co-de Igniter nie wymusza stosowania mo-deli, można operować na bazie danych również w kontrolerach, lecz warto z nich korzystać. Szkielet modelu:

class Nazwa_modelu extends Model {

function Nazwa_modelu()

{

parent::Model();

}

}

Listing 2. Tabela dla modelu nowości

CREATE TABLE `news` ( `news_id` smallint(5) unsigned NOT NULL auto_increment, `news_title` varchar(255) default NULL, `news_text` text,

`news_date` int(10) unsigned NOT NULL, PRIMARY KEY (`news_id`)) ENGINE=MyISAM AUTO_INCREMENT=1 ;

Page 15: PHP Solutions 02 2007 PL

Code Igniter

www.phpsolmag.org 15

Dla początkujących

PHP Solutions Nr 2/2007

Mamy zwykłą klasę dziedziczącą z kla-sy "Model". Tworząc konstruktor musi-my dodać:

parent::Model();

By załadować w Kontrolerze model sto-sujemy:

$this->load->model('Nazwa modelu');

Po załadowaniu modelu uzyskujemy do-stęp do jego metod:

$this->Nazwa_modelu->metoda();

Bazy Danych w CIPołączenie z bazą danych ustawiamy w pliku config/database.php. Znajdzie-my w nim:

$db['default']['hostname'] = "localhost";

$db['default']['username'] =

"użytkownik";

$db['default']['password'] = "hasło";

$db['default']['database'] =

"nazwa bazy";

// sterownik: mssql, mysql, mysqli,

// odbc, postgre, sqlite

$db['default']['dbdriver'] = "mysql";

// prefiks

$db['default']['dbprefix'] = "";

// Czy używać trwałych połączeń

$db['default']['pconnect'] = FALSE;

// czy pokazywać komunikaty błędów

$db['default']['db_debug'] = FALSE;

// czy załadować klasę Active Records

$db['default']['active_r'] = TRUE;

Podajemy dane naszej bazy, a następ-nie przechodzimy do pliku autoload.php i dodajemy "database" do automatycz-nego ładowania: $autoload['libraries'] = array('database');. Code Igniter udo-stępnia nam Active Records – bibliotekę mapującą obiekty na kod SQL. Za jego pomocą możemy tworzyć niezależne od typu bazy danych aplikacje, lecz w przy-padku bardziej złożonych zapytań bę-dziemy zmuszeni do zastosowania suro-wego kodu SQL. Oto przegląd możliwo-ści mapera:

Pobranie danych

$this->db->get('nazwa tabeli');

$this->db->get('nazwa tabeli', LIMIT);

$this->db->get('nazwa tabeli', LIMIT,

OFSET);

Metoda ta pobierze wszystkie wpisy z po-danej tabeli. Można też, jako drugi para-metr, podać limit wyników (LIMIT) lub też Limit i Ofset (np. pobierze 10 wyników, ale nie 10 pierwszych tylko zaczynając od 5 (ofset to 5).

Warunek WHERE

$this->db->where('nazwa kolumny',

wartość);

Określi warunek "WHERE" limitujący wy-niki – pobrane zostaną tylko te rekordy (wpisy z bazy danych), które spełniają ten warunek. Można kilka razy zastosować tą metodą dla uzyskania łączonego warun-ku where. Lub też można zastosować ta-blicę asocjacyjną:

$array = array('pole' => $wartosc,

'pole2' => $wartosc2, 'pole' =>

$wartosc);

$this->db->where($array);

By uzyskać warunki łączone przez "lub" wystarczy użyć metody "orwhere":

$this->db->orwhere(takie same parametry);

Pobieranie określonych kolumn

$this->db->select('pole, pole2, pole3');

Pozwala na pobranie wartości tylko z określonych pól podanych jako argument. Podajemy nazwy pól oddzielone przecin-kami.

LIKE - pobieranie wierszy zawierający podany podłańcuch

$this->db->like('pole', 'wartość');

Operator LIKE w SQL pozwala na wy-branie wpisów, zawierających w okre-ślonym polu podany "podłańcuch". Me-toda like ma takie same opcje z argu-mentami (tablice też może być), jak where. Istnieje też metoda orlike łączą-ca warunki przez "lub".

Sortowanie wyników

$this->db->orderby('pole',

'desc lub asc');

"desc" posortuje malejąco a "asc"

rosnąco.

Listing 3. Kontroler z formularzem i kontrolą danych

class Formularz extends Controller{

function index() {

// dane poszczególnych pól w postaci tablicy

$data["tytul"] = array('name' => 'tytul'); $data['tresc'] = array('name' => 'tresc', 'rows' => 3, 'cols' => 40);

// określenie warunków walidacji

$rules['tytul'] = "required|min_length[5]|max_length[12]";

$rules['tresc'] = "required";

$this->validation->set_rules($rules);

if ($this->validation->run() == FALSE) {

$data['tytul']['value'] = $this->input->post('tytul');

$data['tresc']['value'] = $this->input->post('tresc');

$this->load->view('form', $data);

}

else {

// przypisanie danych z formularza

// wyświetlenie wyników

$news['tytul'] = $this->input->post('tytul');

$news['tresc'] = $this->input->post('tresc');

$this->load->view('wynik', $news);

}

}

}

Page 16: PHP Solutions 02 2007 PL

Code Igniter

www.phpsolmag.org16

Dla początkujących

PHP Solutions Nr 2/2007

Ograniczanie ilości wyników

$this->db->limit(Limit);

Dodawanie wpisu

$dane = array('pole' => wartość,

'pole2' => wartość);

$this->db->insert('tabela', $dane);

Metoda insert dodaje wpis do bazy da-nych. Przyjmuje ona jako parametr nazwę tabeli oraz tablicę asocjacyjną lub obiekt z danymi. Tablica jako klucze musi za-wierać nazwy pól, a jako ich wartości – te wartości, które mają być dodane do bazy.

Zmiana wpisu

$this->db->update('tabela', $dane);

Parametry jak dla "insert". Modyfikuje wpisy nowymi danymi, zazwyczaj towa-rzyszy jej warunek WHERE do modyfika-cji określonego wpisu.

Kasowanie wpisów

$this->db->delete('tabela', array('pole'

=> wartość, 'pole' => wartość));

Kasuje wpisu, dla których podane pola w tablicy spełniają warunek

Łączenie tabel – JOIN

$this->db->select('*');

$this->db->from('tabela1');

$this->db->join('tabela2',

'tabela2.pole = tabela1.pole');

$query = $this->db->get();

Pozwala połączyć wyniki z dwóch zależ-nych tabel. Przykładowy model dla modu-łu nowości przedstawia Listing 1.

Wykonywanie zapytań SQL

$query = $this->db->query(

'Zapytanie SQL');

Metoda "query" wykonuje zapyta-nie i zwraca do niego uchwyt. Dodat-kowo do dyspozycji mamy: $this->db->

escape('łańcuch'); Odpowiednio zabez-piecza znaki specjalne języka SQL.

$this->db->dbprefix

Zwraca prefiks do tabel ustawiony w kon-figuracji.

Wyświetlanie pobranych danychWykonanie własnego zapytania SELECT czy też skorzystanie z "get" w ActiverRecords nie daje nam od razu wyników. Dostajemy uchwyt do nich. By otrzy-

mać wyniki musimy wykonać na uchwy-cie metodę result() zwracającą wyniki w postaci obiektu lub result _ array() w postaci tablicy.

FormularzeCode Igniter posiada pomocnik (ang. helper) do obsługi formularzy. By za-ładować go w autoload.php dodajemy „form” do tablicy $autoload['helper'] lub też ładujemy go bezpośrednio w kontrolerze:

$this->load->helper('form');

Otwarcie Formularza

form_open('kontroler/metoda');

Zwraca tag form z atrybutem „action” ustawionym na podany odnośnik. Dodat-kowo jako drugi parametr można prze-kazać tablicę asocjacyjną, której klucze i wartości staną się atrybutami i ich warto-ściami taga form.

Pola ukryte

form_hidden('nazwa', 'wartość');

Zwróci kod pola ukrytego z podanymi da-nymi.

Pole Input/text

form_input('nazwa', 'wartość');

Można także zastosować tablicę:

$data = array(

'name' => 'username',

'id' => 'username',

'value' => 'johndoe',

'maxlength' => '100',

'size' => '50',

'style' => 'width:50%',

);

echo form_input($data);

// wynik:

<input type="text" name="username"

id="username" value="johndoe"

maxlength="100" size="50"

style="width:50%" />

Lista Select

$options = array(

'small' => 'Small Shirt',

'med' => 'Medium Shirt',

'large' => 'Large Shirt',

'xlarge' => 'Extra Large Shirt',

Listing 4. Implementacja wyszukiwarki Flickr w kodzie strony

<h1>Wyszukiwarka Flickr</h1>

<?PHP

echo $content; ?>

Widok flickr_form.php wygląda następująco:

<center>

<?=$this->validation->error_string; ?>

</center>

<?php

echo form_open('flickr/index'); ?>

<table width="90%" border="0" cellspacing="3" cellpadding="3">

<tr><td width="180"><B>Fraza</B></td><td>

<?php echo form_input($query); ?></td></tr><tr><td> </td><td><?php echo form_submit('submit', 'Szukaj'); ?></td></tr></table>

<?php

echo form_close(); ?>

Natomiast flickr_result.php:

<?PHP

foreach($flickr['img'] as $val) {echo '<a href="http://www.flickr.com/photos/'.$val['owner'].'/'.$val['id']. '/"><img src="http://static.flickr.com/'.$val['server'].'/'.$val['id'].

'_'.$val['secret'].'_s.jpg" style="margin:5px;" alt="" /></a>';

}

Page 17: PHP Solutions 02 2007 PL

Code Igniter

www.phpsolmag.org 17

Dla początkujących

PHP Solutions Nr 2/2007

);

echo form_dropdown('nazwa', $options);

Otrzymamy:

<select name="nazwa">

<option value="small">Small Shirt

</option>

<option value="med">Medium Shirt

</option>

<option value="large">Large Shirt

</option>

<option value="xlarge">Extra Large Shirt

</option>

</select>

Checkbox

form_checkbox('nazwa', 'wartość')

Co zwróci kod checkboxa. By był zazna-czony, jako trzeci parametr wystarczy ustawić wartość logiczną True.

Radio

form_radio('nazwa', 'wartość')

Obsługa taka sama jak checkboxa.

Przycisk Submit

form_submit('nazwa', 'wartość')

Zwraca kod przycisku submit, gdzie "war-tość" to tekst jaki pokaże się na przycisku.

Zakończenie formularza

form_close()

Zwróci tag zamykający „form”. Można ja-ko argument przekazać łańcuch - zosta-nie od dodany za tagiem zamykającym formularz.

By w kontrolerze uzyskać dostęp do pola z wysłanego formularza wystarczy skorzystać z metody input:

$this->input->post('nazwa Pola');

Walidacja FormularzyCode Igniter oferuje również bibliotekę do walidacji m.in. formularzy. Wystar-czy w autoload.php dodać dla tablicy libraries wartość „validation”. Listing 3 przedstawia przykładowy kontroler wy-korzystujący pomocnik form i bibliote-kę validation.

Biblioteka „validation” oferuje kilkana-ście warunków:

• required: pole jest wymagane, musi mieć jakąś wartość,

• valid _ email: pole musi zawierać po-prawny adres email,

• numeric: pole musi zawierać same liczby,

• alpha _ dash: pole może zawierać je-dynie znaki alfanumeryczne, podkre-ślenia i myślniki,

• alpha _ numeric: pole może zawierać jedynie znaki alfanumeryczne,

• alpha: pole może zawierać jedynie li-tery,

• exact _ length[*]: wartość pola mu-si mieć określoną długość exact_length[6] - 6 znaków,

• max _ length[*], min_length[*]: war-

tość pola musi mieć maksymalnie/minimalnie * znaków.

Opcje można łączyć za pomocą znaku |

$rules['username'] = "required|

min_length[5]|max_length[12]";

Możemy dodać dodatkowo do parametrów :

• xss _ clean: oczyszcza dane ze "zło-śliwego" kodu (ataki XSS),

• prep _ for _ form: zamienia znaki HTML na znaki specjalne przez co można je wyświetlać bez problemu w formularzach,

• prep _ url: doda http:// do linków jeże-li brakuje,

• strip _ image _ tags: usunie tagi IMG zostawiając czyste linki URI.

Listing 5. Zmodyfikowany kontroler wyszukiwarki Flickr

<?PHP

class Flickr extends Controller{

private $api_key;

public function __construct() {

parent::Controller();

$this->api_key = 'TWÓJ KLUCZ API';

}

public function index() {

$ar = Flickr::_search('kubica');

foreach($ar['img'] as $val) {

echo '<a href="http://www.flickr.com/photos/'.$val['owner']. '/'.$val['id'].'/"><img src="http://static.flickr.com/'.

$val['server'].'/'.$val['id'].'_'.$val['secret'].

'_s.jpg" style="margin:5px;" alt="" /></a>';

}

}

private function _search($query) {

$x = simplexml_load_file('http://www.flickr.com/services/rest/?method=flickr.

photos.search&text='.$query.'&per_page=20&api_key='.$this->api_key);

$ret['total'] = (int)$x->photos['total']; $r = array();

foreach($x->photos->photo as $res) {

$r[] = array('id' => (int)$res['id'], 'title' =>(string)$res['title'], 'owner' => (string)$res['owner'], 'secret' =>

(string)$res['secret'], 'server' => (int)$res['server']); }

$ret['img'] = $r;

return $ret; }

}

Page 18: PHP Solutions 02 2007 PL

Code Igniter

www.phpsolmag.org18

Dla początkujących

PHP Solutions Nr 2/2007

Wyszukiwarka FlickrStworzymy teraz prostą wyszukiwarkę Flickr.com wykorzystując udostępnione API serwisu. Tworzymy prosty kontro-ler: Po wstawieniu własnego Klucza API kontroler będzie w pełni sprawny i wy-świetli 20 pierwszych grafik znalezionych dla frazy „kubica”. Metoda _ search jest niedostępna poprzez odnośniki, gdyż za-czyna się od znaku podkreślenia. Metoda index wykorzystuje ją i wyświetla zawar-tość zwróconej tablicy. Efekt przedstawio-no na Rysunku 1.

Teraz rozszerzymy istniejący kon-troler o formularz na poszukiwaną frazę oraz skorzystamy z widoków. Kod zmo-dyfikowanego kontrolera widzimy na Li-stingu 3.

Kontroler korzysta z trzech widoków. Pierwszy – index.php jest dość prosty.

Otrzymaliśmy prostą wyszukiwarkę zdjęć z serwisu flickr.com

Siła MVCStworzyliśmy prostą aplikację według wzorca MVC. Prawdziwe aplikacje jak np. forum dyskusyjne to kilka tysięcy lub wię-cej linii kodu, który musimy w stanie roz-wijać. Jakie są zalety MVC?

• każdym elementem (logika, interfejs i model aplikacji) mogą zajmować się inne osoby,

• można stosować dopasowane do ele-mentu programy (np. edytory xhtml do szablonów),

• upraszcza aktualizacje kodu,• dla kontrolerów nie jest ważne jak

model zdobywa dane, ważne jest jedynie w jakiej postaci je zwra-ca. Zachowując tą samą struktu-rę danych możemy zmienić typ ba-zy danych bez edycji całego kodu aplikacji.

Niektórzy mogą spytać, czy nie war-to wybrać jakiś gotowy CMS i nauczyć się go rozszerzać. Otóż jest to jedna możliwość, ale tworzenie nowych mo-dułów do CMS nie jest ani przyjemne ani proste jak we frameworkach. Doku-mentacja API dla modułów jest mniej lub bardziej kompletna, ale co ważniej-sze – każdy CMS narzuca różne ogra-niczenia, które mogą bardzo utrudnić tworzenie specyficznych aplikacji. Dla przykładu – duże i dojrzałe CMSy ta-kie, jak postnuke czy mambo nie ma-ją natywnych modułów for dyskusyj-nych. Istnieją np. zintegrowane modu-ły phpBB, ale nie jest to natywny mo-duł, jak np. w php-fusion czy Drupalu. Wspomniany Drupal, o coraz bardziej rosnącej popularności, to nie zwykły CMS lecz połączenie CMSa z prostym frameworkiem, dzięki czemu zmodyfi-kowane i rozbudowane instalacje Dru-pala działają na wielu serwisach.

Na zakończeniePowyższy artykuł miał za zadania za-prezentowanie możliwości prostego w 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 z tym narzędziem umożliwi ci szybkie i sprawne tworzenie CMSów jak i in-nych skryptów. n

Piotr Maliński jest studentem Politech-niki Warszawskiej na kierunku Techno-logia Chemiczna. Od czterech lat zajmu-je sie tworzeniem aplikacji w PHP, jak też od niedawna o Pythonie. Jest rów-nież autorem serwisów o nazwie Biblio-teka Riklaunima.

Kontakt: [email protected]

O autorze

Listing 6. Ciało klasy Flickr

<?PHP

class Flickr extends Controller {private $api_key;

public function __construct() { parent::Controller();

$this->response = array(); $this->api_key = 'KLUCZ API';

}

public function index() { $data["query"] = array('name' => 'query'); $rules['query'] = "required|max_length[20]|min_length[3]|xss_clean";

$this->validation->set_rules($rules);

if ($this->validation->run() == FALSE) { $data['query']['value'] = $this->input->post('query');

$this->response['content'] = $this->load->view('flickr_form', $data, True);

}

else { $ar = Flickr::_search($this->input->post('query'));

$this->response['content'] = $this->load->view(

'flickr_result', array('flickr' => $ar), True); }

$this->load->view('index', $this->response);

}

private function _search($query) { $x = simplexml_load_file('http://www.flickr.com/services/rest/?method=flickr.

photos.search&text='.$query.'&per_page=20&api_key='.$this->api_key);

$ret['total'] = (int)$x->photos['total']; $r = array();

foreach($x->photos->photo as $res) { $r[] = array('id' => (int)$res['id'], 'title' =>(string)$res['title'], 'owner' => (string)$res['owner'], 'secret' => (string)$res['secret'], 'server' => (int)$res['server']); }

$ret['img'] = $r;

return $ret; }

}

Page 19: PHP Solutions 02 2007 PL
Page 20: PHP Solutions 02 2007 PL

www.phpsolmag.org20

Projekty

PHP Solutions Nr 2/2007

SEO

www.phpsolmag.org 21

Projekty

PHP Solutions Nr 2/2007

Webmaster, projektant i progra-mista WWW odpowiedzą, że standardy służą każdemu in-

ternaucie. Dokładniej służą temu, aby wszystkie przeglądarki poprawnie wyświe-tlały stronę spełniającą wytyczne W3C. Standardy mają zapewnić długoterminowe bezpieczeństwo. Nowa wersja przeglądar-ki lub nowa technologia nie powinny spo-wodować konieczności zmiany witryny.

Wcześniej zwróciłem jednak uwagę, że „czytelnikami” stron WWW nie są jedynie in-ternauci korzystający z przeglądarek interne-towych. Innym ważnym odbiorcą treści pu-blikowanych w internecie są wyszukiwarki. Systemy wyszukiwawcze starają się prze-czytać jak najwięcej stron WWW, a następ-nie zindeksować i uporządkować ze wzglę-du na ich treść. Takie zadanie wymaga bar-dzo dobrego zrozumienia struktury danych.

Zgodnie z powyższym można posta-wić tezę, że wspierając standardy W3C, optymalizujemy strony dla wyszukiwarek internetowych.

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.

SEO i standardy W3CSearch Engine Optimization (SEO), czyli optymalizacja stron WWW dla wyszukiwa-rek internetowych, jest jednym z elementów pozwalających promować serwisy WWW. Optymalizacja może stanowić część szer-szej strategii marketingowej w internecie – Search Engine Maketing (SEM). Dla ko-mercyjnych przedsięwzięć kwestia optyma-lizacji dla wyszukiwarek jest bezsporna, po-zwala bowiem skutecznie dotrzeć do poten-cjalnych zainteresowanych z informacją o

Wsparcie SEO w systemach zgodnych ze standardami W3C na przykładzie eZ PublishJuliusz Całyniuk

Stopień trudności: lll

Co należy wiedzieć...Czym są standardy i technologie WWW: XHTML, CSS, WCAG, RSS; podstawy XHTML; znajomość podstaw budowy serwisów WWW.

Co obiecujemy...Optymalizacja stron WWW dla wyszuki-warek (SEO). Dowiesz się, jaki jest zwią-zek pomiędzy standardami W3C i SEO. Nauczysz się też podstaw optymalizacji dla wyszukiwarek.

Page 21: PHP Solutions 02 2007 PL

www.phpsolmag.org20

Projekty

PHP Solutions Nr 2/2007

SEO

www.phpsolmag.org 21

Projekty

PHP Solutions Nr 2/2007

produktach lub usługach. SEO ma ogrom-ne znaczenie dla witryn WWW, a zwłasz-cza przedsięwzięć komercyjnych. Świadomi tego faktu projektanci potrafili zaimplemen-tować wsparcie dla SEO w budowanych przez siebie systemach zarządzania treścią. Standardy W3C zapewniają wsparcie SEO, ponieważ promują:

• oddzielenie treści od formy jej prezen-tacji (wykorzystanie XHTML dla opisu treści, CSS dla formatowania),

• właściwe wykorzystanie języka opisu strony (brak błędów składni w XHTML ułatwia systemom wyszukiwawczym po-prawnie interpretować treść dokumentu),

• stosowanie właściwej struktury doku-mentu (XHTML udostępnia znaczni-ki dla podstawowych jednostek infor-macyjnych dokumentu: nagłówki, listy, paragrafy, odnośniki, grafiki itd.),

• wykorzystanie metainformacji (XHTML pozwala na zdefiniowanie: tytułu, opi-su zawartości, słów kluczowych, usta-wień języka itp.),

• dostępność treści stron (wskazania Web Content Accessibility Guidlines – WCAG – promują np. dodawanie alternatywnych opisów dla obiektów osadzanych, typu obrazki i multime-dia oraz alternatywnych bloków <no-script> i <noframes>).

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 standardyeZ Publish przedstawiany jest jako:

• Content Management System (CMS) – system zarządzania treścią zawierają-

cy pełną wbudowaną funkcjonalność po-trzebną do zarządzania informacją z bar-dzo elastycznym systemem szablonów,

• Content Management Framework (CMF) – wzorzec projektowy dla różnorodnych systemów informacyjnych; jest otwarty, elastyczny, rozszerzalny, skalowalny, a przede wszystkim wspiera standardy.

eZ Publish wykorzystuje takie standardy i protokoły jak: XHTML, CSS, WCAG, RSS, Open Document, SOAP, WebDav.

Najbardziej istotne z punktu widze-nia systemu WCM są standardy kreowa-ne przez W3C, czyli XHTML, CSS oraz WCAG. Zgodność z nimi zapewnia rów-nież pomoc w optymalizowaniu serwisów dla systemów wyszukiwawczych.

Wbudowane wsparcie dla SEOeZ Publish posiada mechanizm “przyja-znego adresowania”, który podzielić moż-na na 3 poziomy:

• Adresowanie systemowe (automa-tyczne), czyli zapisywanie adresów URL pozbawionych znaków innych niż alfanumeryczne oraz znaków podkre-ślenia. Podstawową zaletą tej transla-cji jest pozbycie się znaków charakte-rystycznych dla przesyłania parame-trów w żądaniu GET protokołu HTTP.

Uzyskujemy dzięki temu adres postaci: http://www.domena.com/content/view/full/66 w miejsce przykładowego ad-resu pozbawionego translacji: http://www.domena.com/index.php?id_kat=news&art=123&SessID=123jkls8je3k-s905lpswas23we89d9ei.

• Translacja z adresowania systemo-wego do “nice urls” (automatyczna), czyli zamiana parametrów systemo-wych na czytelne dla człowieka fra-zy. Translacja odbywa się na podsta-wie nazw kolejnych obiektów w ścież-ce do przeglądanego dokumentu. Przykładowo, zamiana adresu: http://www.domena.com/content/view/full/66 na “nice url”: http://www.domena.com/oferta/uslugi/seo. W efekcie takiej zamia-ny systemy wyszukiwawcze otrzymują dodatkową informację (słowa kluczowe) na temat zawartości dokumentu.

• Translacja manualna dokonywana przez administratora serwisu. Dzięki odpowiedniej funkcjonalności eZ Pu-blish administrator może samodziel-nie dokonać konwersji adresu. Taka funkcja nie jest wykonywana często, jednak może znacznie skrócić adres oraz podkreślić słowa kluczowe. Funk-cja jest również przydatna w sytuacji, kiedy adres URL powinien być łatwy do zapamiętania (np. trzeba go podać słownie lub zamieścić na plakacie).

Rysunek 1. Narzędzie translacji adresów URL dostępne z poziomu panelu administra-cyjnego eZ Publish

Page 22: PHP Solutions 02 2007 PL

SEO

www.phpsolmag.org22

Projekty

PHP Solutions Nr 2/2007

Przykładowo, ważną informację o promo-cji przedstawianą na stronie zamieszczo-nej głęboko w strukturze serwisu WWWi adresowaną: http://www.domena.com/firma/aktualnosci/promocje/promocja_zima_2006_2007, możemy uprościć do: http://www.domena.com/promocja

Poprawne formatowanie dokumentówJak wspomniałem wyżej, standardy siecio-we są sprzymierzeńcem SEO. Podstawo-wym zadaniem wyszukiwarek jest indek-sowanie treści tekstowych. Aby przepro-wadzić ten proces, system wyszukiwaw-czy musi rozumieć czytane dokumenty. Nie trudno się zatem domyśleć, że zgod-ność dokumentów ze standardami W3C, a przede wszystkim HTML i XHTML jest bardzo istotna dla tego procesu.

System WCM powinien zatem wspierać standardy, aby sprawić, by dokumenty były czytelne nie tylko dla ludzi (korzystających z interfejsu przeglądarek WWW), ale również robotów wyszukiwarek. System powinien zapewnić przesłanie metainformacji charak-teryzujących dany dokument:

Format dokumentu.Przykładowo dla XHTML 1.0 Transitional:

<!DOCTYPE html PUBLIC "-//W3C//DTD

XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/

DTD/xhtml1-transitional.dtd">

Język dokumentu oraz kodowanie znaków.

<html xmlns="http://www.w3.org/1999/

xhtml" xml:lang="en" lang="en">

<meta http-equiv="Content-Language"

content="en-GB" />

<meta http-equiv="Content-Type"

content="text/html;

charset=iso-8859-1" />

Tytuł dokumentu.

<title>Tytuł przeglądanej strony</title>

Dodatkowe metainformacjeNajczęściej wykorzystywane znaczniki <meta> zawierają opis zawartości doku-mentu oraz słowa kluczowe:

l <meta name="description" conten-t="eZ Publish Documentation" />,

l <meta name="keywords" content="eZ Publish, documentation, manual, refe-rence, eZ systems" />.

Wszystkie z wymienionych wytycznych wspierane są przez wbudowane szablony eZ Publish. Oto przykładowy szablon ukła-du strony pagelayout.tpl:

<!DOCTYPE html PUBLIC "-//W3C//

DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/

DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/

xhtml" xml:lang="{$site.

http_equiv.Content-language|wash}"

lang="{$site.http_equiv.

Content-language|wash}">

<head>

{include uri="design:page_head.tpl"}

</head>

<body>

<!-- tresc dokumentu -->

</body></html>

Ustawienia językowe:

{$site.http_equiv.Content-language|wash}

czytane są z pliku konfiguracyjnego syste-mu site.ini:

[RegionalSettings]

Locale=eng-GB

W szablonie page_head.tpl włączanym do głównego układu strony (pagelayout.tpl), ustawiane są między innymi znaczni-ki <meta> czytane z konfiguracji zawartej również w pliku site.ini:

[SiteSettings]

MetaDataArray[author]=eZ systems

MetaDataArray[copyright]=eZ systems

MetaDataArray[description]=Content

Management System

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 stosunku do treści kolejnych akapitów),

Rysunek 2. Zawartość znacznika <title> wyświetlona przez przeglądarkę

Rysunek 3. Formatowanie treści w eZ Publish Online Editor

Page 23: PHP Solutions 02 2007 PL

SEO

www.phpsolmag.org 23

Projekty

PHP Solutions Nr 2/2007

• elementy formatowania pomieszane z treścią strony (np. wstawienie instruk-cji dla CSS bezpośrednio w znaczniku HTML lub „tworzenie nagłówka” z ko-mórki tabeli przez odwołanie do odpo-wiedniej klasy zdefiniowanej w CSS),

• skomplikowana interpretacja – kod źródłowy HTML był zwykle dużo więk-szy i często składał się z wielokrotnie zagnieżdżonych tabel.

Ponieważ podstawowym celem stawia-nym CMS jest oddzielenie warstw: treści i prezentacji, szablony wzorcowe w eZ Pu-blish skonstruowane są bez użycia tabel, a oparte na blokach <div>. Taka konstruk-cja pozwala zamknąć stronę WWW w czy-stej formie dokumentu XML.

Zalety takiego rozwiązania są istotne, ponieważ niwelują wady stylu tabelarycz-nego, oferując w zamian:

• oddzielenie treści (zamkniętej w for-macie XHTML) od formy (formatowa-nie w CSS),

• czystą konstrukcję dokumentu (widać, gdzie jest tytuł, nagłówki listy i paragrafy)

• możliwość prostej integracji – importu lub eksportu danych,

• lekką stronę z treścią – mniejszy roz-miar dokumentu,

• przenośność pomiędzy przeglądarka-mi (również urządzeń mobilnych z ma-łymi ekranami).

Znaczniki treści formatowanychWiększość nowoczesnych systemów WCM udostępnia redaktorowi wbudowa-ną aplikację – edytor online, który pozwa-la formatować treść stron WWW. Ważne jest, aby zapisywana po sformatowaniu treść była również zgodna ze standarda-mi W3C. Generowanie kodu zawierające-go wpisane formatowanie CSS lub znacz-niki <FONT> jest niedopuszczalne.

eZ Publish posiada własne dedykowa-ne rozwiązanie wyróżniające się zgodno-ścią ze standardem, za który obrano kre-owany przez W3C XHTML 2. Z pozoru podstawowe formatowanie tekstu jako na-główków, paragrafów, list punktów stano-wi jeden z kluczowych elementów odpo-

wiedniego interpretowania jego zawarto-ści przez wyszukiwarki. Format zapisane-go dokumentu XHTML 2.0 jest następnie konwertowany na zgodny z XHTML 1.0 przy wykorzystaniu szablonów systemu.

Wysokiej jakości formatowanie zgod-ne z XHTML jest kluczowe dla SEO. Po-zwalając redaktorom serwisu na dowol-ność (wstawianie niepoprawnego kodu HTML) niszczy się efekt pracy włożonej w tworzenie zgodnych ze standardami sza-blonów stron.

DostępnośćWskazówki WCAG służą dostosowa-niu treści dostępnych na stronach WWW użytkownikom starszym, niepełnospraw-nym oraz interpretację przez urządze-nia mobilne. Podobnie, jak inne standar-dy kreowane przez W3C, daje on również silny oręż do optymalizacji dla wyszukiwa-rek. Jedną z reguł, którą powinny spełniać witryny zgodne z WCAG, jest konieczność opisywania grafik.

Mówi się, że jeden obraz znaczy wię-cej niż tysiąc słów. Prawdopodobnie dla-tego wyszukiwarki traktują opisy alterna-tywne bardzo poważnie. Nie są w stanie zinterpretować treści ilustracji inaczej niż przez opis, który został do niego dodany.

Także w tym zakresie eZ publish udo-stępnia wygodne narzędzia redaktorskie. Dodanie obrazka i opisanie go pozwoli wygenerować kod XHTML z opisem alter-natywnym, czyli znacznik postaci:

<img src="ilustracja.png"

alt="Alternatywny opis dla ilustracji" />

Mapa stronyDla procesu indeksowania stron WWW niezwykle istotne jest wewnętrzne linko-wanie, czyli powiązania pomiędzy strona-mi serwisu. Stąd dla wyszukiwarek klu-czową rolę odgrywają strony-bramy, czy-li strony zawierające dużą liczbę odnośni-ków wewnętrznych. Najpopularniejszym przykładem takiej strony jest „Mapa ser-wisu”.

Dynamiczna mapa nie jest już nowo-ścią w systemach typu WCM. Jest ona cenna, ponieważ wiarygodnie odzwier-ciedla strukturę serwisu, a przez to do-brze opisuje jego zawartość. Dodatkowo, nazwy działów i dokumentów są wysoko oceniane, ponieważ mają formę nagłów-ków i odnośników.

eZ publish umożliwia generowanie ma-py serwisu lub jego dowolnej gałęzi. Jeżeli zatem tworzymy stronę z kilkoma rozbudo-wanymi działami lub nawet kilka serwisów WWW opartych na jednej instancji systemu CMS, możliwe jest niezależne generowanie map dla działów lub serwisów.

Mapa strony generuje się automa-tycznie po odwołaniu do adresu: http://www.domena.pl/content/view/sitemap/x, gdzie “x” oznacza numer węzła w drze-wie struktury zawartości. Przykładowy kod strony związany bezpośrednio z mapą może posiadać następującą formę:

<h1><a href=”/”>Mapa strony Domena.com

</a></h1>

<h2><a href=”/dzial_pierwszy”>

Dział pierwszy</a></h2>

<ul>

<li><h3><a href="/

dzial_pierwszy/folder_x">

Folder X</a></li>

<li><h3><a href="/

dzial_pierwszy/

folder_y">Folder Y</a></li>

</ul>

<h2><a href=”/dzial_drugi”>

Dział drugi</a></h2>

<ul>

<li><h3><a href="/

dzial_drugi/folder_a">

Folder A</a></li>

<li><h3><a href="/

dzial_drugi/folder_b">

Folder B</a></li>

<li><h3><a href="/

dzial_drugi/folder_c">

Folder C</a></li>

</ul>

Rysunek 4. Kod wygenerowany przez eZ Publish Online Editor

Rysunek 5. Efekt wyświetlenia tekstu al-ternatywnego grafiki przez przeglądarkę

Rysunek 6. Efekt wyświetlenia tekstu al-ternatywnego grafiki przez przeglądarkę z zablokowaną opcją pobierania obrazów

Page 24: PHP Solutions 02 2007 PL

SEO

www.phpsolmag.org24

Projekty

PHP Solutions Nr 2/2007

RSSNowoczesne systemy wyszukiwawcze cenią wysoko aktualne treści, dlatego dla procesu SEO ważna jest częsta aktuali-zacja zawartości. Blogi oraz wszelkiego typu serwisy dostępne w formie RSS sta-nowią cenne źródło bieżącej informacji.

Dodatkową zaletą witryn WWW, udo-stępniających subskrypcję RSS, jest moż-liwość publikowania skrótów wiadomości w innych serwisach. W takich sytuacjach stro-na otrzymuje to, co w przypadku rankingu Google jest najważniejsze – odnośniki do własnej treści z zewnętrznych witryn.

Możliwość importu i eksportu kana-łów RSS jest jedną z podstawowych funk-cjonalności eZ Publish. Wykorzystując na-rzędzia dostępne w panelu administracyj-nym, automatyzujemy generowanie RSS dla eksportu oraz importu.

Import, czyli pobieranie informacji z obcej lokalizacji, pozwala wzbogacić ser-wis o:

• częstą aktualizację,• wartościowe treści związane z tema-

tem witryny (wzmocnienie słów klu-czowych),

• odnośniki zewnętrzne do cennych źró-deł informacji (wartościowe źródła mo-gą wzmacniać wiarygodność strony).

Eksport, czyli udostępnianie własnych treści:

• wzbogaca rozwiązanie o nowy kanał komunikacyjny,

• pozwala uzyskać odnośniki do naszej strony, które pochodzą z innych witryn.

Samodzielne rozszerzenie wsparcia SEOPoza wymienionymi wyżej przykładami wsparcia SEO przez systemy WCM, a

dostarczonymi przez eZ Publish „w pu-dełku”, można wzbogacić go o nową funkcjonalność. Rozszerzalność syste-mu oraz możliwość modyfikacji to rów-nież cechy ważne dla programistów roz-wiązań bazujących na WWW. Dzięki nim można zaimplementować ulepszo-ną obsługę znaczników <meta>, albo Google Sitemaps.

MetatagiGoogle jasno informuje o całkowi-tym ignorowaniu zawartości tagów me-ta “keywords”. Musimy jednak pamię-tać, że inne mechanizmy wyszukiwaw-cze niekoniecznie postępują w ten sam sposób. Jeśli nawet metatagi nie stano-wią podstawy opisu informacji zawartych na stronie, to stanowią część opisu jego zawartość.

Warto zatem w przypadku, gdy SEO jest dla nas bardzo ważne, skonstruować mechanizm obsługi dla osób redagują-cych treść. W przypadku eZ Publish zada-nie jest proste i polega na:

• rozszerzeniu klasy Artykuł, czyli do-daniu nowych atrybutów – pól teksto-wych o nazwach: „Słowa kluczowe” oraz “Description”,

• dodaniu krótkiego skryptu szablo-nowego, który wyświetli zawartość wypełnionych pól w znacznikach <meta name=”description”> i <meta name=”keywords”> niezależnie dla każ-dej strony.

Google SitemapW Google opracowano technikę wspie-rającą proces indeksowania witryn. Go-ogle Sitemaps to dokumenty XML o spe-cyficznej składni, odzwierciedlające struk-turę serwisu.

Dla systemu WCM, którego głównym zadaniem jest oddzielenie treści od pre-zentacji, generowanie dowolnego formatu dokumentu nie powinno stanowić proble-mu. System eZ Publish pozwala budować szablony w dowolnym standardzie zgod-nym z XML. W domyślnej wersji system pracuje z XHTML 1.0 Transitional. Można jednak opracować własny format.

Specjalnie dla potrzeb Google Site-maps udostępniona została wtyczka do systemu, pozwalająca generować doku-menty w takim właśnie formacie.

Rozszerzenie można pobrać ze stro-ny społeczności: http://ez.no/community/contribs/template_plugins/googlesite-maps_extension

PodsumowanieJednym z celów, jaki chcemy osiągnąć przy budowie strony WWW, jest dotarcie do sze-rokiego grona zainteresowanych prezento-waną tematyką odbiorców. Pragniemy, aby planowana grupa docelowa wiedziała o je-go istnieniu. Często nie możemy sobie po-zwolić, żeby było inaczej. Najlepszym przy-kładem jest sklep internetowy.

SEO to nie pozycjonowanie, ale opty-malizacja – pomaganie wyszukiwarce w odpowiedniej interpretacji zawartości wszystkich stron serwisu WWW.

Mając zamiar wykorzystać system CMS, gotowe narzędzie zapewniają-ce podstawową funkcjonalność zarzą-dzania treścią, należy zwrócić uwagę, czy respektowane są w nim standar-dy W3C. Jeśli tak jest, uzyskamy także wsparcie dla procesu SEO.

Wbudowana konwersja adresów URL pozwalająca uzyskać przyjazne odnośni-ki, staje się normą. Należy jednak zwró-cić uwagę na inne elementy optymalizacji, a przede wszystkim odpowiednie dostoso-wanie do standardów sieciowych. Czytelny dokument jest sprzymierzeńcem SEO. n

Rysunek 7. Funkcjonalność eksportu i importu RSS w panelu administracyjnymeZ Publish

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:[email protected]

O autorze

Page 25: PHP Solutions 02 2007 PL

Strona poświęcona językowi PHP. Skierowa-na głównie do webmasterów i twórców opro-gramowania.

www.strefaphp.net

Strona, na której znajdziesz profesjonalne sza-blony stron www. Ponadto prezentuje tutoriale, artykuły i porady dla webmasterów.

www.d4u.pl

Strona jest polską bazą tutoriali, zawierającą różnorodne teksty o tematyce informatycznej.

www.webtutorials.pl

Strona poświęcona językowi php. Można tu znaleźć m.in. artykuły oraz dział “download” oraz wypowiedzieć się na forum.

www.php.org.pl

Portal w całości poświęcony językowi PHP. Można tu znaleźć m.in. recenzje, artykuły oraz newsy poświęcone temu zagdnieniu.

www.php.pl

Strona zajmująca się różnymi zagadnieniami z działu IT. Prezentuje m.in. newsy, artykuły oraz pliki do ściągnięcia i forum.

www.huntersq2.boo.pl

Misją serwisu jest dostarczanie rzetelnych in-formacji z zakresu szeroko pojętej informatyki. Strona zawiera newsy m.in. z działów: progra-mowania, bezpieczeństwa oraz Internetu.

www.itnews.icx.pl

Główna strona firmy gdaq.pl multimedia zajmu-jącej się kreowaniem wizerunku firm poprzez projektowanie stron, hosting, e-marketing etc.

www.gdaq.pl

Strona zawierająca skrypty, newsy i artykuły dotyczące aplikacji CMS oraz forum poświęco-ne temu zagadnieniu.

www.trycms.org

Główna strona studentów Politechniki War-szawskiej.

www.polibuda.info

Serwis dla początkujących, jak i zaawansowa-nych webmasterów. Zawiera gotowe szablony stron oraz posegregowane skrypty PHP i Ja-vaScript.

www.szablonypro.com

To serwis branży IT, oferujący m.in. newsy, ar-tykuły, recenzje książek i magazynów oraz fo-rum. Strona obejmuje również patronat nad projektami IT.

www.webhat.pl

Page 26: PHP Solutions 02 2007 PL

www.phpsolmag.org26 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

Ankiety AJAX-owe Dla zaawansowanych

W dobie społeczności Inter-netu istotne jest, by znać opinie jego użytkowników

na wszelkie tematy. Na wielu witry-nach spotykamy więc ankiety, w któ-rych oceniamy pewne zachowania, sy-tuacje, zdarzenia, czy też informuje-my o naszych upodobaniach. Na pew-no jednak każdy z nas trafił na ankie-tę, która zmusiła go do refleksji – jeże-li bowiem mamy do wyboru dwie nie-mal równoważne możliwości, wybranie jednej, oznacza dyskredytację drugiej. Ten mankament powoduje, że ankiety w Internecie nie odzwierciedlają ide-alnie gustów ankietowanych. Idealna ankieta powinna więc pozwalać nam na udzielenie kredytu nie tylko jednej opcji. Jakkolwiek taki stan rzeczy wy-daje się oczywisty w życiu codzien-nym. Tak, jest to trudne zadanie do zrealizowania przy pomocy formularzy dostępnych w HTML. Możemy wpraw-dzie obok każdej z pozycji umieścić

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.

osobne pole na wybór oceny, jednak wynik będzie uzyskany kosztem wielu kliknięć Internauty – a więc często je-go frustracji. Takiej sytuacji nie ryzyku-ją webmasterzy, tworząc ankiety z jed-ną możliwą odpowiedzią. Od 2005 ro-ku, kiedy to rozpowszechniła się tech-nologia AJAX, zadanie to stało się nie-mal trywialnie proste. Nieznajomość nowej technologii, niechęć do języka JavaScript i obawy o niekompatybil-ności przeglądarek powodują jednak, że w Internecie niemal niemożliwe jest spotkanie ankiet hierarchicznych. Re-

Ankiety w stylu rankingowym z użyciem AJAX-aKrzysztof Trynkiewicz

W SIECI

• http://prototype.conio.net/– framework AJAX-owy,

• http://script.aculo.us/– pakiet Script.Aculo.Us,

• http://www.sergiopereira.com/articles/prototype.js.html – obszerny opis Prototype,

• http://ajax.eldoras.com – witryna projektu ankiet AJAX-owych Autora.

Stopień trudności: lll

Co należy wiedzieć…Przydatna będzie znajomość podstaw technologii AJAX.

Co obiecujemy…Dowiesz się, jak tworzyć ankiety w sty-lu rankingowym przy pomocy technolo-gii AJAX.

Page 27: PHP Solutions 02 2007 PL

www.phpsolmag.org26 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

Ankiety AJAX-owe Dla zaawansowanych

języka CSS (reprezentowanym przez identyfikatory) efektów pojawiania się, ukrywania, przenoszenia i wielu in-nych, kompatybilnych z większością nowoczesnych przeglądarek. Stosującwszystkie te udogodnienia, możemy stworzyć efektowny oraz efektywny system rankingowy.

Niezbędne przygotowaniaDo pełni szczęścia będzie nam po-trzebny, oprócz PHP, framework Proto-type oraz pakiet Scriptaculous. Zestaw Scriptaculous pobierzemy z adresu wi-docznego w ramce W Sieci. Zawiera on także framework Prototype, jednak jeśli chcemy – możemy sprawdzić, czy jest to wersja aktualna na stronie projektu, ewentualnie zamieniając plik prototy-pe.js na odpowiedni. Powinniśmy roz-pakować pliki o rozszerzeniu js z ka-talogu lib pakietu Scriptaculous oraz plik prototype.js do wspólnego folderu, np. javascript. Nasz kod zamieścimy w dwóch plikach PHP: index.php oraz ra-te.php. Pierwszy z nich będzie odpo-wiedzialny za prezentację ankiety oraz wyników, drugi – za zliczanie głosów oraz ich pobieranie z bazy. Kod CSS jest w tym wypadku istotny, znajdziecie go w pliku index.php.

Wygląd zewnętrznyZacznijmy od stworzenia treści ankie-ty. Przykładowa ankieta, wraz z kodem CSS, została zamieszczona na Listin-gu 1. Pobrane biblioteki JavaScript zo-stały włączone do kodu strony, style

Rysunek 1. Gotowa ankieta AJAX-owa

Listing 1. Wygląd ogólny ankiety w kodzie HTML

<!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">

<style>

#categories {

list-style-image:none;

list-style-type:none;

margin:0px;

padding:0px;

}

#categories li {

background-color: #ECF3E1;

border:1px solid #C5DEA1;

cursor: move;

width: 130px;

margin-top:5px;

}

#submit {

background-color: #C5DEA1;

border:1px solid #ECF3E1;

padding: 2px;

width: 80px;

cursor: pointer;

text-align: center;

}

</style>

</head>

<?

$options=array('Rock', 'Pop', 'House', 'Techno', 'Chillout', 'HipHop', 'Other');?>

<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>

wolucja nadeszła jednak wraz z opra-cowanym przez Sama Stephensona frameworkiem Prototype dla języka Ja-vaScript. Dzięki niemu, tworzenie po-łączeń AJAX-owych ze skryptem PHP bez konieczności przeładowania stro-

ny jest banalnie proste i skuteczne. Na bazie tego wspaniałego skryptu stwo-rzono także zestaw graficznych udo-godnień w języku JavaScript – Scrip-taculous. Stosując ten pakiet, otrzyma-my możliwość nadawania elementom

Page 28: PHP Solutions 02 2007 PL

Ankiety AJAX-owe

www.phpsolmag.org28

Dla zaawansowanych

PHP Solutions Nr 2/2007

CSS zostały zdefiniowane tak, by an-kieta wyglądała odpowiednio, mimo że użyjemy do jej prezentacji listy HTML. Biorąc pod uwagę dostępność, nale-żałoby stworzyć formularz HTML dla osób z wyłączoną obsługą JavaScript, który dzięki niemu byłby ukrywany, jednak nie jest to w gestii tego artyku-łu. Możliwości wyboru zostały wpisane do tablicy, a następnie wyświetlone za pomocą pętli. Wygląd ankiety został przedstawiony na Rysunku 1.

Prototype w praktycePo kodzie naszego przycisku można poznać, że aktywuje on funkcję Sub-mitForm z parametrem będącym iden-tyfikatorem listy naszej ankiety. Funk-cja ta (Listing 2.) będzie zdefiniowa-na wewnątrz znacznika head. Będzie to główny silnik naszej aplikacji: jej za-daniem będzie połączenie się z pli-kiem rate.php z parametrami określo-nymi w zmiennej pars (o nich za chwi-lę). Do wykonania połączenia wykorzy-stamy klasę AjaxUpdater frameworka Prototype. Jak można się spodziewać, wywołuje ona witrynę z danymi para-metrami, przekazując je przy pomo-cy określonej metody, zaś to, co zosta-nie odesłane, trafi do znacznika o iden-tyfikatorze target, zastępując już obec-ny tam kod (w naszym wypadku ankie-ta zostanie zastąpiona jej wynikami). Prototype oferuje także szereg innych klas i funkcji, które pomagają w pre-cyzyjnym określeniu, jak ma się zmie-

nić witryna po pobraniu wyników zapy-tania AJAX. Nam wystarczy jednak ta jedna – jeśli zależy nam na transferze, możemy pokusić się o wycięcie nieuży-wanych fragmentów kodu z pliku proto-type.js. Do wyjaśnienia pozostała jesz-cze zmienna pars. Wiąże się ona z pa-kietem Scriptaculous, którego funkcja Sortable.serialize() zwraca ciąg zna-ków w stylu tego z zapytań GET, które-go składowymi są numery pozycji z na-szej listy, przypisane jako kolejne ele-menty tablicy, o nazwie będącej iden-tyfikatorem listy. W naszym przypad-ku, dla niezmienionej kolejności pól, funkcja ta zwróci następujący ciąg:categories[]=1&categories[]=2&catego

ries[]=3&... itd. Kłopot w tym, że jeżeli prześlemy taki ciąg znaków bezpośred-nio jako zbiór parametrów, otrzymamy w PHP tablicę z jedynie jednym – ostat-nim – elementem. Musimy więc cały ciąg znaków eskejpować i przypisać do jednej zmiennej (rates), którą będziemy rozkodowywać na właściwą tablicę po stronie serwera. Pozostało nam jesz-cze przypisanie odpowiednich efektów wizualnych do naszej listy. Uzyskamy to, stosując funkcję Sortable.create() pakietu Scriptaculous. Jej kod, widocz-ny na Listingu 3, musimy umieścić po kodzie listy, bowiem będzie on ją mo-dyfikował – musi więc być już widocz-na. Najlepiej kod ten wkleić zaraz przed znacznikiem kończącym body. Pełen kod pliku index.php, w odpowiedniej ko-lejności, widoczny jest na Listingu 4.

Zliczamy głosyNasz system ankiet jest już niemal goto-wy. Musimy jeszcze dopisać kod odpo-wiedzialny za zliczanie głosów i ich wy-świetlanie. Zadanie może sprawić trudno-ści jedynie przy zagadnieniu rozkodowy-wania przesłanego w zmiennej rates łań-cucha. Listing 5. pokazuje, jak tego doko-namy. Najpierw, zamienimy go na tablicę, z której pozbędziemy się zbędnego wy-miaru (categories). Następnie przetwo-rzymy ją w pętli, przypisując kolejnym po-zycjom (istotna jest tu kolejność w tablicy$options) ich kolejność ustaloną przez użytkownika (przy czym niższa liczba oznacza wyższą pozycję). Wszystko, co pozostało do zrobienia, to wpisanie wyni-ków do bazy danych (zapewne będziemy odejmować wybraną kolejność od ilości wyborów, by uzyskać wyższą notę dla po-zycji wyżej notowanej w hierarchii) przez sumowanie oraz wypisanie aktualnych wy-ników. Tę część pracy pozostawiamy czy-telnikowi, wymaga bowiem jedynie użycia prostych zapytań do bazy oraz kilku lini-jek kodu CSS odpowiednio formatujące-go wyniki (nie zapomnijmy go uwzględnić już w pliku index.php!). By otrzymać wy-niki własnego głosowania względem po-zycji w tablicy $options, wystarczy użyć kodu zaprezentowanego na Listingu 5.Porównując wartości $item['order _ id'] z indeksami tablicy $options, otrzymamy listę dostępnych wyborów.

Co dalej?Jak pokazaliśmy, stworzenie efektownej i efektywnej ankiety przy pomocy frame-worka Prototype, zestawu Scriptaculous oraz PHP jest łatwe i intuicyjne. Jako za-danie domowe pozostawiamy połączenie wyników z bazą danych. Czytelnicy, któ-rzy gustują w rozwiązaniach AJAX-owych, zapewne zechcą użyć dodatku Behavio-ur (http://www.bennolan.com/behaviour/). Został on stworzony przez Bena Nolana, który słusznie zauważył, że wprowadzając dodatkowe parametry do znaczników (np. onClick w naszym "przycisku"), ponow-nie zanieczyszczamy kod, który powinien być zgodny z wytycznymi XML. Behavio-ur pozwala na przypisanie elementom za-chowań JavaScript za pomocą ich identy-fikatorów. W ten sposób dołączamy kolejny plik w nagłówku witryny, jednak oczyszcza-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

Listing 2. Funkcja wysyłająca ankietę

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

// <![CDATA[

function SubmitForm(someid){ var url = 'rate.php'; var pars = 'rates='+escape(Sortable.serialize(someid)); var target = 'container'; var myAjax = new Ajax.Updater(target, url, {method: 'post', parameters: pars});

}

// ]]>

</script>

Listing 3. Funkcja przypisująca efekty wizualne do listy

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

// <![CDATA[

Sortable.create('categories',{dropOnEmpty:true,handle:'handle',

constraint:false});

// ]]>

Page 29: PHP Solutions 02 2007 PL

Ankiety AJAX-owe

www.phpsolmag.org 29

Dla zaawansowanych

PHP Solutions Nr 2/2007

rate.php, przed wpisaniem ich do bazy. Pa-miętać także należy o zablokowaniu moż-liwości wielokrotnego głosowania przez te-go samego użytkownika naszego serwisu. Z pewnością warto także przyjrzeć się bli-żej pakietowi Scriptaculous, bowiem w ar-tykule wykorzystaliśmy zaledwie mały pro-cent jego możliwości, podobnie zresztą, jak samego frameworka Prototype. W koń-cu, polecamy obejrzeć witrynę projektu an-kiet hierarchicznych autora (patrz ramkaW Sieci). n

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">

// <![CDATA[

function SubmitForm(someid){ var url = 'rate.php'; var pars = 'rates='+escape(Sortable.serialize(someid)); var target = 'container'; var myAjax = new Ajax.Updater(target, url, { method: 'post', parameters: pars});

}

// ]]>

</script><style>

#categories {

list-style-image:none;

list-style-type:none;

margin:0px;

padding:0px;

}

#categories li {

background-color: #ECF3E1;

border:1px solid #C5DEA1;

cursor: move;

width: 130px;

margin-top:5px;

}

#submit {

background-color: #C5DEA1;

border:1px solid #ECF3E1;

padding: 2px;

width: 80px;

cursor: pointer;

text-align: center;

}

</style>

</head>

<?

$options=array('Rock', 'Pop', 'House', 'Techno', 'Chillout', 'HipHop', 'Other');?>

<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>

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

// <![CDATA[

Sortable.create('categories',{dropOnEmpty:true,

handle:'handle',constraint:false});

// ]]>

</script>

</body></html>

Rysunek 2. Główna witryna script.aculo.us zawiera wiele prezentacji wizualnych pakietu

Listing 5. Funkcja przypisująca efekty wizualne do listy

<?

parse_str($_POST['rates'], $ratesArray);

$ratesArray = $ratesArray[

'categories'];

for($i=0;$i<count($ratesArray); $i++) {

$finalArray[] = array( 'order_id' =>

$ratesArray[$i], 'rate' =>

$i +1);

}

foreach($finalArray as $item) { print($item['order_id'].' = '.$item['rate'].'<br />');

}

?>

Krzysztof Trynkiewicz od wielu lat zaj-muje się tworzeniem witryn w technolo-gii PHP oraz Flash. Ściśle współpracu-je z magazynem PHPSolutions. Obec-nie rozwija kilka równoległych projektów autorskich, dostępnych na witrynie http://eldoras.com.

Kontakt: [email protected]

O autorze

Page 30: PHP Solutions 02 2007 PL

www.phpsolmag.org30 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

GUI Dla zaawansowanych

Celem artykułu jest przedsta-wienie zalet tworzenia inter-fejsu użytkownika we Flash-u.

Chcemy pokazać, jak łatwo i przyjem-nie da się tworzyć GUI dla aplikacji na-pisanych w PHP. Będziemy do tego ce-lu używać biblioteki ASwing, która po-zwala na budowę aplikacji z gotowych graficznych komponentów. Przekaże-my wiedzę, która każdemu początkują-cemu programiście pozwoli na zbudo-wanie RIA, wykorzystując w zaawan-sowany sposób PHP-owy serwer apli-kacji. Artykuł podzieliliśmy na cztery tematyczne części. W każdej Czytelnik znajdzie konkretny, bardzo uproszczo-ny, ale działający przykład, zgodnie z formułą HelloWorld, czyli bez dodatko-wych upiększaczy. I tak:

• część pierwsza dotyczy procesu two-rzenia aplikacji Flash-owych w opar-ciu o darmowe narzędzia,

Masz już aplikację napisaną w PHP, ale chcesz ulepszyć jej działanie? Możesz łatwostworzyć aplikacje Flash-owe w oparciuo darmowe narzędzia. Prosto i bez truduprzejdziesz trudną drogę, która doprowadzi do powstania serwera aplikacji, który będzie mógł komunikować się z Flash-em. Dodatkowo, pokazujemy zastosowania ASwing.

• część druga wprowadza do podstaw OOP w ActionScript 2.0,

• część trzecia przedstawia ASwing– narzędzie do tworzenia GUI z do-stępnych graficznych komponentów,

• część czwarta zaznajamia z AMFPHP – zapewniającym wydajną komunika-cję Flash-a z PHP-em.

Na samym końcu, w oparciu o to, co zo-stało przedstawione, napiszemy bardziej zaawansowaną aplikację typu klient-ser-

ASwing + AMFPHP,czyli przepis na szybkie GUIRafał Malinowski

Stopień trudności: lll

Co należy wiedzieć...Przydatna będzie znajomość zasad pro-gramowania obiektowego.

Co obiecujemy...Dowiesz się, jak szybko i łatwo stworzyć w GUI dla Twojej PHP-owej aplikacji, jak w prosty sposób przesyłać dane między PHP a Flash-em. Nauczysz się też pod-staw programowania w ActionScript 2.0.

Page 31: PHP Solutions 02 2007 PL

www.phpsolmag.org30 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

GUI Dla zaawansowanych

wer, która będzie już wymagała od Czy-telnika nieco samodzielnej pracy.

Hello World – MTASCNa początek, prosty przykład pokazujący podstawy działania kompilatora MTASC, którego będziemy używać do tworze-nia aplikacji Flash-owych. MTASC (http://www.mtasc.org/) jest kompilatorem pli-ków .as wywoływanym z linii poleceń.

Jego zadaniem jest zamiana kodu zrozumiałego dla człowieka na kod ma-szynowy, dający się uruchomić w prze-glądarce przy pomocy Flash Player-a, czyli popularnie nazywanego SWF lub MovieClip. MTASC wywoływany jest z li-nii poleceń, można go więc zintegrować z różnymi edytorami plików tekstowych czy programów automatyzujących pro-ces kompilacji (np.: Ant) – my w dalszej części artykułu pokażemy, jak zintegro-wać go z Eclipse 3.1. MTASC jest potęż-

nym programem zapewniającym kompa-tybilność z Flash Player-em, w wersjach do 8 włącznie i do tego jest to jeszcze program pisany w konwencji opensour-ce. Jak widać, same plusy.

Przyjrzymy się podstawowej składni kompilującej kod programu do pliku .swf:

mtasc (pliki .as z kodem programu) -swf

(nazwa pliku swf)

W celu przetestowania MTASC na-piszemy prosty program w językuActionScript 2.0. Tworzymy nowy plik w naszym ulubionym edytorze tekstowym i nazywamy go HelloWorld.as, a na-stępnie wpisujemy kawałek kodu przed-stawiony na Listingu 1.Po zapisaniu pliku, komenda:

mtasc HelloWorld.as -swf HelloWorld.swf

-main -header 800:600:20

skompiluje program do postaci Hello-World.swf. Tak przygotowany plik mo-żemy otworzyć w przeglądarce interne-towej z zainstalowanym FlashPlayer-em. Przeglądarka, otwierając plik o rozsze-rzeniu .swf, przekaże jego obsługę do FlashPlayer-a, który powinien pokazać nam w przeglądarce napis Hello World !

Jeśli mamy problemy z kompilacją programu, znaczy to, że popełniliśmy ja-kiś błąd podczas pisania.

Możliwe błędy podczas kompilacji to przede wszystkim błędy występujące w składni kodu. W takim przypadku kompi-lator zwraca dokładne informacje na te-mat umiejscowienia błędu:

nazwa pliku : numer linii : numer znaku

w linii : komunikat błędu.

Kod, w którym nie zamknęlibyśmy klam-ry kończącej definicję klasy HelloWorld spowodowałby komunikat błędu nastę-pującej postaci:

HelloWorld.as:15: character 0 : parse

error Unexpected <end of file>

Nie zawsze więc widać na pierwszy rzut 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 naszegoprogramu. Wiemy już, że program roz-

Listing 1. Plik HelloWorld.as

class HelloWorld {

public static function main (mc:MovieClip) : Void {

mc.createTextField("myText", 1, 100, 200, 300, 400);

mc.myText.text = "Hello World !";

}

}

Rysunek 1. Konfiguracja wtyczek Eclipse – FDT i ASDT

Page 32: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org32

Dla zaawansowanych

PHP Solutions Nr 2/2007

poczyna swoje działanie od wywoła-nia metody statycznej main(mc:Movie-

Clip), (parametr -main). MovieClip (MC) to pojedynczy obiekt widziany na sce-nie (czyli w przeglądarce), który jestjednocześnie pojemnikiem dla innych

MovieClip-ów. MovieClip-y tworzą struk-turę drzewiastą, czyli każdy MC ma swo-jego rodzica i może mieć wiele dzieci. W uproszczeniu, wygląda to więc tak, że mamy np. niebieskie tło, które posiada na sobie dwa kółka, a każde kółko posia-

da np. po dwie kropki i kreskę. Wszyst-kie akcje, które wywołamy na wskaza-nym MovieClip-ie dotyczyć będą rów-nież elementów, które on posiada. Czyli, jeśli teraz sprawimy, by jedno kółko prze-stało być widzialne, to elementy, które są do niego przyczepione (dwie kropki i kre-seczka) też przestaną być widzialne. Jak każde drzewo, tak i to posiada swój ko-rzeń, czyli MovieClip leżący najniżej.W metodzie main jako parametr mc prze-kazywana jest referencja do _ root, czyli głównego MovieClip-a na scenie.

Dostając referencje do _ root – Movie-Clipa leżącego na samym dole sceny, mo-żemy osadzić na scenie dowolny obiekt i będzie on widzialny. W naszym przypad-ku jest to TextField, czyli pole tekstowe. Metoda createTextField tworzy nową in-stancję TextField, nadając jej nazwę „my-Text” i ustawiając głębokość osadzenia na poziomie 1. Głębokość osadzenia Movie-Clip-a na scenie to poprostu kolejność, w jakiej będą rysowane elementy na ekra-nie. Jeśli więc jeden obiekt rysowany bę-dzie wczesniej, a drugi później, to ten dru-gi może zasłonić pierwszy. Sytuacja taka pojawia się, gdy więcej MovieClip-ów na-leży do jednego MovieClip-a i ważna sta-je się ich kolejność. Kolejne parametry metody createTextField to współrzędne x i y (100, 200) oraz wysokość i szerokość pola tekstowego (300,400). Nazwa jaką ustaliliśmy dla tworzonego obiektu („my-Text”), jest potrzebna, by w kolejnych kro-kach operować na jego właściwościach, czyli między innymi przypisać do para-metru text wartość HelloWorld (mc.my-Text.text = "Hello World !";), co jest równoznaczne z wypełnieniem pola tek-stowego tekstem HelloWorld.

Przygotowujemy narzędzia do pracyOczywiste jest, że na dłuższą metę pro-gramowanie w notatniku staje się meczą-ce. Nawet, jeśli używamy edytora teksto-wego, który koloruje nam kod, to podpo-wiadanie składni i wykrywanie błędów semantycznych jest niezastąpioną po-mocą dla każdego, a zwłaszcza począt-kującego programisty. Skupimy się te-raz na przygotowaniu środowiska pra-cy tak, aby programowanie w Action-Script-cie stało się naprawdę przyjemne. 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

Listing 2. Plik ASBasic.as – podstawy składni w ActionScript

// do skompilowania klasy potrzebne są :

// definicje klas z pakietu mx.data

import mx.data.*;

//definicja klasy mx.controls.Button

import mx.controls.Button;

// definicja klasy ASBasic rozszerza def. klasy MovieClip

// ASBasic należeć bedzie do pakietu(ang.:package) : „org.me”

class org.me.ASBasic extends MovieClip { // zmienna w AS poprzedzona musi byc słowem kluczowym "var"

// AS pozwala na określenie typu zmiennych „:Button”

public var button:Button; // kwalifikatora dostępu protected w AS nie występuje

// protected var pProtected;

// typowanie zmiennych nie jest konieczne

public var object; /**

* Konstructor – nazwa methody musi być taka jak nazwa klasy

*/

public function ASBasic(name:String) { // wywołanie konstruktora klasy dziedziczonej

super();

// $this->param zamieniamy na this.param

this.button = new Button(); // try, catch, finally działa identycznie jak w PHP

try {

this.setName(name); }

catch (e:Error){ this.setName("Basic example"); }

finally {

}

}

// metoda w AS tak jak w PHP poprzedzona musi być

// słowem kluczowym „function”

public function add(p1:Number,p2:Number) : Number { var sum : Number = p1 + p2;

return sum; }

private var name:String; public function getName() : String { return this.name; }

public function setName(name:String) : Void { if (name !== null) { this.name = name; }

else { throw new Error("Name can not be null!"); }

}

public function addStrings(s1:String,s2:String) : String { // dodawanie String-ow w AS

// używamy operatora „+”

var sum:String = " " + s1 + s2;

return sum; }

}

Page 33: PHP Solutions 02 2007 PL
Page 34: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org34

Dla zaawansowanych

PHP Solutions Nr 2/2007

przykład Se|Py (http://www.sephiroth.it/python/sepy.php), ale Eclipse jest na-rzędziem znanym większości programi-stów PHP, stąd nasz wybór padł właśnie na niego. Eclipse wymaga zainstalowanej wirtualnej machiny Java. Mamy tu dowol-ność w wyborze wersji Javy, ale propo-nujemy zainstalować wersję 5, którą bę-dzie w przyszłości wymagana przez roz-szerzenie Flashout. Po ściągnięciu Ec-lipse, koniecznie w wersji 3.1.x (my bę-dziemy pracować na 3.1.2) przechodzi-my do instalacji rozszerzeń wspomagają-cych pracę w języku ActionScript. Do wy-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.

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 URLwpisujemy „FDT” i „http://fdt.power-flasher.com/update” (lub „ASDT” i „http://asec l ipsep lug in .source fo rge.ne t /updates/„). Zaznaczamy nowy element

na liście FDT (lub/i ASDT) i klikamy„Finish”.

Aby zainstalować Flashout (który po-trzebny będzie dla tych, którzy wybrali ASDT), ściągamy ze strony projektu pa-kiet instalacyjny. Po rozpakowaniu, prze-grywamy znajdujący się w środku kata-log plugin do odpowiedniego (też plugin) w folderze macierzystym Eclipse.

Konfiguracja EclipsePo zainstalowaniu, FDT (czy ASDT) wy-maga skonfigurowania. Z menu Eclipse wybieramy:

„Windows” -> „Preferences”

Rysunek 1. przedstawia to, co powin-niśmy zobaczyć. Powinniśmy usta-wić tu ścieżkę do kompilatora MTASC (parametr MTASC dla obu wtyczek), oraz ścieżkę do bibliotek Action-Script-a (FDT – „Core Libraries”, ASDT„Core path”). Core Libraries to zbiór podstawowych dla Flash-a bibliotek, które dostajemy wraz z MTASC w ka-talogu /std.

Wtyczki Flashout nie trzeba konfigu-rować.

Rysunek 2. Eclipse i FDT – nowy projekt

Rysunek 3. Eclipse i FDT – konfiguracja parametrów kompilacji

Page 35: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org 35

Dla zaawansowanych

PHP Solutions Nr 2/2007

ActionScript 2.0 (AS2) – podstawyActionScript 2.0 należy do rodziny ję-zyków skryptowych implementujących standard ECMA-262. Do rodziny tej należy między innymi JavaScript czy JScript, stąd też osoby znające JS do-strzegą na pewno duże podobieństwo AS2 do tego języka. Porównując AS2 do JS zauważyć należy jedną podsta-wową różnicę, jaka występuję pomię-dzy tymi językami. JS (w dużym uprosz-czeniu) operuje na danych odzwiercie-dlających strukturę znaczników XML-owych opisujących wygląd strony – do-brym przykładem będzie tu znacznik <DIV>. W AS2 występuje podobna struk-tura danych, odzwierciedla ona jednak drzewo MovieClip-ów – czyli np. anima-cji. Tu i tu mamy więc warstwy, przezro-czystości, współrzędne, ale w AS2 do-tyczą one innego typu obiektów. Innymi słowy MovieClipy to coś takiego jak war-stwy <div> w JS.

Dla programistów PHP naukę Action-Script najlepiej rozpocząć od przedstawie-nia przykładowego kodu. Listing 2 przed-stawia definicję klasy ASBasic. AS2 jest językiem obiektowym. Istnieje możliwość programowania w AS2 metodą procedu-ralną – program zapisany jest w postaci luźno rozsianych funkcji czyli procedury, ale metoda ta wykorzystywana jest głów-nie w pracy z Flash IDE, gdzie graficz-ny interfejs pozwala na zarządzanie po-szczególnymi grupami procedur. Przy du-żych projektach wskazane jest, aby orga-

nizować kod zgodnie z zasadami OOP (Obiect Oriented Programming), czyli w postaci klas zapisywanych w oddzielnych plikach.

W AS2 definicja klasy i nazwa pliku, w którym definicja jest zapisana muszą się pokrywać, czyli klasę ASBasic zapisujemy w pliku ASBasic.as. Dodatkowo w AS2 pojawia się nowe dla programistów PHP pojęcie tzw. pakietu (ang. Package). Pa-kage określa przestrzeń nazw, w obrę-bie której nazwa klasy musi być unikalna. Od strony systemu plików struktura pakie-tów zapisywana jest w postaci drzewa ka-talogów. Definicja klasy org.me.ASBasic zapisana jest więc w pliku ASBasic.as w katalogu org/me/. Dzięki takiemu podej-ściu, nie musimy stosować instrukcji inc-lude(file _ path); a wystarczy nam import my.package.ClassName; który jednoznacz-nie wskaże definicję klasy ClassName w pliku o nazwie ClassName.as w katalogu my/package/.

Dla tych, którzy znają podstawy pro-gramowania obiektowego, definicja kla-sy ASBasic przedstawiona na Listingu 2. powinna być zrozumiała. Dodatkowe ko-mentarze powinny wyjaśnić pozostałe niejasności.

DebugowanieGdy chcemy nauczyć się jeździć na nar-tach, czeka nas lekcja wstawania i upa-dania. Tak też jest i w programowaniu. Zanim więc zaczniemy tworzyć większe programy, przyjrzymy się możliwościom debugowania kodu napisanego w AS2.

Niestety, możliwości, jakie daje nam AS2 nie są duże i polegają w głównej mie-rze na wyświetlaniu komunikatów o sta-nie wykonywania algorytmu w miejscach uznanych przez nas za krytyczne dla pi-sanej aplikacji. Czyli, nie różni się to w ni-czym od metody stosowanej w progra-mowaniu w PHP, prócz tego, że w AS2 zamiast funkcji echo() stosujemy trace() (print _ r() nie posiada swojego odpo-wiednika w AS2 – ale istnieją metody, aby uzyskać podobny efekt. Stosowa-nie metody trace() jest utrudnione, gdy programujemy używając MTASC: jej ko-munikaty bowiem nie są wtedy widziane, wyrzuca ona bowiem tekst do wydzielo-nego okna dialogowego jedynie, gdy pro-gramujemy używając Adobe Flash IDE. Okno dostępne jest tylko podczas uru-chamiania MovieClip-a z poziomu Flash IDE i jest niedostępne dla programistów używających MTASC. Dlatego, aby zo-baczyć prosty wynik działania meto-dy trace() trzeba trochę gimnastyki, co zniechęca wielu początkujących. Same-mu należy bowiem zadbać o to, gdzie i w jaki sposób wyświetlane będą przez nią komunikaty. Przedstawimy teraz scena-riusz, jak szybko zobaczyć wynik dzia-łania metody trace(). Jeśli pracujemy z MTASC, służy do tego następujący para-metr kompilacji:

- trace nazwa_metody_statycznej

Sprawia on, że każde wywołanie me-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 wyglądać tak:Rysunek 4. Eclipse i FDT – konfiguracja dodatkowych parametrów kompilacji

Page 36: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org36

Dla zaawansowanych

PHP Solutions Nr 2/2007

class Tracer() {

public static function

log(msg:String,clazz:String,file:

String,line:Number);

}

Dla tak przygotowanej metody obsługu-jącej logi parametr -trace powinien wy-glądać tak:

-trace Tracer.log

Co do samego miejsca, gdzie komuni-katy powinny być prezentowane, moż-liwości jest dużo i zależą one tylko od tego, co wstawimy w ciało naszej me-tody Trace.log(). Wszystko jednak sprowadza się do wysyłania komuni-katów do zewnętrznego programu lub innego MovieClip-a, który to dopiero zajmuje się wypisaniem ich na ekran. Ciekawsze narzędzia odbierające ta-

kie komunikaty dostępne w interne-cie to:

• http://osflash.org/xray – polecamy dla bardziej zaawansowanych,

• http://sos.powerflasher.de/english/english.html – bardzo prosty, wyma-ga Windows,

• http:/ /sock4log.sourceforge.net /– bardzo prosty, wymaga Java 5– niezależny od OS.

Najszybciej i prościej będzie namrozpocząć pracę używając Sock4Log, który jest małym serwerem nasłuchu-jącym na wskazanym porcie komunika-tów wysyłanych ze specjalnie napisa-nej dla niego metody trace(). Program jest niezależny od systemu operacyj-nego, dlatego też następne przykłady opierać się będą właśnie o współpra-ce z nim.

Eclipse i FDT– tworzymy projektNowy projekt stworzymy używając per-spektywy Flash, która dodana została do Eclipse po zainstalowaniu FDT. Aby użyć perspektywy Flash w Eclipse z menu, wy-bieramy: Windows -> Open Perspective-> Flash.

Teraz w oknie Flash Explorer klika-my prawym przyciskiem myszki i z otwo-rzonego menu wybieramy: New -> New project.

W otwartym oknie New project ko-lejno wykonujemy: Flash -> „New Flash Project, Project name -> wpisujemy na-zwę, np.: HelloWorld.

W oknie konfiguracji źródeł folde-ru powinniśmy mieć zaznaczone źródło „MtascSTD”, które dodaliśmy wcześniej. Teraz Finish i w oknie Flash Explorer po-winna pokazać się nowa pozycja Hello-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 przedstawia Rysunek 2.

Teraz pozostaje nam tylko skompilo-wać i uruchomić program.

Z menu wybieramy: Run” -> Run...W lewej części okna klikamy prawym

przyciskiem myszy na FDT-MTASC Sup-port -> New

Następnie w prawej części okna wy-pełniamy w zakładce „Main” kolejno:

• Name -> helloword – to nazwa, jaka będzie wyświetlać się w menu run,

• Project -> HelloWord – wybieramy, klikając na przycisk Browse... i wska-zując nasz projekt,

• Main Class -> org.me.HelloWord – to tzw. entry point aplikacji – czyli klasa, w której zdefiniowana jest publiczna metoda statyczna main() , od której wywołania rozpoczynać będzie pracę

Listing 3. Program demonstrujący działania Sock4Log

import org.webservicesware.sock4log.Tracer;

class org.me.HelloWorld { public static function main (mc:MovieClip) : Void {

// Inicjacja połączenia socketowego z Sock4Log

Tracer.init();

trace("Start");

mc.createTextField("myText",1,100,200,100,100);

mc.myText.text = "Hello World !";

mc.myText.border = true; mc.myText.type = "input";

// implementujemy metodę wywoływana w reakcji na

// zdarzenie onChanged – czyli na zmianę treści

mc.myText.onChanged = function () {

trace("onChanged Event : " + this.text); };

}

}

Rysunek 5. Sock4log – test funkcji trace()

Page 37: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org 37

Dla zaawansowanych

PHP Solutions Nr 2/2007

program. Finalnie, powinniśmy zoba-czyć to, co na Rysunku 3, a po przej-ściu do zakładki „MTASC Arguments” – to, co na Rysunku 4.

Uruchomienie kompilacji rozpoczyna kliknięcie na przycisk Run. Po wyko-naniu tej akcji, w naszym oknie Flash Explorer pojawić powinien się nowy plik default_mtasc.swf.

Zanim przejdziemy do dalszej części artykułu, należałoby przetestować jeszcze możliwość debugowania naszego progra-mu. My do tego celu wybraliśmy program Sock4Log, jako najprostszy i niezależny od systemu operacyjnego. Zachęcamy jednak do zapoznania się w miarę możli-wości z pozostałymi dwoma programami, jako ciekawymi alternatywami.

Po ściągnięciu Sock4Log ze strony projektu (http://sock4log.sourceforge.net/),należy przegrać plik org/webservicesware/sock4log/Tracer.as do odpowiedniegokatalogu naszego projektu (src/org/web-servicesware/sock4log/Tracer.as). Te-raz dodajemy dodatkowy parametr kon-figurujący proces kompilacji w zakładcez Rysunku 4.

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

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

�������

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

������

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

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

���������

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

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

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

������

�������

�������

������

���������

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

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

����������

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

����������

�����������

�����������

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

�������

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

Listing 4. Plik HelloWorldASwing.as – wprowadzenie do ASwing

import org.aswing.JFrame;

import org.aswing.JLabel;

class org.aswing.me.HelloWorldASwing { /**

* Create the GUI and show it.

*/

private static function createAndShowGUI() : Void { //Tworzymy okno zatutułowane HelloWordlAswing

var frame:JFrame = new Jframe("HelloWorldASwing"); // ustawiamy jak okno ma zareagować gdy chcemy je zamknąć

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

//dodajemy "Hello World" label.

var label:JLabel = new JLabel("Hello World"); // dodajemy label do okna

frame.getContentPane().append(label);

// ustawiamy rozmiar okna

frame.setSize(200,100);

//Display the window.

frame.setVisible(true); }

/**

* Entry point for aplication

*/

public static function main(mc:MovieClip):Void { createAndShowGUI();

}

}

Page 38: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org38

Dla zaawansowanych

PHP Solutions Nr 2/2007

-trace org.webservicesware.sock4log.

Tracer.log

Zmieniamy odpowiednio kod naszego programu tak, by inicjował nowy me-chanizm logowania i wywoływał po-jedynczą metodę trace(); (Listing 3).

Przed uruchomieniem MovieClipa na-leży jeszcze uruchomić program na-słuchujący komunikaty wysyłane przez naszą aplikację. Robimy to komendą:

java -jar „Sock4Log.jar”

Wynik działania kodu widoczny jest na Rysunku 5. Każda zmiana pola teksto-wego wywołuje akcję onChange() i w efekcie wysyła komunikat do programu Sock4Log, który prezentuje go nam na ekranie.

ASwing – wprowadzenieASwing to prawie wierna kopia bibliote-ki Swing napisanej w Java, dlatego też w dużej ilości miejsc dokumentacja ASwing sprowadza się do odesłania czytelnika na strony bardzo dobrze udokumentowa-nej biblioteki Swing. My też radzimy, aby w razie problemów szukać tam pomocy : (http://java.sun.com/docs/books/tutorial/uiswing/index.html http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/package-summary.html)

Ponieważ kopiowanie dokumentacji powszechnie dostępnej w internecie nie jest celem tego artykułu, postaramy się tylko wprowadzić do filozofii tworzenia okienek w ASwing, opisując podstawowe jego elementy. Rysunek 6. przedstawia poglądową strukturę komponentów do-stępnych w ASwing. Jak widać, wszystkie one dziedziczą po klasie Component, która implementuje takie podstawowe mecha-nizmy, jak pokazywanie i ukrywanie kom-ponentu, ustalanie rozmiarów, położe-nia itd. Drugim podstawowym elementem ASwing-a jest klasa Container, która jest pojemnikiem dla komponentów. Contain-er implementuje mechanizmy, jakie po-trzebne są do tego, by mógł on opisać re-lacje, jakie panują między poszczególny-mi komponentami, a w szczególności ich ułożenie względem siebie (tzw. Layout). Jak widać na diagramie Container dzie-dziczy po klasie Component, czyli mo-że przechowywać sam siebie. Wszyst-kie komponenty, które pozwalają na in-terakcję z otoczeniem dziedziczą po kla-sie EventDispatcher. Każdy komponent ma swój zbiór zdarzań (ang. Events), któ-re może wywoływać, dla przykładu JBut-ton wywołuje zdarzenie ON_PRESS – w chwili, gdy zostanie naciśnięty, a JWin-dow ON_WINDOW_CLOSING – gdy zo-staje zamykane. Zdarzenia te zostają wy-słane do wszystkich obiektów, które zgło-siły się, jako nasłuchujące.

Jak widać, zasady działania ASwing są bardzo logiczne: mamy elementy, któ-re możemy układać na scenie i które się ze sobą komunikują. To, co pozostaje nam do zrobienia, to oprogramować re-

Listing 5. Plik CelsiusConverter.as – programowanie zdarzeń

import org.aswing.*;

class org.aswing.me.CelsiusConverter { var converterFrame : Jframe;

var converterPanel : Jpanel;

var tempCelsius : JtextField;

var celsiusLabel, fahrenheitLabel : Jlabel;

var convertTemp : Jbutton;

public function CelsiusConverter() { var frame:JFrame = new JFrame("Convert Celsius to Fahrenheit"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.setSize(250,90);

converterPanel = new JPanel(new GridLayout(2, 2)); addWidgets();

//Add the panel to the window.

frame.getContentPane().append(converterPanel, BorderLayout.CENTER);

//frame.pack();

//Display the window.

frame.setVisible(true); }

/**

* Create and add the widgets.

*/

private function addWidgets() : Void { //Create widgets.

tempCelsius = new JtextField("2"); celsiusLabel = new Jlabel("Celsius",null,JLabel.LEFT); convertTemp = new Jbutton("Convert"); fahrenheitLabel = new Jlabel("Fahrenheit",null,JLabel.LEFT); //Listen to events from the Convert button.

convertTemp.addEventListener(Component.ON_RELEASE,

actionPerformed, this); //Add the widgets to the container.

converterPanel.append(tempCelsius);

converterPanel.append(celsiusLabel);

converterPanel.append(convertTemp);

converterPanel.append(fahrenheitLabel);

}

public function actionPerformed():Void { //Parse degrees Celsius as a double and convert to Fahrenheit.

var tempFahr:Number = (Number(tempCelsius.getText()) * 1.8 + 32);

fahrenheitLabel.setText(tempFahr + " Fahrenheit");

}

/**

* Create the GUI and show it.

*/

private static function createAndShowGUI() : Void { var converter:CelsiusConverter = new CelsiusConverter(); }

/**

* Entry point for aplication

*/

public static function main(mc:MovieClip):Void { createAndShowGUI();

}

}

Page 39: PHP Solutions 02 2007 PL
Page 40: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org40

Dla zaawansowanych

PHP Solutions Nr 2/2007

akcje na te wysyłane przez otoczenie ko-munikaty.

Aby rozpocząć pracę z ASwing, na-leży ściągnąć ostatnie wydanie biblio-tek ASwing ze strony www.aswing.org (w czasie pisania artykułu była to wersja ba-ta 1). Następnie musimy dodać biblioteki do naszego projektu. W tym celu klikamy prawym przyciskiem myszki na nazwę projektu w oknie Flash Explorer i wybie-ramy z listy Properties. Następnie w uka-zującym się oknie wybieramy: Flash Properties -> Add Linked Libraries... -> Add... i, jeśli wykonujemy tę operację po raz pierwszy, klikamy na New.... Wypeł-niamy parametry wymagane do stworze-nia nowej pozycji na liście bibliotek: Na-me -> ASwing – beta1, Location -> ścież-ka do katalogu ze źródłami ASwing.

Klikamy na przycisk OK i nowa biblio-teka powinna pojawić się na naszej liście. Wybieramy ją, klikamy przycisk OK i mo-żemy zacząć kodować.

Przykłady, które wybraliśmy do za-prezentowana działania podstaw ASwing zostały oparte o tutorial Swing na stronie http://java.sun.com/docs/books/tutorial/uiswing /, tak, aby przedstawić wspólne części obu bibliotek i jeszcze raz zapro-ponować naukę ASwing w oparciu o do-kumentację Swing-a.

Najlepiej będzie rozpocząć naukę od kompilacji i uruchomienia programów (Li-sting 4 i 5, Rysunek 7). Są one bardzo proste i właściwie wystarczy spojrzeć na kod, by wiedzieć, co się w nich dzieje.W pierwszym przykładzie (Listing nr 4), 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-ka okna – ale trzeba jeszcze ustawić jego 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-

śnie takim komponentem. Używamy me-tody append, aby dodać Component do naszego okna.

Na Listingu 5 przedstawiamy już nieco bardziej skomplikowany przykład. Na po-czątku tworzymy kolejno dwa pola JLabel,jeden JButton i jedno pole typu Jtext-Field, w którym można będzie wpisywać tekst z klawiatury. Po dodaniu wszystkich elementów do tworzonego okna, należyustalić, jak ma reagować nasz program na zdarzenie naciśnięcia przycisku: służy do tego metoda, jaką posiada klasa JButton : addEventListener();

Metoda ta dodaje słuchacza (ang. Listener), czyli referencję do obiektu, który będzie powiadamiany o zdarze-niach, jakie wywołuje nasz JButton. W naszym przypadku, interesuje nas zda-rzenie kliknięcia, czyli Component.ON _

RELEASE. Dodatkowo, ustawiamy jesz-cze, jaką metodę chcemy, by urucho-mił JButton na naszym obiekcie, gdy zo-stanie wywołane zdarzenie, ustawiamy więc actionPerformed. Całość ostatecz-nie ma postać:

convertTemp.addEventListener

(Component.ON_RELEASE,

actionPerformed, this);

Teraz wystarczy wykonać operację na własnościach text obiektów JTextField i udało się nam stworzyć program konwer-tujący temperaturę w stopniach Celsjusza na Fahrenheita.

Wraz z biblioteką ASwing dostajemy szereg przykładów tego jak wykorzystać

wchodzące w jej skład komponenty. War-to przejrzeć, jakie jeszcze możliwości da-je nam ASwing.

Komunikacja Flashz otoczeniemTwórcy technologii Flash położyli bardzo duży nacisk na to, by ich produkt był w stanie komunikować się ze światem ze-wnętrznym w sposób prosty i ustanda-ryzowany. Firma Macromedia (a teraz Adobe – będziemy używać obu nazw firm, ponieważ w Internecie wciąż wię-cej informacji na temat Flash-a znajdzie-my wyszukując po nazwie Macromedia Flash) wyposażyła ActionScript w sze-reg bibliotek, pozwalających na komuni-kację z otoczeniem w ustandaryzowany sposób. I tak, do komunikacji ze świa-tem zewnętrznym do wyboru mamy:

• FlashRemoting – pozwala na komu-nikację Flash-a z serwerem aplikacji używając do tego standardu Action Message Format (AMF), który po-zwala na serializację i deserializację obiektów przesyłanych między ma-szynami,

• XMLSocket – pozwala na komunika-cję z serwerem używając do tego po-łączenia socketowego,

• LoadVars – odpowiednik AJAX-owe-go XMLHttpRequest. Pozwala na po-bieranie z serwera danych używając do tego protokołu HTTP. Ten typ ko-munikacji wykorzystywany jest, gdy chcemy porozumieć się z serwerem przy pomocy standardu XML-RPC,

Rysunek 7. ASwing – okna programów

Listing 6. HelloWorld AmfPHP – przykładowy serwis

<?php

class HelloWorldService{

function __construct() {

$this->methodTable = array (

"say" => array (

"access" => "remote",

"description" => "Pings back a message"

)

);

}

function say($sMessage) {

return 'You said: ' . $sMessage; }

}

?>

Page 41: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org 41

Dla zaawansowanych

PHP Solutions Nr 2/2007

• FSCommand – umożliwia komu-nikowanie się z odtwarzaczem Flash-a, lub programem, w którym FlashPlayer jest osadzony. Połą-czenie takie wykorzystać można do komunikacji np. z przeglądarką lub w szczególności z JavaScript-em osadzonym na stronie,

• LocalConnection – umożliwia ko-munikowanie się z innymi uru-chomionymi w środowisku klien-ta MovieClip-ami. Komunikacja ta-ka pozwala na porozumiewanie się między odgrywanymi przez Flash-Player, różnymi MovieClip-ami, ale tylko w obrębie jednej aplikacji, tj. np. uruchomionych w jednej prze-glądarce,

• WebService – pozwala na używanie WebService-ów (protokoły SOAPi WSDL) przez Flash, jest to w tej chwili jeden z najczęściej używa-nych standardów komunikacji mię-dzy maszynami.

Ponieważ ramy tego artykułu nie po-zwalają na opisanie wszystkich metod komunikacji, co byłoby niewątpliwie bardzo ciekawe, skupimy się na roz-wiązaniu, jakie daje Flash Remoting. Jest to bowiem rozwiązanie, które za-pewnia najwyższą wydajność, z racji tego, że serializuje i deserializuje dane do plików binarnych, czyli maksymal-nie zmniejsza wielkość przesyłanych danych między klientem a serwerem.

Flash RemotingFlash Remoting to określenie używa-ne przezMacromedia (a teraz Adobe) do zdefiniowania technologii, która używa-na jest do komunikacji serwera aplikacji z Flash-em w oparciu o protokół AMF. Mó-wiąc o Flash Remoting, mamy na myśli dwie strony komunikacji :

• serwer – tą część implementują me-chanizmy potrzebne dla korzystania z AMF przez serwery aplikacji. Adobe wspiera tu jedynie dwie technologie: Java iMicrosoft .Net. My będziemy korzystać z trzeciej, darmowej imple-mentacji AMF dla PHP – AMFPHP,

• klient – część implementująca AMF w języku ActionScript od strony klienta, czyli Flash-a – tzw. Flash Remoting Component. Jest to darmowy kompo-nent, który musimy pobrać ze strony Adobe.

AMFPHP – wprowadzenieAMFPHP (http://www.amfphp.org) – to projekt, który wychodzi na przeciw ocze-kiwaniom środowiska opensource co do darmowego wykorzystania technologii Flash w architekturze klient-serwer. In-stalacja i konfiguracja sprowadza się tu do ściągnięcia źródeł programu i umiesz-czenia ich na serwerze np. w katalogu amfphp/. Aby sprawdzić, czy wszystko działa poprawnie, należy otworzyć stro-nę: http://localhost/amfphp/gateway.php, na której powinien pojawić się komunikat

„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 większą ilość sprawdzeń dla komu-nikatów przychodzących i wychodzą-cych (głównie skupia się na popraw-ności formatowania zapytań).

My będziemy korzystać ze standardo-wych ustawień AMFPHP, dlatego naszą prace rozpoczniemy w katalogu amfphp/services/, gdzie umieścimy pierwszy Hello-WorldService (Listing 6) w pliku helloworld-service.php.

Na początek prześledzimy proces przetwarzania zapytania serwera apli-kacji.

• Krok 1. AmfPhp (gateway.php) odbiera zapytanie w formacie AMF z Flash-a,

• Krok 2. Dane komunikatu zostają de-serializowane i zamienione na obiekty/typy PHP-owe. AMFPHP uzyskuje w tym miejscu informacje o tym, jaka metoda jakiego serwisu ma być wyko-nana i z jakimi parametrami,

• Krok 3. Jeśli nie zostało ustawione in-aczej, AMFPHP przeszukuje katalog services/ w poszukiwaniu pliku, któ-rego nazwa pokrywa się z nazwą wy-woływanego serwisu,

• Krok 4. AMFPHP powołuje do życia instancję obiektu klasy, która została znaleziona w szukanym pliku i urucho-miony zostaje jej konstruktor. W kon-struktorze następuje zainicjowanie ta-blicy methodTable, w której to zosta-ją zapisane informacje, o możliwych do wywołania metodach, jakie wystę-pują w danej klasie oraz informacje o tym, jakie są ewentualne wymagania/

Rysunek 8. Serwis eksplorer dla AMFPHP

Page 42: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org42

Dla zaawansowanych

PHP Solutions Nr 2/2007

dodatkowe parametry wywołania me-tody,

• Krok 5. Jeśli wszystko się zgadza, na-stępuje wywołanie wskazanej przez klienta metody i serializacja tego, co zostało zwrócone,

• Krok 6. AmfPHP wysyła odpowiedź do Flash-a w formacie zgodnym z AMF.

Listing 6. przedstawia prosty serwis,który posiada tylko jedną metodę say($sMessage), która do przekazywa-nej w parametrze wiadomości docze-pia ciąg znaków i zwraca go w postacji'You said : ' .$sMessage;

W konstruktorze mamy inicjację ta-blicy asocjacyjnej $this->methodTable, w której kluczem jest nazwa metody, a ciałem – opis jej parametrów wywołania:

• access – ustawiamy na remote jeśli, chcemy, by metoda była dostępna dla Flash-a,

• description – opis metody widoczny podczas przeglądania metod serwe-ra aplikacji.

Gdy już mamy stworzony serwer, może-my przejść do jego przetestowania. Naj-prościej będzie uruchomić przeglądarkę serwera aplikacji: http://localhost/amfphp/browser/index.html. Powinniśmy móc zo-baczyć w niej, po lewej stronie, listę do-stępnych serwisów, jakie udostępniamyi po wybraniu jednego z nich – po prawej stronie listę metod, które możemy w ramach serwisu wywołać. Jeśli klikniemy na jedną z metod, będziemy mogli przetestować wysła-nie zapytania i odebranie odpowiedzi, co zo-stało przedstawione na Rysunku 8.

Mamy działający serwis, możemy te-raz przejść do programowania Flash-owego klienta.

Flash Remoting ComponentJeszcze do niedawna Flash był techno-logią, z którą pracować można było tyl-ko przy pomocy Flash IDE. Jest to narzę-dzie dostępne dla rodziny Windowsi Mac OS. Dla posiadaczy Flash IDE, przygoto-wanie Flash-a do pracy z AMFPHP spro-wadza się do zainstalowania darmowego komponentu Flash Remoting Component, 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,

Listing 7. Prosty przykład wykorzystujący HelloWorldService

import mx.remoting.*;

import mx.rpc.*;

import mx.remoting.debug.NetDebug;

import mx.services.Log;

import org.webservicesware.sock4log.Tracer;

class org.me.test.AmfPhpClient { private var tfReq:TextField; private var tfResp:TextField; var myLogger:Log;

// Tu rozpoczyna prace program

public static function main(mc:MovieClip) { Tracer.init();

var amf:AmfPhpClient = new AmfPhpClient(mc); }

public function AmfPhpClient(mc:MovieClip) { // Tworzymy nowe pole tekstowe – tekst wysylany

mc.createTextField("tfReq", 0, 10, 10, 200, 50);

this.tfReq = mc.tfReq; // niech obramowanie pola będzie widoczne

this.tfReq.border = true; this.tfReq.text = "Hello AmfPHP"; // niech pole będzie edytowalne

this.tfReq.type = "input"; // Tworzymy nowe pole tekstowe – tekst odbierany

mc.createTextField("tfResp", 1, 10, 60, 400, 100);

this.tfResp = mc.tfResp; this.tfResp.text = "Waiting for response"; // inicjujemy NetConnection Debugger

mx.remoting.debug.NetDebug.initialize();

this.myLogger = new Log( Log.DEBUG, "AmfPhp" ); // piszemy wlasna funkcje obsługi zdarzenia onLog

this.myLogger.onLog = function( message:String ):Void { trace( "AmfPhpClient-Logger => "+message );

};

var thiz:AmfPhp = this; // piszemy wlasna funkcje obsługi zdarzenia onChange

this.tfReq.onChanged = function() { thiz.say(this.text); };

}

var gatewayUrl:String = "http://localhost/amfphp/gateway.php";

public function say(s:String):Void{ // inicjacja nowego servisu (url,logHandler,nazwa serisu)

var _service:Service = new Service(this.gatewayUrl, this.myLogger, 'HelloWorldService', null , null); // wywołujemy zdalnie metodę say()

var pc:PendingCall = _service.say(s);

// ustawiamy reakcję na odpowiedź – referencje do funkcji

pc.responder = new RelayResponder(this, "say_result", "say_error"); }

// funkcja obsługująca odpowiedz metody say

function say_result(re:ResultEvent) {

var resp:String = 'The result is: ' + re.result; trace(resp);

this.tfResp.text =resp;

}

// funkcja obsługująca błąd w wywołaniu metody say

function say_error(fe:FaultEvent) { var resp:String = 'There has been an error.'+ '\n Fault code : ' + fe.fault.faultcode +

'\n Fault message : '+fe.fault.faultstring;

trace(resp);

this.tfResp.text =resp; }

}

Page 43: PHP Solutions 02 2007 PL

GUI

www.phpsolmag.org 43

Dla zaawansowanych

PHP Solutions Nr 2/2007

który powinien znaleźć się gdzieś w oko-licach: \Documents and Settings\user_name\Ustawienia lokalne\Dane aplikacji\Macromedia\Flash 8\en\Configuration\Classes\ do katalogu MTASC_ROOT/std/mx/, gdzie MTASC_ROOT to katalog domowy naszego kompilatora MTASC. Unix-owych użytkowników (lub tych, któ-rzy nie posiadają Flash IDE) czeka trochę dłuższa droga. Należy bowiem:

• Krok 1. Ściągnąć plik flashremoting_comp_sourcecode.zip – który zawie-ra kod źródłowy (dostępny w tym sa-mym miejscu, co Flash Remoting – patrz wyżej),

• Krok 2. Dokonać poprawek w kodzie tak, by można było go kompilować przy pomocy MTASC:

plik: mx.remoting.debug.GlobalLocalCon-nection linia 93 – zmieniamy z : var suc:Boolean = true; na : var suc = true;plik: mx.remoting.NetServiceProxy.aslinia 60 – zmieniamy z : clientna : this.clientlinia 72 – zmieniamy z : serviceNamena : this.servicenamelinia 73 – zmieniamy z : ncna : this.nc (w obu miejsach)linia 74 – dodaj średnik : ; za klamrą za-mykającą funkcję var f=function...plik: mx.remoting.debug.commands.GetConfigdodaj konstruktor: public function

GetConfig() {super();}

usuń wywołanie : super(); z metody

GetConfigCommand()

plik: mx.remoting.RecordSet.as

linia 51 – zmieniamy z : „mx.events.Event-Dispatcher.initialize( this );” na :„GDispatcher.initialize( this );”linia 404 – zmieniamy z : return na : re-turn null

Ściągamy plik Gdispatcher.as z http://www.gskinner.com/blog/archives/2003/09/code_gdispatche.html i przegrywamy go do katalogu std/ w macierzystym fol-derze MTASC.

• Krok 3. Przegrać katalog mx/, w którym poprawialiśmy pliki, do katalogu std/ .

Dopiero teraz możemy przejść do próby połączenia z serwerem aplikacji.

Amf-AS – wprowadzenieTworzymy nowy projekt i nową klasę, naz-wijmy ją AmfPhpClient, w pliku AmfPhp-Client.as. Listing 7. przedstawia przykład klasy komunikującej się z naszym serwisem. W konstruktorze klasy tworzymy dwa po-la tekstowe tfReq i tfResp, które odpowied-nio przechowują tekst do wysłania i pokazu-ją tekst odebrany z serwera. Typ pierwsze-go pola ustawiamy na „input” tak, by mogło być edytowane. Inicjujemy też obiekt klasy Log, który będzie informował nas o szcze-gółach operacji na poziomie Log.DEBUG – czyli najniższym. Metoda onChange(), którą nadpisujemy w obiekcie tfReq, będzie roz-poczynała proces komunikacji z serwerem aplikacji po każdej zmianie treści pola tek-stowego, wysyłając do serwera aktualną je-go wartość. Sam proces komunikacji z ser-werem aplikacji wygląda tak:

• Krok 1: Metoda OnChange rozpoczyna działanie w momencie zmiany treści pola i wywołuje metodę naszej kla-sy say(s:String), gdzie s = wartość tekstu pola,

• Krok 2: Inicjowana jest instancja kla-sy Serwice, która będzie obsługiwać wszystkie wywołania konkretnego ser-wisu serwera aplikacji. Kolejne para-metry konstruktora określają adres ser-wera, ewentualny loger, nazwę serwi-su. O pozostałych dwóch parametrach na razie nie będziemy nic pisać,

• Krok 3: Wywołujemy metodę say() serwera aplikacji. Ponieważ wywo-łanie jest asynchroniczne, czyli nie wiemy, kiedy przyjdzie i czy w ogó-le przyjdzie odpowiedź serwera,wywołanie zdalnej metody zwraca je-dynie tzw. PendingCall – obiekt, któ-ry przechowuje informację o toczącej się, wywołanej akcji,

• Krok 4: Ustalamy, jaka ma być reakcja na odpowiedź serwera aplikacji. Two-rząc nowy obiekt RelayResponder ustalamy, że przy zakończeniu po-myślnym akcji należy wywołać meto-dę say_result na obiekcie this, a przy zakończeniu błędnym – metodę say _

result, również na obiekcie this, • Krok 5: W chwili, gdy serwer aplikacji

przekaże odpowiedź wywołanej przez nas metody, Service przekazuje infor-macje o zakończeniu oczekiwania na odpowiedź do ustawionego przez nas PendingCall, który to, w zależności od tego, jaki był wynik operacji, przekaże odpowiedź do odpowiednio wcześniej ustawionych metod naszej klasy.

W ten sposób możemy przejąć odpo-wiedź z serwera i wyświetlić ją na ekra-nie. Listing 8. przedstawia wykaz komu-nikatów, jakie dostaliśmy podczas wyko-nywania tej operacji: komunikaty rozpo-czynające się od AmfPhpClient-Logger->>zostały wygenerowane przez instancję klasy Log.

PodsumowanieDoprowadziliśmy do powstania serwera aplikacji, zdolnego do komunikacji z Flash-em oraz tzw. grubego klienta (ang. fat client), czyli aplikacji Flash-owej, w której ASwing jest w stanie przedstawić w dowol-ny sposób dane odebrane z serwera. Przy odrobinie chęci, przedstawiony szkielet można rozbudować i stworzyć okienkową 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 AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:

Creating gateway connection for http://localhost/amfphp/gateway.php AmfPhpClient-Logger => 9/4 7:56:21 [INFO] AmfPhpClient:

Successfully created Service

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

Invoking say on HelloWorldService

The result is: You said: Hello AmfPHP!

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

HelloWorldService.say() returned "You said: Hello AmfPHP!"

Rafał Malinowski jest programistą Ac-tionScript, Java i PHP. W wolnych chwi-lach tworzy framework dla Flash-a/Flex-a i udziela się w kilku projektach Open Source. Obecnie pracuje w Superme-dia Interactive jeko projektant / programi-sta Java.

Kontakt: [email protected]

O autorze

Page 44: PHP Solutions 02 2007 PL

www.phpsolmag.org44 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

PHP-Gtk2 Dla zaawansowanych

Słysząc kombinację słów „ba-za danych” oraz “przeglądarka”, na myśl przychodzi nam zazwy-

czaj phpMyAdmin lub podobne jemu na-rzędzie. Wygląd (ang. layout) tych apli-kacji jest w większości przypadków bar-dzo do siebie zbliżony: w górnym lewym rogu mamy menu rozwijane z możliwo-ścią wyboru bazy danych, na której bę-dziemy pracować, zaś poniżej wyświetla-ne są jej tabele.

Cała zawartość prawej części apli-kacji jest przeznaczona na wyświetla-nie zawartości i struktury aktualnie za-znaczonej tabeli. Często zawiera także elementy nawigacyjne, pozwalające na zmianę struktury, właściwości czy za-wartości tabeli.

Ponieważ takie rozmieszczenie jest popularne i dobrze znane większości użytkowników, nasza przeglądarka ba-zy danych będzie także miała taki wy-gląd. Oto lista wszystkich funkcjonalno-ści, które omówimy w ramach artykułu,

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.

wraz z ich reprezentacją koloru w wido-ku strukturalnym (patrz Rysunek 1):

• możliwość wyboru bazy danych z me-nu rozwijanego (pomarańczowy),

• wyświetlanie nazw i ilości wierszy tabel w zaznaczonej bazie danych(zielony),

• wyświetlanie zawartości (wierszy) za-znaczonej tabeli (fioletowy),

• numeracja i sortowanie, nawigacja wierszy za pomocą przycisków w to-olbarze (niebieski).

Przeglądarka bazy danych przy użyciu PHP-Gtk2Christian Weiske

W SIECI

• http://www.gnope.org – pakiet PHP5 + Gtk2 dla

Windows,• http://gtk.php.net – strona główna projektu

PHP-Gtk2 wrazz repozytorium,

• http://cweiske.de/files/download/phpgtk2/DatabaseBrowser.tar.bz2 – pełen kod aplikacji zbudowanej w tym artykule,

• http://pear.php.net/package/MDB2

– pakiet MDB2 dla PEAR,• http://pear.php.net/package/

Gtk2_ExceptionDump – pakiet Gtk_ExceptionDump

dla PEAR,• http://pear.php.net/package/

Structures_Form_Gtk2 – pakiet Structures_Form_Gtk2

dla PEAR.

Stopień trudności: lll

Co należy wiedzieć...Przydatna będzie znajomość podstaw PHP-Gtk oraz podstawowych zapytań SQL.

Co obiecujemy...Dowiesz się, jakie nowe funkcje przynosi druga wersja PHP-Gtk. Zbudujesz prze-glądarkę baz danych z funkcją sortowa-nia i podziału na strony.

Page 45: PHP Solutions 02 2007 PL

www.phpsolmag.org44 PHP Solutions Nr 2/2007

Dla zaawansowanych

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

PHP-Gtk2 Dla zaawansowanych

Na Rysunku 1. pokazaliśmy, jakie wid-gety GTK+ zostaną użyte oraz, w jaki sposób będą zagnieżdżone.

Ponieważ GtkWindow może mieć jedynie jeden element potomny, a my potrzebujemy użyć kilku widgetów, sko-rzystamy z GtkContainer. GtkHPaned z kolei idealnie będzie pasował do na-szych wymagań: dzieli bowiem okno na dwie sekcje, których rozmiar może zmieniać użytkownik.

Dla lewego panelu użyjemy kla-sycznego GtkVBox, w którym zagnieź-dzimy nasze rozwijane menu (Gtk-ComboBox ze specjalnym GtkListStorefunkcjonującym jako jego model), oraz dla listy tabel – także GtkTreeViewz odpowiednim GtkListStore jako mo-delem.

Prawa strona naszej aplikacji jest podobnie zamknięta w GtkVBox. Prze-trzymujący element GtkTreeView, będzie pokazywał wszystkie wiersze. Będzie on także zawierał element GtkToolbar z przyciskami nawigacyjnymi, usprawnia-jącymi poruszanie się po liście: pierw-sza i ostatnia strona, odśwież, następna i ostatnia strona.

Kilka słów na temat stylu kodo-wania i używania klas: z doświadcze-nia wiem, że bardzo pomocne okazu-je się rozszerzanie klas głównych wid-getów Gtk, tworząc własne klasy i osa-dzając je według kolejności zagnież-dżenia. To może powiększyć ilość linii kodu przy małych projektach, jednak jest absolutnie niezbędne przy budo-waniu wielkoskalowych projektów – in-

aczej szybko zgubimy się we własnym kodzie. Ta metoda pozwala także na łatwe przystosowanie kodu do ponow-nego użycia, ponieważ wystarczy za-łączyć klasę i zainicjować ją komendą new MyClassName() – bez porówna-nia jest to mniej kodu, niż w przypad-ku wycinania i kopiowania kodu każdej funkcji (co z kolei utrudnia znalezienie i korektę błędów).

Podłączamy się do bazyWykonanie połączenia do bazy danych, używając MDB2 jest relatywnie proste: wystarczy stworzyć cią DSN (ang. Data Source Name), który odpowiada nasze-mu środowisku, i wywołać metodę sin-gleton klasy MDB2:

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łędamiW 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 kosztowne pod kątem np. czasu wykony-wania, czy pisania aplikacji, użyjemy za-let pakietu PEAR : Gtk2_ExceptionDump. Tworzy on graficzny zrzut wszelkiego ro-dzaju błędów: wyjątków, obiektów PEAR_Error, kiedy zostaną utworzone oraz błę-dów PHP, w przypadku ich pojawienia się (patrz Rysunek 2).

Dobrą wiadomością jest, że ten skom-plikowany z pozoru proces reprezentują w kodzie zaledwie dwie linijki:

require_once 'Gtk2/ExceptionDump.php';

Gtk2_ExceptionDump::setupAllHandlers();

Nie musimy już martwić się o błędy i możemy skupić się na programowaniu funkcjonalności naszej aplikacji. Taki

WymaganiaPrzygotujmy najpierw nasze stanowisko. Niezbędne będą:

• PHP 5.1.x• zainstalowany moduł PHP-Gtk2• zainstalowany PEAR z pakietami MDB2 i Gtk2_ExceptionDump (patrz ramka W Sieci)• dostęp do bazy danych

Ja wybrałem MDB2, ponieważ oferuje najłatwiejszy sposób dostępu do różnych typów baz 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, pozwalające rozpocząć pracę z PHP5 i Gtk2. Jeśli używasz Linuxa lub Macintosha, powi-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 obu systemów. Mamy już zainstalowane narzędzia pracy, możemy więc przejść do właści-wego rzemiosła.

Rysunek 1. Struktura przeglądarki bazy danych

Page 46: PHP Solutions 02 2007 PL

PHP-Gtk2

www.phpsolmag.org46

Dla zaawansowanych

PHP Solutions Nr 2/2007

zabieg jest bardzo przydatny przy two-rzeniu prototypu aplikacji, jednak je-śli zamierzasz rozprzestrzeniać swój kod, powinieneś zaimplementować wła-sny system obsługi błędów, by klient otrzymywał bardziej przydatne i bar-dziej czytelne informacje o ewentual-nych błędach.

Wyświetlamy tabelePierwsze zapytanie SQL, jakiego bę-dziemy używać, to naturalnie "SHOW DATABASES ". Jego wynikiem wypeł-nimy GtkComboBox. By być przygoto-wanym na wprowadzanie zmian i udo-skonaleń w przyszłości, skorzystamyz naszej własnej klasy, która będzie rozszerzała GtkListStore. Widget ten posiada jedynie jedną kolumnę typu Gtk::TYPE_STRING, która przechowu-je nazwy dostępnych baz danych. Kod klas zamieściliśmy na Listingu 1, wynik jego działania widać na Rysunku 3.

GtkListStore oferuje kilka metod do-dawania wierszy. W tym przypadku za-stosujemy append(), ponieważ jest dla nas najłatwiejsza w użyciu. Pobiera ona jako parametr tablicę, która powin-na mieć tyle wartości, ile nasza lista ma kolumn.

Zauważmy, że stosujemy obiekt pu-bliczny $mdb2 typu static naszej głów-nej klasy, DatabaseBrowser, do wykony-wania zapytań do bazy danych...

W połączeniu z dwoma kolejnymi linijkami, otrzymujemy działające me-nu rozwijane z listą dostępnych baz da-nych.

Kiedy użytkownik wybierze bazę danych, powinniśmy wyświetlić mu Gtk-TreeView (Listing 2). Element ten bę-dzie zawierał nazwy tabel oraz ilość wierszy w nich dostępnych. Podobnie, jak poprzednio, stworzymy własną kla-sę rozszerzając GtkListStore. Tym ra-zem musimy pamiętać, że lista musi być czyszczona i ponownie uzupełnia-na przy każdym kolejnym wyborze ba-zy danych przez użytkownika. Tym sa-mym, klasa otrzyma własną metodę lo-adTables(), która będzie wymagała ja-ko jedynego parametru, nazwy bazy danych. Wynik jej działania będziemy wyświetlać w dwóch kolumnach: jednej dla nazwy tabeli, drugiej dla ilości re-kordów w niej istniejących.

Wypełnienie elementu GtkTreeView będzie wymagało tym razem więcej pracy, niż w przypadku baz danych w

Listing 1. Kod klas wyświetlających bazy danych

class DatabaseBrowser_DatabaseList extends GtkListStore{

public function __construct() {

parent::__construct(Gtk::TYPE_STRING);

$this->loadDatabases();

}

protected function loadDatabases() {

$res = DatabaseBrowser::$mdb2->query('SHOW DATABASES');

while (($row = $res->fetchRow())) { $this->append(array($row[0])); }

}

}

$cmbDatabase = GtkComboBox::new_text();

$cmbDatabase->set_model(new DatabaseBrowser_DatabaseList());

Listing 2. Wyświetlamy dostępne tabele

class DatabaseBrowser_TableList extends GtkListStore{

public function __construct() {

parent::__construct(Gtk::TYPE_STRING, Gtk::TYPE_LONG);

}

public function loadTables($strDatabase) {

$this->clear();

DatabaseBrowser::$mdb2->setDatabase($strDatabase);

$res = DatabaseBrowser::$mdb2->query('SHOW TABLES');

while (($row = $res->fetchRow())) { $strTable = $row[0];

$nRows = DatabaseBrowser::$mdb2->queryOne(

t'SELECT COUNT(*) FROM ' . $strTable);

$this->append(array($strTable, $nRows)); }

}

}

$lstTables = new GtkTreeView(new DatabaseBrowser_TableList());$renderer = new GtkCellRendererText();$col = new GtkTreeViewColumn('Table', $renderer, 'text', 0);$lstTables->append_column($col);

$numberRenderer = new GtkCellRendererText();$col->pack_end($numberRenderer, false);

$col->add_attribute($numberRenderer, 'text', 1);

$cmbDatabase->connect('changed', array($this, 'onSelectDatabase'), $lstTables);

public function onSelectDatabase($cmbDatabase, $lstTables){

$strDatabase = $cmbDatabase->get_active_text();

$lstTables->get_model()->loadTables($strDatabase);

}

$scrTables = new GtkScrolledWindow();$scrTables->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);

$scrTables->add($lstTables);

Page 47: PHP Solutions 02 2007 PL

Ciao GmbHCiao GmbH jest właścicielem wiodącego porta-lu konsumenckiego w Europie – Ciao.com. Do nowo powstałego centrum rozwoju oprogramo-wania we Wrocławiu poszukujemy doświadczo-nych programistów PHP. Chcesz dobrze zara-biać, pracować w międzynarodowym środowi-sku i w przyjaznej atmosferze – dołącz do nas.www.ciao-group.com/careers_wroclaw.php

Agencja Interaktywna– br-design.plKreowanie 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

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.

Agnat Sp. z o.o.Dostarcza pełen wachlarz usług związanych ze stronami WWW. Serwis www.agnat.eu obsłu-guje kilkanaście tysięcy Klientów z całej Polski oraz Unii Europejskiej, wyposażając je w do-meny internetowe, hosting, pozycjonowanie, kreację stron WWW, kampanie reklamowo-pro-mocyjne, oprogramowanie i aplikacje niezbędne do prowadzenia biznesu w sieci.

v

protHOSTRewelacyjny 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

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

HostingElastyczny 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 przezcPanel. Rejestracja domen globalnych, krajowych, funkcjonalnych i regionalnych. Ceny od 50 zł.www: http://www.lubman.pl,e-mail: [email protected],Pr

enum

erat

a PR

OW

ięce

j inf

orm

acji:

patrycja.wadolowska@

software.com.pl

tel.:

022

887

-13-

45

v

DzsoftSiedziba firmy znajduje się na Ukrainie. Naszą ofertę kierujemy szczególnie do osób, które zaj-mują się językiem PHP, gdyż sami specjalizuje-my się w tym, pisząc nasz własny kod. Posia-damy również edytor Perl oraz inne przydatne oprogramowania. Nasi pracownicy to specjaliści, zajmujący się optymalizacją specyficznych po-trzeb języka PHP i Perl.http://www.dzsoft.com

Kei.plKei.pl działa na rynku usług hostingowych od 2000 roku. Do naszych zadowolonych Klientów z dumą możemy zaliczyć wiele przedsiębiorstw sektora MSP, instytucji oraz osób prywatnych. W ofercie Kei.pl znajdują się pakiety hostingowe, a także usługi dla wymagających Użytkowników – platformy e-Biznes oraz serwery fizyczne.http://www.kei.pl

Page 48: PHP Solutions 02 2007 PL

PHP-Gtk2

www.phpsolmag.org 49

Dla zaawansowanych

PHP Solutions Nr 2/2007

cjalizować widgetu GtkListStore z usta-loną odgórnie ilością elementów Gtk::TYPE_STRING, lecz musimy robić to dy-namicznie. Poza tym, kolumny baz da-nych SQL nie posiadają typów STRING, lecz szeroki zakres innych typów: INT o różnych długościach, a także VARCHAR, SHORT/MEDIUM/LONG TEXT, ENUM oraz inne.

Mimo, że nie jest to optymalne roz-wiązanie, możemy użyć Gtk::TYPE_STRING dla każdej kolumny, nieza-leżnie od typu danych, które zawiera-ła będąc w bazie danych. Takie podej-ście ma jednak pewne poważne wady: nasz model zużywa więcej pamięci, niż jest to konieczne, przechowując przy tym wszystkie dane w jednym modelu, włącznie z wielkimi BLOBami, które za-pewne nie powinny mieć takiego prze-znaczenia. Przeglądanie tabeli z takimi elementami może być bardzo powolne.

Z drugiej strony, mapowanie bazy danych w taki sposób ma – w celach demonstracyjnych artykułu – niepod-ważalną zaletę: jest bardzo łatwe w im-plementacji, bowiem omija nas koniecz-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-

zodanowego. Wszystko więc, co musi-my zrobić, to ustalić ilość kolumn w ta-beli, ich tytuły, zaś później stworzymy odpowiednią ilość widgetów GtkTree-ViewColumns, by wyświetlić nasze da-ne. Używając oświadczenia SQL-owego

DESCRIBE, otrzymamy w wyniku na-zwy kolumn i ich liczbę.

Problem pierwszy został już wielo-krotnie dostrzeżony przez dewelope-rów PHP-Gtk2, czego skutkiem jest im-plementacja metody set_column_types()

Rysunek 3. Pole wyboru bazy danych

Rysunek 4. Tabele w bazie danych

Listing 4. Model przechowujący nasze dane

class DatabaseBrowser_TableModel extends GtkListStore{

protected $nPageSize = 20;

public function __construct($strDatabase, $strTable, $arTypes) {

$this->strDatabase = $strDatabase;

$this->strTable = $strTable;

parent::__construct();

$this->set_column_types($arTypes);

$this->update('refresh');

}

public function navigate($strAction) {

switch ($strAction) { case 'first': $this->nCurrentPage = 0;

break; case 'back': if ($this->nCurrentPage > 0) { --$this->nCurrentPage;

}

break;...

}

$this->update();

}

...

public function update() {

$this->clear();

$this->nRows = DatabaseBrowser::$mdb2->queryOne(

'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);

Page 49: PHP Solutions 02 2007 PL

PHP-Gtk2

www.phpsolmag.org50

Dla zaawansowanych

PHP Solutions Nr 2/2007

widgetu GtkListStore, która pobiera tabli-cę typów Gtk.

By zaimplementować solucje obu pro-blemów, najpierw musimy stworzyć sta-tyczną metodę getTableStructure, któ-ra wykonuje zapytanie "DESCRIBE $ta-blename" do bazy danych i zwraca tabli-cę asocjacyjną. Nazwy kolumn są uży-wane jako klucze, zaś typy Gtk::TYPE_STRING jako wartości. Dzięki temu, mo-żemy używać tej tablicy tak dla tworzenia GtkTreeViewColumn, jak przekazywać ją do set_column_types() bez dodatkowych modyfikacji.

Kolejnym dobrym pomysłem jest po-dział wyników na strony. Mimo, że GtkLi-stStore może przechowywać dowolną ilość wierszy, przetrzymywanie wszyst-kich danych może zająć za dużo pa-

mięci, czasu na przekazanie danych z serwera do aplikacji, zaś sam użyt-kownik na pewno nie będzie zachwy-cony, widząc miliony wierszy. Dewelo-perzy GTK+ zauważyli potrzebę wpro-wadzenia przycisków nawigacyjnych, dodali więc kilka elementów zwanych Stock Items, które wykonują pożąda-ne przez nas zadania: Gtk::STOCK_GOTO_FIRST, Gtk::STOCK_GO_BACK, Gtk::STOCK_REFRESH, Gtk::STOCK_GO_FORWARD i Gtk::STOCK_GOTO_LAST. Przekazanie każdego z tych ele-mentów do konstruktora new_from_stock() widgetu GtkToolButton's powo-duje, że otrzymamy menu z przyciskami oznaczonymi odpowiednim tekstem i iko-nami. Używając metody insert($btn, -1)widgetu GtkToolbar, otrzymamy pożąda-

ny rezultat w około dziesięciu liniach ko-du, widocznych na Listingu 3.

Następnie, jak widać na Listingu 4, tworzymy klasę DatabaseBrowser_Table, rozszerzając GtkTreeView oraz klasę Da-tabaseBrowser_TableModel, będącą roz-szerzeniem GtkListStore, ponieważ jest to nasz główny silnik przeglądarki, któ-ry powinien umieć wypełniać się dany-mi, gdy zajdzie taka potrzeba. Kieruje-my komendy nawigacyjne, przekazywa-ne przez przyciski, do metody navigate(), po prostu zmieniając wewnętrzną zmien-ną nCurrentPage klasy i wywołując funk-cję update().

update() używa naszego obiektu MDB2 do wykonania zapytania SELECT po użyciu setLimit(), który precyzuje, 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 sortowanieJedna 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 6. Sortowanie tabeli wg ilości pobrań

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();

}

Page 50: PHP Solutions 02 2007 PL

PHP-Gtk2

www.phpsolmag.org 51

Dla zaawansowanych

PHP Solutions Nr 2/2007

dług którego posortowana jest tabe-la. Łącznikiem, między modelem da-nych obecnych w aplikacji z przedsta-wianymi użytkownikowi, jest GtkTree-ModelSort.

Sortowanie danych jest tym, czego zazwyczaj potrzebują użytkownicy. Nam jednak zwykłe sortowanie nie wystarczy, bowiem objęte by nim były jedynie aktu-alnie wczytane wiersze. Użytkownik bę-dzie oczekiwał, że kliknięcie na nagłówek reprezentujący nazwy kolumn spowoduje wyświetlenie wszystkich nazw zaczyna-jących się na “A” na pierwszych stronach, czego nie osiągnęlibyśmy stosując sorto-wanie lokalne.

Bazy danych mają wbudowane funk-cje sortujące, więc najłatwiej będzie nam z tych dogodności skorzystać. Musimy zidentyfikować kliknięcia na nagłówkach kolumn i wygenerować odpowiednie za-pytanie SQL z “ORDER BY ” dla danej kolumny.

Przy tworzeniu naszych kolumn Gtk-TreeViewColumn, każda z nich otrzyma dwa nowe wiersze widoczne na Listingu 5. W funkcji onClickedHeader() wykona-my sortowanie (Listing 6).

Wszystko, czego jeszcze potrze-bujemy, to przekazanie informacji o ty-

pie sortowania do zapytania SQL wy-korzystywanego przez metodę update(). Osiągniemy to, używając prostej meto-dy setOrder(). Rezultaty widać na Ry-sunku 6.

KonkluzjaStworzyliśmy prosty, intuicyjny i niezależ-ny system przeglądania bazy danych w 300 liniach kodu używając Gtk2 oraz pa-kietu MDB2 z repozytorium PEAR. Ob-sługuje on podział danych na strony i sor-towanie, będąc bardzo łatwym w rozsze-rzaniu.

Przeglądarki można użyć jako pod-stawy do budowy własnego edytora baz danych, do którego zapewne przydatny okaże się pakiet Structures_Form_Gtk2 dostępny w repozytorium PEAR (patrz ramka “W Sieci”), idealnie nadający się do manipulacji danymi, o dynamicznie określanej liczbie pól.

Pełny kod przeglądarki bazy danych, którą zbudowaliśmy, jest zamieszczo-ny na CD oraz w Internecie (patrz ramka “W Sieci”).

Co dalej?W tym artykule omówiliśmy jedynie pod-stawy wyświetlania danych z bazy SQL.

Do aplikacji można dodać wiele przydat-nych funkcjonalności:

• obsługa zakładek, by umożliwić prze-glądanie wielu tabel jednocześnie,

• wyświetlanie widoku struktury tabeli,• używanie różnych typów danych w

modelu, w celu usprawnienia prędko-ści i efektywności działania aplikacji,

• dodanie pola tekstowego, pozwalają-cego na wprowadzenie własnych za-pytań SQL z możliwością wyszukiwa-nia wartości,

• możliwość edycji wierszy dzięki wyświe-tlaniu danych rekordów w innym oknie, przy użyciu Structures_Form_Gtk2.

Zapraszamy do wypróbowania nowych możliwości PHP-Gtk2! n

Christian Weiske jest studentem infor-matyki na uniwersytecie w Leipzigu, w Niemczech. Jest członkiem zespołu roz-wijającego i dokumentującego projekt PHP-Gtk2, jak również autorem wielu pakietów PEAR.

O autorze

R E K L A M A

Page 51: PHP Solutions 02 2007 PL

PHP-Gtk2

www.phpsolmag.org48

Dla zaawansowanych

PHP Solutions Nr 2/2007

GtkComboBox, ponieważ nie posiada on odpowiedniego konstruktora, który mógłby ustawić wszystkie kolumny.

Użyjemy więc następujących kompo-nentów:

• GtkTreeView jako główny widget, ma-jący dostęp do modelu Database-Browser_TableList,

• GtkTreeViewColumn, wyświetlający zawartość kolumn,

• GtkCellRendererText, by narysować nazwy tabel w wierszach,

• GtkScrolledWindow, by wyświetlone zostały suwaki na wypadek, gdyby li-sta tabel nie mieściła się w oknie.

Konstruktor GtkTreeView potrzebuje, jako pierwszego i jedynego parame-tru modelu, podajemy więc mu instan-cję naszej klasy DatabaseBrowser_TableList.

GtkTreeViewColumn potrzebuje z kolei czterech parametrów: jako pierw-szego, tytułu nagłówka kolumny. Ja-ko drugiego – obiektu GtkCellRenderer, który zajmuje się rysowaniem danych modelu. Trzeci parametr determinuje, który atrybut GtkCellRenderer zostanie ustawiony (np. GtkCellRendererText ja-ko atrybut “text”, ale już GtkCellRende-rerPixbuf jako "pixbuf", bowiem determi-nuje obraz). Czwarty i ostatni, parametr, 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-delu, który wcześniej zdefiniowaliśmy.

Ostatnie zadanie, to umożliwie-nie przewijania listy, co staje się trywial-ne przy użyciu widgeta GtkScrolledWin-dow. Miejmy na uwadze, że GtkTreeView, w odróżnieniu od wielu innych widge-tów, posiada swój własny system wido-ku. Oznacza to, że jeśli będziemy przewi-jać zawartość widgetu, tytuły kolumn bę-dą zawsze widoczne. Dodatkowo, upew-nijmy się, że paski przewijania nie będą widoczne, jeśli nie są konieczne. To za-danie spełni proste odwołanie do set_policy.

Po połączeniu kodu, otrzymujemy aplikację widoczną na Rysunku 4.

Pokazujemy daneZmapowanie zawartości całej tabeli z ba-zy danych do jednego widgetu GtkList-Store jest możliwe, acz nie trywialne. Będziemy musieli zmierzyć się z dwoma problemami:

Po pierwsze, lista kolumn każdej ta-beli nie jest znana podczas progra-mowania naszej przeglądarki baz da-nych. Oznacza to, że nie możemy zaini-

Listing 3. Tworzymy menu nawigacyjne

$this->tbl = new DatabaseBrowser_Table($strDatabase, $strTable);

$scrwnd = new GtkScrolledWindow();$scrwnd->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);

$scrwnd->add($this->tbl);

$this->pack_start($scrwnd);

$tb = new GtkToolbar();$arButtons = array( Gtk::STOCK_GOTO_FIRST => 'first',

Gtk::STOCK_GO_BACK => 'back',

Gtk::STOCK_REFRESH => 'refresh',

Gtk::STOCK_GO_FORWARD => 'forward',

Gtk::STOCK_GOTO_LAST => 'last'

);

foreach ($arButtons as $nStockItem => $strAction) { $btn = GtkToolButton::new_from_stock($nStockItem);

$btn->connect_simple('clicked', array($this->tbl, 'navigate'), $strAction); $tb->insert($btn, -1);

$this->arButtons[$strAction] = $btn;

}

Rysunek 2. Wynik działania Gtk2_ExceptionDump po stworzeniu obiektu PEAR_Error przez MDB2

Page 52: PHP Solutions 02 2007 PL

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org52

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 53

W PHP5 pojawił się bardzo inte-resujący moduł SOAP. SOAP (ang. Simple Object Access

Protocol) zapewnia nam możliwość two-rzenia własnych oraz wywoływania zdal-nych usług sieciowych, rozsianych po całym Internecie. Implementacja SOAP w PHP5 nie zawiera wszystkich rozsze-rzeń protokołu SOAP, ale sami możemy je dopisać, ponieważ zarówno klasy ser-werów, jak i klientów, możemy rozsze-rzyć (klasy nie są typu final).

Web Services,protokół SOAPAle zacznijmy od początku. Web Servi-ces to systemy, które są projektowane tak, aby komputery o różnych architek-turach, różnych systemach operacyj-nych działające w rozproszonym środo-wisku mogły wywoływać zdalnie swoje pewne operacje poprzez sieć Internet. Najczęściej wykorzystują one jako war-stwę transportową HTTP (lub HTTPS).

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.

Można powiedzieć, że Web Services to nowa wersja CORBA.

SOAP jest to protokół, poprzez który realizowane są wszystkie operacje Web Services. SOAP bazuje na XML, jest więc bardzo prostym protokołem, do któ-rego obsługi wystarczy nam zwykły par-

PHP5 WebServices vs MS .NETvs Java vs Java MobileŁukasz Budnik

Stopień trudności: lll

Co należy wiedzieć...Powinieneś posiadać dobrą znajomość PHP5, znać ogólne zasady współpracy i projektowania systemów rozproszonych na różnych systemach. Mile widziana znajomość podstaw SOAP i WSDL.

Co obiecujemy...Nauczysz się pisać własne usługi siecio-we, dowiesz się, jak rozszerzyć domyśl-ne klasy PHP5 klienta i serwera SAOP. Nauczysz się zabezpieczać swoje usługi z rozszerzeniem WS Security Enhance-ments i HTTPS. Nauczysz się, jak mapo-wać złożone obiekty i przesyłać je pomię-dzy różnymi platformami technologiczny-mi. Dowiesz się, jak połączyć się z usłu-gami sieciowym MS .NET, Jakarta AXIS.

Page 53: PHP Solutions 02 2007 PL

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org52

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 53

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-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ć oraz ewentualne jej parametry. Serwer odpowiada również kopertą, w której mo-że być nagłówek (Header) i zawsze mu-si być ciało (Body), w której znajdują się dane, które są wynikiem wykonania zdal-nej procedury.

Podstawowy schemat żądania został przedstawiony na Listingu 1.

Natomiast odpowiedź została przed-stawiona na Listingu 2.

Nie musimy znać dokładnych struktur kopert wymienianych pomiędzy klientem a serwerem, ponieważ są one tworzone au-tomatycznie i nie potrzebujemy w nie inge-rować, jeśli nie chcemy np. rozszerzać do-myślnych implementacji SOAP w PHP5. W późniejszej części artykułu, pokażę, jak rozszerzać klasy PHP5 i modyfikować ta-kie koperty. Przykład koperty SOAP żąda-nia klienta z security extension możemy zobaczyć na Rysunku 1.

WSDL – Web Services Definition LanguageWSDL to najtrudniejsza część związana z Web Services. WSDL to język, w któ-rym definiujemy naszą usługę tak, aby in-ne systemy mogły z niej korzystać. WSDL składa się z 5 najważniejszych części:

• <types> – definicje typów złożonych, które nie są obsługiwane przez XSD, jeśli nie używamy tablic, czy własnych klas kopertowych, nie musimy definio-wać nic,

• <message> – definicje wiadomości, de-finiujemy tu z jakich typów składają się dana wiadomość, jeśli z typów złożo-nych, muszą one być wcześniej zdefi-niowane w <types>,

Listing 1. Koperta SOAP służąca do wywołania zdalnej usługi PobierzArtykul

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=

"http://schemas.xmlsoap.org/soap/encoding/">

<SOAP-ENV:Body>

<!-- nazwa metody -->

<ns1:PobierzArtykul>

<!-- parametry... tutaj parametr o nazwie id, typu xsd:int o wartości 1212 -->

<id xsi:type="xsd:int">1212</id>

</ns1:PobierzArtykul>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Listing 2. Koperta SOAP będąca odpowiedzią na wywołanie usługi PobierzArtykul

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/

encoding/">

<SOAP-ENV:Body>

<!-- wynik działania PobierzArtykul -->

<ns1:PobierzArtykulResponse>

<!-- typem zwracanym jest xsd:string o podanej zawartości -->

<PobierzArtykulReturn xsi:type="xsd:string">

zalozmy, ze przeszukalismy baze i to jest ten jedyny artykul

</PobierzArtykulReturn>

</ns1:PobierzArtykulResponse>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

Listing 3. Wiązanie ProsteOperacjeSoapBinding

<wsdl:binding name="ProsteOperacjeSoapBinding" type="impl:ProsteOperacje">

<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="PobierzArtykul">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="PobierzArtykulRequest">

<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/

encoding/" namespace="http://t:81/soap/article/

ProsteOperacjeWS.php" use="encoded"/>

</wsdl:input>

<wsdl:output name="PobierzArtykulResponse">

<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/

encoding/" namespace="http://t:81/soap/article/

ProsteOperacjeWS.php" use="encoded"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

Rysunek 1. Rozbudowana koperta SAOP – WS Security Enhancements

Page 54: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org54

• <portType> – definiuje zbiór operacji udostępnianych na zewnątrz, jest od-powiednikiem interfejsu klas, opera-cje definiuje w dzieciach <operation>, które definiują operacje, pobierają na wejściu pewną wiadomość i zwraca-ją wiadomość; wiadomości muszą być definiowane w <message>,

• <binding> – wiążę operacje zdefinio-wane w portType z konkretnym pro-tokołem (najczęściej HTTP/HTTPS) oraz zawiera informacje na temat ko-dowania parametrów/odpowiedzi kon-kretnych operacji,

• <service> – wiąże wcześniej zdefinio-wany binding z konkretnym adresem, pod którym dostępna będzie nasza usługa.

Z tak opisanej usługi klient może dowiedzieć się wszystkiego, czego potrzebuje, aby wy-wołać dowolną metodę. Istnieje wiele pakie-tów typu WSDL2Java, które generują kody klientów w Java-ie, gotowe do użycia i wy-wołania zdalnego serwisu, MS .NET sam tworzy referencje i wiązania obiektów, rów-nież w PHP5 w kliencie SOAP wystarczy podać adres do pliku WSDL, aby można by-ło korzystać ze wszystkich usług zdefiniowa-nych w Web Services.

WSDL może na pierwszy rzut oka wy-dawać się bardzo trudnym. Nic jednak bar-dziej mylnego, jest wręcz dziecinnie prosty. Zobrazuje to nasz pierwszy przykład.

Pierwsza usługa Web Service PHP5 – WSDLZdefiniujmy klasę, której publiczne me-tody będą operacjami udostępnianymi przez naszą usługę. Poniżej pokazuję,

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

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions targetNamespace="http://t:81/soap/article/ProsteOperacjeWS.php"

xmlns:impl="http://t:81/soap/article/ProsteOperacjeWS.php"

xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<wsdl:message name="PobierzArtykulResponse">

<wsdl:part name="PobierzArtykulReturn" type="xsd:string"/>

</wsdl:message>

<wsdl:message name="PobierzArtykulRequest">

<wsdl:part name="id" type="xsd:int"/>

</wsdl:message>

<wsdl:portType name="ProsteOperacje">

<wsdl:operation name="PobierzArtykul" parameterOrder="id">

<wsdl:input message="impl:PobierzArtykulRequest" name="PobierzArtykulRequest"/>

<wsdl:output message="impl:PobierzArtykulResponse" name="PobierzArtykulResponse"/>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="ProsteOperacjeSoapBinding" type="impl:ProsteOperacje">

<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="PobierzArtykul">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="PobierzArtykulRequest">

<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/

encoding/" namespace="http://DefaultNamespace" use="encoded"/>

</wsdl:input>

<wsdl:output name="PobierzArtykulResponse">

<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/

encoding/" namespace="http://t:81/soap/article/

ProsteOperacjeWS.php" use="encoded"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="ProsteOperacjeService">

<wsdl:port binding="impl:ProsteOperacjeSoapBinding" name="ProsteOperacje">

<wsdlsoap:address location="http://t:81/soap/article/

ProsteOperacjeWS.php"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

Listing 5. Kod klasy implementującej interfejs naszej usługi sieciowej

// w normalnych warunkach klasa ProsteOperacje

// łączyła by się z bazą danych i pobierała artykułu

// dodatkowo ciągi znaków przesyłane SOAP muszą być

// zakodowane w UTF-8, używam do tego prostych funkcji konwertujących

require_once ('Strings.inc.php');

class ProsteOperacje { function PobierzNajnowszyArtykul() { return Strings::ConvertFromISOToUTF("załóżmy, że to jest ten artykuł"); }

function PobierzArtykul($id) { return Strings::ConvertFromISOToUTF("zalozmy, ze przeszukalismy baze i to jest ten jedyny artykul");

}

function Pobierz10Najnowszych($kategoria) { return array ( Strings::ConvertFromISOToUTF('pierwszy artykuł'),

Strings::ConvertFromISOToUTF('drugi artykuł'),

Strings::ConvertFromISOToUTF('kolejny artykuł')

);

}

}

Listing 6. Plik ProsteOperacjeWS.php

// plik z naszą klasą ProsteOperacje

require_once 'ProsteOperacje.

inc.php';

// parametrem konstruktora

// SoapServer jest adres do pliku

// WSDL

$server = new SoapServer ('ProsteOperacje.wsdl');

// klasa implementująca portType

$server->setClass('ProsteOperacje');

// przekazujemy sterowanie do PHP5

// – to wszystko

$server->handle();

Page 55: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 55

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:

<wsdl:message name="Pobierz

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).

<wsdl:portType name="Proste Operacje">

<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 z przedrostkiem impl:). Wiązanie na-

Rysunek 2. Jeśli przeglądając usługę przez przeglądarkę zobaczymy błąd przewrot-nie znaczy to, że usługa działa, tylko nie ma danych POST

Rysunek 3. Każda usługa powinna przedstawić się podając swój WSDL po doda-niu ?wsdl do adresu usługi

Rysunek 4. Pierwsze zdalne wywołanie naszej usługi sieciowej

Page 56: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org56

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>';

Listing 8. Tworzenie Thread t = new Thread()

public void run() { String url = "http://t:81/soap/article/ProsteOperacjeWS.php"; HttpTransport transport = new HttpTransport(url, "ProsteOperacje"); SoapObject request = new SoapObject(url, "PobierzArtykul"); request.addProperty("id", Integer.valueOf(idArtykulu.getString())); try {

odpowiedz.setText("\n" + ((String)transport.call(request))); } catch (IOException ex) {

ex.printStackTrace();

}

}

};

t.start();

Rysunek 5. Dodanie Web Reference do projektu C# .NET

Rysunek 6. Usługa sieciowa napisana w PHP5 wywołana z poziomu Java SE

zywam “ProsteOperacjeSoapBinding”, które przedstawia Listing 3.

Ostatnim elementem jest powiązanie wiązania o nazwie ProsteOperacjeSoap-Binding z adresem pod którym będzie do-stępna usługa. W elemencie <port> dla atrybutu binding przypisuję nazwę wiąza-nia z prefiksem impl:.

<wsdl:service name="ProsteOperacjeService">

<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 – serwerJeś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).

Page 57: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 57

Załóżmy, że mamy klasę Proste-

Operacje, taką jak pokazana na Listingu 4, którą chcemy udostępnić jako usługę sie-ciową. Normalnie, wszystkie artykuły po-winny być wyciągane z bazy danych, ale my w przykładzie użyjemy danych wpro-wadzonych na sztywno. Listing 6 prezen-tuje jak powinien wyglądać plik ProsteOpe-racjeWS.php. W tym momencie, jeśli połą-czymy się z naszą usługą np. przez prze-glądarkę WWW, dostaniemy komunikat, że nie znaleziono danych POST (wiado-mości SOAP wrzucane są w ciało wiado-mości HTTP a zatem muszą używać meto-dy POST) – zobacz Rysunek 2. Wiele silni-ków Web Services próbuje w momencie łą-czenia się do usługi pobrać WSDL automa-tycznie. Przyjęło się, że WSDL powinien być zwracany zawsze, jeśli QUERY_STRING jest równy '?wsdl', zatem dopiszmy na samym początku pliku ProsteOperacjeWS.php:

if (0 == strcmp($_SERVER

['QUERY_STRING'], '?wsdl')) {

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

readfile('ProsteOperacje.wsdl');

die();

}

Teraz jeśli w przeglądarce podamy adres: http://t:81/soap/article/ProsteOperacjeWS.php?wsdl zobaczymy definicję WSDL na-szej usługi tak, jak jest to pokazane na Ry-sunku 3.

Pierwsza usługa Web Service PHP5 – klientAby przetestować naszą usługę, należy na-pisać klienta. Napisać klienta podobnie jak serwer jest bardzo prosto, a nawet prościej, bo nie musimy tworzyć żadnego WSDL. Aby wykonać dowolną metodę zdalną w wersji minimalistycznej potrzebujemy 2 linii:

$client = new SoapClient('http://

t:81/soap/article/ProsteOperacjeWS.

php?wsdl');

var_dump(Strings::ConvertFromUTFToISO

($client->PobierzNajnowszyArtykul())

);

Jak widzimy, użyłem tu ponownie funk-cji konwertującej. Wszystko, co jest wy-syłane SOAP musi być w UTF-8, więk-szość stron polskojęzycznych używa jed-nak kodowania ISO-8859-2, użyłem więc prostej funkcji konwertującej polskie zna-ki diakrytyczne z UTF-8 do ISO.

Jeśli spojrzymy na Listing 5, za-uważymy, że SoapClient posiada rów-nież drugi argument, który domyślnie jest NULL. Są to opcje, bardzo przydatne np. podczas testowania. Jeśli włączymy fla-gę trace, będziemy mieli do dyspozycji dwie metody:

$client->__getLastRequest();

$client->__getLastResponse();

które zwracają odpowiednio: ostatnie żą-danie wysłane do serwera i ostatnią odpo-wiedź. Jeśli włączymy flagę exceptions, PHP5 będzie reagował na wyjątki, które zo-stały wyrzucone na zdalnej maszynie, dlate-go też na Listingu dodałem blok try/catch wokół wywołania metod na obiekcie $client. Wynik naszego pierwszego zdalnego wywo-łania przedstawiony jest na Rysunku 4.

Web Service PHP5 serwer – klient w MS .NETMamy już działającą usługę sieciową. Na-pisaliśmy do niej klienta w PHP5. To nic nadzwyczajnego. Połączmy się do niej z innej platformy technologicznej.

Dodanie usługi sieciowej jest dziecin-nie proste. Będąc w oknie Solution, wy-starczy prawym przyciskiem myszki klik-nąć na Project, następnie wybrać Add

Listing 9. Przykładowa usługa sieciowa napisana w C#

namespace WebServiceTest

{

public class WebService : System.Web.Services.WebService { [WebMethod]

public string getString(){ return "Jestem łańcuchem"; }

[WebMethod]

public double getDouble() { return -123123.23123d; }

[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

Page 58: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org58

Web Reference (Zobacz Rysunek 6) i po-dać adres definicji WSDL. U nas będzie to: http://t:81/soap/article/ProsteOperacjeWS.php?wsdl. Wszystkie typy zdalne i obiekty służące do połączeń są domyśl-nie wrzucane do przestrzeni nazw takiej, jak ma nasz projekt z rozszerzeniem na-zwy hosta z jakiego pochodzą. Czyli, wy-wołanie zdalne będziemy zapisywali tak (mój testowy host to t od słówka test):

t.ProsteOperacjeService proxy =

t.ProsteOperacjeService();

int id = 1212;

string artykul = proxy.PobierzArtykul(id);

Web Service PHP5 serwer – klient w Java SEPosłużę się tutaj środowiskiem NetBeans. Stwórzmy nowy projekt. Po utworzeniu klik-nijmy na nim prawym przyciskiem o okienku Navigator i wybierzmy opcję: New -> Web Service Client. Następnie podajemy adres WSDL usługi i klikamy OK. Po kilku sekun-dach będziemy mieli utworzone wszystkie niezbędne pliki do połączeń z usługą. Mo-żemy też skorzystać z narzędzia do testo-wania zdalnych wywołań, za pomcą klik-nięć w NB możemy wywołać dowolną meto-dę z dowolnymi parametrami. Jeszcze tylko jedna mała uwaga: kody źródłowe klas NB generuje dość niestandardowo do katalogu bin. Należy je ręcznie skopiować do katalo-gu src! Następnie, w obsłudze konkretnej akcji piszemy:

ProsteOperacjeService po =

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 MobileAby połączyć się z usługą sieciową w J2ME mamy do wyboru: natywny JSR 175 (dość ograniczony, w dodatku ofe-

Listing 10. Klient PHP5 łączący się do usługi MS .NET

require_once ('Strings.inc.php');

$client = new SoapClient( 'http://localhost/WebServiceTest/WebService.asmx?wsdl',

array('trace' => 1) );

$functions = $client->__getFunctions();

echo '<pre>';var_dump($functions);

$string = $client->getString();

var_dump(Strings::ConvertFromUTFToISO($string->getStringResult));

$double = $client->getDouble();

var_dump($double->getDoubleResult);

$int = $client->getInt();

var_dump($int->getIntResult);

// UWAGA!!

// MS Int64.MAX_VALUE

// jest w PHP jako float!

$long = $client->getLong();

var_dump($long->getLongResult);

$booleanArray = $client->getBooleanArray();

var_dump($booleanArray->getBooleanArrayResult->boolean);

// nie zadziała!

//$response = $client->makeItArray(123, -123.0, "string", true);

class MakeItArray { public $i;

public $d;

public $s;

public $b;

public function __construct($i, $d, $s, $b) { $this->i = $i;

$this->d = $d;

$this->s = $s;

$this->b = $b;

}

}

$response = $client->makeItArray(new MakeItArray(123, "-123.0", "string", true)); var_dump($response->makeItArrayResult->anyType);

echo '</pre>';

Rysunek 8. Klient PHP5 łączący się z usługą MS .NET, rezultat

Page 59: PHP Solutions 02 2007 PL
Page 60: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org60

rujący tylko tryby DOCUMENT/literal) lub skorzystać z darmowych biblio-tek typu kSOAP czy WingFoot. Ja uży-ję kSOAP.

Aby połączyć się z usługą należy utworzyć obiekt HttpTransport podać adres URL do usługi (nie do WSDL, kSOAP sam pobierze WSDL dodając ?wsdl do adresu). Tworzymy żąda-nie jako SoapObject – drugim parame-trem jest nazwa zdalnej metody. Je-śli metoda ma parametry dodajemy je jako property. Służy do tego meto-da addProperty – pierwszym argumen-tem jest nazwa parametru, drugim – je-go wartość (jako obiekt, dlatego użyłem Integer, a nie int).

Samo łączenie się do usługi musi być wykonane w odrębnym wątku, inaczej emulator generuje ostrzeżenie o możli-wym dead-locku podczas prawdziwych połączeń z komórki, tworzę więc

Thread t = new Thread() {. Przedstawia

to Listing 8.

PHP5 jako klientJak zauważyliśmy Java, Java mobile czy .NET komunikuje się bez problemu z na-szym serwerem SOAP. Java pracuje na Unicode, .NET zazwyczaj na WinCp1250, a jak zauważyliśmy, wszystkie znaki są poprawnie przedstawiane, nie ma także problemów z przesyłaniem różnych ty-pów danych.

Ale to tylko i wyłącznie dlatego, że to Java czy .NET biorą na siebie wszystkie rzeczy związane z przekształ-ceniem odpowiedzi na swoją wewnętrz-ną reprezentację.

Co będzie, jeśli to my z poziomu PHP5 będziemy wołali metody z .NET czy z Jakarta AXIS?

Web Service PHP5 klient – serwer MS. NETStwórzmy testową usługę sieciową napi-saną w C#. Jej kod przedstawiony jest na Listingu 9. Dla skrócenia listingu, usuną-łem automatycznie wygenerowane meto-dy typu: InitializeComponent, oraz usu-nąłem dyrektywy using.

Widzimy, że mamy zdefiniowane ope-racje, które mają nam zwrócić różne ty-py danych, począwszy od int, double, string po tablice typów prostych a skoń-czywszy na tablicach obiektów. (w .NET int, double, string czy bool są równoznacz-ne z obiektami).

Listing 11. Przykładowa usługa sieciowa napisana w Java'ie

public class WebServiceTest {

public String getString() { return "Jestem łańcuchem ąśź"; }

public double getDouble() { return -123123.23123d; }

public long getLong() { return Long.MAX_VALUE; }

public int getInt() { return Integer.MAX_VALUE; }

public boolean[] getBooleanArray() { return new boolean[] { true, false, false, true }; }

public Object[] makeItArray(int i, double d, String s, boolean b) { Object[] o = new Object[] {new Integer(i), new Double(d), s, new Boolean(b) };

return o; }

}

Listing 12. Klient PHP5 łączący się do usługi AXIS (Java)

require_once ('Strings.inc.php');

$client = new SoapClient( 'http://localhost:8080/axis/WebServiceTest.jws?wsdl', array('trace' => 1));

$functions = $client->__getFunctions();

echo '<pre>';var_dump($functions);

// UWAGA!

// AXIS zwraca odpowiedź w formacie:

// Jestem &#x139;&#x201A;a&#x139;&#x201E;cuchem

// &#xC4;&#x2026;&#x139;&#x203A;&#x139;&#x15F;

// jest ona błędna - polskie znaki nie są kodowane w UTF-8

// tylko zamieniane na encje, stąd problem ponieważ PHP

// próbuje najpierw rozkodować UTF-8

var_dump($client->getString());

var_dump($client->getDouble());

var_dump($client->getInt());

// UWAGA!!

// Java Long.MAX_VALUE

// jest w PHP jako float!

var_dump($client->getLong());

var_dump($client->getBooleanArray());

// działa bez problemu!

// nie trzeba niczego pakować w obiekty

var_dump($client->makeItArray(123, -123.0, "string", true));

echo '</pre>';

Page 61: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 61

Bardzo pożyteczną funkcją, z ja-kiej skorzystamy, jest __getFunctions, która jest wywoływana na obiekcie SoapClient, a która zwraca nam sygna-tury zdalnych metod. Z nich dowiemy się np. że MS .NET opakowuje wszystkie wiadomości zarówno input jak i output. I tak np. $client->getString() zwraca nam obiekt, w którym znajduje się pole getStringResult. Aby wywołać metody z parametrami, musimy utworzyć obiekt, którego nazwy pól są takie same jak na-zwy parametrów usługi MS .NET. Listing 7 wyjaśni wszelkie wątpliwości, a Rysu-nek 8 potwierdzi poprawne działanie na-szego kodu.

Klient Web Service PHP5 – Serwer Jakarta AXIS (Java)Stwórzmy teraz analogiczny kod usłu-gi sieciowej AXIS. Jest on pokazany naListingu 11. Usługi sieciowe JWS to nor-malne kody źródłowe Java'y z rozsze-rzeniem nie java, a właśnie jws, które kopiujemy (tak, tylko kopiujemy!) bez-pośrednio do $CATALINA_HOME/webapps/axis/.

Znów skorzystamy z funkcji __get-Functions, która zwróci nam sygnatu-ry zdalnych metod. Z nich dowiemy się np. że Jakarta AXIS w przeciwieństwie do MS .NET nie opakowuje wszystkich wiadomości. Możemy z nich korzystać wprost tak, jakby były lokalnie wywoły-wanymi funkcjami. Ale zauważymy, że coś jest nie tak. Polskie kodowanie! Tak, jeśli podejrzymy koperty SOAP wymie-niane z usługą AXIS okaże się, że pol-skie znaki nie są kodowane w UTF-8, tylko są zamieniane na kody znaków ty-pu &#1111;. Jest to niewątpliwie błądAXISa, można oczywiście z tego wybrnąć 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 pokazuje jak wywoływać usługi sieciowe Java'y w PHP5, a Rysunek 9 potwierdzi poprawne działanie naszego kodu.

Typy złożone i mapowaniaNie jest sztuką przesłać obiekt ty-pu string czy int, sztuką jest przesłanie obiektu PHP do np. MS .NET czy do Ja-va'y. Załóżmy, że mamy usługę siecio-wą z metodą, która zwraca klasę Autor, z polami nazwisko – typu string oraz po-lem ksiazki, które jest tablicą obiektów Ksiazka. W WSDL będziemy musieli zde-

Listing 13. Definicja WSDL typów złożonych: autor, ksiazka oraz tablica książek

<wsdl:types>

<schema targetNamespace="http://t:81/soap/article/ComplexTypeWS.php"

xmlns="http://www.w3.org/2001/XMLSchema">

<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>

<xsd:complexType name="autor">

<xsd:all>

<xsd:element name="nazwisko" type="xsd:string"/>

<xsd:element name="ksiazki" type="impl:ArrayOf_impl_ksiazka"/>

</xsd:all>

</xsd:complexType>

<xsd:complexType name="ksiazka">

<xsd:all>

<xsd:element name="tytul" type="xsd:string"/>

<xsd:element name="isbn" type="xsd:int"/>

</xsd:all>

</xsd:complexType>

<complexType name="ArrayOf_impl_ksiazka">

<complexContent>

<restriction base="soapenc:Array">

<attribute ref="soapenc:arrayType" wsdl:arrayType="impl:

ksiazka[]"/>

</restriction>

</complexContent>

</complexType>

</schema>

</wsdl:types>

Listing 14. Definicja WSDL typów złożonych: autor, ksiazka oraz tablica książek

if (0 == strcmp($_SERVER['QUERY_STRING'], '?wsdl')) { header('Content-type: text/xml'); readfile('ComplexType.wsdl'); die();}

class Autor { private $ksiazki = array(); function __construct($nazwisko) { $this->nazwisko = $nazwisko;

}

function dodajKsiazke(Ksiazka $ksiazka) { $this->ksiazki[] = $ksiazka;

}

}

class Ksiazka { private $tytul;

private $isbn;

function __construct($tytul, $isbn) { $this->tytul = $tytul;

$this->isbn = $isbn;

}

}

// klasa usługi sieciowej

class ComplexType { function PobierzAutora($id) { // załóżmy, że szukamy w bazie autora o id = $id i znaleźliśmy

$autor = new Autor('Budnik'); $autor->dodajKsiazke(new Ksiazka('PHP vs .NET vs Java vs J2ME', 1212)); $autor->dodajKsiazke(new Ksiazka('PHP LIZ DB', 1313)); return $autor; }

}

// mapowanie klas! TypZłożonyWSDL => NazwaKlasyPHP

$classmap = array('autor' => 'Autor', 'ksiazka' => 'Ksiazka');$server = new SoapServer("ComplexType.wsdl");$server->setClass("ComplexType");

$server->handle();

Page 62: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org62

finiować trzy typy złożone: autor, książka oraz tablicę książek. WSDL przedstawio-ny jest na Listingu 13.

Klasa PHP implementująca np. typy autor czy ksiazka, wcale nie musi mieć publicznych pól. Mogą one być ukryte we wnętrzu jako pola private. Wystar-czy, że jest pewien mechanizm za po-mocą, którego możemy te pola ustawić. W naszym prostym przykładzie posta-nowiłem przypisywać pola w konstrukto-rach. Spójrzmy na implementację i kod usługi sieciowej zamieszczonej na Li-stingu 14.

Połączmy się z nią w MS .NET. Plat-forma Microsoft wykonuje mapowanie praktycznie za nas, ja napisałem dodat-kowo klasę Ksiazka ze statyczną meto-dą Convert. Aby móc dodać do Data-Source tablice klas, klasy muszą mieć stworzone publiczne property, które au-tomatycznie będą mapowane na kolum-ny. Kod łączenia się z usługą wygląda jak poniżej, kod klasy Książka zamiesz-czony jest na Listingu 15, a wynik dzia-łania z kolei na Rysunku nr 10.

t.ComplexTypeService proxy =

new t.ComplexTypeService();

t.autor autor = proxy.PobierzAutora

(Int32.Parse(this.idAutora.Text));

nazwiskoAutora.Text = autor.nazwisko;

ksiazkiDataGrid.DataSource = Ksiazka.

Convert(autor.ksiazki);

Implementujemy SOAP Security Enhancements plus HTTPS – serwerImplementacja SOAP w PHP5 zawie-ra jedynie podstawowe operacje. Jeśli chcemy skorzystać z jakiegoś rozsze-rzenia musimy sami je zaimplemento-wać. Spróbujemy teraz udostępnić na-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-ście udostępnienie naszej usługi przez HTTPS, wymaga to jedynie wgrania na-szej usługi na serwer z obsługą SSL i zmienienie w WSDL elementu <address> atrybutu location tak, jak przedstawia to Listing 16.

Stwórzmy zatem na naszą nową klasę serwera, szkielet będzie wyglądał tak, jak na Listingu 17.

Widzimy w nim, że rozszerzamy podsta-wową klasę SoapServer, nadpisujemy tylko metodę handle, w której z $rawData wczy-

Listing 15. Kod klasy C# Ksiazka, z publicznymi property i metodą konwertującą obiekty

class Ksiazka { private xh.ksiazka ksiazka; public string Tytul { get {

return ksiazka.tytul; }

}

public int ISBN { get {

return ksiazka.isbn; }

}

public Ksiazka(xh.ksiazka ksiazka) { this.ksiazka = ksiazka; }

public static Ksiazka[] Convert(xh.ksiazka[] ksiazki) { Ksiazka[] dotNetKsiazki = new Ksiazka[ksiazki.Length]; for (int i = 0; i < ksiazki.Length; i++) { dotNetKsiazki[i] = new Ksiazka(ksiazki[i]); }

return dotNetKsiazki; }

}

Listing 16. Wgranie usługi na serwer z obsługą SSL i zmienienie w WSDL ele-mentu <address> atrybutu location

<wsdl:service name="ProsteOperacjeService">

<wsdl:port binding="impl:ProsteOperacjeSoapBinding" name="ProsteOperacje">

<wsdlsoap:address location="https://ers:4433/soap/article/

ProsteOperacjeWSSecExt.php"/>

</wsdl:port>

</wsdl:service>

Listing 17. Szkielet nowej klasy serwera

class SecExtSoapServer extends SoapServer { public function __construct($wsdl) { parent::__construct($wsdl);

}

public function handle($rawData) { // sprawdź dane użytkownika

$this->CheckCredentials($dom); // zapisz zmodyfikowane żądanie i prześlij do klasy rodzica

parent::handle($dom->saveXML());

}

private function CheckCredentials(&$dom) { // tu napiszemy własną obsługę WS-SE

}

}

Listing 18. Częściowy kod serwera

$nodes = $dom->getElementsByTagNameNS ('http://docs.oasis-open.org/wss/

2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd', 'UsernameToken');

if ($nodes->length == 0) { $valid = false;} else { // użytkownik jest tu:

$nodes->item(0)->firstChild->textContent;

// hasło tu:

$nodes->item(0)->firstChild->nextSibling->textContent;

$valid = true;}

Page 63: PHP Solutions 02 2007 PL

SOAP w PHP5 Narzędzia

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

if (0 == strcmp($_SERVER['QUERY_STRING'], 'wsdl')) { header('Content-type: text/xml'); readfile('ProsteOperacjeSecExt.wsdl'); die();}

class SecExtSoapServer extends SoapServer { public function __construct($wsdl) { parent::__construct($wsdl);

}

public function handle($rawData) {

if (true == empty($rawData)) { $this->fault('SOAP-ENV:Server',

'Bad Request. Can\'t find HTTP_RAW_POST_DATA');

}

$dom = new DOMDocument('1.0'); try {

// ładuję dokument danymi z POST

$dom->loadXML($rawData);

} catch (DOMException $e) {

$this->fault('SOAP-ENV:Client', 'Bad Request.');

}

// weryfikuję dane użytkowników

$this->CheckCredentials($dom);

// zapisz zmodyfikowane żądanie i

// prześlij do klasy rodzica

parent::handle($dom->saveXML());

}

private function CheckCredentials(&$dom) { $valid = true;

$nodes = $dom->getElements ByTagNameNS(

'http://docs.oasis-open.org/wss/2004/01/

oasis-200401-wss-wssecurity-secext-1.0.xsd',

'UsernameToken'

);

if ($nodes->length == 0) { $valid = false;

} else { // użytkownik jest tu:

$nodes->item(0)->firstChild->textContent;

// hasło tu:

$nodes->item(0)->firstChild->nextSibling

->textContent;

// załóżmy, że tu połączymy się z bazą i to sprawdzimy

$valid = true;

}

// wyrzuć zdalny wyjątek jeśli jest błąd

if (false == $valid) { $this->fault('SOAP-ENV:Client', 'Invalid credentials');

}

// teraz muszę usunąć nagłówki, które już przetworzyłem

// domyślna implementacja PHP5 SOAP nie obsłuży nam

// WS Security, a element Security ma podany atrybut

// mustUnderstand="1" wtedy przesłane do parent::handle

// wyrzuci wyjątek, że nie zrozumiał

$header = $dom->getElementsByTagNameNS (

'http://schemas.xmlsoap.org/soap/envelope/',

'Header')->item(0);

// cały węzeł Security

$security = $dom->

getElementsByTagNameNS ( 'http://docs.oasis-open.org/

wss/2004/01/oasis-200401-wss-wssecurity-secext-

1.0.xsd', 'Security')->item(0);

$header->removeChild($security);

}

}

require_once ('Strings.inc.php');

require_once ('ProsteOperacje .inc.php');

$server = new SecExtSoapServer ('ProsteOperacjeSecExt.wsdl');$server->setClass('ProsteOperacje');

// trzeba jawnie podać: $HTTP_RAW_POST_DATA

$server->handle($HTTP_RAW_POST_DATA);v

R E K L A M A

Page 64: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org64

Listing 20. Łączenie z usługą

ers.ProsteOperacjeServiceWse proxy=

new ers.ProsteOperacjeServiceWse();

string pw = "I love Jessica Simpson";

proxy.RequestSoapContext.Security.Tokens.Add (

new UsernameToken( "xh", pw, PasswordOption.SendPlainText

)

);

try {

textBox1.Text = proxy.PobierzNajnowszyArtykul();

}

catch (Exception ex)

{

System.Console.WriteLine(

"Wyjątek: " + ex.GetType() + "\n" + ex.Message + "\n" +ex.StackTrace

);

}

Listing 21. Szkielet klienta przy zastosowaniu metody AddWSSEHeader

class ExtendedSoapClient extends SoapClient {

function __construct($wsdl, $options = null) { parent::__construct($wsdl, $options);

}

function __doRequest($request, $location, $action, $version) {

$this->AddWSSEHeader($dom);

// doRequest do rodzica

return parent::__doRequest ( $request, $location, $action, $version);

}

public function SetUsername($username) { } public function SetPassword($password) { } private function AddWSSEHeader($domDocument) { // tutaj wygenerujemy nagłówek

}

}

tamy dokument DOM XML (nie ma tego w powyższym szkielecie, nie ma także po-kazanej weryfikacji, czy dane POST wpro-wadzone nie są puste, czy żądanie jest po-prawnym dokumentem XML), przekażemy później przez referencję dokument do meto-dy prywatnej CheckCredentials. W tej meto-dzie pobierzemy elementy <Username> oraz <Password> elementu <UsernameToken> we-wnątrz <Security> w nagłówku koperty. Ko-perta ta została przedstawiona na Rysunku 1. Samo pobranie użytkownika i jego hasła jest sprawą banalną, wystarczy wyszukać element Username z przestrzeni nazw http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd, póź-

niej, za pomocą API DOM XML, pobrać od-powiednie wartości. Praktyczna uwaga: dla hasła należy sprawdzić jeszcze atrybut Ty-pe, aby dowiedzieć się, czy hasło jet skró-tem SHA1 czy PlainText. Sam kod jest pro-sty i przedstawia go Listing 18. Pełny kod serwera umieściłem na Listingu 19.

Aby mieć pewność, że poprawnie zaim-plementowaliśmy to rozszerzenie, stwórz-my projekt np. w MS .NET. W przypadku VS 2003 musimy mieć doinstalowany pakiet WS Security Enhancements 2.0 w wersji dla developerów. Dodajemy Web Reference jak poprzednio, podajemy adres do WSDL czyli: https://ers:4433/soap/article/ProsteOperacjeWSSecExt.php?wsdl, przejdźmy na-

stępnie do katalogu Web References i po-prawmy MS, dopisując do każdego http:// kluczowe 's' czyli https://. Używam testowe-go certyfikatu serwera, który sam stworzy-łem, muszę więc przekonać MS, że jest on wartościowy (inaczej nie będę mógł się po-łączyć z serwerem SOAP): najprościej jest otworzyć w IE stronę: https://ers:4433/soap/article/ProsteOperacjeWSSecExt.php?wsdl lub dowolną z serwera ers:4433 i po prostu zainstalować certyfikat. Po zainstalowaniu i włączeniu WS SE 2.0, po wygenerowaniu referencji do usługi sieciowej będziemy mie-li do dyspozycji dwa obiekty służące do wy-woływania zdalnych usług. Pierwszy z nich 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 – klientNapisanie 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-główki WS SE. Szkielet klienta wygląda tak jak na Listingu 21. Pełny kod klienta umie-

Rysunek 11. Klient MS .NET łączący się po HTTPS do naszej usługi WS Security Enhancements

Page 65: PHP Solutions 02 2007 PL

SOAP w PHP5

PHP Solutions Nr 2/2007

Narzędzia

www.phpsolmag.org 65

'https://ers:4433/soap/article/

ProsteOperacjeWSSecExt.php?wsdl',

array('trace' => 1, 'exceptions'

=> 1, 'local_cert' => 'cert.pem'

)

);

$artykuly = $client->

Pobierz10Najnowszych();

PodsumowanieNauczyliśmy się dziś, jak współpracować z innymi platformami technologicznymi. Teraz śmiało możemy współtworzyć sys-temy rozproszone na bazie Web Servi-ces komunikujących się z takimi giganta-mi jak MS .NET, J2EE, Java Mobile. Wię-

cej, możemy korzystać z różnych rozsze-rzeń standardu WS Security Enhance-ments, które możemy z łatwością w kilka chwil zaimplementować. n

Listing 22. Kod klienta SOAP wspierającego WS Security Enhancements i łączącego się z usługą po HTTPS

class ExtendedSoapClient extends SoapClient { private $Username;

private $Password;

function __construct($wsdl, $options = null) { parent::__construct($wsdl, $options);

}

function __doRequest($request, $location, $action, $version) { $dom = new DOMDocument('1.0'); try {

$dom->loadXML($request);

} catch (DOMException $e) {

die('Dokument nie jest prawidłowy: ' . $e->code);

}

// dodaję nagłowek WSSE Security Header

$this->AddWSSEHeader($dom);

// musimy recznie dodac https, bo inaczej nici...

// PHP tez sobie do konca nie radzi z HTTPS

$location = 'https://vega.eti.pg.gda.pl/~xh/soap_ssl/

ProsteOperacjeWSSecExt.php';

// doRequest do klasy nadrzędnej SoapClient

return parent::__doRequest($dom->saveXML(), $location, $action, $version);

}

public function SetUsername ($username) { $this->Username = $username;

}

public function SetPassword ($password) { $this->Password = $password;

}

private function AddWSSEHeader ($domDocument) { $soapEnvelope = $domDocument->

documentElement;

// pobieram nagłówek

$nodes = $domDocument->getElementsByTagNameNS

('http://schemas.xmlsoap.org/

soap/envelope/', 'Header');

// jeśli go nie ma muszę go stworzyć

if ($nodes->length == 0) { $header = $domDocument->

createElementNS

('http://schemas.xmlsoap.org/

soap/envelope/', 'Header');

$body = $domDocument->

getElementsByTagNameNS ('http://schemas.xmlsoap.org/soap/

envelope/', 'Body');

$body = $body->item(0);

$header = $soapEnvelope->

insertBefore($header, $body);

}

else { $header = $nodes->item(0);

}

// tworzę właściwy element Security

$security = $domDocument->createElementNS

('http://docs.oasis-open.org/wss/2004/01/

oasis-200401-wss-wssecurity-

secext-1.0.xsd', 'wsse:Security');

// w nim element UsernameToken

$usernameToken = $domDocument->createElementNS('http://

docs.oasis-open.org/wss/2004/01/oasis-200401-

wss-wssecurity-secext-1.0.xsd', 'UsernameToken');

// w nim Username

$username = $domDocument->createElementNS

('http://docs.oasis-open.org/wss/2004/01/

oasis-200401-wss-wssecurity-secext-1.0.xsd',

'Username');

$usernameText = $domDocument->createTextNode

($this->Username);

// załóżmy, że Password zawsze będzie PlainText

$password = $domDocument->createElementNS

('http://docs.oasis-open.org/wss/2004/01/

oasis-200401-wss-wssecurity-secext-1.0.xsd',

'Password');

$passwordText = $domDocument->

createTextNode($this->Password);

$type = $domDocument->createAttribute('Type');

$type->value = 'http://docs.oasis-open.org/wss/2004/01/

oasis-200401-wss-username-token-profile-

1.0#PasswordText';

// podpinam wszystkie elementy do dokumentu żądania

$username->appendChild($usernameText);

$password->appendChild($type);

$password->appendChild($passwordText);

$usernameToken->appendChild($username);

$usernameToken->appendChild($password);

$security->appendChild($usernameToken);

$header->appendChild($security);

}

}

ściłem na Listingu 22. Aby jednak wywołać taką zdalną zabezpieczoną usługę, musi-my stworzyć odpowiedni certyfikat. Konia z rzędem temu, kto wyczyta w dokumentacji 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-watnego i certyfikatu w jednym! Wystarczy połączyć oba te pliki w jeden i zapisać jako np. cert.pem Wywołanie takiej metody jest już banalne, sprowadza się jedynie to 3 lo-gicznych linii:

require_once (

'ExtendedSoapClient.inc.php');

$client = new ExtendedSoapClient(

Łukasz Budnik jest studentem V ro-ku Informatyki na Politechnice Gdańskiej, uczestniczy w projektach nad rozwijaniem systemów zbierania i analizy danych w po-staci XML, jest rówież administratorem serwisu www.komputery-internet.net.

Kontakt:[email protected]

O autorze

Page 66: PHP Solutions 02 2007 PL

www.phpsolmag.org66

Kasa dla Webmastera

PHP Solutions Nr 2/2007

Zarabianie Kasa dla Webmastera

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

Jak zarobić na stronie www? Poradnik dla przedsiębiorczych webmasterówPaweł 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.

Przez kilka ostatnich lat zaszło w sieci wiele pozytywnych zmian. Nie boimy się już płacić za to-

wary i usługi. Coraz chętniej korzysta-my więc ze sklepów internetowych. Ich korzyści odkrywa coraz więcej osób, nie tylko dlatego, że są szybszą metodą na zakupienie dokładnie tego, co potrzebu-jemy. Zakupy w sieci są także tańszą al-ternatywą pozyskiwania dóbr, bo kosz-ty prowadzenia sprzedaży przez Inter-net są znacząco niższe. Niewątpliwie, istotny wpływ na popularność płacenia przez internet miały serwisy aukcyjne. Zaufanie, jakim darzymy najpopularniej-szy serwis aukcyjny, Allegro.pl świadczy dobitnie o ogromnym postępie, jaki do-konał się w świadomości użytkowników sieci. Omawiane zjawisko, niczym na-czynia połączone odbija się na byt wła-ścicieli wszelkiego rodzaju serwisów in-ternetowych. Mowa tu oczywiście o ser-wisach nie nastawionych bezpośred-nio na sprzedaż towarów, czyli o takich,

W SIECI

• Ad.net, http://www.adnet.pl/• AdClick, http://www.adclick.pl/• ARBOmedia, http://www.arbomedia.pl/• IDMnet, http://www.idmnet.pl/• phpAdsNew, http://www.phpadsnew.com/• phpPgAds, http://www.phppgads.com/• http://www.google.pl/adsense/• OnetKontekst, http://

kontekst.onet.pl/• Adkontekst, http://adkontekst.wp.pl/• AdPortal, http://www.adportal.pl/• AllPay.pl, http://www.allpay.pl/• CashBill, http://www.cashbill.pl/• Ebill.pl, http://www.ebill.pl/• Wapacz, http://www.wapacz.pl/• Wapster.pl, http://www.wapster.pl/

mobilepay/• AllPay.pl, http://www.allpay.pl/• Platnosci.pl, http://www.platnosci.pl/• Przelewy24.pl, http://

www.przelewy24.pl/

Stopień trudności: lll

które oferują przede wszystkim intere-sujące treści lub usługi internetowe. Fi-nansowe możliwości wielu tych serwi-sów zmieniły się odkąd użytkownicy są bardziej skorzy do płacenia za warto-ściową treść. W polskiej sieci trend pła-cenia za korzystanie ze stron interne-towych stał się masowy i nieunikniony. Wszystko to za sprawą fatalnej kondy-cji rynku reklamowego nastawionego ra-czej na duże przedsięwzięcia, typu por-tale, niż pojedyncze serwisy. W dodatku portale prowadzą sprzedaż reklam sa-modzielnie, stąd brak tu prowizji należ-nych sieciom reklamowym. Choć i we-wnętrzna sprzedaż reklam przez portale to tylko kropla w morzu ich potrzeb. Ta forma aktywności może być jedynie do-datkiem w ogólnym rozrachunku rodzi-mych portali. Zarabia się w najróżniej-szy sposób, np. wprowadzając opłaty za szybszą indeksację witryny w porta-lowym katalogu, czy wyszukiwarce. Są to usługi mocno wątpliwe, bo ideą po-

Page 67: PHP Solutions 02 2007 PL

www.phpsolmag.org66

Kasa dla Webmastera

PHP Solutions Nr 2/2007

Zarabianie Kasa dla Webmastera

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

wstania katalogu stron www, czy wyszu-kiwarki jest rzetelne i równorzędne trak-towanie wszystkich stron www.

W ciągu ostatniego roku stał się bar-dzo zauważalny rozwój reklamy kontek-stowej, która nie dość, że nie jest na-chalna, to jeszcze okazuje się klikalna. Dzieje się tak nie z nieudanej próby za-mknięcia reklamy, a z faktycznej warto-ści przekazu reklamowego.

Wszystkie do tej pory omówione czynniki rodzą sobą pytanie: czy nasta-ły dobre czasy dla tych, którzy utrzymu-ją się z prowadzenia serwisów w sieci? Spróbujmy odpowiedzieć na to pytanie podsumowując możliwości zarobkowe właściciela strony www.

Pierwszym podziałem, który rysu-je się, gdy mowa o płatnościach jest fi-zyczne źródło dochodu. Wyróżniamy więc metody, które:

• Pozyskują środki bezpośrednio od użytkownika. By skorzystać z usłu-gi, użytkownik musi dokonać płat-ności na stronie www. Jego rachu-nek telefoniczny lub bankowy ob-ciążany jest należną kwotą,

• Pozyskują środki od reklamodaw-ców, czy pośrednio od użytkownika. Reklamodawca zainteresowany pro-mowaniem swoich towarów i usług decyduje się na uiszczenie opłaty na podstawie ustalonego modelu ce-

nowego. Użytkownik płaci za rekla-mę pośrednio, ponieważ koszt rekla-my zawarty jest w cenie towaru lub usługi.

Sieci reklamoweW myśl zasady „reklama dźwignią han-dlu” powstały pierwsze sieci reklamo-we. Najstarsza polska sieć, IDMnet za-wiązała się już w 1997 roku. Podstawo-wym zadaniem sieci reklamowej jest po-średnictwo w sprzedaży powierzchni re-klamowej należącej do partnerów sieci oraz obsługa w ten sposób powstałych kampanii.Możemy zatem wyróżnić trzy strony biorą-ce udział w transakcjach:

• Reklamodawca – dom mediowy, fir-ma, agencja reklamowa dysponują-ca określonym budżetem na reali-zację kampanii marketingowej wła-snego produktu. Część środków kierowana jest do realizacji w sie-ci. W ten sposób w/w zleca realiza-cję kampanii sieci reklamowej. Na podstawie grupy docelowej, sta-nowiącej przedmiot zainteresowa-nia reklamodawcy, dobierani są ci partnerzy sieci reklamowej, którzy spełniają założenia. Reklama trafia do internautów, którzy mogliby być najbardziej zainteresowani przeka-zem danej kampanii,

• Partner – firma (rzadko osoba fi-zyczna) dysponująca serwisem lub serwisami internetowymi o określonej powierzchni reklamo-wej. Partner przyłącza się do sieci reklamowej podpisując stosowną umowę na wyłączność. Sieć rekla-mowa zapewnia partnerowi pro-cent od dochodów uzyskanych w wyniku realizacji kampanii na jego stronach. Partnerowi może przy-sługiwać tzw. gwarancja – o ne-gocjowanej wartości. Gwarancją określamy minimalną miesięcz-ną kwotę, którą partner otrzymuje bez względu na wyniki sprzedaży w danym okresie rozliczeniowym,

• Sieć reklamowa – odpowiada za pozyskiwanie klientów oraz ich ob-sługę. Sieć realizuje kampanie re-klamowe, kierując je do serwisów wybranych partnerów w oparciu o ich oglądalność oraz tematykę. To sieć reklamowa najczęściej decy-duje o tym, komu przydzielić da-ną kampanię, a komu nie. Jest to jak najbardziej stronnicza decy-zja, stąd partner nie ma wpływu na ilość realizowanych u niego kam-panii. Sieć reklamowa dostarcza tzw. technologię adserverową, czy-li oprogramowanie zdolne do rota-cji reklamami oraz zbierania i ana-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-czył na nią reklamodawca.Rysunek 1. Ad.net to największa sieć reklamowa w Polsce

Page 68: PHP Solutions 02 2007 PL

Zarabianie

PHP Solutions Nr 2/2007

Kasa dla Webmastera

www.phpsolmag.org68

Zarabianie

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

Kasa dla Webmastera

Sieci reklamowe to nie tylko wyświe-tlenie różnego rodzaju i formatu reklam na stronach www. To także realizacja kampanii opartych o mailing, czyli wy-syłkę internetowych przesyłek poczto-wych o treści reklamowej do dużej gru-py odbiorców. Stworzenie rozległej listy osób zainteresowanych treściami po-chodzącymi z danego serwisu owocu-je możliwością zaoferowania sieci rekla-mowej tego typu usługi. W przypadku, gdy znajdzie się reklamodawca skłonny zrealizować kampanię mailingową, mo-żemy liczyć na jednorazowe zwiększe-nie dochodu.

Sprzedaż reklamna 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.

Ustalanie cen na usługi w zakresie sprzedaży powierzchni reklamowej jest zadaniem niezmiernie trudnym. Należy pamiętać, że nie tylko zbyt wysokie, lecz także i zbyt niskie ceny mogą odstraszyć reklamodawcę.

Problem technologii służącej do ob-sługi tej formy reklamy jest łatwy do roz-wiązania. Wystarczy skorzystać z jednej z bezpłatnych aplikacji. Oprogramowa-nie na otwartym źródle, służące do rota-cji bannerów, jest nieskomplikowane do

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śnikiPewnym 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-nej z dostępnych metod (mikropłatno-ści sms, płatność bankowa – przelew z..., kartą kredytową).

Reklama kontekstowaGłównym zarzutem wobec reklamy bannerowej jest jej mała skuteczność. Przy użyciu coraz większej siły raże-nia (coraz większe reklamy, w dodatku w postaci filmów wyświetlanych na peł-ny ekran) sieci reklamowe starają się możliwe zwiększyć zasięg i skutecz-ność reklamy. Z marnym skutkiem.

Reklama kontekstowa powsta-ła, by odmienić los rynku reklamowe-

Rysunek 2. phpAdsNew to bezpłatne oprogramowanie do obsługi kampanii rekla-mowych

Rysunek 3. Reklama kontekstowa w wynikach wyszukiwania to dziś żadne novum

Page 69: PHP Solutions 02 2007 PL

Zarabianie

PHP Solutions Nr 2/2007

Kasa dla Webmastera

www.phpsolmag.org68

Zarabianie

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

Kasa dla Webmastera

go w sieci. Pomysł, który wdrożyła na świat jako pierwsza wyszukiwarka Go-ogle jest stosunkowo prosty. Dostar-czyć użytkownikom reklamę, która bę-dzie dostosowana treścią do wyników wyszukiwania.

Google AdWords był pierwszym na świecie programem skierowanym do re-klamodawców na całym świecie. Po re-jestracji, reklamodawca zyskuje możli-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 AdSenseGoogle 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-wym $100 ogólnego zarobku.

Reklamy dobierane są na podsta-wie treści strony. Roboty indeksują-ce analizują każdą ze stron, na której znajduje się reklama, tak, by zaofero-wać reklamy, które są możliwie zbliżo-ne do tematyki serwisu.

W praktyce zysk osiągany z tego tytułu może być bardzo zróżnicowany. Głównym tego powodem jest brak inte-resujących reklam. Jeżeli reklama tek-

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 wymiary.

Google nawiązuje współprace nie-mal z każdym serwisem internetowym. Wadą takiego rozwiązania są bardzo niskie stawki, ponieważ system może pobierać dla siebie prowizję dochodzą-cą nawet do 80%. Informacje te są jed-nak niejawne. Wielu właścicieli kont Ad-Sense zostało posądzonych o zjawisko kradnięcia kliknięć (ang. Click Fraud). Mieli oni jakoby dokonywać kliknięć na własne reklamy. Taki proceder jak za-

Rysunek 4. Z Google AdSense można bardzo szybko zacząć zarabiać

Rysunek 5. OnetKontekst to próba stworzenia polskiej alternatywy dla Google AdSense

Page 70: PHP Solutions 02 2007 PL

Zarabianie

PHP Solutions Nr 2/2007

Kasa dla Webmastera

www.phpsolmag.org70

Zarabianie

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

Kasa dla Webmastera

broniony i grozi za niego utrata zgro-madzonych środków oraz usunięcie z programu. Wiele serwisów broniło się przed takimi oskarżeniami, lecz Google pozostało nieugięte. To jeden z proble-mów AdSense, trudny do rozwiązania, bo tym sposobem można w bardzo ła-twy sposób pozbawić konkurencję tego źródła dochodu.

Reklama kontekstowa po polskuSukces AdSense wiąże się z ogromnym odpływem polskiego kapitału za granicę. Powstały więc polskie odpowiedniki, któ-re wyraziły chęć podzielenia rynku stwo-rzonego przez AdSense.

Systemy reklamy kontekstowej pol-skich portali powstały w drugiej połowie 2005 roku, natomiast AdPortal (w mo-mencie przygotowywania tekstu w prze-budowie) – w połowie roku 2006. Ponie-waż żadna z tych firm nie prezentuje in-formacji na temat osiąganych zysków, trudno wyrokować o skuteczności dzia-łania tych programów. Można stwierdzić, iż z pewnością ich zasięg jest znacznie mniejszy od Google AdSense. Prowizje utrzymywane na ok. 50% nie są w sta-nie skłonić większości webmasterów do przejścia na rozwiązania polskie. Powo-dem jest przede wszystkim zauważalnie mniejsza ilość reklamodawców. Tech-nologia oferowana przez polskie syste-my kontekstowe odbiega też od rozwią-

zań oferowanych przez Google. Brak tu-taj mechanizmu przydzielającego rekla-my na podstawie zawartości strony. To webmaster ustala tematykę serwisu, ko-rzystając przy tym ze specjalnego kata-logu.

Mikropłatności SMSDotychczas wszystkie zaprezentowa-ne metody oscylowały wokół zarabiania na publikacji reklam. Przejdźmy teraz do formy bardziej inwazyjnej, to znaczy mikropłatności SMS. Inwazyjność ozna-cza tu konieczność wprowadzenia opłat za pewien rodzaj usługi. Wiele witryn za-blokuje tutaj powszechny dostęp do arty-kułów lub do działu z plikami. Użytkow-nik otrzyma dostęp do pobierania plików lub możliwość obejrzenia artykułów do-piero wówczas, gdy uiści opłatę. Formy dostępu, to znaczy ilość plików, czy ilość artykułów, które można objerzeć po jed-nym zakupie, różnią się w zależności od serwisu.

Odwiecznym problemem, przed któ-rym stawali posiadacze stron www, by-ła obsługa płatności. Brakowało środ-ka płatniczego, który byłby dostępny dla większości użytkowników Interne-tu, a przy tym nie wymagał zbyt wiele wysiłku. Wiadomości SMS o podwyż-szonej wartości spełniły te oczekiwania więcej niż dobrze. Po wysłaniu wiado-mości o podwyższonej wartości (np. 2 zł + vat, 5 zł + vat), użytkownik otrzymuje

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.

Po utworzeniu nowej usługi w ser-wisie partnera, generujemy listę kilku tysięcy kodów, które następnie umiesz-czamy w bazie danych. Gdy użytkow-nik naszej strony wyśle wiadomość SMS, kolejny kod z listy zostanie do niego wysłany. Wystarczy teraz spraw-dzić, czy na naszej liście kodów istnie-je ten, wprowadzony na stronie przez użytkownika. Po jego wykorzystaniu, następuje usunięcie kodu. Algorytm wydaje się więc bardzo łatwy do imple-mentacji i taki też jest w praktyce.Oto lista partnerów obsługujących mi-kropłantości SMS:

Zarobki z tytułu wprowadzenia mi-kropłatności SMS mogą być bardzo znaczące, o ile dobrze zostanie prze-myślana strategia odnośnie sprzeda-ży. Stawki oferowane przez partne-rów są stosunkowo niskie w porówna-niu do wartości jednostkowej wiadomo-ści SMS. Przykładowo za SMS wysła-ny przez użytkownika o wartości 6 zł + vat otrzymamy nieco ponad 2 zł netto. Stawki są negocjowalne, gdzie większa sprzedaż oznacza nieco wyższe zyski. Nie można jednak liczyć na zbyt wyso-kie stawki. Znaczną część prowizji po-bierają przede wszystkim sieci komór-kowe i to one powodują, że usługi SMS są drogie i przynoszą zyski jedynie na masową skalę. Najdroższy SMS to wia-domość o wartości 9 zł + vat, najtańszy – 1 zł + vat, stąd usługi muszą opero-wać właśnie w tych granicach ceno-wych. Warto wybierać dużych partne-rów, ponieważ mają oni największy ob-

Rysunek 6. Zarabianie na mikropłatnościach SMS jest łatwe dzięki pośrednikom, ta-kim jak Wapacz

Page 71: PHP Solutions 02 2007 PL

Zarabianie

PHP Solutions Nr 2/2007

Kasa dla Webmastera

www.phpsolmag.org70

Zarabianie

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

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 bankoweDla 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,• MultiTransfer – przelew z MultiBanku,• Przelew z BPH,• Przelew z ING BankOnLine,• Przelewy24 – przelew z BZWBK,• Płać z Nordea – przelew z Nordea

Bank Polska,• Przelew z PKO Inteligo.

Także i w przypadku płatności kartą zalecane jest korzystanie z pośredni-ków. Oferują oni znacznie korzystniej-sze stawki niż przy mikropłatnościach SMS, ponieważ prowizje krążą w oko-licy kilku procent.

Implementacja tego typu płatności jest znacznie trudniejsza i uwzględnia sporą dawkę programowania. Właściciel serwisu musi bowiem upewnić się, iż pie-niądze zostały poprawnie przelane, co niestety trwa. Zazwyczaj do ok. 15 minut (i tak ta sytuacja uległa znaczącej popra-wie). Ta metoda płatności nie jest już tak dostępna, jak mikropłatności SMS, stąd skorzysta z niej znacznie mniej użytkow-ników. Mikropłatności kartą lub przele-wem należy stosować wszędzie tam, gdzie grupę docelową stanowi pokole-nie 30-40 latków, gdzie poczucie bezpie-czeństwa płatnościami kartą jest wyso-kie, a samodzielność podejmowania de-cyzji i posiadanie tego środka płatnicze-go najczęstsze (w porównaniu do prze-ważającego pokolenia 15-30 latków).

Programy partnerskieJedną z najstarszych metod zarobkowa-nia na stronach www są programy part-nerskie. Po przyłączeniu do programu,

właściciel rozpoczyna reklamowanie ser-wisu oferującego program. W zależności od programu, właściciel zarabia np. uzy-skując procent od sprzedaży będący wy-nikiem przejścia z serwisu reklamującego. Technologia stosowana w tym przypadku ogranicza się do plików cookies oraz sto-sowania specjalnych parametrów wejścio-wych przesyłanych metodą get (poprzez wpisanie adresu URL z parametrem).

Swoje programy partnerskie oferuje ogromna ilość firm, głównie sklepy in-ternetowe. Programy oferują witryny z bardzo różnych sektorów rynku. Warto wybrać programy należące do sklepów internetowych skorelowanych z tematy-ką danego serwisu. Powodzenie znaj-dą także programy niszowe, oferują-ce unikalne programy. Idea programów partnerskich, choć stara, bardzo rzad-ko oferuje przyzwoite zyski. Rzadko też dochodzi do wypłaty środków, które w dodatku mogą po pewnym okresie cza-su bezpowrotnie przepaść.

Przykładem korzystnej sieci rekla-mowej jest pośrednictwo w sprzedaży logo i dzwonków na telefony komórko-we. Wszelkiego rodzaju dodatki tego ty-pu cieszą się nieustającą popularnością i przynoszą duże zyski, jako że stanowią produkt czysto usługowy. Przykłady ser-wisów oferujących takie programy:

• PP Wapacz.pl, http://partner.wapacz.pl/• PP WapSter, http://partner.wapster.pl/

PodsumowanieW artykule przyjrzeliśmy się dostępnym metodom zarobkowania. Warto teraz wy-brać zestaw metod najbardziej pasują-cych do przedmiotu działalności danego serwisu internetowego. Wdrożenie więk-szości z powyżej zaprezentowanych me-tod zarobkowania nie powinno sprawić większych trudności programistycznych. Jako że rejestracja, czy nawiązanie współpracy jest bezpłatne, do zarabia-nia, oprócz wartościowej strony www, nie potrzebne są już żadne dodatkowe środ-ki finansowe. Zainteresowanych szer-szym ujęciem tematu zachęcamy do za-głębienia się w pozycję książkową auto-ra tegoż artykułu. Szersze podejście do problematyki oraz zestaw przykładowych wdrożeń mogą okazać się przydatne w podejmowaniu dalszych decyzji. n

Rysunek 7. Platnosci.pl w znaczący sposób ułatwiają wdrożenie usług elektronicznych płatności bankowych

Paweł Grzesiak jest projektantem witryn internetowych z sześcioletnim doświad-czeniem. Zajmuje się tworzeniem rozbu-dowanych witryn w oparciu o rozwiązania własnego autorstwa. Jest autorem ponad 50 publikacji w Magazynie Internet, Inter-net Maker oraz phpSolutions. W styczniu br. nakładem wyd. Helion ukazała się je-go książka pt. „Jak zarabiać w Internecie. Witryna, która przynosi zysk.”

Kontakt: [email protected]

O autorze

Page 72: PHP Solutions 02 2007 PL

MySQLAutor: 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 technicznegoi 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

«««««

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

Tworzenie sklepów internetowych. PHP i MySQL. Wydanie II.Autor: Marc Wandschneider

«««««

Recenzje

Page 73: PHP Solutions 02 2007 PL
Page 74: PHP Solutions 02 2007 PL

www.phpsolmag.org74

Testy

PHP Solutions Nr 2/2007

Nowoczesne społeczeństwo informa-tyczne, z uwagi na ostatnie trendy

w rozwoju usług internetowych skupiają-cych się na interaktywności, współtwo-rzeniu przez internautów zawartości por-tali oraz przesyłania dużych plików multi-medialnych stawia coraz większe wyma-gania firmom prowadzącym działalność w oparciu o nowoczesne technologie in-ternetowe oraz globalną sieć jako platfor-mę komunikacji. Podmioty takie zmuszo-ne są do ciągłego rozwijania własnej in-frastruktury informatycznej, co nierzad-ko łączy się z koniecznością ponoszenia wysokich nakładów inwestycyjnych. Taka sytuacja może stanąć na drodze rozwoju lub stanowić poważną barierę wejścia dla wielu firm chcących zaistnieć na poważ-nie w środowisku internetu.

Takim właśnie firmom proponuje-my współpracę polegającą na możliwo-ści umieszczenia ich serwerów w na-szym Centrum Hostingu i Kolokacji w Su-permedia (Data Center Supermedia). Jest to propozycja dająca możliwości wykorzy-stania zaawansowanej i stale rozbudo-wywanej infrastruktury firmy Supermedia oraz przy okazji zapewniająca najlepsze z możliwych warunki pracy serwerów. Ofer-ta usług Kolokacji (hotelingu) serwerów w Supermedia Internet Provider jest rozwija-na właściwie od początku 10-letniej dzia-łalności firmy. Nasze Data Center znaj-

duje się w siedzibie firmy: w Pałacu Pry-masowskim przy ulicy Senatorskiej, w sa-mym centrum miasta. Taka lokalizacja za-pewnia Klientom łatwy dostęp do powie-rzonego nam sprzętu, z drugiej daje pew-ność stałego nad nim nadzoru. Paradok-salnie historyczne wnętrza doskonale na-dają się dla nowoczesnych technologii – chronione przez grube mury pałacu oraz system zamków elektronicznych i dodat-kowej ochrony komputery naszych Klien-tów są bezpieczne jak nigdzie indziej. Do-datkowo Kolokacja w Supermedia zapew-nia wszystkie wysokie standardy jakie przewidziano dla tej usługi: klimatyzowa-ne pomieszczenia, wydajny system pod-trzymywania napięcia, odcięcie od „brud-nego” prądu, ochrona i opieka administra-torów. Jednak nasi Klienci wybierają nas również dlatego, że zapewniamy ich sys-temom doskonałą łączność z internetem dzięki własnym łączom światłowodowym oraz łączom do najważniejszych operato-rów i dostawców internetu. Niejednokrot-nie zdarza nam się słyszeć opinie, że pod tym względem nasze usługi są nieco „na wyrost” w stosunku do potrzeb naszych Klientów. Wiemy jednak, że wraz z roz-wojem internetu oraz rozwojem naszych Klientów te potrzeby mogą rosnąć – dla-tego staramy się uprzedzać fakty i rozbu-dowywać strukturę by móc rosnąć wraz z nimi.

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-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 potrafią radzić sobie z kłopotami. Tak doświadczony zespół jest zresztą nie-zbędnie potrzebny na miejscu, ponie-waż jako centrum usług internetowych Supermedia świadczy Klientom usłu-gi daleko bardziej kompleksowe, wy-kraczające niejednokrotnie poza stan-dardowe ramy usług kolokacji. Dlatego część z naszych kolokacji to przypadki nietypowe, połączone z szeregiem in-nych usług.

Potrafimy również sprostać często nietypowym wymaganiom Klientów na-szej agencji interaktywnej Superme-dia Interactive – i właśnie dlatego pro-fesjonalna obsługa oraz indywidualne podejście do każdego Klienta to głów-ne atuty kolokacji w Supermedia. Naj-lepszym dowodem skuteczności oraz jakości naszej pracy i naszych usług jest duża popularność kolokacji w na-szym Data Center oraz stale rosnąca liczba Klientów. Cieszymy się również, że nasi obecni Klienci zaczynając od jednej usługi, często zaczynają korzy-stać z szerokiej oferty usług Superme-dia zamawiając i aktywując kolejne z nich. Dzięki temu mamy powody i mo-tywację, aby dbać o nich jak najlepiej. No i ciągle się rozwijać:).

Marcin KowalczykKierownik Działu Systemów i Serwerowni

Page 75: PHP Solutions 02 2007 PL

Testy konsumenckie

www.phpsolmag.org 75

Testy

PHP Solutions Nr 2/2007

W 2002 roku szukaliśmy miejsca, w którym moglibyśmy umieścić nasz

serwer internetowy. W tym czasie wybór usługodawców krajowych był bardzo ograniczony, ponadto nie było takiego dostępu do tanich usług firm zagranicz-nych jak w chwili obecnej. O usłudze ko-lokacji firmy SUPERMEDIA dowiedzieli-śmy się od jednego z naszych klientów, który wtedy także z niej korzystał. Fir-

ma ta miała jedną z najkorzystniejszych ofert cenowych, ponadto nie stosowała dopłat z tytułu użycia serwera w obudo-wie wolnostojącej, jaką my wtedy dyspo-nowaliśmy – pozostałe firmy preferowa-ły obudowy do montażu w szafie rack i dopłaty innych obudów były stosunko-wo wysokie. Z perspektywy tych kilku lat współpracy uznaliśmy, że decyzja wybo-ru kolokacji w kraju była słuszna, ponie-

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-ły, prawdopodobnie dzięki konkurencji zagranicznej. Podsumowując, jesteśmy zadowoleni ze współpracy z firmą SU-PERMEDIA, ponieważ za rozsądną ce-nę gwarantuje ona dobrą jakość świad-czonej usługi i bezpośredni dostęp do serwera.

W skali ocen od 1 do 5 ocenił-bym firmę i usługi przez nią oferowa-ne na 5.

R E K L A M A

Page 76: PHP Solutions 02 2007 PL

Testy konsumenckie

www.phpsolmag.org76

Testy

PHP Solutions Nr 2/2007

Daniel Maksymiuk,Warszawskie Centrum Numizmatyczne

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 dzierżawienia pamięci dyskowej okaza-ła się nieefektywna. Postanowiliśmy za-tem zakupić własny serwer, który w peł-ni miałby spełnić nasze oczekiwania i kolokować go w profesjonalnej firmie w Warszawie. Firma, którą wybrano z po-śród wielu innych konkurencyjnych firm to Supermedia Internet Provider. Oka-zało się, że spełnia ona wszystkie nasze podstawowe ustalenia. Do kryterium wy-boru, które miały być spełnione należa-ły: profesjonalizm, dogodna lokalizacja, całodobowy dostęp do serwera i konku-rencyjne ceny. Siedziba firmy Superme-dia Internet Provider ma doskonałą loka-

lizację – znajduje się niedaleko Starego Miasta, firma ma profesjonalną obsługę, a także może poszczycić się korzystną ofertą cenową. Podczas całego okresu współpracy nie pojawiły się żadne pro-blemy z działaniem naszego serwera, z czego jesteśmy niezwykle zadowole-ni. Dzięki temu możemy całkowicie sku-pić się na działalności firmy i nie myśleć o ciągłym kontrolowaniu poprawności działania naszego serwera. Biorąc pod uwagę usługę, która jest nam świadczo-na przez firmę Supermedia można jej z całą pewnością dać maksymalną oce-nę, jeśli chodzi o jakość hotelingu. Jeśli miałbym ponownie wybrać firmę do ko-lokacji serwera zdecydowanie byłaby to Supermedia Internet Provider.

W o b e c n y c h czasach suk-

ces firmy oraz jej przetrwanie na rynku zależne jest od wielu czynników.

Do niektórych z nich na pewno zali-czymy profesjona-lizm i doświadczenie, a także postęp i szybkość wdrażania nowych technolo-gii. Wychodząc na przeciw swoim klien-tom nasza firma zdecydowała się uru-chomić sprzedaż poprzez internet. W przyszłości planuje także uruchomienie aukcji on-line. Do tej pory wydzierża-wialiśmy jedynie miejsce na serwerze, a strony internetowe z całą naszą ofer-

Szybki rozwój technologiczny gospo-darki wymusza na większości firm

konieczność dostosowania się do sytu-acji i dokonywanie licznych inwestycji w nowe technologie. Internet jest jedną z inwestycji, której patrząca w przyszłość firma nie może zignorować. Dlatego od samego początku działalności inwesto-waliśmy w budowę własnego systemu informatycznego, który pozwalałby na optymalizację procesu realizacji i przyj-mowania zleceń. Po wdrożeniu modułów pozwalających na przyjmowanie zleceń przez Internet niezbędne okazało się za-pewnienie dobrego łącza o dużej przepu-stowości oraz cechującego się dużą nie-zawodnością – klienci nasi razem ze zle-ceniami dostarczają najczęściej pliki gra-ficzne, których rozmiar znacznie przekra-cza 10MB. Szybko okazało się, że łącze indywidualne do którego podłączony był nasz system jest niewystarczające, dlate-go byliśmy zmuszeni do znalezienia roz-wiązania, które zapewniałoby odpowied-nie parametry łącza.

Nasze rozwiązanie od obsługi Klien-tów on-line pozwala na wybór właściwej technologii druku, ustawienie wszyst-kich niezbędnych do tego parametrów oraz co ważniejsze przesłanie goto-wych do druku przy wykorzystaniu sie-ci internet. Niweluje to również koniecz-ność bezpośredniego kontaktu w celu uzyskania wyceny czy złożenia zamó-wienia ale w rezultacie generuje duży

ruch w sensie ilości spływających za-pytań czy obsługiwanych jednocześnie Klientów. Dokonując wyboru odpowied-niego dostawcy musieliśmy skupić się na możliwości ciągłego przekazywania informacji oraz zapewnienia ciągłości obsługi on-line wielu Klientów naszej fir-my jednocześnie. Tak więc ważna była nie tylko przepustowość łącza, ale rów-nież gwarancja ciągłości działania sys-temów. Wybierając firmę Supermedia Internet Provider kierowaliśmy się po-ziomem obsługi oferowanej przez firmę oraz dostępnością do naszych serwe-rów ulokowanych w centrum Hostingu i Kolokacji Supermedia w Warszawie. Centrum mieści się w dogodnym punk-cie niedaleko warszawskiej starówki a sama firma zaoferowała bardzo dobre warunki umożliwiające zarówno zdalną konfigurację systemów jak i bezpośred-ni dostęp do własnych maszyn uloko-wanych w Supermedia. Zespół wykwa-lifikowanych inżynierów pracujących w Dziale Technicznym bez żadnych pro-blemów radzi sobie z obsługą koloko-wanych urządzeń oraz konfiguracją urządzeń do backupu.

Zastosowanie tego rozwiązania po-zwoliło na czerpanie korzyści wynikają-cych z posiadania specjalnie przygoto-wanego systemu informatycznego, od-powiednio wydajnej infrastruktury tech-nicznej oraz bezpośredniego dostępu do łącz światłowodowych w jakich po-

siadaniu jest firma Supermedia bez ko-nieczności ponoszenia kosztów budo-wy własnych specjalnie zaprojektowa-nych pomieszczeń utrzymujących od-powiednie warunki do pracy nasze-go systemu oraz tworzenia kosztownej infrastruktury. Nie bez znaczenia po-zostaje fakt, że firma Supermedia za-pewniła nam jednocześnie bezpośred-nie stałe łącza internetowe do naszych lokalizacji w Warszawie, co pozwa-la na optymalne wykorzystanie posia-danego pasma na komunikację pomię-dzy wszystkimi systemami i serwera-mi QPrint. Pozwoliło to na zbudowanie wydajnej infrastruktury opartej o dodat-kowe lokalne serwery, które pełnią jed-nocześnie funkcje mirrora systemu cen-tralnego, dzięki czemu pracownicy ma-ją bezpośredni i szybki dostęp do ma-teriałów nadesłanych przez klientów w ramach sieci lokalnej danego punktu usługowego – jest to rozwiązanie nie-zbędne do zapewnienia optymalnego przepływu zadań i związanych z nimi materiałów graficznych. Dodatkowym atutem takiego rozwiązania okazała się możliwość konfiguracji systemu tele-komunikacyjnego na bazie VoIP i inte-gracji wszystkich linii telefonicznych ze-wnętrznych jak i wewnętrznych w jeden system telekomunikacyjny. Dzięki temu klienci dzwoniący do pod jeden nr te-lefonu mogą zostać przełączeni do do-wolnej lokalizacji firmy Qprint.

Jakub Kuran,QPrint

Page 77: PHP Solutions 02 2007 PL

Testy konsumenckie

www.phpsolmag.org 77

Testy

PHP Solutions Nr 2/2007

Grzegorz Pilarski Warsaw Data Center

Kolokacja serwerów lub innych urzą-dzeń w wyspecjalizowanym ośrod-

ku jest najlepszym sposobem uzyskania warunków niezbędnych w prowadzeniu e-biznesu: bezpiecznej i stale monitorowa-nej lokalizacji serwera, niezawodnych łącz oraz sprzętu elastycznie dostosowane-go do aktualnych potrzeb. Usługi Warsaw Data Center stanowią idealne rozwiązanie dla każdej firmy, która opiera swój rozwój na wykorzystaniu aplikacji internetowych.

Oferta WDC zaspokaja wszelkie po-trzeby związane z kolokacją serwerów.

Klienci mogą instalować własne syste-my lub skorzystać z wynajmu serwerów lub innych urządzeń. Lokalizacja siedzi-by WDC gwarantuje najwyższy stopień bezpieczeństwa, zapewnia przestrzeń umożliwiającą nieskrępowany rozwój oraz infrastrukturę stworzoną specjal-nie dla potrzeb serwerów. Ponadto na miejscu przebywają wysokokwalifiko-wani inżynierowie i technicy WDC, któ-rzy przez 24 godziny na dobę 7 dni w ty-godniu dbają o utrzymanie wszystkich urządzeń w ruchu i reagują natychmiast

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 potrzeby inwestycji w urządzenia archi-wizujące, oprogramowanie i nośniki,

• zapewnia monitoring i obsługę przez 24 godziny na dobę 7 dni w tygodniu bez zatrudnienia działu technicznego pracującego całą dobę,

• umożliwia prostą rozbudowę i dostęp do usług wedle narastających potrzeb,

• zdecydowanie skraca czas dostępno-ści usług (większość usług dostępna w przeciągu 24 godzin),

• zapewnia Gwarancję Jakości Usług (SLA).

R E K L A M A

Page 78: PHP Solutions 02 2007 PL

Testy konsumenckie

www.phpsolmag.org78

Testy

PHP Solutions Nr 2/2007

Prowadzę 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-ra dedykowanego. Długo się nie zasta-nawiałem. Później okazało się, że była to słuszna koncepcja. Po migracji aplikacji i danych serwis ładował się znacznie szyb-ciej, a co najważniejsze, po raz pierw-szy od dłuższego czasu mogłem spokoj-nie spędzać weekendy i święta. W cią-gu kilku lat które od tego czasu upłynę-ły aplikacja obsługująca portal interneto-wy się rozwijała, zarejestrowanych użyt-kowników przybywało, wysyłaliśmy coraz więcej codziennych newsletterów, a w do-datku około roku 2003 pojawił się znaczą-cy ruch przychodzący z wyszukiwarki Go-ogle. Wszystkie te czynniki uświadomiły nam zapotrzebowanie rozmaitych usług internetowych na pasmo, przestrzeń dys-kową, szybkość procesora, czy wielkość pamięci. Uruchamiając kolejny portal zde-cydowałem się na usługę kolokacji serwe-ra. Oczywiście w Warsaw Data Center.

Alternatywą do kolokacji był wyna-jem serwera dedykowanego, ale chciałem

Michał Faberserwis biznes.net

mieć swobodę w kształtowaniu całego roz-wiązania składającego się z aplikacji porta-lowej, określonej struktury dość dużej ba-zy danych i konfiguracji sprzętowej serwe-rów. Chciałem po prostu eksperymentować z różnymi ilościami pamięci dostępnymi dla PHP i MySQL, dostepną przestrzenią dys-kową, czy sprzętowym rozdzielaniem ser-wera bazy danych, aplikacji i webserwera. Przy wykorzystaniu serwerów dedykowa-nych nie zawsze było to możliwe, ze wzglę-du na ich standaryzację: ograniczenia maksymalnej wielkości pamięci, czy rodza-ju dysków. Poza tym chyba dojrzałem do posiadania własnego sprzętu, co w przy-padku biznesu portalowego daje poczucie, że jest się właścicielem czegoś więcej niż tylko domeny, bazy danych i aplikacji we-bowej. Kolokacja okazała się dla mnie do-brym kompromisem bo daje swobodę dzia-łania, a jednocześnie nie wymaga budo-wania własnej serwerowni i utrzymywa-nia rozbudowanej infrastruktury. Od kilku lat jestem zadowolony z usług kolokacji w

W pewnym momencie działalności naszej firmy stwierdziliśmy, że po-

trzebujemy skorzystać z usługi kolokacji serwerów. Wybraliśmy tę usługę, ponie-waż posiadamy własne zasoby sprzęto-we – farma 40 serwerów. Nie mamy też potrzeby dzierzawić ich od innych provi-derow, tylko sami, we własnym zakresie je dostarczamy i wykorzystujemy.

Generalnie w kraju korzystaliśmy już z paru firm kolokacyjnych i dalej z nich korzystamy. Jednak potrzebując alterna-

Magdalena Stec,shooters.pl

tywnego pomieszczenia dla naszych ser-werów, zaczęliśmy szukać kolejnej firmy i tak trafiliśmy do Warsaw Data Center. Fir-ma zapewniła nam najbardziej elastycz-ną usługę tego typu w kraju, dotyczą-cą zarówno oferowanego pasma inter-netowego, jak również samego dostepu do urzadzeń. Możemy liczyć na pomoc o dowolnej porze dnia i nocy. Zdecydo-waliśmy się na Warsaw Data Center, po-nieważ ich oferta wydała nam się najbar-dziej korzystna. W momencie poszukiwań

firmy, u której moglibyśmy kolokować na-sze serwery, były brane pod uwagę roz-wiązania konkurencyjne. Jednakże w po-równaniu z innymi, Warsaw Data Center zapewniało nam największą elastyczność rozwojową oraz dostępność. Na pytanie, czy skorzystalibyśmy z usług kolokacji fir-my Warsaw Data Center, odpowiedzia-łabym zdecydowanie tak. Nie żałujemynaszego wyboru i jesteśmy zadowoleni z jakości usługi, którą oferuje nam ta firma. W skali 1-5 gwiazdek oceniamy ją na 5.

Warsaw Data Center, a kilka lat w tej bran-ży to wieczność. Zmieniają się technologie, zmienia się rynek usług telekomunikacyj-nych. Na szczęście nie muszę znać szcze-gółów tych przemian.

Jestem zadowolony z usług WDC. Wszystko działa jak należy, ale co waż-niejsze w praktyce poznałem ich procedu-ry i organizację działania. Właśnie po pro-cedurach poznaje się doświadczenie zdo-byte w walce z materią teleinformatyczną, która złośliwa jest i skrupulatnie przestrze-ga praw Murphy'ego.

Korzystałem z usług WDC zarówno jako osoba prywatna, jako przedstawi-ciel kilku firm, polecałem także ich usługi swoim klientom. Można powiedzieć, że je-stem stałym klientem co przekłada się na pewien rodzaj zażyłości i zaufania między dostawcą, a odbiorca usługi. Tego rodzaju relacja pozwala spokojnie i profesjonalnie przezwyciężać trudności, które miewają obie strony. Wystawiam WDC ocenę pię-ciu gwiazdek.

Page 79: PHP Solutions 02 2007 PL

Cyber rzeczywistość – Cyber uzależnienie

www.phpsolmag.org 79

Felieton

PHP Solutions Nr 2/2007

Cyber rzeczywistość – Cyber uzależnienie

Popatrzmy na nasz współczesny świat. I zastanówmy się, co wi-dzimy – widzimy samych siebie,

widzimy innych ludzi i oczywiście widzi-my nieodłączny element naszej cywilizacji – komputery. Maszyny, które służą nam do pracy i nauki, bo przecież do tego zostały stworzone. Ale z biegiem czasu te narzę-dzia zaczęły umożliwiać nam też rozryw-kę, robienie zakupów, kontakt z przyjaciół-mi. Mało tego, komputery stają się naszy-mi przyjaciółmi. Wracając do domu, pierw-sze, co robimy, to pędzimy do niego – że-by biedaczek nie był sam – z myślą : sią-dę na chwilkę i sprawdzę czy nie ma no-wych wiadomości. Po chwili, co najczę-ściej oznacza godzinę, wygrywa fizjologia. Kiedyś przecież trzeba coś zjeść. Szyb-ka przekąska i znowu wracamy do naszej maszyny. Godzina za godziną, dzień za dniem – po chwili – rok za rokiem, przy-zwyczajamy się do takiego życia. Lubimy

takie życie, to jest przecież nasze życie. To jest nasza rzeczywistość. I tu właśnie zaczyna się problem.

Powstają nowe określenia typu: sie-cioholizm, cybernałóg. Uzależnienie od komputera staje się problemem, takim jak alkoholizm czy każdy inny nałóg. Specja-liści coraz głośniej nas przed tym ostrze-gają. Ale przecież nas to nie dotyczy. Jesteśmy pewni, że panujemy nad kom-puterem. Tkwimy w przekonaniu, że każdy normalny człowiek korzysta z komputera przez 20 godzin dziennie. Bo przecież, po co mi jakaś inna forma aktywności. Je-stem najlepszy w grę sieciową, zostałem doceniony przez użytkowników mojego ulubionego forum, jestem na bieżąco, bo internet jest moim źródłem informacji – to jest rzeczywistość. Rzeczywistość, w któ-rej znajduję akceptację.

Niestety, takie myślenie jest nagmin-ne i bardzo szkodliwe. Najczęściej taka osoba nie zdaje sobie sprawy ze skali pro-blemu. W naszym skomputeryzowanym społeczeństwie, coraz częściej możemy zauważyć młodych ludzi, nie tylko w wieku szkolnym, którzy już nie widzą niczego poza komputerem. W Polsce nie jest to jeszcze tak widoczne jak, np. w Stanach Zjednoczonych, ale warto zwrócić na to uwagę już teraz. Nie jest to tylko problem ludzi młodych. Uzależniony i nieświadomy rodzic przekazuje ten model życia swoim dzieciom, które z kolei przekazują ten styl swoim rówieśnikom. Tak powstaje pewnego rodzaju pętla, którą ktoś kiedyś

musi przerwać. To jest jak wirus, który atakuje nieświadomych zagrożenia. Ist-nieją też już przypadki rozwodów, właśnie z powodu nadużywania komputera przez jednego z małżonków. Zarażony człowiek z każdym dniem oddala się od innych ludzi, otaczając się murem, w którym jedy-nym wyjściem jest jego komputer.

Dla dobra swojego i otaczających nas ludzi, sprawdźmy się. W sieci mnó-stwo jest testów sprawdzających nasz stan uzależnienia lub od razu wybierz-my lepszą drogę. Postawmy sprawę ja-sno – komputer jest urządzeniem, któ-re ma nam umożliwić sprawną pracę i naukę oraz rozrywkę w rozsądnych ilo-ściach. Zamiast poświęcać czas na bez-produktywne siedzenie przed monitorem wybierzmy się na spacer, spotkajmy ze znajomymi, poczytajmy książkę lub Wasz ulubiony magazyn. Ocalimy dzięki temu zdrowie psychiczne jak i fizyczne, któ-re przy dłuższym nadużywaniu kompute-ra na pewno by ucierpiało. Otyłość, pro-blemy z kręgosłupem i układem krążenia, słabszy wzrok, to tylko nieliczne “atrak-cje” nadmiernego poświecenia się takie-mu “hobby”. Dodatkowym atutem powro-tu do normalności niech będzie fakt, że w dzisiejszym realnym świecie, każdy chce osiągnąć sukces. Każdy chce być KIMŚ. Żeby to osiągnąć musimy dokonać wybo-ru. Poświęćmy się rodzinie, pracy, nauce. Zdecydujmy się na prawdziwe życie, do którego zostaliśmy stworzeni, a nie na cy-ber namiastkę świata. n

Łukasz Skowroński

Page 80: PHP Solutions 02 2007 PL

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!

www.buyitpress.com zamówienie prenumeraty

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

Page 81: PHP Solutions 02 2007 PL

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: [email protected]. 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)............................................................................................................................................................................

zamówienie prenumeraty

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

Jeżeli chcesz zapłacić kartą kredytową, wejdź na stronę naszego sklepu internetowego:

www.buyitpress.com

automatyczne przedłużenie prenumeraty

Suma

Tytuł Ilość numerów

Ilość zamawianych prenumerat

Od numeru pisma lub miesiąca

Opłata w zł

z VATSoftware Developer’s Journal (1 płyta CD)– dawniej Software 2.0Miesięcznik profesjonalnych programistów

12 250/1801

SDJ Extra (od 1 do 4 płyt CD lub DVD)– dawniej Software 2.0 Extra!Numery tematyczne dla programistów

6 150/1352

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

Page 82: PHP Solutions 02 2007 PL

W sprzedaży od kwietnia

W następnym numerze PHP Solutions 3/2007 (20)

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

BEZPIECZEŃSTWO

n Bezpieczeństwo Sesji

NARZĘDZIA

n ImageMagick i PHP graficzny kombajn

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

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

UWAGA KOLEJNY TEST KONSUMENCKI

n Sprzęt: Serwery

NOWE ARTYKUŁY W DZIAŁACH:

n dla początkujących

n dla zaawansowanych

n kasa dla webmastera

Page 83: PHP Solutions 02 2007 PL
Page 84: PHP Solutions 02 2007 PL