Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00509 008266 11004448 na godz. na dobę w sumie
Po prostu PHP. Techniki zaawansowane - książka
Po prostu PHP. Techniki zaawansowane - książka
Autor: Liczba stron: 512
Wydawca: Helion Język publikacji: polski
ISBN: 83-7197-775-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> php - programowanie
Porównaj ceny (książka, ebook, audiobook).
Język programowania PHP stanowi dla wielu osób przepustkę w świat pisania aplikacji działających po stronie serwera WWW. Łatwość z jaką przychodzi nauczenie się tego języka, sprawiła, że używają go setki tysięcy amatorów i profesjonalistów na całym świecie.

Po pewnym czasie wiedza wyniesiona z podręczników opisujących podstawy PHP języka przestaje wystarczać. Niniejsza książka pomoże Ci w wykonaniu kolejnego kroku: kroku w kierunku pisania zaawansowanych aplikacji. Dzięki niej wzbogacisz swoją wiedzę i staniesz się prawdziwym ekspertem programowania w PHP, poszukiwanym na rynku pracy.

Pomoże Ci w tym prosty język w jakim napisana jest książka oraz liczne przykłady kodu, a także osoba autora, doświadczonego programisty i wykładowcy PHP na Uniwersytecie Kalifornijskim w Berkeley.
Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Po prostu PHP. Techniki zaawansowane Autor: Larry Ullman T³umaczenie: Rados³aw Meryk ISBN: 83-7197-775-1 Tytu³ orygina³u: PHP Advanced For The World Wide Web. Visual QuickPro Guide Format: B5, stron: 492 Jêzyk programowania PHP stanowi dla wielu osób przepustkê w ġwiat pisania aplikacji dzia³aj¹cych po stronie serwera WWW. £atwoġæ z jak¹ przychodzi nauczenie siê tego jêzyka, sprawi³a, ¿e u¿ywaj¹ go setki tysiêcy amatorów i profesjonalistów na ca³ym ġwiecie. Po pewnym czasie wiedza wyniesiona z podrêczników opisuj¹cych podstawy PHP jêzyka przestaje wystarczaæ. Niniejsza ksi¹¿ka pomo¿e Ci w wykonaniu kolejnego kroku: kroku w kierunku pisania zaawansowanych aplikacji. Dziêki niej wzbogacisz swoj¹ wiedzê i staniesz siê prawdziwym ekspertem programowania w PHP, poszukiwanym na rynku pracy. • Poznasz tajniki programowania obiektowego. • Nauczysz siê korzystaæ z baz danych. • Dowiesz siê, w jaki sposób zabezpieczaæ stworzone przez siebie aplikacje. • Napiszesz w³asny sklep internetowy, korzystaj¹c z sesji i bazy SQL. • Poznasz sposoby uruchamiania programów PHP w oderwaniu od serwera WWW. • Nauczysz siê generowaæ nie tylko strony WWW, ale tak¿e grafikê i pliki PDF. • Dowiesz siê, jak i po co u¿ywaæ jêzyka XML. • Skorzystasz z wielu rozszerzeñ jêzyka, które u³atwiaj¹ rozwi¹zywanie z³o¿onych problemów. Pomo¿e Ci w tym prosty jêzyk w jakim napisana jest ksi¹¿ka oraz liczne przyk³ady kodu, a tak¿e osoba autora, doġwiadczonego programisty i wyk³adowcy PHP na Uniwersytecie Kalifornijskim w Berkeley. Spis treści Spis treści WSTĘP Rozdział 1. Zaawansowane programowanie w PHP 9 19 Struktura i dokumentowanie kodu ...................................................o......... 20 Tablice ...................................................o...................................................o 28 Stałe ...................................................o...................................................o.... 37 Funkcje rekurencyjne i zmienne statyczne ............................................... 42 Funkcje a odwołania ...................................................o.............................. 52 Rozdział 2. Programowanie obiektowe 59 Definiowanie klas ...................................................o.................................. 61 Tworzenie obiektu ...................................................o................................. 64 Tworzenie konstruktorów ...................................................o...................... 70 Dziedziczenie...................................................o......................................... 76 Użycie metod klas bez ich egzemplarzy ...................................................o 82 Szeregowanie obiektów ...................................................o......................... 84 Usuwanie obiektów...................................................o................................ 93 S p i s t r e ś c i Rozdział 3. Bazy danych 97 Projekt bazy danych i normalizacja ...................................................o....... 99 Tworzenie bazy danych ...................................................o....................... 108 Generowanie wyników zapytań ...................................................o........... 113 Rozdział 4. Bezpieczeństwo 139 Sprawdzanie poprawności danych w formularzach................................ 141 Sprawdzanie danych w formularzu za pomocą skryptów JavaScript ..... 155 Mcrypt...................................................o.................................................. 164 Uwierzytelnianie HTTP ...................................................o....................... 175 Bezpieczeństwo serwera WWW...................................................o.......... 181 Rozdział 5. 185 Projektowanie aplikacji WWW Projekt bazy danych...................................................o............................. 186 Struktura ośrodka ...................................................o................................. 190 PHP a szablony obiektowe...................................................o................... 202 5 i c ś e r t s i p S Spis treści Obsługa sesji ...................................................o........................................ 224 Wykorzystanie sesji bez znaczników cookie .......................................... 233 Uruchamianie diagnostyczne ...................................................o............... 243 Rejestrowanie i zgłaszanie błędów ...................................................o...... 244 Rozdział 6. E-commerce 247 Tworzenie bazy danych ...................................................o....................... 249 Administracja...................................................o....................................... 255 Wyświetlanie towarów online...................................................o.............. 271 Implementacja koszyka na zakupy ...................................................o...... 279 Rozdział 7. PHP w sieci 289 Wykrywanie przeglądarki ...................................................o.................... 290 Dostęp do innych ośrodków WWW za pomocą PHP............................. 298 Wykorzystanie fsockopen() ...................................................o................. 303 Rozdział 8. PHP a serwer 309 Uruchamianie skryptów za pomocą usługi cron ..................................... 310 Kompresja plików za pomocą PHP ...................................................o..... 317 Wykorzystanie modułu COM w PHP...................................................o.. 322 Rozdział 9. XML i PHP 331 Czym jest XML?...................................................o.................................. 332 Składnia języka XML ...................................................o.......................... 334 Definicje typu dokumentów...................................................o................. 337 Analiza dokumentów XML za pomocą PHP oraz Expat........................ 344 Obsługa błędów w XML...................................................o...................... 351 Rozdział 10. Generowanie grafiki 355 Tworzenie prostej grafiki ...................................................o..................... 357 Zastosowanie czcionek TrueType...................................................o........ 368 Tworzenie wykresów na podstawie danych z bazy danych.................... 376 Zapisywanie i modyfikowanie istniejących grafik ................................. 387 Rozdział 11. Tworzenie plików PDF 395 Tworzenie prostego dokumentu PDF ...................................................o.. 397 Wprowadzanie tekstu w dokumentach PDF ........................................... 403 Rysowanie figur ...................................................o................................... 416 Wykorzystanie ilustracji graficznych...................................................o... 424 Tworzenie wielostronicowych dokumentów PDF .................................. 431 6 Rozdział 12. Rozszerzenia PHP Spis treści 439 PEAR ...................................................o...................................................o 440 Zend ...................................................o...................................................o.. 447 PHP-GTK...................................................o............................................. 451 Kod źródłowy PHP ...................................................o.............................. 464 Dodatek A 465 Instalacja Instalacja PHP wraz z serwerem Apache w systemie Linux .................. 466 Instalacja PHP z serwerem Xitami w systemie Windows ...................... 472 Dodatek B Bazy danych 475 Aplikacje systemów zarządzania bazami danych ................................... 476 SQL ...................................................o...................................................o... 477 Informacje dotyczące bazy danych MySQL ........................................... 480 Inne zasoby ...................................................o.......................................... 482 Dodatek C Zasoby ogólne 483 Ośrodki WWW poświęcone PHP ...................................................o........ 484 Dodatkowe biblioteki...................................................o........................... 486 Bezpieczeństwo...................................................o.................................... 488 Inne zasoby ...................................................o.......................................... 489 Skorowidz 493 S p i s t r e ś c i 7 Zaawansowane programowanie w PHP Zaawansowane programowanie w PHP Zaawansowane programowanie w PHP Na najprostszym poziomie dobre programowanie wyraża się tym, czy aplikacja lub skrypt działa zgodnie z zamiarem. Poctzątkujący programiści pozostaną na tym poziomie i nie ma w takim podejścitu nic złego. Jednakże zaawansowany programista będzie próbował pójść nieco dalej. Będzie dążył do zapewnienia lepszej wydajności, niezawodności, bezpieczeństwa i przenośności. Ta książka nauczy nas, w jaki sposób rozwinąć umiejętności zaawansowanego programisty PHPt. Ten rozdział opisuje niektóre nowe funkcje i właściwotści języka PHP w wersji 4., techniki, jakie będą stosowane w tej kstiążce, oraz kilka wskazówek i sztuczek rzemiosła. Chociaż zapewne już wtiemy, w jaki sposób korzystać z tablic, to prawdopodobnie jeszczet nie znamy konstrukcji HQTGCEJ lub starszej, ale wciąż bardzo użytecznej funkcji CTTC[AYCNM . Prawdopodobnie mieliśmy już okazję zapisać własną funkcję, ale być może nie do końca wiemy, w jaki spostób wykorzystywać rekurencję oraz zmienne statyczne. W rozdziale tym topiszemy te elementy, a także inne podstawowe informacje, jak: dtokumentowanie kodu, tworzenie jego struktury, stałe oraz powiązania. Wyjaśnimy też różnice pomiędzy wykorzystaniem funkcji RTKPV a funkcji GEJQ , a także w jaki sposób tworzyć aliasy zmiennych — technikę, która jest nowa dla języka PHP w wersji 4. Ostatecznie w prtocesie pisania przykładowych skryptów dowiemy się, że można tworzyć dynamiczne aplikacje WWW, stosując bazę danych w prostym pliku tekstowym. W rozdziale tym utworzymy kilka skryptów, służących do utworzenia i zarządzania ośrodkiem totalizatora sportowego onltine, gdzie użytkownicy odgadują zwycięskie zespoły. W każdym tygodniu oraz w całym sezonie obliczany jest współczynnik poprawnych typów dla każdego z użytkowników. Wymaga to wykonania niewielu czynności administracyjnych. Wybrałem ten przykład nie ze wzgltędu na to, że odpowiada tematowi, ale również dlatego, że sięga otn czasów moich początków w PHP. Nauczyłem się tego języka (po przejśtciu z języka Perl) przy okazji tworzenia podobnej aplikacji. Oczytwiście wtedy zakończyłem pracę, kiedy tylko skrypt zaczął działatć. Nie muszę dodawać, że skrypty zaprezentowane w tym rozdziale tsą bardziej wydajne, niezawodne, bezpieczne oraz przenośne niż tte skrypty, które opracowałem wtedy. Z a a w a n s o w a n e p r o g r a m o w a n i e w P H P 19 Rozdział 1. Struktura i dokumentowanie kodu Skrypt 1.1. Ten skrypt będzie działać prawidłowo, ale znacznie trudniej go poprawiać i zrozumieć niż skrypt 1.2 Właściwa struktura kodu oraz jego dokumentowanie, mimo że nie ma wpływu na działanie aplikacji, stanowi podstawę zaawansowanego programowania w PHP. Właściwa struktura oraz dokumentowanie jest elementem, który należy zastosować dla wygody własnej oraz naszych klientów i współpracowników, a także dla programisty, który w przyszłości będzie być może zmuszony poprawiać nasz kod. Kiedy piszę o strukturze kodu, mam na myśli sposób fizycznej organizacji kodu PHP w samym dokumencie (W rozdziale 5., „Projektowanie aplikacji WWW” omówię zagadnienie szersze — strukturę witryny). Porównajmy skrypty 1.1 oraz 1.2. Obydwa są poprawnymi dokumentami PHP, ale który z nich wolelibyśmy przeglądać i poprawiać? Podstawy budowania struktury kodu odnoszą się do sposobu stosowania wcięć w kodzie, pozostawiania pustych wierszy, używania nawiasów zwykłych i klamrowych itp. Ogólne zasady są następujące: u należy stosować wcięcia bloków kodu (np. wyników instrukcji warunkowych lub zawartość funkcji) o szerokości jednej tabulacji lub czterech spacji (w zasadzie powinno się stosować spacje, a nie tabulatory, ale programiści stosują wygodniejsze tabulacje); u określone fragmenty kodu należy oddzielać pustym wierszem, aby wyróżnić je wizualnie; u należy wprowadzać spacje pomiędzy słowami, argumentami funkcji, operatorami itp. (generalnie, choć nie zawsze, w języku PHP liczba spacji nie ma znaczenia); u funkcje należy umieszczać na początku dokumentu.  1 6;2 JVON27$.+ 9  6 :*6/. 6TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON  6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJRUETKRVAARJR FGHKPG 9Y  HWPEVKQPYTKVGAFCVC XMHR ] UVCVKEHN KH HN ] HRWVU HR9KGTUCVTCRC P  HN647  _ HRWVU HRX P  _ H RKEMUA 9 A9KPPGTUAVZV  KH HR HQRGP HY ] CTTC[AYCNM Y YTKVGAFCVC HR  HENQUG HR  GEJQ CRKUCPQY[EKúEÎYDT DT  _GNUG] GEJQ0KGOQľPCQVYQT[èRNKMWH 0CNGľ[WRGYPKèUKúľGOKGPPCOCYCTVQħè DT DT  _ HWPEVKQPTGCFARKEMU FRF ] INQDCNR KH HPTGCFFKT FR ] KH UWDUVT HP RKEMUA ] RHPGZRNQFG AHP  KH RHP=?9 CPF RHP=? 9KPPGTU ] WPRHP=? VHFHP WRHKNG VH  R=WP?WR _ _  _ _ RCTTC[  F   TGCFARKEMU FRF  u d o k e i n a w o t n e m u k o d i a r u t k u r t S 20 Skrypt 1.1. ciąg dalszy FRQRGPFKT F  TGCFARKEMU FRF  ENQUGFKT FR   YJKNG NKUV MX GCEJ R ] YU NU YJKNG NKUV MX GCEJ X ] XUWDUVT X UVTNGP X   KH XY=M? CPF M ] YU  _GNUGKH M ] NU  _ _ T=M?CTTC[ YU  YU NU  NU  _ MUQTV T  HWPEVKQPYTKVGATGUWNVU XMHR ] UVCVKEHN KH HN ] HRWVU HR7ľ[VMQYPKM VYU VNU P  HN647  _ FKORNQFG  VX  HRWVU HRM VF P   H TGUWNVUA 9 AVZV  KH HR HQRGP HY ] CTTC[AYCNM T YTKVGATGUWNVU HR  HENQUG HR  COMPKúEKGRNKMW GEJQ CRKUCPQY[PKMKDT DT  _GNUG] GEJQ0KGOQľPCWVYQT[èRNKMW V[IQFPKQY[OKY[PKMCOKHDT DT  _ ! DQF[ JVON Zaawansowane programowanie w PHP Po utworzeniu struktury naszego kodu powinniśmy zapewnić, aby był on dobrze udokumentowany. Dokumentowanie kodu jest programowym odpowiednikiem umieszczania notatek na żółtych, samoprzylepnych karteczkach. Można zaryzykować stwierdzenie, że dokumentowania pracy nigdy za dużo. Należy opisać działanie funkcji, zmiennych, fragmentów kodu oraz całych stron. W skrypcie 1.3 pokazałem, jak wyglądałby skrypt 1.2, gdyby zawierał komentarze. Oto kilka rad dotyczących dokumentowania kodu: u zapisujmy przeznaczenie zmiennych, chyba że ich przeznaczenie nie jest oczywiste nawet dla początkujących programistów; u opisujmy zastosowanie funkcji; u wyjaśniajmy, jaki jest cel działania fragmentów kodu; u wymieniajmy pliki, z którymi program się komunikuje, których wymaga itp.; u oznaczajmy zamykające nawiasy klamrowe dla złożonych funkcji oraz struktur sterujących (instrukcji warunkowych, pętli itp.). S t r u k t u r a i d o k u m e n t o w a n i e k o d u 21 Rozdział 1. Skrypt 1.2. Wstawienie pustych wierszy i tabulatorów znacznie zwiększa czytelność skryptu Skrypt 1.2. ciąg dalszy u d o k e i n a w o t n e m u k o d i a r u t k u r t S  1 6;2 JVON27$.+ 9  6 :*6/. 6TCPUKVKQPCN2. JVVRYYYYQTI64 4 ZJVON 6 ZJVON VTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJR  FGHKPG 9 -YGGM   HWPEVKQPYTKVGAFCVC XCNWGMG[HR ]  UVCVKEHKTUVANKPG  KH HKTUVANKPG ] HRWVU HR9KGTUCVTCRC P  HKTUVANKPG647  _  HRWVU HRXCNWG P  _  HKNG RKEMUA 9 -  A9KPPGTUAVZV   KH HR HQRGP HKNGY ]  CTTC[AYCNM YKPPGTU YTKVGAFCVC  HR  HENQUG HR   GEJQ CRKUCPQY[EKúEÎY DT DT   _GNUG] GEJQ0KGOQľPCQVYQT[èRNKMWH 0CNGľ[WRGYPKèUKúľGOKGPPCOC YCTVQħè DT DT  _  HWPEVKQPTGCFARKEMU FRFKTGEVQT[ ]  INQDCNRKEMU  KH HKNGAPCOGTGCFFKT FR ]  KH UWDUVT HKNGAPCOG  RKEMUA ] 22  RCTUGAHKNGAPCOGGZRNQFG  AHKNGAPCOG   KH RCTUGAHKNGAPCOG=? 9 - CPF RCTUGAHKNGAPCOG=? 9KPPGTU ]  WUGTPCOG RCTUGAHKNGAPCOG=? VJGAHKNGFKTGEVQT[ HKNGAPCOG WUGTUARKEMUHKNG  VJGAHKNG  RKEMU=WUGTPCOG? WUGTUARKEMU _ _  TGCFARKEMU FRFKTGEVQT[  _ _  RKEMUCTTC[   FKTGEVQT[   FRQRGPFKT FKTGEVQT[  TGCFARKEMU FRFKTGEVQT[  ENQUGFKT FR    YJKNG NKUV MG[XCNWG GCEJ  RKEMU ]  YKPU NQUUGU  YJKNG NKUV MG[XCNWG GCEJ  XCNWG ]  XCNWGUWDUVT XCNWG  UVTNGP XCNWG    KH XCNWGYKPPGTU=MG[? CPF MG[ ] YKPU  _GNUGKH MG[ ]  _ _  TGUWNVU=MG[?CTTC[ YKPU  YKPU NQUUGU  NQUUGU  _ NQUUGU  Skrypt 1.2. ciąg dalszy  MUQTV TGUWNVU    HWPEVKQPYTKVGATGUWNVU XCNWGMG[ HR ]  UVCVKEHKTUVANKPG  KH HKTUVANKPG ] HRWVU HR7ľ[VMQYPKM V6[R[ RQRTCYPG V6[R[DđúFPG P  HKTUVANKPG647  _  FCVCKORNQFG  VXCNWG  HRWVU HRMG[ VFCVC P    HKNG TGUWNVUA 9 -  AVZV   KH HR HQRGP HKNGY ]  CTTC[AYCNM TGUWNVU  YTKVGATGUWNVU HR  HENQUG HR  COMPKúEKGRNKMW GEJQ CRKUCPQY[PKMKDT DT   _GNUG]  GEJQ0KGOQľPCQVYQT[èRNKMW V[IQFPKQY[OKY[PKMCOK HKNGDT DT  _ ! DQF[ JVON Zaawansowane programowanie w PHP Skrypt 1.3. Ta wersja skryptu 1.2 została właściwie udokumentowana, ale oczywiście jest miejsce na dodanie dodatkowych notatek !RJRUETKRVAARJR  5KGEKQY[U[UVGOVQVCNKCVQTC RKđMCTUMKGIQ  1RTCEQYCđ.CTT[ 7NNOCP   CRKUCPQ5KGTRKGē 2QRTCYKQPQUKGTRPKC  -QPVCEVRJR / KPUKIJVUEQO  5VTQPCRTQEGUUAYKPPGTURJRQDUđWIWLG UVTQPúRKEMAYKPPGTURJRRCIG 1MTGħNCQPCUMWVGEPQħèV[RÎY RQUEGIÎNP[EJITCE[KCRKUWLGVG KPHQTOCELGYRNKMWVGMUVQY[O   !  1 6;2 JVON27$.+ 9  6 :*6/. 6TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON  6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJR  7UVCYKGPKGUVCđGLYGGM FGHKPG 9 -YGGM        CRKUY[EKúEÎYYRNKMW      HWPEVKQPYTKVGAFCVC XCNWGMG[HR ] (WPMELCYTKVGAFCVCCRKUWLGV[R[ YRNKMW  UVCVKEHKTUVANKPG  KH HKTUVANKPG ] CRKUCPKG RKGTYUGIQYKGTUCCVTCR[CNGV[NMQ TC HRWVU HR9KGTUCVTCRC P  HKTUVANKPG647  _  23 S t r u k t u r a i d o k u m e n t o w a n i e k o d u u d o k e i n a w o t n e m u k o d i a r u t k u r t S Rozdział 1. Skrypt 1.3. ciąg dalszy Skrypt 1.3. ciąg dalszy HRWVU HRXCNWG P  QFCPKG PCMWTGVWTPCD[MCľF[CRKUPCNCđ UKúYQUQDP[OYKGTUW _  HKNG RKEMUA 9 -  A9KPPGTUAVZV 9UMCCPKGPCY[ RNKMWYHQTOCEKG RKEMUAA9KPPGTUAVZV   KH HR HQRGP HKNGY ] 2TGE[VCPKGRNKMWFQVCDNKE[  CTTC[AYCNM YKPPGTU YTKVGAFCVC  HR 9[UđCPKGECđGLVCDNKE[ FQHWPMELKYTKVGAFCVC HENQUG HR  COMPKúEKGRNKMW  GEJQ CRKUCPQY[EKúEÎYDT DT   _GNUG]9[ħYKGVNGPKGDđúFWYRT[RCFMW IF[D[QVYCTEKGRNKMWD[đQPKGOQľNKYG GEJQ0KGOQľPCQVYQT[èRNKMWHKNG 2TQUúWRGYPKèUKúľGOKGPPCYGGM OCYCTVQħèDT DT  _       2QDTCPKGV[RÎYITCE[      HWPEVKQPTGCFARKEMU FRFKTGEVQT[ ]  [PPQħèVúY[MQPWLGHWPMELCTGCFARKEMU  INQDCNRKEMU  KH HKNGAPCOGTGCFFKT FR ] 5RTCYFGPKGMCľFGIQRNKMWYMCVCNQIW  KH UWDUVT HKNGAPCOG  RKEMUA ]-QPV[PWCELC YRT[RCFMWQFPCNGKGPKCRNKMW V[RCOK  RCTUGAHKNGAPCOGGZRNQFG  AHKNGAPCOG  2TGMUVCđEGPKGPCY[RNKMW PCQFRQYKGFPKHQTOCV  KH RCTUGAHKNGAPCOG=? 9 - CPF RCTUGAHKNGAPCOG=? 9KPPGTU ],GľGNKVQ PKGLGUVRNKMFCP[OK QY[EKúECEJCPWOGTV[IQFPKC LGUVYđCħEKY[ 24  WUGTPCOG RCTUGAHKNGAPCOG=? VJGAHKNGFKTGEVQT[ HKNGAPCOG WUGTUARKEMUHKNG  VJGAHKNG  RKEMU=WUGTPCOG? WUGTUARKEMU _ _   TGCFARKEMU FRFKTGEVQT[  -QNGLPCKVGTCELCHWPMELK _ _  RKEMUCTTC[  CKPKELQYCPKG IđÎYPGLOKGPPGL  FKTGEVQT[   FRQRGPFKT FKTGEVQT[  TGCFARKEMU FRFKTGEVQT[  ENQUGFKT FR        1DNKEGPKGV[IQFPKQY[EJY[PKMÎY      YJKNG NKUV MG[XCNWG GCEJ  RKEMU ]2úVNCFNCY[PKMÎY YIđÎYPGLVCDNKE[  YKPU7UVCYKGPKGPCYCTVQħè FNCMCľFGLVCDNKE[ NQUUGU7UVCYKGPKGPCYCTVQħè FNCMCľFGLVCDNKE[  YJKNG NKUV MG[XCNWG GCEJ  XCNWG ]2úVNCFNCMCľFGL VCDNKE[Wľ[VMQYPKMC  XCNWGUWDUVT XCNWG  UVTNGP XCNWG   7UWPKúEKGPCMWTGVWTP  KH XCNWGYKPPGTU=MG[? CPF MG[ ],GľGNKV[R Wľ[VMQYPKMCLGUVYđCħEKY[ RT[PCLGO[OWRWPMVCNGPKG NKE[O[YKGTUCPT YKPU  _GNUGKH MG[ ] NQUUGU  Skrypt 1.3. ciąg dalszy Skrypt 1.3. ciąg dalszy Zaawansowane programowanie w PHP _GNUG]9[ħYKGVNGPKGMQOWPKMCVW QDđúFKGLGľGNKQVYCTEKGRNKMW PKGRQYKQFđQUKú  GEJQ0KGOQľPCQVYQT[èRNKMW V[IQFPKQY[OKY[PKMCOK HKNGDT DT  _ ! DQF[ JVON _ _  TGUWNVU=MG[?CTTC[ YKPU  YKPU NQUUGU  NQUUGU   CRKUCPKGY[PKMÎYMCľFGIQ Wľ[VMQYPKMÎYYVCDNKE[ _  MUQTV TGUWNVU 7RQTæFMQYCPKG VCDNKE[CNHCDGV[EPKG        CRKUCPKGV[IQFPKQY[EJY[PKMÎY      HWPEVKQPYTKVGATGUWNVU XCNWGMG[ HR ] CRKUWLGY[PKMKFQRNKMW  UVCVKEHKTUVANKPG  KH HKTUVANKPG ] CRKUCPKG RKGTYUGIQYKGTUCCVTCR[CNGV[NMQ TC HRWVU HR)TCE VRQRTCYPG VDđúFPG P  QFCPKGPCMW TGVWTPVCMCD[MCľF[CRKU PCNCđUKúYQUQDP[OYKGTUW HKTUVANKPG647  _  FCVCKORNQFG  VXCNWG  HRWVU HRMG[ VFCVC P   QFCPKGPCMWTGVWTPVCMCD[ MCľF[CRKUPCNCđUKúYQUQDP[O YKGTUW _  HKNG TGUWNVUA 9 -  AVZV 9UMCCPKGPCY[RNKMW YHQTOCEKG TGUWNVUAAVZV   KH HR HQRGP HKNGY ] 1VYCTEKGRNKMWFQCRKUW  CTTC[AYCNM TGUWNVU  YTKVGATGUWNVU HR 9[UđCPKG CYCTVQħEKECđGLVCDNKE[FQHWPMELK YTKVGATGUWNVU HENQUG HR  COMPKúEKGRNKMW GEJQ 9[PKMKCRKUCPQDT DT   S t r u k t u r a i d o k u m e n t o w a n i e k o d u 25 u d o k e i n a w o t n e m u k o d i a r u t k u r t S Rozdział 1. Poruszyliśmy już sporo zagadnień, dotyczących dobrej struktury kodu oraz właściwego jego dokumentowania. Zwięzły dokument poświęcony temu tematowi — Standard kodowania w PHP (PHP Coding Standard) można znaleźć pod adresem www.DMCinsights.com/phpadv /coding_standard.php (rysunki 1.1 oraz 1.2). W dokumencie tym opisano formalne reguły zapisywania kodu w PHP wraz z ich uzasadnieniem. W tej książce będę wskazywał miejsca, gdzie przestrzegam konwencji, i te, gdzie je łamię. Należy jednak pamiętać o trzech sprawach. Po pierwsze, chciałbym podkreślić, że bez względu na to, czy będziemy przestrzegać standardu kodowania PHP, czy moich przyzwyczajeń, najważniejsze jest zachowanie spójności. Niespójność nie tylko jest na bakier z każdym standardem, ale prowadzi do błędów i z pewnością spowoduje konieczność spędzenia dodatkowych godzin w czasie prób uruchamiania. Poza tym, jeżeli pracujemy w zespole, musimy opracować plan, którego powinni przestrzegać wszyscy członkowie zespołu. Jeżeli programujemy dla klienta, powinniśmy pozostawić przejrzystą, spójną dokumentację, tak aby klient lub inny programista mógł z łatwością zrozumieć naszą pracę. Po drugie, struktura kodu i jego dokumentowanie jest elementem, który powinniśmy stosować od momentu rozpoczęcia kodowania i kontynuować w czasie pracy. Próby tworzenia komentarzy po zapisaniu kodu nigdy nie będą tak skuteczne, a często w ogóle nie będą podjęte. To, co wydaje się oczywiste w trakcie tworzenia, stanie się niejasne trzy miesiące później. Jeżeli jeszcze tego nie doświadczyliśmy, to z pewnością zdarzy się to nam pewnego dnia. Po trzecie, ze względu na ograniczenia formatu książkowego, skrypty opracowane w tej książce od tego momentu nie będą tak dobrze ułożone, ani udokumentowane, jak to być powinno. Istnieje przecież limit wykorzystania cennej przestrzeni książkowej na zapiski typu  GXGNQRGFD[.CTT[ 7NNOCP Osobiście zawsze stosuję się do trzech wymienionych niżej konwencji (będę to robił także w tej książce): 26 Rysunek 1.1. „PHP Coding Standard” (Standard kodowania w PHP) jest przewodnikiem „gramatycznym” programowania w PHP Rysunek 1.2. „PHP Coding Standard” (Standard kodowania w PHP) doskonale opisuje reguły, uzasadnia je i demonstruje, w jaki sposób przestrzegać tych zasad podczas tworzenia kodu Rysunek 1.3. Program PHPDoc opracowano w celu zautomatyzowania procesu dokumentowania kodu. Program wykorzystuje wyrażenia regularne do analizowania kodu i wstawiania opisów Rysunek 1.4. Jeżeli programujemy z wykorzystaniem biblioteki PEAR, powinniśmy przestrzegać specyficznych zasad dokumentowania i tworzenia struktury kodu (http://pear.php.net/manual/en/ standards.php). Zaawansowane programowanie w PHP u Nazwy zmiennych powinny być zapisywane małymi literami ze znakiem podkreślenia jako separatorem słów. Niektórzy zalecają, aby nazwy zmiennych globalnych zaczynały się na literę g, ale ja nie stosuję tej zasady. u Ponieważ w języku XML skrócone wersje znaczników (! oraz ! ) są wykorzystywane, zatem jeżeli korzystamy z XML-a, powinniśmy stosować formalne znaczniki PHP (!RJR ! ). Przekonamy się o tym w rozdziale 9., „XML”. Zalecam, aby zawsze stosować znaczniki formalne, ponieważ jest to najlepszy sposób zachowania zgodności pomiędzy serwerami. u Dla stron, które mają być interpretowane jako skrypty PHP, zaleca się wykorzystywanie rozszerzenia .php (dla plików włączanych, jak np. klas i stron konfiguracyjnych, można wykorzystywać inne rozszerzenia). Dopuszczalne rozszerzenia plików są określone przez konfigurację serwera WWW, ale w społeczności PHP domyślnie przyjmuje się rozszerzenie .php (rozszerzenie stosowane w PHP w wersji 3. — .php3 będzie działać w większości serwerów z PHP4, ale wydaje się, że ze względu na istnienie nowych wersji, stosowanie tego rozszerzenia jest nieuzasadnione). Wskazówki  Program PHPDoc jest aplikacją typu open source, wspomagającą pracę w PHP. Opracowano go na podstawie popularnego programu JavaDoc (służącego do dokumentowania programów w języku Java). Program ten jest przeznaczony do wspomagania procesu dokumentowania kodu. Więcej informacji na temat tego programu można znaleźć pod adresem www.PHPDoc.de (rysunek 1.3).  Jeżeli zamierzamy stworzyć kod, który będzie wykorzystywany wraz z pakietem PEAR (zobacz rozdział 12., „Rozszerzanie PHP”), wówczas powinniśmy przestrzegać reguł formatowania obowiązujących dla tego pakietu (rysunek 1.4). 27 S t r u k t u r a i d o k u m e n t o w a n i e k o d u Zgodnie ze składnią funkcja CTTC[AYCNM pobiera tablicę jako pierwszy parametr oraz nazwę funkcji bez żadnych nawiasów ani argumentów jako drugi parametr. W czasie wykonywania iteracji funkcji CTTC[AYCNM funkcja będzie otrzymywać kolejne indeksy tablicy oraz wartości. Powyższy kod spowoduje wygenerowanie następującego wyniku: 2CDNQ*QPG[DT 6JG$GPFUDT 1- QORWVGTDT -KF#DT #OPGUKCEDT Ze skryptów znajdujących się w dalszej części książki dowiemy się, w jaki sposób przekazać więcej argumentów funkcji wywoływanej za pomocą CTTC[AYCNM . Zwróćmy uwagę, że funkcja CTTC[AYCNM działa jedynie z funkcjami definiowanymi przez użytkownika i nie będzie działać z wbudowanymi funkcjami PHP. Należy też pamiętać o konieczności wykonania funkcji TGUGV w PHP4, jeżeli chcemy skorzystać z tablicy ponownie. Dla zademonstrowania niektórych zaawansowanych technik obsługi tablic zapiszemy pierwszą część aplikacji obsługującej totalizator sportowy. Jej przeznaczeniem jest obsługa profesjonalnego futbolu amerykańskiego, ale można ją z łatwością przystosować do dowolnej innej dziedziny. Pierwsze dwa skrypty dynamicznie wygenerują formularz, gdzie użytkownicy będą mogli wprowadzać swoje typy. Ponieważ nie wszyscy mamy dostęp do bazy danych, aplikacja ta do zapisu informacji będzie wykorzystywać jednorodny plik tekstowy. e c i l b a T Rozdział 1. Tablice Tablice są specjalnego rodzaju zmiennymi, które mogą działać jak tabele w arkuszu kalkulacyjnym. Ze względu na możliwości, jakie oferują, oraz elastyczność, tablice są powszechnie wykorzystywane w zaawansowanym programowaniu w PHP. W tym podrozdziale opiszemy kilka najbardziej powszechnych funkcji obsługi tablic. Nowością w PHP4 jest konstrukcja HQTGCEJ, którą opracowano w celu umożliwienia łatwiejszego dostępu do wszystkich indeksów i wartości tablicy. Zakładając, że mamy tablicę o nazwie CTTC[, możemy uzyskać dostęp do każdego jej elementu za pomocą następującego kodu: HQTGCEJ CTTC[CUMG[ XCNWG ] MQF _ Osobiście do obsługi tablic wykorzystuję konstrukcję HQTGCEJ i będę to robił także w tej książce. Jeżeli korzystamy z wcześniejszej wersji PHP, będziemy musieli przepisać powyższy kod na następującą postać: TGUGV CTTC[  YJKNG NKUV MG[XCNWG GCEJ CTTC[ ] MQF _ Podstawową różnicą pomiędzy konstrukcją HQTGCEJ oraz YJKNG jest fakt, że pierwsza z tych pętli automatycznie ponownie ustawia tablicę na pozycję początkową, natomiast druga tego nie robi. Inną funkcją obsługi tablic, którą często wykorzystuję, chociaż nie jest to nowość wersji PHP4, jest CTTC[AYCNM . Funkcja ta pozwala na podstawienie każdego elementu tablicy do funkcji zdefiniowanej przez użytkownika. HWPEVKQPRTKPVACNDWOU XCNWGMG[ ] GEJQXCNWGDT P _ CTTC[CTTC[ 2CDNQ*QPG[6JG$GPFU1- å QORWVGT-KF##OPGUKCE  CTTC[AYCNM CTTC[ RTKPVACNDWOU  28 Skrypt 1.4. Dane dla totalizatora będą zapisywane w plikach tekstowych rozdzielanych tabulatorami jak plik przedstawiony niżej: )QħEKG)QURQFCTG 0GY1TNGCPU$WHHCNQ 0GY PINCPF KPEKPPCVK 5GCVVNG NGXGNCPF 6CORC$C[ CNNCU  GVTQKV)TGGP$C[ 1CMNCPF-CPUCU KV[  CTQNKPC/KPPGUQVC +PFKCPCRQNKU0;,GVU 2KVVUDWTIJ,CEMUQPXKNNG  JKECIQ$CNVKOQTG 5V.QWKU2JKNCFGNRJKC 9CUJKPIVQP5CP KGIQ #VNCPVC5CP(TCPEKUEQ /KCOK6GPPGUUGG 0;)KCPVU GPXGT Zaawansowane programowanie w PHP Aby skorzystać z tablic: 1. Utworzymy plik tekstowy w edytorze tekstów. 2. Zapiszemy wiersz nagłówka (skrypt 1.4): )QURQFCTG)QħEKG W pliku tekstowym najpierw będzie wymieniona drużyna gości, a następnie drużyna gospodarzy. Każdy mecz będzie zajmował oddzielny wiersz. Wiersz nagłówkowy służy do wyznaczenia układu tablicy oraz działa jako obejście niektórych specyficznych właściwości tablic. Kiedy ten plik będzie wczytany do tablicy, rozpocznie się ona — jak zwykle w przypadku tablic — od indeksu 0. Ponieważ wolę, aby indeksy tablic były zgodne z numerami gier, a chciałbym numerować wiersze od 1. do 15. (lub 14., 16. itp.), dlatego opuszczam jeden wiersz. Tak więc pierwsza gra jest wymieniona w drugim wierszu, zatem będzie umieszczona pod indeksem 1. 3. Wpiszemy kolejne gry: 0GY1TNGCPU$WHHCNQ 0GY PINCPF KPEKPPCVK 5GCVVNG NGXGNCPF 6CORC$C[ CNNCU GVTQKV)TGGP$C[ 1CMNCPF-CPUCU KV[ CTQNKPC/KPPGUQVC +PFKCPCRQNKU0;,GVU 2KVVUDWTIJ,CEMUQPXKNNG JKECIQ$CNVKOQTG 5V.QWKU2JKNCFGNRJKC 9CUJKPIVQP5CP KGIQ #VNCPVC5CP(TCPEKUEQ /KCOK6GPPGUUGG 0;)KCPVU GPXGT Gry są wyszczególnione w formacie Drużyna gości [TAB] Drużyna gospodarzy [RETURN] (bez spacji). Znaku tabulacji użyjemy w celu rozróżnienia dwóch elementów każdego wiersza. 4. Zapiszemy plik jako week1.txt. 29 T a b l i c e Rozdział 1. 5. Podobne pliki stworzymy dla pozostałych tygodni w sezonie, nazywając je na przykład week2.txt, aż do week17.txt. Jeżeli śledzimy ten przykład bez zmian, możemy pobrać wszystkie te pliki z witryny pod adresem www.DMCinsights.com/phpadv. W plikach tych nie należy wprowadzać żadnych komentarzy, ponieważ kolidowałoby to ze sposobem ich wykorzystania (i tak będą odczytywane tylko przez PHP). 6. Stworzymy katalog 2001 na naszym serwerze WWW. Możemy użyć dowolnej innej nazwy, która będzie określała sezon jako całość. 7. Uprawnienia do katalogu ustawimy jako 777 (odczyt, zapis, wyszukiwanie dla wszystkich). Ze względów bezpieczeństwa, jeżeli to możliwe, powinniśmy umieścić ten katalog poniżej katalogu głównego serwera. Jeżeli już to zrobimy, powinniśmy upewnić się, że stosujemy właściwe odwołania do tego katalogu we wszystkich przedstawionych poniżej skryptach (tzn. używając odwołania../2001 zamiast 2001/). 8. Umieścimy wszystkie pliki dla poszczególnych tygodni w katalogu 2001. Teraz, kiedy utworzyliśmy dane zawierające informacje o wszystkich grach sezonu, czas zapisać skrypt, który przekształci te dane na format HTML. 9. W edytorze tekstowym stworzymy nowy dokument HTML (skrypt 1.5):  1 6;2 JVON27$.+ 9  6 :*6/. å6TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON å 6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF e c i l b a T 30 Skrypt 1.5. Ten skrypt dynamicznie generuje formularz na podstatwie pliku w formacie zwykłego tekstu Zaawansowane programowanie w PHP  1 6;2 JVON27$.+ 9  6 :*6/.62TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON 6 ZJVON2VTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJROCMGARKEMUAHQTORJR YGGM HKNG YGGM YGGM VZV 9UMCCPKGRNKMWPCRQFUVCYKGPWOGTWV2[IQFPKC  KH ICOGU HKNG HKNG ]9E[VCPKGRNKMWFQVCDNKE[  2QRTGE[VCPKWRNKMWY[ħYKGVNGPKGHQTOWNCTC GEJQ HQTOCEVKQPUVQTGARKEMURJROGVJQFRQUV VCDNGDQTFGTYKFVJEGNNURCEKPIEGNNRCFFKPICNKIPEGPVGT2 VTCNKIPEGPVGTXCNKIPVQR VFEQNURCPYKFVJCNKIPEGPVGTXC2NKIPVQRPQYTCRPQYTCR 9RTQYCFļPCYúWľ[VMQYPKMC KPRWVV[RGVGZVPCOGWUGTPCOGUKGOCZN2GPIVJ VF VT    HQTGCEJ ICOGUCUMG[ CTTC[ ] CUVQUQYCPKGVCDNKE[FQY[ħYKGVNGPKCMCľF2GLIT[  KH MG[ ]9KGTUC)QħEKG)QURQFCTGPKGY[ħYKGVNCO[  UGEQPFACTTC[GZRNQFG  VCTTC[ 2TGMUVCđEGPKGMCľFGIQYKGTUC2VCDNKE[ YQFFKGNPæVCDNKEú CYC[UGEQPFACTTC[=?2KGTYU[GNGOGPVQFRQYKCFCGURQđQYKIQħEK JQOGUWDUVT UGEQPFACTTC[=? UVTNGP UGEQPFACTTC[=?    TWIKGNGOGPVQFRQYKCFCGURQđQYKIQURQFCT[CNGOWUKO[WUWPæèPCMTGVWTP2  GEJQVTCNKIP EGPVGT XCNKIP VQR  VFCNKIP NGHV XCNKIP VQR PQYTCR PQYTCR  KPRWVV[RG TCFKQ  PCOG RKEMU=MG[? XCNWG CYC[  CYC[VF VFCNKIP EGPVGT XCNKIP VQR  RTGEKYVF VFCNKIP TKIJV XCNKIP VQR PQYTCR PQYTCR  KPRWV V[RG TCFKQ PCOG RKEMU=MG[? XCNWG JQOG  JQOGVF VT P _ _  7WRGđPKGPKGHQTOWNCTCKVCDGNK GEJQVTCNKIP EGPVGT XCNKIP VQR  VFEQNURCP  YKFVJ  CNKIP EGPVGT XCNKIP VQR  KPRWV V[RG UWDOKV PCOG UWDOKV XCNWG 9[ħNKL  VT VCDNG KPRWVV[RG JKFFGP PCOG YGGM XCNWG YGGM  HQTO P  _GNUG]9[ħYKGVNGPKGMQOWPKMCVWQDđúFKGLGľGNKQVYCTEKGRNKMWPKGRQYKQFđQUKú GEJQ0KGOQľPCQVYQT[èRNKMWHKNG0CNGľ[WRGYPKèUKúE[OKGPPCYGGMOCWUVC2YKQPæ YCTVQħèDT DT  _ ! DQF[ JVON T a b l i c e 31 Rozdział 1. Instrukcje echo, print oraz cudzysłowy W PHP istnieje kilka sposobów przesyłania tekstu doj przeglądarki. Najbardziej popularne sposoby polegają na wykorzystaniu instrukcji RTKPV oraz GEJQ. Istnieją tylko pewne subtelne różnice w sposobie działania tych dwóch instrukcji. jW jakich sytuacjach należy stosować którą, jest raczej kwestią indywidualnego wyboru nijż czegokolwiek innego. Jedna z różnic polega na tym, że instrukcja echo jest jminimalnie, prawie niezauważalnie szybsza niż instrukcja print. Wynika to stąd, że poj pomyślnym wykonaniu instrukcja print zwraca wartość (1 oznacza, że instrukcja zakończyła sięj pomyślnie), natomiast instrukcja echo tego nie robi. Właściwością funkcji echo, której nie znajdziemy w funkcjji print, jest możliwość łatwego umieszczania zmiennych w kodzie HTML. Zazwyczaj (w naszycjh skryptach) fragment formularza zapisanego w formacie HTML ma następującą postjać: KPRWVV[RGVGZVPCOGWUGTPCOGXCNWG!RJRGEJQWUGTPCOG!  W takim przypadku możemy zastosować dwa skróty. Po piejrwsze, zawsze możemy pominąć ostatni średnik w skrypcie PHP, chociaż korzysjtanie z tego nie jest dobrą praktyką. Poza tym, stosując instrukcję echo, możemy skrócić kod, wjpisując znak równości po początkowym znaczniku PHP (ale tylko w przypadku jwykorzystywania krótkiej postaci znacznika). Tak więc zapis: !RJRGEJQWUGTPCOG! przyjmie postać: !WUGTPCOG! Ważniejsze od tego, z której funkcji skorzystamy (technicznie to nie są funkcje, a konstrukcje języka), jest odpowiedź na pytanie, czy skorzystamy z ajpostrofów, czy też z cudzysłowów. W obu instrukcjach echo oraz print można korzystać zarjówno z apostrofów, jak też z cudzysłowów. Różnica polega na sposobie interpretjowania zmiennych oraz na tym, że niektóre znaki należy poprzedzić znakiem odwrotnejgo ukośnika. Użycie apostrofu spowoduje wyświetlenie zawartości w postaci takiej, jjak jest i wymaga poprzedzenia znakiem odwrotnego ukośnika jedynie samego znaku aposjtrofu. Tak więc instrukcja: GEJQ CJTGHKPFGZRJR *QOGC  zadziała bez problemu. Odpowiednik tej instrukcji z jzastosowaniem cudzysłowów przyjąłby następującą postać: GEJQCJTGH KPFGZRJR  *QOGC  Aby w źródle HTML znalazł się znak cudzysłowu (co jest kjonieczne dla zachowania poprawności składni), należy go poprzedzić znakiem odwjrotnego ukośnika. Z tego względu wysyłając kod HTML do przeglądarki, stosuję instrukcję jecho z apostrofem. Jednym z problemów podczas wykorzystywania apostrofów jjest sposób interpretacji zmiennych i sekwencji specjalnych, które w tym przypadjku są traktowane dosłownie, co oznacza, że instrukcje postaci: OKGPPC YCTVQUE  GEJQ OKGPPC P  spowodują wyświetlenie ciągu $zmienna , a nie wartoścji zmiennej, po której następuje znak końca wiersza, co nastąpi w wyniku zastosowaniaj poniższego kodu: e c i l b a T OKGPPC YCTVQUE  GEJQOKGPPC P 32 Zaawansowane programowanie w PHP Instrukcje echo, print oraz cudzysłowy (ciąg dalszy) Ten sam problem występuje w czasie przypisywania wartjości do zmiennej lub przy odwołaniach do indeksów tablic. OKGPPC YCTVQUE  GEJQVCDNKEC= OKGPPC ?1FPQUKUKúFQGNGOGPVWRQFKPFGMUGOOKGPPC GEJQVCDNKEC=OKGPPC?1FPQUKUKúFQGNGOGPVWRQFKPFGMUGOYCTVQUE Biorąc pod uwagę sposób wyświetlania zmiennych, powiniejnem także wyjaśnić sposób interpretowania w PHP tablic wielowymiarowych. Zazwycjzaj element tablicy wielowymiarowej (tablicy złożonej z tablic) możemy zlojkalizować, stosując konstrukcję: PCYCAVCDNKE[= PCYCAVCDNAYGYP ?= KPFGMUAVCDNAYGYP ? Ale próba wyświetlenia tego elementu za pomocą instrukjcji GEJQ9CTVQħèY[PQUKPCYCAVCDNKE[= PCYCAVCDNAYGYP ?= KPFGMUAVCDNAYGYP ? nie zadziała. W takim przypadku mamy dwie możliwości. jPo pierwsze, możemy użyć operatora konkatenacji, aby opuścić cudzysłów. Niestejty, w niektórych systemach (np. Mac OS X) taka konstrukcja nie zadziała: GEJQ9CTVQħèY[PQUKPCYCAVCDNKE[= PCYCAVCDNAYGYP ?= KPFGMUAVCDNAYGYP ? Możemy też wykorzystać nawiasy klamrowe wewnątrz cudzyjsłowów: GEJQ9CTVQħèY[PQUK]PCYCAVCDNKE[= PCYCAVCDNAYGYP ?= KPFGMUAVCDNAYGYP ?_ Dotyczy to zarówno instrukcji GEJQ, jak też instrukcji RTKPV. Doskonały przewodnik dotyczący ciągów znaków, cudzysjłowów, apostrofów itp. zagadnień można znaleźć pod adresem www.zend.com/zend/tut/using-strings.php. T a b l i c e 33 Rysunek 1.5. Ponieważ nie wprowadziliśmy wartości zmiennej $week (zobacz wiersz adresu), to skrypt nie mógł odczytać pliku. Na rysunku 1.6 pokazano uzyskany wynik, kiedy zastosowano znak @ w celu wyłączenia komunikatu o błędzie generowanego przez PHP Rysunek 1.6. Zastosowanie znaku @ umożliwia wyłączenie wyświetlania mylących i brzydkich technicznych komunikatów o błędach Rozdział 1. 10. Rozpoczniemy wpisywanie treści dokumentu HTML oraz umieścimy inicjujący znacznik PHP: DQF[ !RJR 11. Wskazujemy plik, który będzie wykorzystywany: HKNG YGGM YGGM VZV  Zakłada się, że do skryptu zostanie przekazana zmienna YGGM o wartości od 1 do 17 (w moim przypadku). Tak więc wygenerowanie formularza dla każdego tygodnia wymaga jedynie przekazania do tego skryptu numeru tego tygodnia. 12. Utworzymy instrukcję warunkową, w której podejmiemy próbę odczytania określonego pliku do tablicy: KH ICOGU HKNG HKNG ] Jeżeli skrypt prawidłowo odczyta plik, wówczas zostanie utworzona tablica ICOGU, zawierająca informacje o wszystkich grach danego tygodnia. Dzięki zastosowaniu znaku spowodujemy, że nie będą wyświetlane komunikaty o błędach w przypadku, gdy odczytanie pliku nie powiedzie się (porównajmy rysunek 1.5, gdzie nie zastosowano znaku , z rysunkiem 1.6, gdzie zastosowano ten znak). 13. Rozpoczniemy formularz HTML. GEJQ HQTOCEVKQPUVQTGARKEMURJROGVJQF åRQUV VCDNGDQTFGTYKFVJEGNNURCEKPI åEGNNRCFFKPICNKIPEGPVGT VTCNKIPEGPVGTXCNKIPVQR VFEQNURCPYKFVJCNKIPEGPVGT åXCNKIPVQRPQYTCRPQYTCR 9RTQYCFļ åPCYúWľ[VMQYPKMC KPRWVV[RGVGZVPCOGWUGTPCOG åUKGOCZNGPIVJ VF VT   e c i l b a T 34 Formularz HTML jest dosyć prosty, służy do wprowadzania jedynie nazwy użytkownika oraz typu dla każdej gry. Później można opracować system uwierzytelniania, który będzie działać, zanim użytkownik wykona ten krok (system ten mógłby następnie automatycznie wprowadzać lub zapisywać nazwy użytkowników).  Uwaga: Zakończenie instrukcji echo kończącym znakiem apostrofu w osobnym wierszu może wydawać się dziwne, ale w rezultacie kod HTML staje się bardziej czytelny. Dzięki niemu mamy pewność, że następna instrukcja HTML rozpocznie się w osobnym wierszu, a nie od kończącego VT  14. Utworzymy pętlę, przeglądającą tablicę, wpisując każdą grę do formularza: HQTGCEJ ICOGUCUMG[ CTTC[ ] KH MG[ ] UGEQPFACTTC[GZRNQFG  VCTTC[  CYC[UGEQPFACTTC[=? JQOGUWDUVT UGEQPFACTTC[=? å UVTNGP UGEQPFACTTC[=?   GEJQVTCNKIP EGPVGT  åXCNKIP VQR  VFCNKIP NGHV XCNKIP VQR  åPQYTCR PQYTCR  KPRWVV[RG TCFKQ  åPCOG RKEMU=MG[?  åXCNWG CYC[  CYC[VF VFCNKIP EGPVGT  åXCNKIP VQR  RTGEKYVF VFCNKIP TKIJV XCNKIP VQR  åPQYTCR PQYTCR  KPRWVV[RG TCFKQ  åPCOG RKEMU=MG[?  åXCNWG JQOG  JQOGVF VT P _ _ Zaawansowane programowanie w PHP Pierwszy wiersz w tym kodzie stanowi nowa konstrukcja HQTGCEJ, której użycie stanowi łatwą i w pewnym sensie szybszą metodę obsługi tablic. Drugi wiersz zapewnia, że obsługiwany element nie jest pierwszym elementem w pliku. Jak wynika z przykładu pokazanego wyżej (skrypt 1.4), elementem tablicy pod indeksem  jest wiersz o wartości )QħEKG =6#$?)QURQFCTG, którego nie będziemy wyświetlać. Jeżeli nie jest to pierwszy element tablicy, wówczas zostanie on podzielony za pomocą funkcji GZRNQFG na poszczególne części (drużynę gości oraz drużynę gospodarzy). Każda drużyna jest formalnie przyporządkowana osobnej zmiennej (za każdym razem obcinany jest znak RETURN z nazwy drużyny gospodarzy). Ostatecznie wyświetlany jest wiersz tabeli złożony z uzyskanych informacji. T a b l i c e 15. Uzupełnimy kod formularza HTML oraz tabeli. GEJQVTCNKIP EGPVGT XCNKIP VQR  VFEQNURCP  YKFVJ   åCNKIP EGPVGT XCNKIP VQR  KPRWV åV[RG UWDOKV PCOG UWDOKV  åXCNWG 9[ħNKL  VT VCDNG KPRWVV[RG JKFFGP PCOG YGGM  åXCNWG YGGM  HQTO P Należy pamiętać, aby zastosować typ *+ 0 w celu przechowania numeru tygodnia, aby był on dostępny w skrypcie store_picks.php, który obsługuje formularz. 35 Rozdział 1. 16. Zakończymy główną instrukcję warunkową i zamkniemy znaczniki PHP i HTML. _GNUG] GEJQ0KGOQľPCQVYQT[èRNKMWHKNG å0CNGľ[WRGYPKèUKúE[OKGPPCYGGMOC åWUVCYKQPæ→YCTVQħèDT DT  _ ! DQF[ JVON Komunikat o błędzie, wygenerowany przez powyższy kod, jest przeznaczony bardziej dla programisty niż dla użytkownika (prawdopodobnie nie będziemy chcieli wyświetlać nazwy pliku w komunikacie o błędzie, który może być przeglądany przez wszystkich). Komunikat ten można przetworzyć na bardziej przyjazny dla użytkownika w zależności od sposobu działania naszej aplikacji. e c i l b a T 17. Zapisujemy plik jako make_picks_form.php i kopiujemy ten plik na nasz serwer, do tego samego katalogu, gdzie utworzyliśmy katalog 2001. Ładujemy go w przeglądarce WWW, dodając do adresu URL ciąg !YGGM, aby skrypt mógł działać poprawnie (rysunki 1.7 oraz 1.8). Na razie nie korzystamy z przycisku Wyślij. Wskazówki  W rozdziale 5., „Projektowanie aplikacji WWW”, zostanie omówione bardziej szczegółowo użycie symbolu .  W rozdziale 4., „Bezpieczeństwo”, opracujemy system rejestracji użytkowników oraz uwierzytelniania, którego będziemy mogli używać wraz z tymi skryptami oraz z dowolnymi innymi. 36 Rysunek 1.7. Oto formularz utworzony przez skrypt make_picks_form, umożliwiający wytypowanie zwycięzcy we wszystkich 15 grach Rysunek 1.8. Rozważne wykorzystywanie instrukcji echo oraz spacji w skryptach PHP powoduje, że kod źródłowy HTML staje się bardziej czytelny Zaawansowane programowanie w PHP Stałe Stałe to specjalny rodzaj zmiennych, któremu — moim skromnym zdaniem — nie poświęca się dostatecznie dużo uwagi. Stałe, jak wskazuje nazwa,t zawierają wartość, która nie zmienia się, ani też nie może się zmieniać w czasie działania skryptu. Ponadto dodatkową zaletą stałych jest fakt, że w danym zakresie są one globalne, co oznacza, że są automatycznie dostępne wewnątrz funkcji. W nazwach stałych wielkość liter ma znaczenie, podobnie jak w nazwach wszystkich zmiennych w PHP. Zasadą jest zapisywanie nazw stałych tylko wielkimi literami. W czasie nadawania nazw zmiennym należy stosować te same zasady, jak w przypadku zmiennych — litera (z wyjątkiem początkowego znaku dolara) lub znak podkreślenia, po którym następują litery, cyfry lub znaki podkreślenia. Stałą tworzy się za pomocą funkcji FGHKPG w następujący sposób: FGHKPG 0# 9#A56#Đ ,YCTVQħè  Stałą można zdefiniować tylko jako liczbę (całkowitą lub zmiennoprzecinkową), albo jako ciąg znaków. Nie można zdefiniować stałej jako tablicy lub jako obiektu, a po utworzeniu stałej jetj wartości nie można aktualizować, tak więc nie można przekształcić stałej łańcuchowej na liczbę całkowitą. Stałą można uważać za niezmienną zmienną. W PHP istnieje wiele wbudowanych stałych, włącznie z 2*2A15 (system operacyjny), 2*2A8 45+10 (np. 4.0.3pl1), 647 oraz (#.5 . Dwie zmienne wbudowane — AA(+. AA oraz AA.+0 AA oznaczające bieżącą nazwę pliku oraz numer wiersza — zmieniają się w czasie działania skryptu. Stałe te przydają się do uruchamiania diagnostycznego, o czym przekonamy się w rozdziale 5., „Projektowanie aplikacji WWW”. Lubię wykorzystywać stałe tam, gdzie występują zmienne, które nie powinny się zmieniać, lub w przypadku, jeżeli zmienna ma być dostępna w całym skrypcie. Jako demonstrację zdefiniowania i wykorzystania stałych zapiszemy skrypt store_ picks.php dla naszego totalizatora online. Skrypt ten będzie obsługiwał dane pochodzące ze strony make_picks_form.php utworzonej poprzednio. 37 S t a ł e Rozdział 1. Aby wykorzystać stałe: 1. W edytorze tekstowym utworzymy nowy dokument HTML (skrypt 1.6).  1 6;2 JVON27$.+ 9  6 :*6/. å6TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON å 6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF 2. Rozpoczniemy wpisywanie treści dokumentu HTML oraz umieścimy inicjujący znacznik PHP: DQF[ !RJR 3. Zdefiniujemy stałą 9 - FGHKPG 9 -YGGM  e ł a t S Ponieważ na każdej ze stron wykorzystywana jest wartość zmiennej YGGM, chcemy zapewnić, żeby zmienna ta nie zmieniała wartości w czasie działania skryptu. Z tego powodu zmienną tę przekształcimy na stałą. 4. Utworzymy funkcję, zapisującą typy użytkowników. HWPEVKQPYTKVGAFCVC XCNWGMG[HR ] HRWVU HRXCNWG P  _ Funkcja YTKVGAFCVC będzie wykorzystywana w połączeniu z funkcją CTTC[AYCNM zgodnie z tym, co napisano we wcześniejszej części tego rozdziału. Funkcja YTKVGAFCVC otrzymuje element tablicy, jej indeks oraz wskaźnik do pliku. Zawartość zapisaną do pliku będzie stanowić nazwa zespołu wybrana przez użytkownika zakończona znakiem RETURN. W celu wygenerowania znaku RETURN należy wykorzystać sekwencję P, ponieważ alternatywna sekwencja T powoduje problemy z odczytem pliku w niektórych systemach (pierwsza sekwencja generuje znak RETURN, natomiast druga — znak CR). Skrypt 1.6. Skrypt store_picks.php definiuje zmienną YGGM jako stałą, aby zapewnić niezmienność jej wartości w czasie działania skryptu  1 6;2 JVON27$.+ 9  6 :*6/. 6TCPUKVKQPCN 0 JVVRYYYYQTI644 ZJVON  6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJR 6GPUMT[RVQDUđWIWLGFCPGGUMT[RVW OCMGARKEMUAHQTORJR  7UVCYKGPKGPWOGTWV[IQFPKCLCMQUVCđGL FGHKPG 9 -YGGM   (WPMELCYTKVGAFCVCCRKUWLGV[R[ YRNKMW HWPEVKQPYTKVGAFCVC XCNWGMG[HR ] HRWVU HRXCNWG P  QFCPKG PCMWTGVWTPCD[WOKGħEKèMCľF[ GNGOGPVYQFFKGNP[OYKGTUW _  HKNG RKEMUA 9 - A  WUGTPCOG AVZV 9UMCCPKGRNKMW YHQTOCEKG RKEMUAA.CTT[AVZV  KH HR HQRGP HKNGY ] 1VYCTEKGRNKMWFQCRKUW  HRWVU HR9KGTUCVTCRC P  7VYQTGPKGYKGTUCCVTCR[ CTTC[AYCNM RKEMU YTKVGAFCVC  HR 9[UđCPKGECđGLVCDNKE[ FQHWPMELKYTKVGAFCVC HENQUG HR  COMPKúEKGRNKMW GEJQ 6YQLGV[R[QUVCđ[CRKUCPG   _GNUG]9[ħYKGVNGPKGMQOWPKMCVW QDđúFKGLGľGNKQVYCTEKGRNKMWPKG RQYKQFđQUKú GEJQ0KGOQľPCQVYQT[èRNKMW HKNG0CNGľ[WRGYPKèUKúE[ OKGPPCYGGMOCWUVCYKQPæYCTVQħè DT DT  _ ! DQF[ JVON 38 Zaawansowane programowanie w PHP 5. Wskazujemy plik, który będzie wykorzystywany HKNG RKEMUA 9 - A  åWUGTPCOG AVZV  Nazwa pliku składa się z przedrostka RKEMUA, po którym następuje numer tygodnia, znak podkreślenia, nazwa użytkownika i ponownie znak podkreślenia. Plik ma rozszerzenie .txt. Nazwy stałej nie można umieścić w apostrofach ani w cudzysłowach, ponieważ w takim przypadku PHP interpretowałby ją dosłownie jako 9 -, a nie jako wartość, którą stała reprezentuje. Jeżeli katalog 2001 umieścimy poza głównym katalogiem dokumentów WWW, wówczas w celu właściwego odwołania się do tego katalogu powinniśmy zastosować odpowiednią składnię. 6. Próbujemy otworzyć plik do zapisu. KH HR HQRGP HKNGY ] Jeżeli ta instrukcja warunkowa przyjmie wartość HCNUG, wówczas należy sprawdzić, czy poprawnie ustawiliśmy uprawnienia do katalogu 2001 — nieprawidłowe ich ustawienie jest najbardziej prawdopodobną przyczyną błędu, ponieważ sam plik do tej pory nie istniał, zatem powinna istnieć możliwość zapisu do tego pliku. Inną prawdopodobną przyczyną może być użycie złego parametru, na przykład C zamiast Y. S t a ł e 7. Zapisujemy dane do pliku. HRWVU HR9KGTUCVTCRC P  CTTC[AYCNM RKEMU YTKVGAFCVC HR  Pierwszym wierszem, który zapisujemy do pliku, jest wiersz — atrapa, a po nim, wykorzystując połączenie funkcji CTTC[A YCNM ze zdefiniowaną uprzednio funkcją YTKVGAFCVC , zapisujemy pozostałe dane. Teoretycznie moglibyśmy zdefiniować dodatkową funkcję, która przed zapisem danych sprawdzałaby, czy wytypowano wszystkich zwycięzców. 39 Rozdział 1. 8. Zamykamy plik, a po pomyślnym jego zamknięciu wysyłamy komunikat. HENQUG HR  COMPKúEKGRNKMW GEJQ 6YQLGV[R[QUVCđ[CRKUCPG  9. Kończymy instrukcję warunkową, PHP oraz HTML. _GNUG] GEJQ0KGOQľPCQVYQT[èRNKMWHKNG å0CNGľ[WRGYPKèUKúE[OKGPPCYGGM åOCWUVCYKQPæYCTVQħèDT DT  _ ! DQF[ JVON 10. Zapisujemy plik jako store_picks.php i kopiujemy go na serwer, do tego samego katalogu, gdzie zapisaliśmy skrypt make_ picks_form.php (skrypt 1.5). Uruchamiamy ten drugi skrypt w przeglądarce WWW (rysunek 1.7) tak, aby skrypt store_picks.php został wykonany (rysunek 1.9). e ł a t S 11. Sprawdzamy w katalogu 2001, czy utworzono nowy plik (rysunek 1.10). Możemy pobrać nowo utworzony plik i sprawdzić jego zawartość (skrypt 1.7). Rysunek 1.9. Jeżeli skrypt działa prawidłowo, wówczas użytkownik uzyska ten lakoniczny komunikat Rysunek 1.10. Katalog 2001, który jest bazą danych plików tekstowych, zawiera wszystkie dane, włącznie z nowo utworzonym plikiem picks_1_NAZWA_txt 40 Skrypt 1.7. Po wykonaniu skryptu make_picks_ form.php oraz store_picks.php zostanie utworzony poniższy plik, zawierający moje typy dla gier w pierwszym tygodniu 9KGTUCVTCRC $WHHCNQ 0GY PINCPF 5GCVVNG 6CORC$C[ )TGGP$C[ -CPUCU KV[ /KPPGUQVC +PFKCPCRQNKU 2KVVUDWTIJ  JKECIQ 2JKNCFGNRJKC 5CP KGIQ 5CP(TCPEKUEQ /KCOK  GPXGT Zaawansowane programowanie w PHP Wskazówki  Aby sprawdzić, czy zdefiniowano stałą przed jej użyciem, można skorzystać z funkcji FGHKPGF : KH FGHKPGF 0# 9#A56#. , ] Należy uważać, aby nie pomylić funkcji FGHKPGF z funkcją FGHKPG , która służy do ustawiania wartości stałej.  Aby obejrzeć listę wszystkich zdefiniowanych stałych, należy skorzystać z funkcji IGVAFGHKPGFAEQPUVCPVU .  Chociaż posiadanie katalogu z prawem zapisu w obrębie katalogu WWW (uprawnienia ustawione na 777), tak jak w powyższym przykładzie katalog 2001, nie jest bezpieczne, to czasami jest to konieczność. Istnieją obejścia oraz elementy, na które należy zwracać uwagę w takich przypadkach. Zostaną one omówione w rozdziale 4., „Bezpieczeństwo”. Jeżeli istnieje możliwość umieszczenia katalogu z prawem zapisu poza katalogiem WWW, tak będzie lepiej, chociaż niektóre firmy świadczące usługi hostingu nie dadzą nam takiego wyboru. S t a ł e 41 Funkcja ta będzie wywoływać samą siebie dopóty, dopóki zmienna P nie osiągnie wartości większej niż 100. W tym momencie działanie funkcji zakończy się. Wykorzystując rekurencję lub dowolny skrypt, gdzie ta sama funkcja wykonuje się wiele razy, warto rozważyć zastosowanie instrukcji UVCVKE. Użycie tej instrukcji powoduje, że wartości zmienne są pamiętane pomiędzy poszczególnymi wywołaniami funkcji bez konieczności użycia zmiennych globalnych. Funkcję EQWPVAVQA , dla zapewnienia identycznego wyniku jej działania, można przepisać następująco: HWPEVKQPEQWPVAVQA ] UVCVKEP KH P ] GEJQPDT DT  P  EQWPVAVQA  _ _ Jako kolejny krok na drodze do stworzenia aplikacji totalizatora piłkarskiego online zapiszemy skrypt, który wykorzystuje rekurencję oraz instrukcję UVCVKE. Skrypt ten będzie umożliwiał administratorowi wprowadzenie zwycięzców każdego meczu, a następnie porównanie zwycięzcy z typami poszczególnych graczy. Rozdział 1. Funkcje rekurencyjne i zmienne statyczne Programując, z pewnością będziemy mieli okazję zdefiniowania i zastosowania własnej funkcji — jest to doskonałe narzędzie, które pomaga właściwie zorganizować nasz kod oraz zaoszczędzić czas. Elementem, z którego być może jeszcze nie korzystaliśmy, jest rekurencja wewnątrz funkcji. Rekurencja to właściwość wywoływania funkcji w obrębie jej samej. HWPEVKQPPCYCAHWPMELK ] LCMKħMQF PCYCAHWPMELK  _ W wyniku zastosowania rekurencji uzyskamy efekt, gdzie będziemy mogli wykorzystać funkcję zarówno zgodnie z jej przeznaczeniem, jak też jako pętlę. Stosując tę technikę, należy uwzględnić jedną, ogromnie ważną uwagę. Należy upewnić się, że funkcja posiada warunek wyjścia. Na przykład funkcja o kodzie pokazanym poniżej będzie działać w nieskończoność: HWPEVKQPCFFAQPG P ] P  CFFAQPG P  _ CFFAQPG   Brak warunku określającego zakończenie obliczeń funkcji tworzy olbrzymi problem programistyczny — pętlę nieskończoną. Porównajmy funkcję pokazaną wyżej do następującej: HWPEVKQPEQWPVAVQA P ] KH P ] GEJQPDT DT  _ _ EQWPVAVQA   e n z c y t a t s e n n e i m z i e n j y c n e r u k e r e j c k n u F 42 Aby wykorzystać rekurencję oraz instrukcję static: 1. W edytorze tekstowym otwieramy skrypt make_picks_form.php (skrypt 1.5). Napiszemy skrypt nieco inny od tego, tak aby można było dokonać wyboru zwycięzców. 2. Modyfikujemy wiersze 15. – 21. oryginalnego dokumentu tak, aby formularz był obsługiwany przez inny skrypt oraz bez możliwości wprowadzania danych przez użytkowników (skrypt 1.8). Zaawansowane programowanie w PHP GEJQ HQTOCEVKQPRTQEGUUAYKPPGTURJR åOGVJQFRQUV VCDNGDQTFGTYKFVJEGNNURCEKPI åEGNNRCFFKPICNKIPEGPVGT  Chociaż formularz ten będzie bardzo podobny do formularza w skrypcie make_picks_form.php, to jednak będzie on obsługiwany inaczej — przez skrypt process_winner.php, który zapiszemy jako następny. F u n k c j e r e k u r e n c y j n e i z m i e n n e s t a t y c z n e Skrypt 1.8. Skrypt pick_winners.php to tylko nieznaczna modyfikacja jego poprzednika — skryptu make_picks_form.php  1 6;2 JVON27$.+ 9  6 :*6/.6TCPUKVKQPCN2. JVVRYYYYQTI644 ZJVON 6 ZJVONVTCPUKVKQPCNFVF JVONZONPUJVVRYYYYQTIZJVON JGCF VKVNG 6QVCNKCVQTRKđMCTUMKVKVNG JGCF DQF[ !RJROCMGARKEMUAHQTORJR  HKNG YGGM YGGM VZV 9UMCCPKGRNKMWPCRQFUVCYKGPWOGTWV2[IQFPKC  KH ICOGUHKNG HKNG ]9E[VCPKGRNKMWFQVCDNKE[  2QRTGE[VCPKWRNKMWY[ħYKGVNGPKGHQTOWNCTC GEJQ HQTOCEVKQPRTQEGUUAYKPPGTURJROGVJQFRQUV VCDNGDQTFGTYKFVJEGNNURCEKPIEGNNRCFFKPICNKIPEGPVGT 
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Po prostu PHP. Techniki zaawansowane
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: