You are on page 1of 390

Spis Treści

SPIS TREŚCI............................................................................................................................................................ 1 WSTĘP ...................................................................................................................................................................... 7 Dla kogo jest przeznaczona ta książka ............................................................................................................... 7 Konwencje .......................................................................................................................................................... 7 Omówienie książki.............................................................................................................................................. 7 Od autora ........................................................................................................................................................... 8 Przykłady kodu ................................................................................................................................................... 8 CZYM JEST PHP ...................................................................................................................................................... 8 DLACZEGO POWINIENEŚ UŻYĆ PHP......................................................................................................................... 9 GDZIE SZUKAĆ POMOCY .......................................................................................................................................... 9 PODZIĘKOWANIA ................................................................................................................................................... 10 O AUTORZE............................................................................................................................................................ 10 ROZDZIAŁ 1. KOMPILACJA I INSTALOWANIE PHP................................................................................ 11 WSTĘP ................................................................................................................................................................... 11 POBIERANIE PHP................................................................................................................................................... 11 INSTALOWANIE WERSJI BINARNEJ.......................................................................................................................... 11 Binarna instalacja dla Windows ...................................................................................................................... 11 Instalowanie PHP w postaci modułu ISAPI................................................................................................. 12 Użycie PHP jako CGI................................................................................................................................... 14 Inne instalacje binarne..................................................................................................................................... 14 KOMPILOWANIE PHP ............................................................................................................................................ 15 Kompilowanie PHP w Uniksach ...................................................................................................................... 15 Kompilacja modułu CGI .............................................................................................................................. 15 Kompilacja PHP jako statycznie dołączanego modułu Apache................................................................... 17 Kompilacja PHP do postaci dynamicznie ładowanego modułu Apache ..................................................... 17 Podsumowanie kompilacji PHP w systemach Unix .................................................................................... 18 Kompilowanie PHP w środowisku Windows ................................................................................................... 18 Podsumowanie kompilacji PHP....................................................................................................................... 20 KONFIGUROWANIE PHP ........................................................................................................................................ 20 Korzystanie z pliku php.ini ............................................................................................................................... 20 Inne metody zmiany konfiguracji PHP............................................................................................................. 21 PODSUMOWANIE ................................................................................................................................................... 22 ROZDZIAŁ 2. JĘZYK .......................................................................................................................................... 23 WSTĘP ................................................................................................................................................................... 23 OGÓLNE INFORMACJE NA TEMAT SKŁADNI ............................................................................................................ 23 TYPY ..................................................................................................................................................................... 24 Liczby — całkowite i zmiennoprzecinkowe ...................................................................................................... 24 Ciągi ................................................................................................................................................................. 24 Tablice.............................................................................................................................................................. 25 ZMIENNE I STAŁE ................................................................................................................................................... 26 Zmienne predefiniowane .................................................................................................................................. 26 Zasięg zmiennych ............................................................................................................................................. 30

Stałe.................................................................................................................................................................. 31 OPERATORY I KOLEJNOŚĆ OPERATORÓW ............................................................................................................... 31 PROGRAMOWANIE PRZEPŁYWU STEROWANIA ....................................................................................................... 32 if, else, elseif ..................................................................................................................................................... 32 while ................................................................................................................................................................. 32 do .. while ......................................................................................................................................................... 32 for ..................................................................................................................................................................... 33 foreach.............................................................................................................................................................. 33 switch................................................................................................................................................................ 33 break i continue ................................................................................................................................................ 35 include i require ............................................................................................................................................... 36 FUNKCJE ................................................................................................................................................................ 36 Klasy i programowanie obiektowe................................................................................................................... 37 PORÓWNYWANIE WZORCÓW ................................................................................................................................. 39 Podsumowanie ................................................................................................................................................. 39 ROZDZIAŁ 3. FORMULARZE I COOKIE....................................................................................................... 40 WSTĘP ................................................................................................................................................................... 40 OBSŁUGA FORMULARZY W PHP............................................................................................................................ 41 Skalarne i wielowartościowe elementy formularza.......................................................................................... 41 Alternatywne metody odczytywania wartości z formularza ............................................................................. 42 Użycie formularzy do przesyłania plików ........................................................................................................ 45 Użycie rysunku jako przycisku wysłania danych.............................................................................................. 45 KONTROLA POPRAWNOŚCI DANYCH FORMULARZA................................................................................................ 46 Kontrola danych za pomocą wyrażeń regularnych.......................................................................................... 46 Kontrola poprawności za pomocą sprawdzania typów.................................................................................... 47 Klasa Validator ................................................................................................................................................ 48 COOKIE ................................................................................................................................................................. 49 WAŻNE ZAGADNIENIA PROGRAMOWANIA DLA WWW .......................................................................................... 50 Obsługa nieprawidłowych danych ................................................................................................................... 50 Obsługa i formatowanie wyświetlanych danych .............................................................................................. 52 PODSUMOWANIE ................................................................................................................................................... 57 ROZDZIAŁ 4. OPERACJE NA PLIKACH........................................................................................................ 58 WSTĘP ................................................................................................................................................................... 58 ODCZYT I ZAPIS PLIKÓW ........................................................................................................................................ 58 UŻYCIE GNIAZD ..................................................................................................................................................... 59 UŻYCIE POTOKÓW ................................................................................................................................................. 60 KLASA FILE ........................................................................................................................................................... 61 PODSUMOWANIE ................................................................................................................................................... 61 ROZDZIAŁ 5. WYSYŁANIE PLIKÓW PRZEZ FORMULARZ.................................................................... 62 WSTĘP ................................................................................................................................................................... 62 WYSYŁANIE POJEDYNCZEGO PLIKU ....................................................................................................................... 62 PUŁAPKI ................................................................................................................................................................ 64 PRZESYŁANIE WIELU PLIKÓW ................................................................................................................................ 64 BEZPIECZEŃSTWO ................................................................................................................................................. 65 PODSUMOWANIE ................................................................................................................................................... 66 ROZDZIAŁ 6. WSPÓŁPRACA Z BAZAMI DANYCH.................................................................................... 67 WSTĘP ................................................................................................................................................................... 67 WPROWADZENIE ................................................................................................................................................... 67 FUNKCJE BAZ DANYCH .......................................................................................................................................... 67 MYSQL................................................................................................................................................................. 68 2 Spis Treści

Rozpoczynamy pracę z MySQL ........................................................................................................................ 68 Użycie MySQL.................................................................................................................................................. 68 ODBC................................................................................................................................................................... 71 Podstawy ODBC .............................................................................................................................................. 71 Instalowanie i kompilowanie unixODBC .................................................................................................... 72 Kompilowanie PHP z obsługą unixODBC .................................................................................................. 72 Instalowanie sterownika OOB...................................................................................................................... 72 Konfigurowanie OOB .................................................................................................................................. 72 Korzystanie z ODBC ........................................................................................................................................ 73 PHPLIB ................................................................................................................................................................ 74 PRZECHOWYWANIE DANYCH Z FORMULARZY........................................................................................................ 75 WYKORZYSTANIE MOŻLIWOŚCI BAZY DANYCH ..................................................................................................... 77 PODSUMOWANIE ................................................................................................................................................... 78 ROZDZIAŁ 7. SESJE I STAN APLIKACJI....................................................................................................... 80 WSTĘP ................................................................................................................................................................... 80 PODSTAWY MECHANIZMU SESJI ............................................................................................................................. 80 WBUDOWANY W PHP MECHANIZM ZARZĄDZANIA SESJAMI .................................................................................. 81 Rozpoczęcie pracy z sesjami w PHP ................................................................................................................ 81 Przesyłanie identyfikatora sesji bez użycia cookie........................................................................................... 83 Zapisywanie zmiennych sesji w bazie danych .................................................................................................. 85 Inne funkcje i opcje dotyczące sesji.................................................................................................................. 89 UŻYCIE PHPLIB DO OBSŁUGI SESJI ....................................................................................................................... 90 TWORZENIE WŁASNEGO MECHANIZMU SESJI ......................................................................................................... 92 INŻYNIERIA PROGRAMOWANIA A SESJE ................................................................................................................. 92 PODSUMOWANIE ................................................................................................................................................... 94 ROZDZIAŁ 8. UWIERZYTELNIANIE.............................................................................................................. 95 WSTĘP ................................................................................................................................................................... 95 PODSTAWOWE UWIERZYTELNIANIE W APACHE ..................................................................................................... 95 AKTUALIZACJA PLIKU .HTACCESS PRZY UŻYCIU PHP............................................................................................ 97 PODSTAWOWE UWIERZYTELNIANIE ZA POMOCĄ PHP ........................................................................................... 99 KOMPLETNY SYSTEM UWIERZYTELNIANIA OPARTY O PHP ................................................................................. 100 PODSUMOWANIE ................................................................................................................................................. 104 ROZDZIAŁ 9. NIEZALEŻNOŚĆ OD PRZEGLĄDARKI ............................................................................. 105 WSTĘP ................................................................................................................................................................. 105 ROZPOCZYNAMY ................................................................................................................................................. 105 WEWNĘTRZNE FUNKCJE PHP .............................................................................................................................. 106 Dodatkowe informacje na temat Browscap ................................................................................................... 106 BROWSERHAWK .................................................................................................................................................. 109 WYKORZYSTANIE DANYCH O PRZEGLĄDARCE..................................................................................................... 113 PODSUMOWANIE ................................................................................................................................................. 114 ROZDZIAŁ 10. URUCHAMIANIE................................................................................................................... 115 WSTĘP ................................................................................................................................................................. 115 INŻYNIERIA PROGRAMOWANIA A URUCHAMIANIE ............................................................................................... 115 Projekt aplikacji ............................................................................................................................................. 115 Definiowanie standardów programowania.................................................................................................... 116 Przegląd oprogramowania............................................................................................................................. 116 Testowanie...................................................................................................................................................... 117 Uruchamianie................................................................................................................................................. 117 PROGRAMOWANIE DEFENSYWNE ......................................................................................................................... 118 WŁASNA OBSŁUGA BŁĘDÓW................................................................................................................................ 122 PHP – Kompendium wiedzy 3

ZAAWANSOWANA OBSŁUGA BŁĘDÓW ................................................................................................................. 125 PODSUMOWANIE ................................................................................................................................................. 129 BIBLIOGRAFIA ..................................................................................................................................................... 130 ROZDZIAŁ 11. PONOWNE WYKORZYSTANIE KODU ............................................................................ 131 WSTĘP ................................................................................................................................................................. 131 PONOWNE WYKORZYSTANIE KODU A INŻYNIERIA PROGRAMOWANIA .................................................................. 131 PONOWNE UŻYCIE ISTNIEJĄCEGO KODU .............................................................................................................. 132 PHP ................................................................................................................................................................ 132 C/C++ ............................................................................................................................................................ 133 Java ................................................................................................................................................................ 138 Dodawanie obsługi Javy w PHP na *niksach ............................................................................................ 138 Dołączanie obsługi Javy w PHP dla Windows .......................................................................................... 139 Opcje konfiguracji Javy.............................................................................................................................. 139 COM ............................................................................................................................................................... 141 Inne metody .................................................................................................................................................... 143 PODSUMOWANIE ................................................................................................................................................. 144 BIBLIOGRAFIA ..................................................................................................................................................... 144 ROZDZIAŁ 12. ODDZIELANIE KODU HTML OD PHP ............................................................................. 145 WSTĘP ................................................................................................................................................................. 145 WPROWADZENIE ................................................................................................................................................. 145 ODDZIELENIE I INTEGRACJA PRZY UŻYCIU WBUDOWANYCH FUNKCJI PHP.......................................................... 146 Motywacja ...................................................................................................................................................... 146 Implementacja ................................................................................................................................................ 147 Czego należy unikać ....................................................................................................................................... 151 Podsumowanie: Oddzielanie i integracja przy wykorzystaniu funkcji PHP.................................................. 151 WYKORZYSTANIE SYSTEMU SZABLONÓW............................................................................................................ 152 FastTemplate .................................................................................................................................................. 152 Zaawansowane techniki użycia FastTemplate ............................................................................................... 157 PODSUMOWANIE ................................................................................................................................................. 159 BIBLIOGRAFIA ..................................................................................................................................................... 159 ROZDZIAŁ 13. FAJNY PHP.............................................................................................................................. 160 WSTĘP ................................................................................................................................................................. 160 WYSYŁANIE DO PRZEGLĄDARKI PLIKÓW INNYCH NIŻ HTML.............................................................................. 160 SKRYPTY AUTOMATYZUJĄCE .............................................................................................................................. 164 WDDX................................................................................................................................................................ 168 MONITOROWANIE SIECI ....................................................................................................................................... 172 PODSUMOWANIE ................................................................................................................................................. 174 ROZDZIAŁ 14. WITRYNY OPARTE O SZABLONY ................................................................................... 175 PODSTAWY WYKORZYSTANIA SZABLONÓW ......................................................................................................... 175 ZAPOŻYCZANIE ................................................................................................................................................... 183 PERSONALIZACJA WITRYNY................................................................................................................................. 185 OBSŁUGA WIELU JĘZYKÓW .................................................................................................................................. 187 PODSUMOWANIE ................................................................................................................................................. 189 ROZDZIAŁ 15. WITRYNY OPARTE O BAZĘ DANYCH............................................................................ 190 WSTĘP ................................................................................................................................................................. 190 PROJEKT BAZY DANYCH ...................................................................................................................................... 190 ZARZĄDZANIE DANYMI APLIKACJI....................................................................................................................... 192 WYŚWIETLANIE DANYCH .................................................................................................................................... 199 PODSUMOWANIE ................................................................................................................................................. 204 4 Spis Treści

ROZDZIAŁ 16. GENEROWANIE STATYCZNYCH STRON HTML W OPARCIU O DYNAMICZNE DANE..................................................................................................................................................................... 205 WSTĘP ................................................................................................................................................................. 205 KONCEPCJA ......................................................................................................................................................... 205 GENEROWANIE STRON STATYCZNYCH ................................................................................................................. 205 Użycie buforowania........................................................................................................................................ 205 Użycie FastTemplate ...................................................................................................................................... 207 TECHNIKI BUFOROWANIA .................................................................................................................................... 208 PODSUMOWANIE ................................................................................................................................................. 210 ROZDZIAŁ 17. WITRYNY HANDLU ELEKTRONICZNEGO ................................................................... 211 WSTĘP ................................................................................................................................................................. 211 BEZPIECZEŃSTWO ............................................................................................................................................... 211 Zastosowanie SSL........................................................................................................................................... 211 Certyfikaty ...................................................................................................................................................... 211 Bezpieczeństwo bazy danych.......................................................................................................................... 212 PRZETWARZANIE PŁATNOŚCI ............................................................................................................................... 212 DOSTARCZANIE PRODUKTÓW .............................................................................................................................. 219 PODSUMOWANIE ................................................................................................................................................. 220 DODATEK A. FUNKCJE ................................................................................................................................... 221 DODATEK B. PREDEFINIOWANE ZMIENNE I STAŁE PHP................................................................... 367 ZMIENNE ............................................................................................................................................................. 367 Zmienne Apache ............................................................................................................................................. 367 Zmienne środowiska....................................................................................................................................... 369 Zmienne PHP ................................................................................................................................................. 369 STAŁE .................................................................................................................................................................. 370 DODATEK C. OPCJE KOMPILACJI PHP..................................................................................................... 372 BAZY DANYCH .................................................................................................................................................... 372 HANDEL ELEKTRONICZNY ................................................................................................................................... 374 GRAFIKA ............................................................................................................................................................. 374 RÓŻNE ................................................................................................................................................................. 375 --enable-inline-optimization........................................................................................................................... 376 SIEĆ ..................................................................................................................................................................... 379 DZIAŁANIE PHP .................................................................................................................................................. 379 SERWER ............................................................................................................................................................... 380 TEKST I JĘZYK ..................................................................................................................................................... 380 XML ................................................................................................................................................................... 381 DODATEK D. OPCJE KONFIGURACJI PHP ............................................................................................... 382 OGÓLNE DYREKTYWY KONFIGURACJI ................................................................................................................. 382 DYREKTYWY KONFIGURACJI POCZTY .................................................................................................................. 385 DYREKTYWY KONFIGURACJI TRYBU BEZPIECZNEGO ........................................................................................... 385 DYREKTYWY KONFIGURACJI DEBUGGERA ........................................................................................................... 385 DYREKTYWY ŁADOWANIA ROZSZERZEŃ ............................................................................................................. 385 DYREKTYWY KONFIGURACJI MYSQL ................................................................................................................. 386 DYREKTYWY KONFIGURACJI MSQL .................................................................................................................... 386 DYREKTYWY KONFIGURACJI POSTGRESQL ........................................................................................................ 386 DYREKTYWY KONFIGURACJI SYBASE .................................................................................................................. 387 DYREKTYWY KONFIGURACJI SYBASE-CT ........................................................................................................... 387 DYREKTYWY KONFIGURACJI INFORMIX .............................................................................................................. 388 DYREKTYWY KONFIGURACJI BC MATH .............................................................................................................. 389 5 PHP – Kompendium wiedzy

DYREKTYWY KONFIGURACJI MOŻLIWOŚCI PRZEGLĄDAREK ................................................................................ 389 DYREKTYWY KONFIGURACJI ZUNIFIKOWANEGO ODBC ..................................................................................... 389 DODATEK E. ZASOBY SIECI.......................................................................................................................... 390

Spis Treści

6

Wstęp
Książka ta jest przeznaczona dla programistów tworzących aplikacje WWW za pomocą PHP. Należy zwrócić uwagę, że zostało użyte określenie aplikacje WWW a nie strony WWW lub witryny WWW. W przeszłości w Sieci znajdowały się w większości proste strony HTML o ograniczonej możliwości interakcji. Dzisiejszy obraz Sieci jest o wiele bardziej skomplikowany. Użytkownicy i firmy oczekują od Sieci coraz więcej. Powoduje to powstanie coraz większej ilości dynamicznych aplikacji WWW. PHP jest idealny do tworzenia takich aplikacji, ponieważ został zaprojektowany właśnie do realizacji tego zadania.

Dla kogo jest przeznaczona ta książka
Książka ta powinna być użyteczna dla szerokiego grona programistów WWW, ale pisana była z myślą o średnio zaawansowanych lub zaawansowanych programistach. PHP jest językiem programowania a nie językiem opisu strony, więc przydatne będzie doświadczenie w programowaniu. Programiści znający C lub Perla powinni uznać PHP za język bardzo przyjazny, natomiast programiści pracujący w ASP Microsoftu (Active Server Pages) uznają PHP za język o podobnej strukturze. Ponieważ książka ta nie jest kierowana do początkujących programistów, podstawowe pojęcia dotyczące programowania zostaną przedstawione bardzo skrótowo. Zakłada się, że Czytelnik zna takie pojęcia programowania, jak funkcje, zmienne i stałe.

Konwencje
W książce przyjęto następujące konwencje: • Kod programu i jego wyniki zaznaczone są czcionką o stałej • Nazwy plików i katalogów zaznaczone są czcionką pochyłą. • Komendy i elementy języka zaznaczone są czcionką o stałej
szerokości. szerokości.

Omówienie książki
Książka zawiera zwięzłe wprowadzenie do PHP, oraz opis języka. Został w niej również przedstawiony sposób instalacji i konfiguracji PHP. Druga część, „Specjalne wymagania przy programowaniu WWW”, przeznaczona jest dla programistów tradycyjnych aplikacji rozpoczynających pracę przy aplikacjach WWW. W części tej przedstawione zostały takie zagadnienia jak: przetwarzanie formularzy, interakcję z użytkownikiem, utrzymywanie stanu oraz niezależność od przeglądarki. Następna część, „Zarządzanie projektem aplikacji WWW” opisuje zalety modularności i powtórnego użycia kodu. Część „Przykłady zastosowań” pokazuje użycie PHP na podstawie fragmentów działających już aplikacji. Część ta łączy zagadnienia przedstawione w poprzednich częściach i pokazuje przykłady pełnej wymiany informacji pomiędzy przeglądarką użytkownika i aplikacją zainstalowaną na serwerze WWW. Na końcu książki znajduje się skorowidz zawierający wszystkie funkcje PHP4.

1 zainstalowany na Windows NT.Kod PHP wkleić poniżej --> </body> </html> Większe fragmenty kodu były tworzone od razu razem z kodem HTML. sposoby przeniesienia istniejącego kodu do nowych projektów WWW. Oficjalnym rozwinięciem skrótu PHP jest „PHP: Hypertext Preprocessor” (preprocesor hipertekstu). ?> </body> </html> Po uruchomieniu tego przykładu (poprzez odpowiednio skonfigurowany serwer WWW) generowany jest kod HTML zamieszczony na wydruku 2. www. Przykłady kodu Zamieszczone przykłady kodu były tworzone i testowane pzy użyciu PHP 4. Do edycji plików HTML i PHP wykorzystuję edytor Allaire Homeite 4. ale pokazuje jak łatwo można umieszczać kod PHP w kodzie HTML. Wydruk 1.3. identycznie jak w przypadku zwykłych stron.Od autora Od około trzech lat tworzę aplikacje WWW przy użyciu PHP i ASP.net. Perla i Javy. że przeglądarka nie wie. że do stworzenia strony był używany PHP.php. Wynik działania wydruku 1 <html> <head> <title>Prosty przykład kodu PHP</title> </head> <body> Witajcie w PHP! </body> </html> Preprocesor PHP wykonuje cały kod zawarty pomiędzy znacznikami <?php i ?> umieszczonymi w kodzie HTML i zwraca wynik w postaci tekstu. Wydruk 2.11 działającym w systemie RedHat 6. Przedstawię również kilka przydatnych narzędzi napisanych dla PHP. Więcej na ten temat znajduje się w Wstęp 8 . oraz jest wystarczająco wydajny i pewny nawet do tworzenia dużych aplikacji WWW. Nie jest to szczególnie interesujący. Wszystkie te informacje można znaleźć na oficjalnej witrynie PHP. Na wydruku 1.5. Do testowania małych fragmentów kodu stosowałem następujący szablon HTML do którego wklejałem odpowiedni kod PHP: <html> <head> <title>Nazwa przykładu</title> </head> <body> <!-. jako niezależny przedsiębiorca. że kod ten jest wykonywany na serwerze WWW a nie na kliencie. Celem tej książki jest przekazanie innym programistów użytecznych informacji. Oznacza to. Należy pamiętać. Nie będę opisywał różnic pomiędzy PHP i innymi tego typu narzędziami i nie będę zajmował się historią PHP. Fundamentem mojego sukcesu było użycie PHP.1. Czym jest PHP PHP to język programowania przeznaczony dla programistów WWW pozwalający na szybkie tworzenie dynamicznych aplikacji WWW. Jest to język programowania osadzany w HTML składniowo podobny do C. ponieważ pozwala on na szybkie budowanie prototypów. Otrzymuje ona po prostu strumień kodu HTML. Zamiast tego pokażę zastosowanie PHP do stworzenia aplikacji WWW. przedstawiony jest przykład kodu PHP. Omówię również inżynierię programowania w projektach WWW. Prosty przykład kodu PHP <html> <head> <title>Prosty przykład kodu PHP</title> </head> <body> <?php echo "Witajcie w PHP!" .0.1 (poprawka 2) na Apache 1.

Ponieważ PHP jest rozprowadzany głównie w postaci kodu źródłowego. Dlaczego powinieneś użyć PHP PHP jest pełnowartościowym językiem programowania pozwalający na tworzenie aplikacji WWW z wszystkimi potrzebnymi funkcjami. Dzięki temu może on działać z praktycznie każdym serwerem WWW. W lutym 2000 roku około 1400000 domen korzystało z PHP. W celu utworzenia najbardziej elastycznego środowiska pracy należy samodzielnie skompilować i zainstalować PHP. może być skompilowany na wielu różnych platformach. Gdzie szukać pomocy Pomoc można uzyskać na witrynie PHP oraz poprzez kilka grup dyskusyjnych i wysyłkowych. PHP może być użyty we wielu konfiguracjach serwerów. PHP może działać jako program CGI lub może być zainstalowany jako moduł Apache lub rozszerzenie ISAPI. możesz zastosować binarną dystrybucję PHP. Dostępne są również binarne dystrybucje dla Win32. którzy mogą odpowiedzieć na pytania. POP3. PHP współpracuje z wieloma systemami baz danych. NNTP i TTP. istnieje ogromna grupa programistów i konsultantów. Pozwala on również na otwieranie gniazd sieciowych i podłączanie się do innych protokołów TCP/IP. Możliwy jest również dostęp do usług sieciowych takich jak IMAP. od Apache na Linuksie do IIS na Windows NT. Jeżeli wolisz szybko zacząć pracę. Więcej informacji na temat dostępnych zasobów Sieci znajduje się w części „Zasoby” na końcu książki. Pozwala to na bardzo łatwe tworzenie aplikacji WW korzystających z informacji zapisanych w bazie danych. 9 PHP – Kompendium wiedzy . Ponieważ jest on tak popularny.części „Specjalne wymagania przy programowaniu WWW”. na przykład na Linuksie. FreeBSD i nawet na Windows.

Szczególne podziękowania należą się Rebece Young za wsparcie i pomoc w technicznych aspektach pisania książki. Battilana za pomoc przy Cloanto Currency Server.net.Podziękowania Na początku chciałbym podziękować wszystkim z wydawnictwa McGraw-Hill za umożliwienie mi zrealizowania tego zadania. Dziękuję Tracy Ard za pożyteczne komentarze do tej pracy oraz za jego niezmienną przyjaźń. O autorze Blake Schwendiman rozpoczął programowanie w 1980 roku rozpoczynając od Apple IIe i języka Basic. Dziękuję również Michaelowi C. Zdobył licencjat na uniwersytecie Arizona State University w roku 1994. Dziękuję Mattowi Wilson za umożliwienie mi wykorzystania w przykładzie do książki kodu MWeather. Podziękowania dla Nate Weiss za pomoc przy użyciu deserializera WDDX dla JavaScript. To oni spędzili setki lub tysiące godzin tworząc ten wspaniały język programowania i bogatą dokumentację.intechra. Cała część zawierająca skorowidz funkcji jest ich zasługą. za stworzenie tego świetnego produktu. która ma siedzibę w Rexburg. Wstęp 10 . dla Johna Kos za pomoc przy unixODBC i EasySoft ODBC-ODBC Bridge. Dziękuję pani Barton. Dziękuję Richardowi Litofski za pomoc przy BrowserHawk. Oczywiście. Dla Sama Ockman za umożliwienie wykorzystania w książce rysunku serwera Penguin 1U. Idaho. Dziękuję Michaelowi Justin za pomoc przy konwerterze RTF do HTML firmy Scrooge. należy podziękować całemu zespołowi tworzącemu PHP. który niezmiernie pomógł mi swoimi trafnymi uwagami i informacjami. Na koniec najważniejsze podziękowania należą się mojej żonie i córce za umożliwienie mi zakończenia tej pracy. http://www. Dziękuję Garemu Rogers i Jasonowi Wallin za wskazanie mi PHP i Linuksa w czasie gdy coraz bardziej pogrążałem się wykorzystując ASP i Windows. Dla Martina Evans. Teraz znów możemy wieczorami chodzić skakać na trampolinie. głównego programisty ODBCODBC Bridge. Intechra LLC specjalizuje się w tworzeniu oprogramowania dla WWW. Dziękuję Nickowi Bradbury za pozwolenie wykorzystania informacji i rysunków z edytora TopStyle. Podziękowania dla Ali Ersheid za umożliwienie wykorzystania w książce dokumentacji CyberCash. Wiele osób z tego zespołu pomagało mi w pracy nad książką. mojemu redaktorowi technicznemu. Dziękuję rodzicom i braciom za nieustanne wsparcie nawet. W chwili obecnej Blake zarządza firmą Intechra LLC.net. Można się z nim skontaktować pod adresem blake@intechra. pani Smith i panu Wakefield. którzy mieli ogromny wpływ na moje pisanie. moim nauczycielom angielskiego z liceum. Dziękuję Josephowi Harris (znany jako CDI) za klasę FastTemplate oraz inne fantastyczne narzędzia dostępne na witrynie The Webmasters. gdy w latach osiemdziesiątych spędzałem całe noce na pisaniu programów w Apple Basicu. Blake ma żonę Holy i trzyletnią córkę. Dziękuję Johnowi Steele.net/. firmą konsultingową specjalizującą się w oprogramowaniu.

BSD. więc jest mniej efektywny od dynamicznego modułu jakim jest rozszerzenie ISAPI.net umieszczone jest kilka wariantów tego pakietu. . Najnowsza wersja zawsze znajduje się na górze listy.Rozdział 1. W przypadku Windows zaleca się pobranie binarnej instalacji PHP.php. że ilustrują ogólne zasady instalacji pakietu PHP na większości platform. Najczęściej binarna instalacja PHP jest przeznaczona dla Windows. Wersja CGI powoduje. jeżeli masz już gdzieś zainstalowane PHP i nie chcesz ryzykować niekompatybilności. Ze strony zawierającej pakiety instalacyjne można również pobrać poprzednie wersje programów. Szczegółowe dane na temat określonej platformy można również znaleźć na witrynie www. Jeżeli korzystasz z serwera IIS (Internet Information Server) lub PWS (Personal Web Server) zalecane jest użycie modułu ISAPI. opisany zostanie również taki przypadek. Binarna instalacja dla Windows W PHP prawie wszystkie operacje można wykonać na kilka sposobów. dokumentację i narzędzia pomocnicze. jak również wersję ISAPI. że PHP jest uruchamiany za każdym odwołaniem do strony. Są to często spotykane konfiguracje serwerów WWW i są one na tyle różne. ale podane informacje są wystarczająco uniwersalne i mogą być wykorzystane przy konfigurowaniu środowiska pracy na innych platformach. Solaris itp.net. Na witrynie www. Ponieważ pakiet PHP może działać na wielu serwerach WWW i systemach operacyjnych. W przypadku serwerów uniksowych zaleca się pobranie pakietu zawierającego kompletny kod źródłowy i przeprowadzenie samodzielnej kompilacji. Platformy uniksowe to między innymi Linux. Poprzednie wersje mogą być potrzebne. Instalacja binarna dla Windows zawiera zarówno wersję CGI (Common Gateway Interface) PHP.php. Ponieważ jednak niektóre dystrybucje Uniksa zawierają binarną dystrybucję PHP. Instalowanie wersji binarnej Po pobraniu binarnej dystrybucji PHP. W rozdziale tym opisane zostaną szczegółowo Apache dla Linuksa oraz IIS dla Windows NT. Pobieranie PHP Pierwszym krokiem do rozpoczęcia pracy z PHP jest zaopatrzenie się w kopię interpretera PHP. Moduł ISAPI jest również ze swojej natury bezpieczniejszy od programu CGI. w rozdziale tym znajdą się szczegółowe opisy instalacji na jedynie kilku platformach. Kompilacja i instalowanie PHP Wstęp Zanim rozpoczniemy naukę języka PHP. należy go poprawnie zainstalować i skonfigurować w używanym środowisku interpreter PHP. instalacja jest banalna.

Dodatkowo można skopiować do katalogu systemowego inne pliki . Opcja ta pozwala na dodawanie i edycję skojarzeń.dll do katalogu systemowego Windows (zwykle \windows\system w Windows 95 lub \winnt\system32 w Windows NT).2.3. Uruchamianie aplikacji konfigurującej IIS Po uruchomieniu konsoli Menedżer usług internetowych należy kliknąć prawym przyciskiem myszy na węźle serwera WWW (prawdopodobnie zatytułowany Domyślna witryna sieci Web) i wybrać Właściwości. PWS lub innego serwera WWW obsługującego moduły ISAPI. ale nie jest to konieczne do ich użycia. aby korzystał z modułu ISAPI do obsługi plików php. znajduje jest rozwinięte menu pokazujące położenie tego programu w Windows NT.1.dll i msvcrt. Na rysunku 1.1. Rysunek 1. Na rysunku 1. Są to współdzielone biblioteki niezbędne do prawidłowej pracy każdej wersji PHP dla Windows.dll. Następnie w oknie Właściwości należy przejść na zakładkę Katalog macierzysty i kliknąć przycisk Konfiguracja. należy skopiować pliki php4ts.2. najlepszym rozwiązaniem będzie użycie PHP w postaci modułu ISAPI. Rozdział 1 – Kompilacja i instalowanie PHP 12 . Rysunek 1. Aby zainstalować taką wersję. Konfigurowanie IIS Teraz należy kliknąć przycisk Dodaj i wprowadzić potrzebne informacje. Następnie należy tak skonfigurować IIS lub PWS. tak jak jest to pokazane na rysunku 1.Instalowanie PHP w postaci modułu ISAPI Jeżeli korzystasz z serwera IIS. pokazany jest proces dodawania mapowania rozszerzenia phtml do modułu ISAPI PHP. Serwer IIS można konfigurować za pomocą konsoli konfiguracji zainstalowanej w menu Option Pack.

?> </body> </html> 13 PHP – Kompendium wiedzy . Rysunek 1. Jest to przydatne przy testowaniu różnic pomiędzy wersjami 3 i 4 PHP.Rysunek 1. Dodawanie mapowania dla rozszerzenia w IIS Po dodaniu mapowania zmiany są od razu widoczne w oknie dialogowym Konfiguracja aplikacji.1. lub uruchamiając z linii poleceń następujące polecenia: net stop iisadmin net start w3svc Po uruchomieniu serwera należy go przetestować tworząc prosty plik testowy. i otwierając go poprzez twój serwer. Na rysunku widać mapowania dla PHP3.4. na przykład taki. Można to zrobić przy użyciu modułu Usługi w Panelu sterowania.4. Testowy skrypt PHP <html> <head> <title> phpinfo() </title> </head> <body> <?php phpinho(). Jeżeli wszystko jest skonfigurowane poprawnie. Na rysunku 1. Wydruk 1. pokazana jest konfiguracja mojego serwera WWW.3. jak pokazany na wydruku 1. Czasami może być pożyteczne skojarzenie niektórych rozszerzeń z modułem ISAPI a niektórych z programem CGI.1. powinieneś zobaczyć ekran z informacjami na temat instalacji PHP. Mapowanie rozszerzeń PHP Po zakończeniu konfiguracji należy ponownie uruchomić serwer WWW. dla PHP4 jako CGI oraz PHP4 jako ISAPI.

php. Zaletą użycia plików RPM jest łatwość instalacji.: Action application/x-httpd-php /cgi-bin/php Dyrektywa Action definiuje typ pliku powodujący uruchomienie PHP po otrzymaniu żądania ściągnięcia strony z serwera WWW. czy PHP będzie działało jako program CGI czy w postaci modułu.net/manual/config-apache-nt. Serwer IIS lub PWS wysyła parametry do pliku wykonywalnego CGI. aby korzystał z zainstalowanych właśnie plików binarnych PHP. Zakładając.inc jako pliki typu application/x-httpd-php. Dla większości użytkowników katalogi te są prawidłowe.php. aby Apache załadował moduł PHP: LoadModule php4_module libexec/libphp4. Po instalacji należy ręcznie skonfigurować serwer WWW tak. . Zamiast wybierać bibliotekę . przedstawiony na wydruku 1.exe.php. problemem dla początkujących może być nawet wybór właściwego pliku.net. Jest to pokazane na rysunku 1. należy wprowadzić nieco inne zmiany do pliku konfiguracji httpd. Do przetwarzania tego typu plików wykorzystywane jest PHP. Niektórzy dostawcy.rpm>.conf. możesz go zainstalować wydając polecenie rpm -i <plikrpm. Poniżej przedstawimy sposób konfiguracji Apache. znalezienie gotowej wersji działającej na określonym Rozdział 1 – Kompilacja i instalowanie PHP 14 . dla rozszerzenia . Trzeba utworzyć skojarzenie pomiędzy rozszerzeniem pliku a wewnętrznym typem stosowanym przez serwer. Inne serwery WWW wymagają przeprowadzenia podobnych czynności. różnice występują jedynie przy mapowaniu rozszerzeń. należy wybrać plik php. że masz zainstalowane PHP w postaci modułu Apache.html. Instalacja taka jest wykonana w formie plików RPM (Red Hat Package Manager).phtml AddType application/x-httpd-php . Następna część rozdziału opisuje użycie PHP jako CGI.phtml i . kolejnym krokiem będzie modyfikacja pliku konfiguracyjnego httpd.Trzeba pamiętać. należy przeprowadzić instalację PHP jako CGI. Instalacja jest bardzo podobna do tej przedstawionej powyżej.inc Dyrektywy te powodują. Wadą jest to. aby zaczęły działać nowe ustawienia. Inne instalacje binarne Niektóre instalacje Uniksa posiadają instalację binarną PHP zintegrowaną z instalacją serwera WWW.php AddType application/x-httpd-php . że nie powinien być stosowany w środowisku produkcyjnym.conf tak. Robi się to dodając do pliku konfiguracyjnego następujące linie: AddType application/x-httpd-php . więc oprócz nazwy pliku wykonywalnego należy podać opcje linii poleceń %s %s. że w celu zapewnienia odpowiedniej stabilności powinna być użyta wersja CGI.dll ISAPI. Różne serwery WWW mają różne metody określenia mapowania rozszerzeń. że w pakiecie instalacyjnym PHP znajduje się uwaga na temat stanu modułu ISAPI która ostrzega. Poza tym w pliku RPM nie zawsze są ustawione wszystkie potrzebne opcje konfiguracji. ale może ona sprawiać problemy. Z powodu istnienia wielu wariantów Uniksów. Po wprowadzeniu zmian należy ponownie uruchomić serwer WWW. Oczywiście należy podać właściwą ścieżkę do pliku wykonywalnego. ale odwołuje się do programu w postaci pliku wykonywalnego. że z powodu wielu możliwych wariantów platform dla Uniksa. Powoduje to zainstalowanie plików binarnych do katalogów określonych przez twórcę pliku RPM. pierwszy krok konfiguracji jest zawsze taki sam. niezbędne do prawidłowego działania programu. Jeżeli masz plik RPM z PHP. Niezależnie od tego. Binarna dystrybucja PHP ułatwia szybkie rozpoczęcie pracy z PHP w Uniksach. Dyrektywa konfiguracji jest podobna do poprzedniej.so Jeżeli zainstalowana została wersja CGI. Sugeruje się. Użycie PHP jako CGI Jeżeli nie masz zainstalowanego serwera WWW obsługującego moduły ISAPI lub istnieją inne powody wyboru wersji CGI. Do Apache dla Windows istnieje świetny podręcznik dostępny pod adresem www. udostępniają również binarną instalację na swoich witrynach. na przykład Red Hat. ponieważ plik RPM zawiera gotową do użycia odpowiednio skompilowaną wersję programu. że Apache uważa wszystkie pliki z rozszerzeniami .1.php4. Serwer Apache można zrestartować za pomocą polecenia: /ścieżka/do/apachectl restart Aby przetestować konfigurację można wczytać za pomocą przeglądarki skrypt testowy. Zasoby sieci na temat instalacji PHP na różnych serwerach WWW dla Windows można odszukać za pomocą wyszukiwarki umieszczonej na witrynie www. Nie trzeba martwić się szczegółami procesu kompilacji.4.

W wielu przypadkach będzie to bardziej czasochłonne niż ściągnięcie kodu źródłowego. ponieważ polecenia w nich umieszczone są używane jedynie do wyczyszczenia poprzedniej konfiguracji i pozostałości po poprzedniej kompilacji. występują problemy z bezpieczeństwem. może okazać się.cache make clean . Kompilowanie PHP w Uniksach W tej części rozdziału przedstawione zostaną informacje na temat kompilowania PHP na platformie Unix. usunięcie plików wynikowych a następnie skompilowanie PHP do postaci CGI. Kompilacja modułu CGI Kompilacja PHP do postaci wykonywalnego modułu CGI jest najprostszą metodą kompilacji i dobrym rozwiązaniem./configure make make install Wykonanie tych operacji spowoduje usunięcie podręcznych danych konfiguracji. jako najlepsze rozwiązanie dla większości aplikacji. aby kompilacja przebiegła prawidłowo.php. Kompilowanie PHP Jeżeli chcesz skorzystać z elastyczności własnej instalacji PHP lub jeżeli przewidujesz dodawanie własnych rozszerzeń do języka PHP (opisane w rozdziale 11. że Unix określa całą rodzinę systemów. Poniżej przedstawiona jest kompletna lista operacji jakie należy wykonać. dla której nie ma instalacji binarnej. że wykonanie czyszczenia jest niezbędne. Więcej informacji na temat określonej platformy można odszukać za pomocą wyszukiwarki dostępnej na witrynie www.: Linux. Jeżeli pracujesz na platformie. możesz nie mieć innego wyboru jak tylko samodzielnie kompilować PHP. Druga i trzecia linia jest nieobowiązkowa. Na koniec trzeba zainstalować gotowe PHP i zrestartować serwer WWW. choć czasami ich wykonanie jest niezbędne. jeżeli nigdy wcześniej nie kompilowałeś programów dla Uniksa. na którym wykonywana jest kompilacja. nie są one potrzebne. BSD. cd <php_dir> rm config. Informacje na temat skryptu konfiguracyjnego są przedstawione w części poświęconej kompilowaniu modułu CGI. Przy okazji możemy zarekomendować korzystanie z PHP w postaci dynamicznie ładowanego modułu. Należy pamiętać. Oczywiście systemy te różnią się między sobą. przeprowadzenie całej konfiguracji i kompilacji może zająć dosyć dużo czasu. ale wiele z kroków niezbędnych do kompilacji PHP jest identycznych. Proces ten zostanie opisany w kolejnej części rozdziału. np. 15 PHP – Kompendium wiedzy . można skompilować PHP jako plik wykonywalny. W zależności od szybkości komputera. który ustawia opcje kompilacji. W kolejnych częściach zakładamy. Proces kompilacji jest właściwie taki sam dla każdego typu pliku wynikowego. W prawdziwej kompilacji do skryptu konfiguracyjnego dołącza się opcje określające atrybuty PHP. należy odszukać w dokumentacji PHP i serwera WWW szczegóły postępowania.net. Dla każdej platformy istnieje kilka sposobów kompilacji PHP. przytoczona jedynie jako przykład. skompilowanie i zainstalowanie PHP. Solaris i inne. Jeżeli nie korzystasz z Apache. jako moduł ładowany dynamicznie lub jako statyczną bibliotekę. „Ponowne wykorzystanie kodu”). Następnie przy pomocy narzędzia make przeprowadza się kompilację. Jeżeli wprowadzane są poważne zmiany w konfiguracji lub zmieniasz typ kompilacji z CGI na inny.systemie może być czasami trudne. Jest to najprostsza metoda kompilacji. każda zmiana konfiguracji wymaga większego nakładu pracy. Jeżeli PHP zostanie statycznie dołączony do Apache. więc zaleca się przeczytanie tego fragmentu jako wprowadzenia. Niektóre z nich nie są obowiązkowe. musisz dokładnie poznać proces kompilowania PHP. Można również nie korzystać z tych opcji przy kompilacji PHP. W przypadku modułu CGI. Na początku trzeba uruchomić skrypt configure. Jeżeli wcześniej nie konfigurowałeś ani nie kompilowałeś PHP. Odwołanie do <php_dir> powinno być zamienione na nazwę twojego katalogu bazowego PHP. że ściągnąłeś już źródła PHP i rozpakowałeś je. Jeżeli serwerem WWW jest Apache. Operacje opcjonalne są zaznaczone czcionką pochyłą.

Wszyscy. Po wykonaniu wszystkich podanych poleceń zostanie utworzony nowy plik wykonywalny — php. natomiast pozostałe są standardowymi elementami konfiguracji opisanymi w skorowidzu na końcu książki.2 --enable-ucd-snmp-hack Powyższe wywołanie konfiguracji powoduje dodanie do PHP obsługi Javy. które mogą być dołączone do PHP. że przytoczone polecenia umożliwiają skompilowanie PHP. Później omówimy to zagadnienie dokładniej.6-i586-pc-linuxgnulibc2. więc badanie systemu nie musi być powtarzane przy ponownym uruchomieniu konfiguracji. SNMP (Simple Network Management Protocol) oraz unixODBC. ustawić opcje potrzebne w aplikacji a następnie ponownie skompilować i zainstalować PHP. Jeżeli potrzebujesz obsługi innej bazy danych lub innego rozszerzenia./configure --with-apxs=/www/bin/apxs --with-java --with-cybercash=/home/blake/mck-3. Dodatkowo została dodana opcja -withapxs. X-Powered-By: PHP/4. Nie zostało podane położenie katalogu Javy. Jeżeli w czasie działania skryptu konfiguracyjnego nastąpi awaria. Następnie na podstawie tych danych tworzy specyficzny dla systemu skrypt za pomocą można skompilować kod. W ten sposób upewniamy się. często zdarza się. która powoduje.cache zawierający szczegóły na temat systemu. Trzeba ponownie uruchomić skrypt konfiguracyjny. takie jak możliwość wykorzystywania krótkich znaczników lub obsługa protokołu FTP. że wymagany plik lub narzędzie nie jest odnajdywane lub niewłaściwie skonfigurowane. fin-funcs oraz ucd-snmp-hack.1 --withunixODBC=/usr/local/unixODBC --disable-debug --enabletrack-vars -. udało ci się poprawnie skompilować i zainstalować PHP w postaci CGI. Lista dostępnych opcji jest wyświetlana po wpisaniu: . Oznacza to. Większość opcji konfiguracji wpływających na dostępne funkcje PHP ma postać --enable-FUNKCJA lub -Aby dodać funkcję do PHP należy użyć jednej z poniższych form: Aby usunąć funkcję z PHP. musisz usunąć plik tymczasowy przed kolejnym uruchomieniem skryptu konfiguracyjnego.0. który pozwala na rozpoczęcie nauki języka. Po zakończeniu działania skryptu konfiguracyjnego tworzony jest plik tymczasowy config.0. którzy nigdy nie przeprowadzali takiego procesu powinni wiedzieć. wiele innych. plików i innych danych systemowych. Rozdział 1 – Kompilacja i instalowanie PHP 16 .2. Te własności wymagają zwykle wskazania zewnętrznego pliku i do jego włączania korzysta się z następującego zapisu: --with-PAKIET=/ścieżka/do/pakietu Aby wyłączyć pakiet należy użyć poleceń: --with-PAKIET=no --without-PAKIET Jako przykład przedstawimy następującą konfigurację: .Pozostawienie zapisanych opcji konfiguracji oraz obiektów binarnych spowoduje znaczne skrócenie czasu tworzenia PHP. na przykład obsługa bazy danych Oracle lub Javy. trzeba dodać odpowiednią opcję konfiguracji. Funkcje korzystające ze składni --enable są to zwykle wbudowane opcje PHP. sesji i wiele.).1. że skrypt konfiguracyjny poszukuje w systemie narzędzi. Pożyteczną cechą zestawu domyślnych ustawień jest to. że PHP jest kompilowane do postaci dynamicznie ładowanego modułu Apache a nie jako program typu CGI. że dołączone jest do niego wiele często używanych opcji konfiguracji.2 Content-type: text/html Trzeba zauważyć. Można przetestować poprawność kompilacji za pomocą następującego polecenia: php < /dev/null Jeżeli zobaczysz wynik podobny do poniżej przedstawionego. CyberCash. W przedstawianej konfiguracji wyłączono informacje dla debuggera oraz włączono opcje track-vars. Opcja fin-funcs powoduje dodanie własnego modułu rozszerzeń opisanego w dalszej części książki (rozdział 11. ponieważ została skompilowana z użyciem tylko ustawień domyślnych. Jeżeli wprowadzisz duże zmiany do konfiguracji systemu./configure --help with-PAKIET. które być może będziemy chcieli wykorzystywać w aplikacjach. należy użyć: --enable-FUNKCJA --enable-FUNKCJA=yes --disable-FUNKCJA --enable-FUNKCJA=no Pełna lista opcji konfiguracji znajduje się w skorowidzu na końcu książki. więc skrypt konfiguracyjny użyje domyślnej ścieżki do katalogu z tym pakietem. że zmiany te zostaną wykryte. Pakiety są to zwykle moduły zewnętrzne. że skompilowana właśnie wersja PHP nie posiada funkcji.enable-fin-funcs --withsnmp=/home/blake/ucd-snmp-4. w tym obsługa bazy danych MySQL.

/configure Po zakończeniu działania tego skryptu można zająć się konfigurowaniem i kompilowaniem PHP.php AddType application/x-httpd-php . należy wprowadzić odpowiednie zmiany. cd <php_dir> . W zależności od rozszerzeń jakie zostały wybrane do reprezentowania plików PHP. można znaleźć w dokumentacji na witrynie www. Zakładamy. należy użyć następujących poleceń: cd <apache_dir> . gdzie można zaopatrzyć się w potrzebne pakiety. Teraz należy uruchomić serwer Apache i przy wykorzystaniu skryptu testowego z wydruku 1. Ostatnia dyrektywa powoduje wysłanie wszystkich plików tego typu do pliku wykonywalnego php./configure --with-apache=<apache_dir> make make install Opcja --with-apache powoduje kompilację do postaci statycznej biblioteki oraz pozwala podać katalog z plikami źródłowymi Apache.conf.phtml AddType application/x-httpd-php . Aby Apache prawidłowo przetwarzał pliki PHP należy odpowiednio zmodyfikować plik httpd. Więcej informacji na temat tego. Kompilacja PHP jako statycznie dołączanego modułu Apache Apache pozwala na statyczne dołączanie modułów bezpośrednio do pliku binarnego Apache. I tym razem standardowa konfiguracja wygląda następująco: AddType application/x-httpd-php . Jednak niektóre aplikacje wymagają zastosowania statycznie dołączanego modułu Apache.Wiele z pakietów oprogramowania jakie chcemy dodać do PHP musi być osobno zainstalowane. aby PHP był skompilowany do postaci dynamicznie ładowanego modułu. Aby Apache obsługiwał dynamicznie ładowane moduły należy go przekompilować z następującymi opcjami konfiguracji: cd <apache_dir> make clean . Aby skonfigurować serwer Apache należy dodać następujące dyrektywy do pliku httpd. phtml i inc jako typ application/x-httpd-php. sprawdzić poprawność konfiguracji.inc Action application/x-httpd-php /cgi-bin/php Pierwsze trzy dyrektywy definiują zawartość plików z rozszerzeniami php.conf: AddType application/x-httpd-php . że plik ten jest umieszczony w katalogu cgi-bin serwera WWW. że na dysku jest już katalog z kodem źródłowym Apache. Zakładamy.inc Przedstawiony opis przedstawia jedynie bardzo prostą wersję PHP. Kompilacja PHP do postaci dynamicznie ładowanego modułu Apache Sposób kompilacji PHP do postaci dynamicznie ładowanego modułu Apache nie różni się zbytnio od innych przedstawionych do tej pory metod. opiszemy teraz sposób jego tworzenia.a make make install Dyrektywa prefix może być inna w twoim systemie. ponieważ w przypadku wystąpienia kłopotów z konfiguracją PHP.php. Może być to czasochłonne i frustrujące. Również niektóre moduły rozszerzeń (na przykład Java) wymagają do poprawnej pracy. Apache może również przestać działać. Więcej szczegółów można znaleźć w dokumentacji do Apache.. Dyrektywy te są minimum wymaganym do konfiguracji PHP w Apache. ale ta sama czynność może być zrealizowana jeszcze na kilka sposobów./configure --enable-module=so --enable-rule=SHARED_CORE --prefix=/www make 17 PHP – Kompendium wiedzy .php AddType application/x-httpd-php ./configure --prefix=/www --activate-module=src/modules/php4/libphp4. Przed skonfigurowaniem i skompilowaniem PHP niezbędne jest skonfigurowanie Apache.1. Następnie należy skompilować serwer Apache za pomocą poleceń: cd <apache_dir> . która zawiera jedynie opcje domyślne. W porównaniu z wersją CGI użycie modułu pozwala poprawić wydajność aplikacji oraz zwiększyć bezpieczeństwo systemu. Więcej informacji o zmianie konfiguracji kompilacji PHP znajduje się w części na temat kompilacji wersji CGI. należy skonfigurować serwer WWW do współpracy z nowym programem.phtml AddType application/x-httpd-php . Zaletą tej metody jest możliwość kompilacji PHP bez konieczności równoczesnej kompilacji Apache. Aby skonfigurować Apache. ponieważ wskazuje ona katalog gdzie zostaną zainstalowane pliki zależne od architektury.net. Wadą tej metody jest konieczność powtórnej kompilacji Apache po każdej kompilacji PHP. Po utworzeniu PHP w postaci CGI.

Po skompilowaniu PHP i sprawdzeniu. Dokumentacja zaleca użycie Visual C++ wersja 6.zip Win32 Obsługa BCMath www.net/version4/downloads/num ber.bat. Teraz trzeba Rozdział 1 – Kompilacja i instalowanie PHP 18 . Zostały one opisane w dalszej części rozdziału. aby przetwarzał pliki PHP. ale nie udało mi się tego zrobić. ponieważ bez problemu radzi sobie z plikami . gdzie były dostępne w czasie pisania książki.net/extra/win32build.php. Tak jak w przypadku poprzednich sposobów kompilacji należy prawidłowo skonfigurować Apache. a później uzupełniać potrzebne opcje. Po zapoznaniu się z procesem kompilacji jest już bardzo łatwo testować różne konfiguracje i dodawać niestandardowe rozszerzenia. jeżeli PHP był już kompilowany w innej konfiguracji. W poniższym opisie zakładamy użycie Visual C++. takie jak gcc. Problem stanowiły prekompilowane pliki lib. Inne potrzebne pliki są integralną częścią dystrybucji PHP. ponieważ Microsoft i Borland korzystają z różnych formatów tych plików. Również inne programy posiadają takie możliwości. Próbowałem sprawdzić. Jeżeli pracujesz w Windows 95. należy skompilować PHP w następujący sposób: cd <php_dir> make clean rm config. czy można użyć pakietu Borland C++ Builder. Podsumowanie kompilacji PHP w systemach Unix Celem tego fragmentu książki nie było podawanie szczegółowego i wyczerpującego opisu wszystkich możliwych opcji konfiguracji.gz Zastępnik pliku resolv. czy działa z Apache.php. trzeba dodać tą zmienną ręcznie do pliku autoexec./configure --with-apxs=/www/bin/apxs (pozostałe opcje) make make install Polecenia porządkujące są zalecane.net/download. można zapoznać się z opcjami konfiguracji.php. co spowoduje ponowne wygenerowanie prawidłowo skonfigurowanego skryptu.zip Pakiet Cygwin zawiera popularne narzędzia GNU. Jeżeli wystąpią kłopoty ze skryptem apxs można powtórnie wykonać przedstawione polecenia. Dodatkowe pliki pomocnicze i ich adresy w Sieci Program Położenie Kod źródłowy PHP www.php Pakiet Cygwin http://sources. który jest używany do utworzenia wersji dla Uniksa. Tabela 1.redhat.make install Oprócz kompilacji Apache przedstawione polecenia przygotowują skrypt apxs. który jest niezbędny do kompilacji dynamicznego modułu PHP. ale pokazanie podstawowych metod kompilowania PHP do różnych postaci. Ja używam programu Winzip.con/cygwin/ Narzędzia do kompilacji PHP dla www. ale trzeba wcześniej przekompilować wszystkie biblioteki. Tabela 1.php. Po skompilowaniu Apache z obsługą dynamicznie ładowanych modułów.lib www. Ścieżka podana w dyrektywie konfiguracji --with-apxs powinna być pełną ścieżką do skryptu apxs na serwerze.gz. Na początku należy zainstalować narzędzia Cygwin. Potrzebny jest również program do rozpakowywania plików. Trzeba ręcznie dodać zmienną środowiska wskazując na położenie plików Cygwin. Jeżeli nie kompilowałeś wcześniej PHP. powinieneś na początku spróbować skompilować podstawową konfigurację. Prawdopodobnie można zastosować kompilator Borlanda. Po zmodyfikowaniu konfiguracji należy uruchomić Apache i wywołać skrypt testowy. Kompilowanie PHP w środowisku Windows Kompilowanie PHP dla Windows jest na początku bardziej skomplikowanym procesem niż kompilacja PHP dla Uniksa. zawiera wszystkie dodatkowe programy oraz adresy w Internecie. make i bison. Niektóre z tych programów są wykorzystywane w procesie kompilacji.1. choć wersja 5 również powinna działać. więc trzeba wcześniej zainstalować ten pakiet.tar.tar. Przed rozpoczęciem pracy należy się zaopatrzyć w kilka programów i plików pomocniczych. W Windows NT należy kliknąć prawym przyciskiem myszy ikonę Mój komputer i wybrać z menu Właściwości. Kod źródłowy PHP jest identyczny jak ten.cache .net/version4/downloads/bind lib_w32.1. które można ustawiać bez potrzeby ponownej kompilacji.

Zmienna nazywa się CYGWIN a jej wartością jest ścieżka do katalogu. Naciśnij klawisz F7.5. gdzie zainstalowane są narzędzia Cygwin. Po zakończeniu kompilacji należy skopiować plik resolv. Rysunek 1.lib. tak jak jest to pokazane na rysunku 1.5. Rysunek 1. Teraz z listy rozwijalnej wybierz Include files i dodaj katalog z win32build\include (rysunek 1. Najpierw utwórz nowy katalog i rozpakuj do niego pliki z archiwum bindlib_w32.6.) i przy użyciu listy rozwijalnej opisanej Show directories for. Teraz wybierz zakładkę Directories (rysunek 1. wybierz opcję Executable files i dodaj katalog z plikami Cygwin.tar. Skopiuj rozpakowane pliki number.lib do katalogu win32build\lib.zip.gz za pomocą zewnętrznego programu lub narzędzia tar z pakietu Cygwin. Z menu Build wybierz Set Active Project Configuration i wybierz wersję handlową biblioteki lub wersję do uruchamiania.dsp.zip.6. Ustawienie zmiennej środowiskowej CYGWIN Następnie utwórz katalog i rozpakuj do niego zawartość pliku win32build. 19 PHP – Kompendium wiedzy . Na koniec wybierz Library files i dodaj katalog win32build\lib.h do katalogu ext/bcmath w katalogu z kodem źródłowym PHP.kliknąć zakładkę Środowisko i dodać nową zmienną. Od tej pory kompilator Visual C++ będzie mógł korzystać z zainstalowanych narzędzi i plików.6.c i number.). Następnie rozpakuj źródła PHP i plik number. Ustawienie katalogów w Visual C++ Kolejnym krokiem będzie skompilowanie nowej wersji pliku resolv. Uruchom Visual C++ i wybierz Options z menu Tools. W Visual C++ otwórz projekt bindlib. aby skompilować projekt.

Dokładna wiedza na temat procesu kompilacji PHP jest również niezbędna.2. Platformy PHP i położenie pliku php.ini jest odczytywany za każdym uruchomieniem programu CGI.ini Platforma Położenie pliku php.ini-dist i php. W tabeli 1.ini i ponowne uruchomienie serwera WWW.Jeżeli wykonałeś wszystkie opisane wcześniej czynności. tak jak jest to pokazane na rysunku 1. ale gdy wszystkie potrzebne dodatki zostaną odpowiednio skonfigurowane. cała reszta jest tak samo prosta jak w Uniksie. jesteś gotowy do kompilacji PHP. spełniających precyzyjnie potrzeby konkretnej witryny.dsp. należy do niego wprowadzić odpowiednie zmiany. ponieważ plik php. jak w standardowych plikach ini systemu Windows. Pierwszym krokiem będzie skopiowanie i zmiana nazwy pliku. Najłatwiej jest rozpocząć od skompilowania wersji CGI wybierając wersję handlową lub wersję z danymi dla debuggera. Opcje te mają następujące wartości domyślne: Rozdział 1 – Kompilacja i instalowanie PHP 20 . Plik powinien być nazwany php. najtrudniejszą częścią było wstępne przygotowanie środowiska.ini-optimized.ini-dist. Aby wprowadzić zmiany najczęściej zmienia się plik php.ini. ale istnieją również inne mechanizmy zmiany opcji. Jak wspomniałem wcześniej. powinieneś rozpocząć do podstawowych ustawień z pliku php.7.ini Windows Katalog <windows> zwykle \windows w Windows 95 i \winnt w Windows NT Unix Można to sprawdzić za pomocą funkcji phpinfo(). Konfigurowanie PHP Niezależnie od platformy na której działa PHP. zamieszczone są podstawowe warianty. Gdy wszystko jest już gotowe. Wykorzystuje się w tym celu plik php. ale zwykle jest to /usr/local/lib. Plik ten jest dostarczany w dystrybucji PHP jako php. Zagadnienie to zostało opisane w rozdziale 11. Projekt ten zawiera kilka konfiguracji.ini i ponownie uruchamia Apache. sposób jego konfigurowania jest taki sam. Wybór konfiguracji dla wersji CGI Skompiluj projekt i jeżeli wszystko pójdzie dobrze posiadasz już własną wersję PHP. Rysunek 1.ini jest podzielony na sekcje.ini Zalecaną metodą zmiany konfiguracji jest modyfikacja pliku php. Jeżeli korzystasz z PHP w postaci programu CGI nie musisz restartować serwera. Mechanizmy te opisane zostaną w późniejszej części rozdziału. Podsumowanie kompilacji PHP Kompilowanie wersji PHP dla Windows jest za pierwszym razem dużo trudniejsze od wersji dla Uniksa. Jeżeli nie znasz dobrze opcji konfiguracji. korzystając z odpowiednich opcji konfiguracji. rozpoczynające się od linii [nazwa_sekcji] podobnie. znajdujący się w podkatalogu win32 katalogu z kodem źródłowym PHP. wystarczy wybrać odpowiednią konfigurację dla kompilacji i ponownie skompilować projekt. Uruchom Visual C++ i otwórz plik projektu php4ts.7. Plik php.2.ini i skopiowany do katalogu zależnego od używanej platformy. aby móc tworzyć rozszerzenia PHP. Korzystanie z pliku php. jest już proste. Tabela 1. nazwę opcji oraz wartość. Po umieszczeniu pliku konfiguracyjnego w odpowiednim katalogu. Plik ten zawiera obszerne komentarze opisujące przeznaczenie sekcji i opcji konfiguracji. W pozostałej części książki czasami będą przytaczane opcje niezbędne do uruchomienia przykładów. Jeżeli potrzebujesz wersji PHP jako ISAPI lub NSAPI. Gdy poznałeś już proces kompilowania PHP dla obu platform możesz tworzyć wysoce specjalizowane wersje PHP. Zwykle przykład taki zawiera nazwę sekcji. Dla przykładu można zmienić sposób raportowania błędów przez PHP.

conf. Druga metoda jest wykorzystywana.1. aby serwer WWW mógł zapisać w nim dane. Zapisuj błędy do pliku błędów syslog . ponieważ plik .1> ServerAdmin admin@server. będą zapisywane w pliku /tmp/php_log. Należy użyć dyrektyw konfiguracji php_value i php_flag do ustawienia potrzebnych opcji. używają one konfiguracji określonej przez plik php. że zostanie ustawiony sposób raportowania błędów dla serwera wirtualnego o nazwie www. Na przykład. Zwykle znajduje się tam sporo komentarzy opisujących możliwe wartości danej opcji. nie zostaną tu przedstawione wszystkie możliwe opcje. Z powodu dużej ilości opcji konfiguracji. Pokaż wszystkie błędy oprócz informacji On . należy użyć następujących dyrektyw Apache: <VirtualHost 192. Zapisuj błędy do dziennika systemowego Pierwsza opcja powoduje generowanie komunikatów dla wszystkich typów błędów poza typem E_NOTICE.ini. można zmienić sposób raportowania błędów dla jednego katalogu na czas uruchamiania skryptów w nim się znajdujących. W tym celu należy stworzyć plik .conf. Jeżeli musisz zmienić konfigurację PHP a nie masz dostępu do pliku php. jeżeli chcemy mieć różne ustawienia PHP dla różnych serwerów wirtualnych lub różnych katalogów. a zamiast tego błędy będą zapisywane do określonego pliku. Następna linia powoduje wstawianie komunikatów błędów do wynikowego kodu HTML. Aby zmienić opcję konfiguracji. Jest to jednak najmniej zalecana metoda. W przeciwnym wypadku efekty mogą być niespodziewane.conf spowoduje. możesz wykorzystać pliki Apache . w tym informacje. Na przykład.ini ani do httpd. Zapisuj błędy do pliku /tmp/php_log Taka konfiguracja powoduje.testserver. Oczywiście plik ten powinien mieć odpowiednio ustawione prawa dostępu. witryna jest umieszczona na dzierżawionym serwerze zewnętrznej firmy. Inne metody zmiany konfiguracji PHP Istnieją dwie metody zmiany konfiguracji PHP bez konieczności modyfikacji pliku php. Pełna lista znajduje się w skorowidzu na końcu książki. że wszystkie komunikaty błędów. jeżeli określony katalog musi mieć inne ustawienia konfiguracji niż reszta witryny. W obu tych przypadkach sposób zmiany konfiguracji PHP jest tak sam. że w instalacji produkcyjnej nie chcemy wyświetlać błędów. że konfigurując PHP poprzez dyrektywy Apache nie można używać jako wartości żadnych stałych PHP. Pozwala to na posiadanie różnych konfiguracji PHP dla różnych serwerów wirtualnych lub katalogów. Tutaj przedstawione zostaną jedynie ogólne sposoby wykorzystywania tych opcji. Można to zrealizować zmieniając konfigurację w następujący sposób: error_reporting display_errors log_errors error_log = = = = E_ALL .error_reporting display_errors log_errors error_log = = = = E_ALL & ~E_NOTICE .1. należy otworzyć w edytorze plik php. Jest to również użyteczne.ini i odszukać opcję.conf lub do pliku . przedstawiony został schemat możliwości konfiguracji środowiska PHP. Jeżeli na tej samej maszynie istnieją inne serwery wirtualne.htaccess. On .ini i httpd. Zapisuj błędy /tmp/php_log .testserver. Wypisuj błędy (jako część wynikowego HTML) Off .htaccess jest wczytywany i analizowany za każdym odwołaniem do stron znajdujących się w tym katalogu. Pokaż wszystkie błędy Off .8. Jest to częsta sytuacja. Następne dwa wiersze powodują zapisywanie komunikatów błędów w pliku. Jest o jedyny sposób poprawnego ustawienia wartości. Pierwszym sposobem jest wstawienie tych opcji do pliku konfiguracyjnego Apache httpd. gdy nie jest możliwy dostęp do plików php.htaccess z następującą zawartością: php_value error_reporting 2039 php_flag log_errors off php_flag display_errors on Należy zauważyć.com php_value error_reporting 2047 php_flag display_errors off php_flag log_errors on php_value error_log /tmp/php_log </VirtualHost> Umieszczenie tych ustawień w pliku httpd.com. Powoduje to znaczne spowolnienie serwera WWW. że w obu przykładowych plikach konfiguracyjnych Apache wartość zmiennej konfiguracji error_reporting jest ustawiana za pomocą wartości numerycznej a nie stałej. 21 PHP – Kompendium wiedzy .htaccess. Aby zilustrować potęgę dostępnego mechanizmu konfiguracji na rysunku 1. aby ustawić poprzednio opisane opcje konfigurujące sposób raportowania błędów. Należy pamiętać.ini. Załóżmy. Pierwsza metoda jest użyteczna.net DocumentRoot /www/hosts/wwwprojects/ ServerName www.

że PHP posiada wiele własnych funkcji zmieniających ustawienia konfiguracji. Przykładami takich funkcji są error_reporting() oraz set_time_limit(). Z powodu elastyczności i dużej ilości obsługiwanych platform niemożliwe jest szczegółowe opisanie wszystkich dostępnych konfiguracji.8. Korzystając jednak z informacji umieszczonych w tej książce.php.ini oraz plików konfiguracyjnych Apache Podsumowanie W tym rozdziale przedstawiono kilka informacji niezbędnych do rozpoczęcia pracy z PHP. Trzeba zauważyć. Więcej informacji na temat tych funkcji można znaleźć w skorowidzu na końcu książki. oraz na witrynie www. Rozdział 1 – Kompilacja i instalowanie PHP 22 .Rysunek 1.net powinieneś być w stanie zainstalować i skonfigurować PHP na twojej platformie. Elastyczność konfiguracji z zastosowaniem php.

Rozdział 2. Język
Wstęp
W rozdziale tym znajduje się zwięzły opis języka programowania PHP. Jak wspomniałem we wstępie do książki nie jest moją intencją poświęcać zbyt wiele czasu na omawianiu ogólnych koncepcji programowania. W tym rozdziale znajduje się opis składni podstawowych konstrukcji programowania, na przykład zmiennych, stałych i funkcji. Przykłady przytoczone w tym rozdziale nie pokazują najlepszych technik programowania a jedynie ilustrują składnię i użycie omawianych elementów. Pełny opis języka znajduje się w dokumentacji języka dostępnej na witrynie http://www.php.net.

Ogólne informacje na temat składni
Ponieważ PHP jest zwykle wbudowywany w kod HTML istnieją specjalne znaczniki ograniczające bloki PHP. Użycie tych znaczników jest nazywane czasem wyjściem z trybu HTML. Wydruk 2.1. Sposoby oznaczania bloku kodu PHP w HTML
<? echo "użycie krótkich znaczników PHP do wyjścia z trybu HTML<br>"; ?> <?php echo "wyjście przy użyciu pełnych znaczników PHP<br>"; ?> <script language="php"> echo "niektóre edytory HTML nie obsługują instrukcji przetwarzania<br>"; </script> <% echo "można stosować również znaczniki w stylu ASP<br>"; %>

Pierwsza metoda oznaczania bloków PHP jest dostępna jedynie wtedy, gdy uaktywnione są krótkie znaczniki. Aby to zrobić należy użyć funkcji short_tags(), włączyć w pliku konfiguracyjnym opcję short_tag_open lub skompilować PHP z opcją -enable-short-tags. Znaczniki w stylu ASP są dostępne jedynie wtedy, gdy uaktywniona jest opcja konfiguracji asp_tags. Więcej informacji na temat kompilowania i konfiguracji PHP znajduje się w rozdziałach „Kompilacja i instalowanie PHP” oraz dodatku D - „Opcje konfiguracji”. PHP jest syntaktycznie bardzo podobny do C. Na przykład, instrukcje są oddzielone średnikiem. Znacznik ?> jest niejawnym końcem instrukcji, więc poniższe przykłady są poprawne składniowo: Wydruk 2.2. Koniec instrukcji
<?php echo "Test, test...<br>"; ?> <?php echo "Test, test...<br>" ?>

Komentarze w PHP można oznaczać symbolami komentarzy pochodzącymi z C, C++ lub stosowanych w skryptach Uniksa. Komentarze jednoliniowe komentują tekst do końca linii lub do końca bieżącego bloku PHP w zależności od tego, co będzie pierwsze. Nie można zagłębiać wielowierszowych komentarzy w stylu C. Wydruk 2.3. Komentarze
<?php echo "Witaj świecie!<br>"; // To jest jednowierszowy komentarz w stylu C++ /* To jest wielowierszowy blok komentarza */ echo "Witamy ponownie.<br>"; # To jest komentarz w stylu skryptów Uniksa ?> <?php /* Poniższa linia spowoduje wypisanie "To wyświetli nic." */ ?> To wyświetli <?php # echo "coś"; ?> nic.<br> <?php

/* echo "A tutaj mamy problem."; /* Komentarz ten jest nieprawidłowy */ */ ?>

Typy
PHP posiada następujące typy: liczby zmiennoprzecinkowe, liczby całkowite, ciągi, tablice i obiekty. Typ zmiennej jest ustalany w oparciu o kontekst w jakim jest użyta zmienna i nie jest on jawnie ustalany przez programistę. Jest to ważna cecha o której należy pamiętać podczas programowania aplikacji PHP, ponieważ niejawna konwersja typów może spowodować trudne do odnalezienia błędy. Na przykład poniższa instrukcja jest prawidłowa i spowoduje wyświetlenie liczby 9:
print( 3* "3 małe świnki");

Aby można było zapanować nad typami, PHP posiada funkcje gettype() i settype() oraz kilka funkcji przeznaczonych dla określonych typów, na przykład is_integer() lub is_array(). W skorowidzu funkcji na końcu książki znajduje się pełne omówienie tych funkcji. Teraz zostanie opisany każdy z typów zmiennych (oprócz obiektów). Obiekty PHP zostaną opisane w dalszej części rozdziału.

Liczby — całkowite i zmiennoprzecinkowe
Liczby całkowite można podawać używając notacji dziesiętnej, ósemkowej i szesnastkowej. Liczby zmiennoprzecinkowe można podawać używając notacji zwykłej lub zapisu naukowego. Na poniższym wydruku pokazana jest składnia PHP dla wszystkich tych notacji. Wydruk 2.4. Reprezentacja liczb
<?php $int1 = 523; // liczba dziesiętna $int2 = -523; // dziesiętna ujemna $int3 = 01013; // ósemkowa reprezentacja liczby 523 $int4 = 0x20B; // szesnastkowa reprezentacja liczby 523 $float1 = 523.197; // zwykły zapis liczby zmiennoprzecinkowej $float2 = 5.23197e2; // notacja naukowa liczby zmiennoprzecinkowej /* Wypisanie wszystkich liczb. Wyświetla "523, -523, 523, 523, 523.197, 523.197". */ print( "$int1, $int2, $int3, $int4, $float1, $float2<br>" ); ?>

Ciągi
Ciągi w PHP są ograniczane apostrofami (') lub cudzysłowami ("). Zapisy te różnią się sposobem interpretacji ciągu. Jeżeli ciąg jest otoczony cudzysłowami, zmienne zapisane w ciągu zostają zamienione na ich wartości. Aby zapisać znaki specjalne w ciągach otoczonych cudzysłowami, należy użyć znaku lewego ukośnika (\), tak jak zostało to pokazane w tabeli 2.1. Tabela 2.1. Znaki specjalne w ciągach otoczonych cudzysłowami Sekwencja znaków Znaczenie \n nowa linia \r powrót karetki (CR) \t tabulacja \\ lewy ukośnik \" cudzysłów \$ znak dolara W ciągach otoczonych apostrofami zmienne nie są zastępowane. Jedynymi dopuszczalnymi sekwencjami sterującymi są te oznaczające lewy ukośnik (\\) i apostrof (\'). Sekwencje te pozwalają na wpisanie do ciągu znaku apostrofu i lewego ukośnika. Ciągi mogą być łączone przy użyciu operatora kropki (.). Dokładniej jest to opisane w części rozdziału na temat operatorów. Podobnie jak w języku C, mamy dostęp do poszczególnych znaków ciągu, traktując go jak tablicę znaków. Wydruk 2.5. Przykład operacji na ciągach
<?php

Rozdział 2 – Język

24

$aStr1 print( $aStr2 print( $aStr3

= "To jest zwykły ciąg."; "$aStr1<br>" ); = "Thatcher"; "$aStr2<br>" ); = "Nazywam się $aStr2"; // $aStr3 = "Nazywam się Thatcher" print( "$aStr3<br>" ); $aStr4 = "Nazywam się \$aStr2"; // $aStr4 = "Nazywam się $aStr2" print( "$aStr4<br>" ); $aStr5 = 'Nie rozwijaj \'$aStr2\''; // $aStr5 = "Nie rozwijaj '$aStr2'" print( "$aStr5<br>" ); // wypisuje "Nazywam się Thatcher i Nazywam się $aStr2" print( "$aStr3" . " i " . "$aStr4" ); ?>

Z powodu ulotnej natury typów w PHP, zmienne mogą zmieniać swój typ w zależności od kontekstu w jakim występują. Liczby mogą być konwertowane niejawnie na ciągi, jeżeli zostaną użyte jako argument operatora operującego na ciągach. Ciągi mogą również zostać skonwertowane na liczby, jeżeli będą użyte w wyrażeniach matematycznych. Jeżeli PHP próbuje skonwertować ciąg na liczbę, korzysta z następujących zasad: • Jeżeli ciąg zaczyna się od danych numerycznych, zostaną one skonwertowane na liczbę. • Jeżeli ciąg nie zaczyna się prawidłowymi danymi liczbowymi, wartością ciągu będzie zero (0). • Jeżeli dane numeryczne zawierają jeden ze znaków .,e lub E, wartość będzie liczbą zmiennoprzecinkową a w przeciwnym przypadku liczbą całkowitą. Prawidłowymi danymi numerycznymi są: opcjonalny znak po którym następuje jedna lub więcej cyfr, opcjonalna kropka dziesiętna oraz opcjonalny znak wykładnika. Znakiem wykładnika jest „e” lub „E”, po którym następuje jedna lub więcej liczb. Wydruk 2.6. Niejawna konwersja pomiędzy ciągiem i liczbą
<?php $aVar = 123; print( "\$aVar = $aVar, typ = " . gettype( $aVar ) . "<br>" ); $aVar2 = $aVar . " niejawnie skonwertowane do ciągu"; print( "\$aVar2 = $aVar2, typ = " . gettype( $aVar2 ) . "<br>" ); $aVar3 = $aVar2 + 1; // niejawna konwersja na liczbę całkowitą print( "\$aVar3 = $aVar3, typ = " . gettype( $aVar3 ) . "<br>" ); $aVar3 = $aVar2 * 1.1; // niejawna konwersja na liczbę zmiennoprzecinkową print( "\$aVar3 = $aVar3, typ = " . gettype( $aVar3 ) . "<br>" ); $aNotNumber = "abc"; $aVar4 = $aNotNumber * 1; // próba konwersji na liczbę, zwracane jest 0 print( "\$aVar4 = $aVar4, typ = " . gettype( $aVar4 ) . "<br>" ); $aIsNumber = "3 małe świnki"; $aVar5 = $aIsNumber + 1; // konwersja $aIsNumber na liczbę 3 print( "\$aVar5 = $aVar5, typ = " . gettype( $aVar5 ) . "<br>" ); ?>

Tablice
Tablice w PHP zachowują się zarówno tak jak tablice indeksowane (wektory) oraz jak tablice mieszające (asocjacyjne). PHP pozwala również na tworzenie tablic wielowymiarowych. Z powodu unikalnej konstrukcji tablic w PHP, można indeksować jeden wymiar tablicy wielowymiarowej liczbami a inny w sposób asocjacyjny. Tablice mogą być tworzone przy użyciu funkcji list() lub array() albo poprzez jawne podanie każdej z wartości. W skorowidzu funkcji na końcu książki zostały opisane wszystkie funkcje do manipulacji tablicami. Jednowymiarowe tablice mogą zamieniane w ciągach przez mechanizm zastępowania zmiennych na wartości w sposób identyczny jak wszystkie inne zmienne. W przypadku tablic wielowymiarowych należy użyć nawiasów klamrowych do zaznaczenia indeksów. Poniższy wydruk pokazuje przykłady użycia różnych typów tablic. Wydruk 2.7. Inicjowanie i użycie tablic
<?php // Jawne tworzenie prostej tablicy $a[0] = "Ryan"; $a[1] = "Scott"; $a[] = "Randall"; // jawne przypisanie do indeksu (klucza) 2 $a[] = "Sherie"; // jawne przypisanie do indeksu (klucza) 3

25

PHP – Kompendium wiedzy

print( "$a[3], $a[2], $a[1], $a[0]<br>" ); // Tworzenie tablicy asocjacyjnej $color["niebieski"] = "#0000FF"; $color["zielony"] = "#00FF00"; $color["czerwony"] = "#FF0000"; print( "Wartość szesnastkowa koloru czerwonego wynosi {$color['czerwony']}<br>" ); // Tworzenie tej samej co poprzedniej tablicy asocjacyjnej // tylko nieco prościej $color = array( "niebieski" => "#0000FF", "zielony" => "#00FF00", "czerwony" => "#FF0000" ); print( "Wartość szesnastkowa koloru zielonego wynosi {$color['zielony']}<br>" ); // Ręczne tworzenie tablicy wielowymiarowej $m[0][0] = "Zero Zero"; $m[0][1] = "Zero Jeden"; print( "Wartością \$m[0][1] jest {$m[0][1]}<br>" ); // Ręczne tworzenie asocjacyjnej tablicy wielowymiarowej $counties["Idaho"][0] = "Ada"; $counties["Idaho"][1] = "Adams"; $counties["Idaho"][2] = "Bannock"; $counties["Arizona"][0] = "Apache"; $counties["Arizona"][1] = "Cochise"; $counties["Arizona"][2] = "Coconino"; print( "\$counties['Idaho'][0] = {$counties['Idaho'][0]}<br>" ); ?>

Zmienne i stałe
Zmienne PHP są oznaczane znakiem dolara ($), po którym następuje nazwa zmiennej. Wielkość liter w nazwach zmiennych jest rozróżniana. Prawidłowe nazwy zmiennych muszą zaczynać się literą lub znakiem podkreślenia, po których może nastąpić litera, liczba lub znak podkreślenia. Prawidłowymi literami w zmiennych są a-z, A-Z lub dowolne znaki ASCII z zakresu 127-255 (0x7f-0xff). Wydruk 2.8. Nazwy zmiennych
<?php $variable1 = "Ryan"; $variable2 = "Scott"; print( "$variable1, $variable2<br>" ); // wypisuje "Ryan, Scott" $1variable = 123; // nieprawidłowa nazwa zmiennej $_test = "test"; // prawidłowo, rozpoczyna się podkreśleniem $_ąęć = "test2"; // prawidłowo ?>

Wartości mogą być przypisywane do zmiennych przez wartość lub przez referencję. Gdy przypisanie jest realizowane przez wartość, obliczona wartość wyrażenia jest przepisywana do docelowej zmiennej. Po przypisaniu zmienne są niezależne i zmiana wartości w jednej nie wpływa na wartość drugiej zmiennej. Gdy wartości są przypisywane przez referencję, nowa zmienna staje się odwołaniem do oryginalnej zmiennej. Zmiana wprowadzona do dowolnej zmiennej powoduje zmianę drugiej. Aby wykonać przypisanie przez referencję, należy poprzedzić nazwę znakiem &. Wydruk 2.9. Przypisywanie zmiennych
<?php $variable1 = "Ryan"; $variable2 = $variable1; // przypisanie wartości print( "$variable1, $variable2<br>" ); // wypisuje "Ryan, Ryan" $variable2 = "Scott"; print( "$variable1, $variable2<br>" ); // wypisuje "Ryan, Scott" $variable3 = &$variable1; // przypisanie przez referencję print( "$variable1, $variable3<br>" ); // wypisuje "Ryan, Ryan" $variable3 = "Katie"; print( "$variable1, $variable3<br>" ); // wypisuje "Katie, Katie" ?>

Zmienne predefiniowane
Oprócz zmiennych definiowanych przez użytkownika, w PHP istnieją zmienne tworzone przez system. Lista tych zmiennych zależy od kontekstu wykonania skryptu (na przykład, czy jest uruchamiany samodzielnie, Rozdział 2 – Język 26

czy poprzez serwer WWW), wersji PHP i typu serwera WWW. Ponieważ lista zmiennych jest zależna od wielu czynników, niektóre z nich mogą nie być nigdy dostępne. PHP generuje również zmienne dla cookie i danych formularzy przesyłanych za pomocą metod GET i POST. Szczegółowe omówienie tych zmiennych zawarte jest w rozdziale 3 „Formularze i cookie”. Część ta zawiera podzbiór dostępnych zmiennych dostępnych w czasie pracy PHP4 wraz z serwerem Apache 1.3.11. Aby zobaczyć wszystkie zmienne dostępne w środowisku można użyć funkcji phpinfo(). Kompletniejsza lista predefiniowanych zmiennych znajduje się w skorowidzu na końcu książki. Tabela 2.2. zawiera podzbiór zmiennych środowiska Apache, tabela 2.3., podzbiór zmiennych środowiska systemu a tabela 2.4. zawiera zmienne generowane przez PHP. W tabeli 2.5. zebrane są operatory arytmetyczne, natomiast operatory bitowe w tabeli 2.6. Tabela 2.7. zawiera operatory porównania, tabela 2.8 operatory zwiększania i zmniejszania a tabela 2.9. zawiera operatory logiczne. Ostatnia tabela, 2.10. zawiera operatory przypisania. Tabela 2.2. Zmienne środowiska serwera Apache Zmienna Definicja HTTP_HOST Zawartość nagłówka Host: o ile został wysłany przez przeglądarkę. HTTP_USER_AGENT Zawartość nagłówka User Agent: wysłanego przez przeglądarkę. Nagłówek ten opisuje przeglądarkę żądającą strony, na przykład: „Mozilla/4/0 (compatible; MSIE 5.01; Windows NT)”. Więcej na temat wykorzystania tej zmiennej znajduje się w rozdziale 9 „Niezależność od przeglądarki”. REMOTE_ADDR Adres IP użytkownika oglądającego stronę. SERVER_PROTOCOL Nazwa i wersja protokołu za pomocą którego zostało wysłane żądanie strony, na przykład HTTP/1.1. GATEWAY_INTERFACE Wersja specyfikacji CGI używanej przez serwer, na przykład CGI/1.1. Tabela 2.3. Zmienne środowiska systemu Zmienna
HOSTNAME HOSTTYPE PATH OSTYPE

Definicja Nazwa komputera serwera. Typ komputera, na przykład i386. Systemowa ścieżka serwera. System operacyjny działający serwerze, na przykład Linux.

na

Tabela 2.4. Zmienne generowane przez PHP Zmienna
PHP_SELF HTTP_COOKIE_VARS

HTTP_GET_VARS

HTTP_POST_VARS

Definicja Nazwa pliku z wykonywanym skryptem. Tablica asocjacyjna zmiennych przekazanych do skryptu poprzez cookie HTTP. Tablica asocjacyjna zmiennych przekazanych do skryptu za pomocą metody GET. Tablica asocjacyjna zmiennych przekazanych do skryptu za pomocą metody POST. PHP – Kompendium wiedzy

27

Tabela 2.5. Operatory arytmetyczne Operator Nazwa + Dodawanie Odejmowanie
* / %

Przykład
$a + $b $a - $b $b $a * $b $a / $b

Wynik Suma $a i $b Różnica $a i Iloczyn $a i $b Iloraz $a i $b Reszta z dzielenie $a przez $b Wynik Bity ustawione w $a i $b są ustawione Bity ustawione w $a lub $b są ustawione Bity ustawione w $a lub $b, ale nie w obu na raz są ustawione Bity ustawione nie są teraz ustawione i odwrotnie Przesunięcie bitów w $a w lewo o $b kroków Przesunięcie bitów w $a w prawo o $b kroków Wynik True, jeżeli $a jest równe $b True, jeżeli $a jest równe $b i są one tych samych typów True, jeżeli $a jest różne od $b True, jeżeli $a jest mniejsze od $b True, jeżeli $a jest większe od $b True, jeżeli $a jest mniejsze lub równe $b True, jeżeli $a jest większe lub równe $b

Mnożenie Dzielenie Reszta dzielenia

z

$a % $b

Tabela 2.6. Operatory bitowe Operator Nazwa & Iloczyn bitowy
|

Przykład
$a & $b $a | $b

Suma bitowa Różnica symetryczna Negacja Przesunięcie w lewo Przesunięcie w prawo

^

$a ^ $b

~

~$a

<<

$a << $b

>>

$a >> $b

Tabela 2.7. Operatory porównania Operator Nazwa == Równy
===

Przykład
$a == $b $a === $b

Identyczny Różny Mniejszy Większy Mniejszy równy Większy równy lub lub

!= < > <=

$a != $b $a < $b $a > $b $a <= $b

>=

$a >= $b

Tabela 2.8. Operatory zwiększania i zmniejszania Rozdział 2 – Język 28

Operator, przykład
$a++ ++$a $a---$a

Nazwa Postinkrementacja Preinkrementacja Postdekrementacja Predekrementacja

Wynik Zwraca $a, a następnie zwiększa $a o jeden Zwiększa $a o jeden i zwraca $a Zwraca $a, a następnie zmniejsza $a o jeden Zmniejsza $a o jeden i zwraca $a Wynik True, jeżeli $a mają wartość
True,

Tabela 2.9. Operatory logiczne Operator Nazwa and Iloczyn logiczny
or

Przykład
$a and $b

i
$a or $b

$b True $b

Suma logiczna Różnica symetryczna Negacja Iloczyn logiczny Suma logiczna

lub
True xor $a xor $b

jeżeli $a mają wartość

! &&

!$a $a && $b

jeżeli $a mają wartość True, ale nie razem True, jeżeli $a nie jest True True, jeżeli $a i $b mają wartość lub
$b True True,

True,

||

$a || $b

lub
True

$b

jeżeli $a mają wartość

Tabela 2.10. Operatory przypisania Operator Przykład
= += $a = $b

Wynik Przypisuje wartość do $a.

$b

$a += $b

-=

$a -= $b

*=

$a *= $b

/=

$a /= $b

.=

$a .= $b

%=

$a %= $b

|=

$a |= $b

Przypisuje wartość ($a+$b) do $a. Jest to identyczne z $a=$a+$b. Przypisuje wartość ($a-$b) do $a. Jest to identyczne z $a=$a-$b. Przypisuje wartość ($a*$b) do $a. Jest to identyczne z $a=$a*$b. Przypisuje wartość ($a/$b) do $a. Jest to identyczne z $a=$a/$b. Przypisuje wartość ($a.$b) do $a. Jest to identyczne z $a=$a.$b. Przypisuje wartość ($a%$b) do $a. Jest to identyczne z $a=$a%$b. Przypisuje wartość PHP – Kompendium wiedzy

29

Zasięg zmiennych <?php $aGlobal1 = "To jest test". function DoPrint2( ) { global $aGlobal1. */ include( "example10_inc. $aVal++. Rozciąga się on również na pliki dołączane. } DoPrint2(). function DoPrint( ) { /* Poniższa instrukcja wydrukuje tylko <br> ponieważ zmienna $aGlobal1 wewnątrz funkcji jest poza zasięgiem. które deklarowane wewnątrz funkcji zapewniają utrzymywanie swojej wartości pomiędzy kolejnymi wywołaniami funkcji. zmienne globalne PHP mają taki sam zasięg. aby mogły być wykorzystywane wewnątrz funkcji. Przypisuje wartość ($a>>$b) do $a. a następnie 1 StaticFunc(). Jest to identyczne z $a=$a|$b. Zmienne globalne muszą być deklarowane jako globalne.&= $a &= $b ^= $a ^= $b <<= $a <<= $b >>= $a >>= $b do $a. ($a|$b) Zasięg zmiennych Ogólnie rzecz ujmując. Jest to identyczne z $a=$a^$b. POwyższa zmienna $aGlobal1. ?> --. function StaticFunc( ) { static $aVal = 0. Jest to identyczne z $a=$a<<$b. Wydruk 2.php" ).php3 --<?php print( "$aGlobal1<br>" ). StaticFunc(). ?> Rozdział 2 – Język 30 . Jest to identyczne z $a=$a&$b. /* Dołączamy inny plik z kodem PHP.Zawartość pliku example10_inc. PHP posiada również zmienne statyczne.10. print( "$aVal<br>" ). */ print( "$aGlobal1<br>" ). Przypisuje wartość ($a&$b) do $a. Jest to identyczne z $a=$a>>$b. Wewnątrz funkcji definiowanych przez użytkownika zmienne mają zasięg lokalny. Przypisuje wartość ($a<<$b) do $a. */ print( "$aGlobal1<br>" ). Przypisuje wartość ($a^$b) do $a. } // Poniższe wywołania spowodują wypisanie 0. } DoPrint(). /* Poniższa instrukcja wypisze wartość zmiennej ponieważ została zadeklarowana jako globalna. będzie dostępna w dołączanym pliku.

" stałych. zamieszczone zostało zestawienie dostępnych operatorów. a następnie konwersję znaków nowej linii na znaczniki <br> I wypisanie wyników */ $aListing = `ls -l`. // drukuje "Wartości są równe" = ( 1 === "1" ) ? "Wartości są identyczne" : "Wartości nie są identyczne". // prints "Wartości nie są identyczne" /* Poniższy fragment powoduje przypisanie do $aListing zawartości bieżącego katalogu serwera. $aFmtList = nl2br( $aListing ). więc aby kontrola błędów działała poprawnie. Operator trójskładnikowy. Aby zdefiniować nową stałą używa się funkcji define().11. print( "Mamy tutaj zdefiniowane " . Niektóre działania z operatorami <?php $aNum1 = 1. ?> Operatory i kolejność operatorów PHP posiada zestaw operatorów znanych programistom C i C++. $aNum2 = 2. Gdy operator ten jest umieszczony przed wyrażeniem. 1 ). $aVal = ( $aNum1 == $aNum2 ) ? "Wartości są równe" : "Wartości są różne". komunikaty błędów zatrzymane przez operator @ są zapamiętywane w zmiennej globalnej $php_errormsg. "To jest stały ciąg znaków" ). nie są generowane komunikaty błędów powodowanych przez to wyrażenie. Gdy opcja ta jest aktywna. o ile uaktywniona jest opcja track_errors. jeżeli wyrażenie1 będzie miało wartość True.10.<br>" ). W tabelach od 2. Wydruk 2. define( "aNumber". Oprócz operatorów umieszczonych w tabelach istnieje jeszcze kilka operatorów. PHP posiada również operator kontroli błędów @. ale są one trudniejsze do klasyfikacji. aNumber . do 2. Pełna lista stałych znajduje się w skorowidzu na końcu książki. Użycie tego operatora pozwala na stworzenie lepszej obsługi błędów. // drukuje "Wartości są różne" = ( 1 == "1" ) ? "Wartości są równe" : "Wartości są różne". Operator wykonania oznaczany przez znak ` (na jednym klawiszu ze znakiem ~) jest podobny do operatora dostępnego we wielu językach programowania powłoki. Wyrażenie otoczone znakami ` jest wykonywane na serwerze a zwracana wartość przekazywana do zmiennej. print( "<br>Zawartość katalogu:<br><b>$aFmtList</b><br>" ).Stałe PHP posiada kilka predefiniowanych stałych oraz pozwala na definiowanie własnych. Zauważ. że stałe PHP nie są makrami w stylu C i dlatego muszą być wartościami skalarnymi. print( "$aVal<br>" ). przypisuje do zmiennej $wart wartość wyrażenie2. Wydruk 2. Stałe <?php define( "aString". print( "$aVal<br>" ). ?> $aVal $aVal 31 PHP – Kompendium wiedzy .5. print( "$aVal<br>" ). natomiast w przeciwnym przypadku $wart będzie miało wartość wyrażenie3. Zmienna ta jest nadpisywana przez kolejne błędy. zmienna ta powinna być sprawdzana możliwie szybko. Wyrażenie $wart = (wyrażenie1) ? (wyrażenie2) : (wyrażenie3).12. print( "Jej wartością jest '" . aString . zapisywany jako ?: jest dostępny zarówno w PHP jak i w C. "'<br>" ).

Gwarantuje to. do . elseif Jest to oczywiście najważniejszy element języka. Przykład użycia if. ?> Rozdział 2 – Język 32 . } ?> if organizuje przepływ sterowania poprzez while Jest to najprostszy typ pętli w PHP.. $nIndex = 0. Dodatkowo PHP posiada dwie funkcje dołączania plików z kodem źródłowym: include() i require(). if ( $aValue == 1 ) { // Używamy nawiasów klamrowych do otaczania bloków instrukcji print( "\$aValue == 1<br>" ).while <?php print( "Liczenie w górę przy użyciu <b>while</b>.. } print( "Liczenie w dół przy użyciu <b>do. } elseif ( $aValue == 2 ) { print( "\$aValue == 2<br>" ). else i elseif <?php if ( 1 < 2 ) print( "To zostanie wydrukowane.while</b>.14. $nIndex--. // wypisuje liczby od 0 do 9 while ( $nIndex < 10 ) { print( "$nIndex<br>" ).<br>" ).Programowanie przepływu sterowania PHP posiada standardowe instrukcje programowania przepływu sterowania takie jak if oraz pętle while i for..13. } while ( $nIndex > 0 ). to w pętli do.<br>" ). } elseif ( $aValue == 3 ) { print( "\$aValue == 3<br>" ). else print( "To nie zostanie wydrukowane. if. $nIndex++. Programiści C nie będą mieli kłopotu ze składnią tych instrukcji. while Mimo.. Przykład użycia while i do. $aValue = 2.while warunek pętli jest sprawdzany po pierwszym przebiegu pętli. Wydruk 2.<br>" ). } else { print( "\$aValue nie jest 1. // wypisuje liczby od 10 do 1 do { print( "$nIndex<br>" ).<br>" ). która zachowuje się identycznie jak w C i innych językach wysokiego poziomu. Instrukcja tworzenie rozgałęzień na podstawie wyrażeń logicznych. 2 ani 3<br>" ). else. że ciało pętli zostanie wykonane co najmniej raz. Wydruk 2. że jest to pętla podobna do while.

ale dodatkowo do zmiennej (zmienna_klucz) jest przypisywany klucz bieżącej pozycji. Każde z tych trzech wyrażeń może być puste. } /* $nIndex ma wartość 10. $nIndex-. "Zielony". Przykład użycia foreach <?php $aArray = array( "Czerwony". Druga postać realizuje to samo. Nie jest to zalecane ze względu na czytelność kodu. przyjmowane jest. } ?> foreach Wyrażenie foreach jest wygodnym sposobem na przeglądanie tablic. wyr2. } $aColorArray = array( "Czerwony" => "#FF0000". Na końcu każdego przebiegu pętli wykonywane jest trzecie wyrażenie (wyr3). Jej składnia jest następująca: for (wyr1. Wydruk 2. Pokażemy teraz. "Niebieski" => "#0000FF" ).elseif. że ma ono wartość True. wyr3) instrukcja Wartość pierwszego wyrażenia (wyr1) jest obliczana raz.) { print( "$nIndex<br>" ). foreach( $aArray as $aValue ) { print( "Bieżąca wartość to $aValue<br>" ). że każde z trzech wyrażeń może zostać opuszczone. $nIndex++ ) { print( "$nIndex<br>" ). PHP posiada dwa warianty składni: foreach ( tablica as zmienna_wartosc) instrukcja foreach ( tablica as zmienna_klucz => zmienna_wartosc) instrukcja Pierwsza postać pętli przebiega po podanej tablicy i w każdym przebiegu wartość bieżącego elementu tablicy jest przypisywana do zmiennej (zmienna_wartosc) a wskaźnik bieżącego elementu tablicy jest przesuwany. Składnia i implementacja tej instrukcji jest identyczna jak w C. $nIndex < 10.16. Jeżeli będzie ono miało wartość True. na początku pętli. $nIndex > 0.. Wartość drugiego (wyr2) jest obliczana na początku każdego przebiegu pętli. "Zielony" => "#00FF00". "Niebieski" ).. Pętla powoduje wypisanie liczb od 10 do 1 */ for ( . Podobne konstrukcje znajdują się w VBScript. Wydruk 2. Jest ona często używana zamiast skomplikowanych konstrukcji if. ale jest ona składniowo identyczna z instrukcją for w języku C. pętla będzie się nadal wykonywała i zostaną wykonane instrukcje ciała pętli. Jeżeli drugie wyrażenie jest puste.. foreach( $aColorArray as $aKey => $aValue ) { print( "Wartość szesnastkowa $aKey to $aValue<br>" ). Korzystnym ulepszeniem w PHP jest możliwość używania ciągów jako wyrażeń instrukcji switch. 33 PHP – Kompendium wiedzy .else zawierających wiele wystąpień elseif. Przykład użycia for <?php // Wypisuje liczby od 0 do 9 for ( $nIndex = 0..15. Perl i innych językach.for Pętla for jest najbardziej złożoną instrukcją pętli w PHP. } ?> switch Instrukcja switch upraszcza tworzenie wielokrotnych warunków.

wykonane zostaną ostatnie dwie instrukcje print. case "niebieski": print( "#0000FF<br>" ). break. */ $nIndex = 0. default: print( "inny<br>" ). Jeżeli $nIndex jest 0. } // Użycie frazy 'default' $nIndex = 17. break. Poniższy przykład ilustruje częste zastosowania instrukcji switch. switch( $aColor ) { case "czerwony": print( "#FF0000<br>" ).17. } /* opuszczenie instrukcji break może być czasami przydatne */ $aColor = "Czerwony". Przykłady użycia switch <?php $nIndex = 2. case 1: print( "jeden<br>" ). case 2: print( "dwa<br>" ). że w konstrukcji switch w C występują instrukcje break. case 2: print( "dwa<br>" ). case 1: print( "jeden<br>" ). break. switch ( $nIndex ) { case 0: print( "zero<br>" ). break. Wydruk 2. case 1: print( "jeden<br>" ). } /* Opuszczenie instrukcji break spowoduje wykonanie wszystkich wyrażeń po pasującej pozycji.Programiści Delphi i Pascala mają zwykle kłopoty z zapamiętaniem. break. switch( $aColor ) Rozdział 2 – Język 34 . switch ( $nIndex ) { case 0: print( "zero<br>" ). break. } // Switch z użyciem ciągu $aColor = "niebieski". case "zielony": print( "#00FF00<br>" ). jeden ani dwa<br>" ). Jeżeli $nIndex jest 1. default: print( "Nie jest to zero. break. case 2: print( "dwa<br>" ). break. // Najprostsza instrukcja switch switch ( $nIndex ) { case 0: print( "zero<br>" ). break. break. zostaną wykonane wszystkie trzy instrukcje print. Czasami opuszczenie tej instrukcji jest wygodne. break.

które należy przerwać lub rozpocząć od początku. czy istnieje w tablicy wartość większa od bieżącej wartości maksymalnej. case "zielony": case "Zielony": print( "#00FF00<br>" ). 20. break. Przykłady użycia break i continue <?php $aArray = array( 4. // możemy napisać 'break 1. endfor i endswitch. for i switch. } ?> PHP osiada alternatywną składnię dla konstrukcji sterujących if. Wydruk 2. break.19. $nIndex < 20. break. break. W przypadku pętli prostych. while. Najczęściej instrukcje break i continue są stosowane w zagnieżdżonych pętlach. /* Sprawdzamy. */ foreach( $aArray as $aValue ) { /* Wyrażenie będzie prawdziwe.{ case "czerwony": case "Czerwony": // Poniższa instrukcja zostanie wykonana. default: print( "inny<br>" ). } ?> break i continue PHP posiada również znane z C instrukcje break i continue. 12.' print( "$nIndex<br>" ). for ( $nIndex = 0. case "niebieski": case "Niebieski": print( "#0000FF<br>" ). 11.18. jeżeli $aColor // będzie miał wartość "Czerwony" lub "czerwony" print( "#FF0000<br>" ). 3. $aCurMax = 17. Obie te instrukcje pozwalają na podanie im parametru numerycznego. endwhile. składnia alternatywna może być użyteczna. wyrażenia warunkowe są wystarczające do realizacji tych zadań. Wyrażenie continue jest używane jedynie w pętlach. 15. 7. 31 ). break. który określa ilość zagłębionych pętli. ponieważ zapewnia wyraźną identyfikację końca struktur sterujących. Gdy tworzysz duże skrypty wbudowane w HTML. W każdej z tych konstrukcji otwierająca klamra jest zamieniona na dwukropek (:) a zamykająca klamra na odpowiednio endif. Ponieważ wykonujemy instrukcję break. Przykład użycia alternatywnej składni PHP na stronie HTML <html> <head> <title>Przykład 19</title> 35 PHP – Kompendium wiedzy . które pozwalają na dodatkowe sterowanie pętlami. Wydruk 2. $nIndex++ ) { if ( ( $nIndex % 2 ) == 0 ) continue. gdy osiągnięta zostanie wartość 20. // wypisuje liczby nieparzyste od 0 do 20 $nIndex = 0. Powoduje ono opuszczenie pozostałych instrukcji ciała pętli i rozpoczęcie nowej iteracji. 5. Wyrażenie break kończy wykonanie bieżącej konstrukcji sterującej (pętli lub wyrażenia switch). // opcjonalnie 'continue 1. nie sprawdzamy wartości które są w tablicy po wartości 20 */ if ( $aValue > $aCurMax ) { $aCurMax = $aValue.' } } // wypisuje "Bieżącym maksimum jest 20" print( " Bieżącym maksimum jest $aCurMax<br>" ).

że pliki dołączane za pomocą require() nie mogą zwracać wartości. że pliki nie mogą być warunkowo dołączane za pomocą require(). włączając w to wywołania innych funkcji. argumenty domyślne i argumenty przekazywane przez referencję.Używamy PHP do utworzenia listy opcji --> <form action="someotherpage. Próba zwrócenia wartości w wyrażeniu require() powoduje błąd składni. Funkcja include() jest wykonywana za każdym jej wywołaniem i może znajdować się wewnątrz pętli lub instrukcji warunkowych. endwhile. którą można następnie przypisać do zmiennej. jeżeli znajduje się w instrukcji warunkowej. może być trudno znaleźć końcowy średnik. która posiada kilka ograniczeń. Oznacza to. nie ma również mechanizmu usuwania lub przedefiniowania wcześniej zdefiniowanych funkcji. ?> </option> <?php $aCurYear--.</head> <body> <!-. Oznacza to. natomiast require() jest konstrukcją językową. że nie wchodzi w skład konstrukcji sterujących. Inną różnicą jest to. Rozdział 2 – Język 36 . Wyrażenie require() różni się tym od include(). /* zakładając. Zdolność ta pozwala również na tworzenie funkcji rekurencyjnych. Pozwala to warunkowo włączać pliki. */ ?> </select> </td> </tr> </table> </form> </body> </html> include i require PHP posiada dwa mechanizmy dołączania plików zewnętrznych: include() i require(). PHP pozwala na wykonywanie dowolnego kodu w ciele funkcji. Wyrażenie jest zwykłą funkcją PHP. PHP nie pozwala na przeciążanie funkcji. że pomiędzy while i endwhile jest dużo więcej tekstu. której warunek ma wartość False. aby dołączany plik zwracał wartość. while( $aCurYear >= 1920 ): ?> <option value="<?php print( $aCurYear ). Funkcje w PHP mogą posiadać następujące cechy: zmienne nazwy funkcji. Przetwarzanie pliku w instrukcji include() kończy się. ?>"> <?php print( $aCurYear ). Wyrażenie to jest wykonywane raz. include() Funkcje PHP pozwala na tworzenie funkcji definiowanych przez użytkownika. jeżeli znajduje się w pętli lub nawet. W obu przypadkach po dołączeniu pliku PHP przechodzi do trybu HTML na początku dołączanego pliku. zmienna liczba argumentów. Na końcu pliku analizator wraca do trybu PHP. lub włączać grupy plików przy pomocy odpowiednio skonstruowanej pętli. że dowolny kod zawarty w pliku dołączanym musi być otoczony prawidłowymi znacznikami PHP.phtml" method="post"> <table> <tr> <td> Wybierz swój rok urudzenia: </td> <td> <select name="BirthYear" size="1"> <?php /* Generujemy znaczniki dla lat 1920-2000 w odwrotnej kolejności */ $aCurYear = 2000. jeżeli użyjemy zwykłej składni. Funkcja include() pozwala również. Funkcje nie muszą być deklarowane przed ich użyciem w kodzie PHP4. gdy zostanie napotkana instrukcja return.

$nIndex < $aNumArgs. "Zobaczmy jeszcze raz przykład 10" ). print( "<br>" ). // wypisuje "Marysia miała małą owieczkę" PrintAnchorTag( "example10. Poniższe przykłady pokazują użycie funkcji w PHP. muszą być one umieszczone po wszystkich argumentach obowiązkowych. } } print( "ReturnSum( 3. } else { print( "<a href=\"$aHREF\" target=\"$aTarg\">$aText</a>" ).Domyślnie argumenty są przekazywane przez wartość. PHP posiada (i wymaga używania) wskaźnik $this. 4. Aby przekazać argument przez referencję. "text" ). print( "<br>" ). należy poprzedzić nazwę zmiennej znakiem &. Dostępne jest dziedziczenie jednobazowe. "małą owieczkę" ).phtml". func_get_arg() i func_get_args(). PrintEverything( 1. 4. 2. $nIndex++ ) { $aArgVal = func_get_arg( $nIndex ). Używając argumentów domyślnych. Istnieją konstruktory klas. for ( $nIndex = 0.20. dostępne są funkcje func_num_args(). PrintAnchorTag( "href". $aText. 2. "target" ). ale nie ma destruktorów. 5 ):<br>" ). PHP posiada również bardzo prostą implementację programowania obiektowego. który jest 37 PHP – Kompendium wiedzy . 5 ) .= $AddString. */ function PrintAnchorTag( $aHREF. } // przekazanie argumentu przez referencję function StringAppend( &$BaseString. $aTarg = "" ) { if ( $aTarg == "" ) { print( "<a href=\"$aHREF\">$aText</a>" ). Przykłady funkcji definiowanych przez użytkownika <?php // prosta funkcja function ReturnSum( $a. print( "Argument $nIndex: $aArgVal<br>" ). print( "$aString<br>" ). } } // zmienna lista argumentów function PrintEverything( ) { $aNumArgs = func_num_args(). która jest jednak wystarczająca dla większości aplikacji WWW. PrintAnchorTag( "example10. print( "Wywołanie PrintEverything( 1. $AddString ) { // ponieważ jest to przekazane przez referencję. 3. "text". 3. ReturnSum( 3. "Zobaczmy jeszcze raz przykład 10 w nowym oknie". 5 ): " . wartość // $BaseString może być zmieniona poza tą funkcją $BaseString .phtml". 5 ). "_blank" ). za pomocą których można pobrać dane przekazane jako argumenty. Wydruk 2. } // wartości domyślne /* Funkcja ta może być wywołana przy użyciu jednej z postaci: PrintAnchorTag( "href". $aString = "Marysia miała ". StringAppend( $aString. W przypadku zmiennej listy argumentów. "<br>" ). $b ) { return $a + $b. nie ma dziedziczenia wielobazowego. ?> Klasy i programowanie obiektowe PHP posiada zdolność tworzenia klas za pomocą składni podobnej jak w C++.

Może być to stała prowizja lub rabat. */ function ShoppingBasket( $aInitialValue = 0. } else { return False.50 ). } } } /* Tworzenie nowego obiektu ShoppingBasket. return True. Tak samo jak w C++ konstruktor może posiadać argumenty W tym przypadku jest to początkowa wartość koszyka. gdy była dostępna wystarczająca ich ilość if ( $this->fItems[$aName]["Quantity"] > $aQuantity ) { $this->fItems[$aName]["Quantity"] -= $aQuantity. $aBasket->PrintBasket(). $aValue. Więcej przykładów na ten temat znajdzie się w późniejszych rozdziałach książki. 15 ). Przykłady użycia klas w PHP <?php // tworzenie prostej klasy class ShoppingBasket { var $fItems.21. Dodanie kilku przedmiotów usunięcie kilku przedmiotów i wypisanie zawartości koszyka */ $aBasket = new ShoppingBasket( 3. $this->fCurValue += $aValue * $aQuantity. print( "</blockquote>" ). $this->fCurValue -= $this->fItems[$aName]["Value"] * $aQuantity. // dodanie 1 gizmo $aBasket->PrintBasket(). 2 ) ). Poniższy przykład pokazuje tworzenie prostej klasy. ponieważ ma taką samą nazwę jak klasa. 2. $aQuantity = 1 ) { // Usuwamy określoną ilość przedmiotów // jedynie. $aBasket->RemoveItem( "foobar". /* jest to konstruktor klasy. Wydruk 2. Rozdział 2 – Język 38 .stosowany do odwoływania się do metod i zmiennych obiektu. var $fCurValue.10. } // Dodanie określonej ilości przedmiotów function AddItem( $aName. $aBasket->AddItem( "foobar". // dodanie 6 foobarów $aBasket->PrintBasket().. number_format( $this->fCurValue. $aBasket->AddItem( "gizmo". $this->fItems[$aName]["Value"] = $aValue. } else { print( "<i>Koszyk jest pusty</i><br><br>" ). foreach( $this->fItems as $aKey => $aValue ) { print( "{$aValue['Quantity']} $aKey<br>" ). 6 ). print( "<br>" ).0 ) { $this->fCurValue = $aInitialValue. $aQuantity = 1 ) { $this->fItems[$aName]["Quantity"] += $aQuantity.50 ). 1. } print( "Wartość całkowita: $" . } function RemoveItem( $aName. } } function PrintBasket( ) { if ( count( $this->fItems ) > 0 ) { print( "Zawartość koszyka:<blockquote>" ).

$aBasket->RemoveItem( "foobar". ale jest przygotowany do tworzenia aplikacji dla WWW. Bieżąca implementacja tych funkcji odpowiada Perl 5. PHP korzysta z rozszerzonych wyrażeń regularnych zdefiniowanych przez POSIX 1003. Podsumowanie Rozdział ten jest zwięzłym opisem języka PHP i nie zawiera szczegółowo opisanych podstaw programowania. Pierwszy typ jest zgodny ze specyfikacją POSIX i są to funkcje ereg().2. Dlatego nie zawiera on dyskusji na temat tego kiedy lub dlaczego należy używać określonych konstrukcji. eregi(). Nazwy tych funkcji są poprzedzone ciągiem preg_.005. eregi_replace() oraz split(). 3 ). Różnica pomiędzy implementacją w Perl 5. co zostanie pokazane w kolejnych rozdziałach.php. ?> Porównywanie wzorców PHP posiada dwa typy funkcji do porównywania wzorców (lub wyrażeń regularnych). Każda z tych funkcji jako pierwszego argumentu wymaga wyrażenia regularnego. Składnia tych wyrażeń jest taka sama jak w Perl 5 z kilkoma różnicami.005 i w PHP jest dokładnie opisana w dokumentacji PHP dostępnej z witryny http://www. Drugi typ funkcji porównywania wzorców jest zgodny z wyrażeniami regularnymi Perl. ereg_replace(). 39 PHP – Kompendium wiedzy . Język jest wystarczająco sprawny do realizacji większości zadań.$aBasket->PrintBasket(). Pełna lista tych funkcji znajduje się w skorowidzu na końcu książki. które w pełni opisują wyrażenia regularne POSIX.net. PHP zawiera wszystkie własności potrzebne do tworzenia złożonych i łatwych do zarządzania aplikacji WWW. PHP zawiera w katalogu regex strony podręcznika. $aBasket->PrintBasket(). Zamieszczone zostały za to przykłady ilustrujące składnię i dostępne funkcje.

Rozdział ten zawiera informacje nie tylko na temat sposobu użycia formularzy HTML w PHP. który jest zwykle potrzebny w czasie dialogu z użytkownikiem. które zostały opisane w rozdziale 1. obsługuje on automatycznie wiele szczegółów przetwarzania formularzy.inc" ). Możesz używać dowolnego rozszerzenia dla skryptów PHP. że uważam że rozszerzenie . Konwencje nazw plików We wszystkich przykładach oraz w mojej aktualnej pracy do oznaczania skryptów PHP które generują strony HTML używam rozszerzenia .<br>" ).php3 do plików dołączanych. HTML posiada elementy formularzy.phtml oraz rozszerzeń .phtml lepiej wygląda.php lub . Cookie mogą również pomóc w zrealizowaniu mechanizmu utrzymywania stanu.123". Nie używam typowego rozszerzenia inc. Jeżeli nie zrobisz tego. gdy źle skonfigurowany zostanie serwer WWW. ponieważ jest ono składniowo podobne do obsługi elementów formularzy.Rozdział 3. „Kompilacja i instalowanie PHP”.Plik: bogus. // powatającą. które są używane do zbierania danych od użytkownika.inc --> <?php // Jest to dołączany plik PHP demonstrujący // potencjalną dziurę w systemie zabezpieczeń. Rozważmy następujący przykład: <!-. ?> </body> </html> <!-. print( "Poznajmy dziurę w systemie bezpieczeństwa.34. że jest to kod PHP. że serwer WWW został tak skonfigurowany. natomiast PHP zapewnia prosty mechanizm przetwarzania tych formularzy. Nie używam najczęściej używanych rozszerzeń . Na przykład. Ponieważ PHP został zaprojektowany jako język programowania dla WWW. powinieneś się upewnić. użytkownik może zapisać twoje skrypty.php3 do stron wyświetlających dane jedynie dlatego. Rozszerzenia te konfiguruje się używając opcji konfiguracji. że będzie traktował oba te rozszerzenia jako pliki PHP i przetwarzał je przed wysłaniem do przeglądarki użytkownika. Wszystkie rozszerzenia jakich używasz do skryptów PHP i plików dołączanych powinny zostać dołączone do konfiguracji serwera WWW. Dla programistów.php i .Plik: securityhole. Jest to jedyny powód. /* .56. jeżeli używasz rozszerzeń php i inc do oznaczania skryptów PHP i plików dołączanych. Do plików dołączanych używam innego rozszerzenia i chcemy zaznaczyć. która sygnalizuje niektóre problemy jakie powstają gdy jako urządzenie wyjściowe używana jest przeglądarka WWW. */ include( "bogus. Formularze i cookie Wstęp W czasie tworzenia dowolnego typu aplikacji utworzenie dobrego mechanizmu interakcji z użytkownikiem jest jednym z najważniejszych zadań programisty. W rozdziale tym znajduje się również omówienie mechanizmu cookie. ale również na temat kontroli poprawności i przetwarzania danych formularza.phtml --> <html> <head> <title>Przykład: błędny plik dołączany otwiera dziurę w systemie zabezpieczeń</title> </head> <body> <?php /* Plik dołączany bogus. $aDatabaseIP = "12. $aDatabasePass = "secretpassword". $aDatabaseUser = "secretuser". zawiera błąd ale również znajduje się w nim nazwa użytkownika bazy danych i hasło.inc. którzy przechodzą od pisania zwykłych aplikacji do tworzenia aplikacji WWW przeznaczona jest część zatytułowana „Ważne zagadnienia programowania dla WWW”.

do którego należy wpisać nazwę użytkownika i jego hasło. Poniższa strona HTML zawiera prosty formularz. ale aby uniknąć potencjalnego zagrożenia bezpieczeństwa należy tak skonfigurować serwer WWW. print( "Hasło: $Password<br>" ).1.inc wpisując odpowiedni URL w pasku adresu. <!-. Jeżeli serwer WWW jest tak skonfigurowany. dołączany jest plik bogus. W trakcie tworzenia aplikacji PHP możesz użyć dowolnego rozszerzenia. Obsługa formularzy w PHP Do pobierania danych od użytkownika w HTML stosuje się formularze. Zamieszczony na wydruku 1 przykład zawiera formularz z dwoma wartościami skalarnymi — nazwą użytkownika i hasłem. Dołączany plik zawiera dane na temat połączenia z bazą danych.To jest skrypt PHP. Można również tworzyć elementy formularza zawierające wiele wartości. ?> </body> </html> Skalarne i wielowartościowe elementy formularza Elementy formularzy HTML zawierają zwykle wartości skalarne. cały tekst pliku pojawi się w przeglądarce. w tym nazwę użytkownika i hasło. użytkownik zobaczy jedynie wcześniej wspomniany komunikat błędu.listing1. wyświetlony zostanie błąd: „Parse error: parse error in bogus.1 . W domyślnej konfiguracji PHP po przesłaniu danych formularza do skryptu PHP.phtml. należy dodać do nazwy nawiasy kwadratowe oznaczające zmienną tablicową.phtml</title> </head> <body> <?php print( "Nazwa użytkownika: $Username<br>" ).phtml" method="post"> Nazwa użytkownika: <input type="text" name="Username"><br> Hasło: <input type="password" name="Password"><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> <!-.To jest strona HTML. Aby użyć nieskalarnych elementów formularza w PHP.2. Dociekliwy użytkownik może spróbować obejrzeć plik bogus. Po przesłaniu formularza do skryptu post1. Wydruk 3. Zawiera on również błąd syntaktyczny.html --> <html> <head> <title>Wydruk 3. Jeżeli serwer WWW jest skonfigurowany taj aby traktować pliki .phtml.1: post1. aby traktować pliki .inc on line 12”.html</title> </head> <body> <form action="post1. aby analizował wszystkie pliki posiadające używane przez ciebie rozszerzenia.phtml. listing1.inc jako tekst (tak jak mój).inc. Gdy otwarty zostanie plik securityhole.phtml" method="post"> <table> <tr> 41 PHP – Kompendium wiedzy . Formularz na wydruku 2 pokazuje takie wielowartościowe elementy formularza. Wydruk 3.Zagnieżdżony komentarz powoduje błąd. Strona HTML i skrypt PHP ilustrujące procedurę logowania się użytkownika.html --> <html> <head> <title>Wydruk 3. /* właśnie tutaj */ */ ?> W przykładzie tym do głównego pliku. na przykład listę wielokrotnego wyboru.inc jak każdy inny skrypt PHP. zmienne $UserName i $Password będą zawierały wartości wpisane jako nazwę użytkownika i hasło. Podsumowując. securityhole. konwertuje wszystkie elementy formularza na zmienne PHP. Formularz HTML z elementami wielowartościowymi <form action="displayall. post1.

aby nie udostępniał tych zmiennych globalnych i tak pisać skrypty. Poniższa funkcja demonstruje użycie tablic HTTP_GET_VARS i HTTP_POST_VARS do wyświetlenia wszystkich danych przekazanych z formularza do skryptu: function DisplayGetVars() { global $HTTP_GET_VARS. Skrypt wyświetlający dane z wydruku 1 może zostać przepisany w następujący sposób: <!-. aby korzystały z wartości zawartych w tablicach HTTP_GET_VARS i HTTP_POST_VARS.html --> <html> <head> <title>Wydruk: post2.Nazwy są indeksami tablicy --> <select name="Colors[]" size="5" multiple> <option value="Red">Czerwony</option> <option value="Green">Zielony</option> <option value="Blue">Niebieski</option> <option value="Purple">Purpurowy</option> <option value="Yellow">Żółty</option> </select> </td> </tr> <tr> <td valign="top"> Wprowadź twój adres: </td> <td valign="top"> <!-. Można więc tak skonfigurować PHP. print( "Nazwa użytkownika: {$HTTP_POST_VARS['Username']}<br>" ).phtml</title> </head> <body> <?php error_reporting( 255 ). $Colors[] i $adress[] Alternatywne metody odczytywania wartości z formularza PHP posiada alternatywną metodę dostępu do danych przesłanych do skryptu. ?> </body> </html> W niektórych przypadkach preferowane jest użycie zmiennych HTTP_GET_VARS lub HTTP_POST_VARS zamiast korzystania ze zmiennych globalnych. post2. Więcej na temat tej dyrektywy konfiguracji napisane zostało na końcu książki przy opisie opcji konfiguracji register_globals. } function DisplayPostVars() { Rozdział 3 – Formularze i cookie 42 . Używamy notacji tablicowej aby zaznaczyć użycie wielu wierszy tablicy --> <input type="text" name="address[]"><br> <input type="text" name="address[]"><br> <input type="text" name="address[]"><br> </td> </tr> <tr> <td colspan="2"> <input type="submit" name="Submit" value="Wyślij"> </td> </tr> </table> </form> Po przesłaniu danych formularza z wydruku 2 do skryptu PHP.<td valign="top"> Wybierz kolory które lubisz: </td> <td valign="top"> <!-. Predefiniowane zmienne tablicowe HTTP_GET_VARS i HTTP_POST_VARS zawierają tablice asocjacyjne elementów przesłanych do skryptu przy pomocy metod odpowiednio GET i POST. można tu nieco zyskać. print( "Hasło: {$HTTP_POST_VARS['Password']}<br>" ). Jeżeli bardzo przejmujesz się wydajnością serwera WWW.Trzy linie na dane adresowe.To jest skrypt PHP. każda z tablic będzie zawierać zero lub więcej wartości. ponieważ PHP nie będzie musiał tworzyć zmiennych globalnych dla każdego z elementów formularza. Na przykład możesz chcieć wyświetlić w czasie uruchamiania skryptu wartości wszystkich danych wysłanych z formularza. DisplayArray( $HTTP_GET_VARS ).

// Wyświetlenie nagłówka tabeli print ( " <tr><th>Klucz</th><th>Wartość</th></tr>")./include/gen_form_funcs. } else { print( "<td>$aKey</td><td><i>$aValue</i></td>"). } } Używając tej funkcji można pisać własne skrypty PHP wyświetlające wartości wszystkich przesłanych elementów formularza. ?> <br><br> <h2>Cała zawartość HTTP_COOKIE_VARS</h2> <?php 43 PHP – Kompendium wiedzy . które same są tablicami. Wydruk 3. DisplayArray( $aValue ).php" ). poinformujmy o tym if (empty( $aValue )) { print( "<td>$aKey</td><td><i>pusty</i></td>"). } } else { print( "<td>$aKey(array)</td><td>"). } else { print("<i>pusty lub nieprawidłowy</i>").phtml powoduje wyświetlenie wszystkich danych przesłanych przez HTTP GET. } Obie z tych funkcji opierają się o funkcję DisplayArray przedstawioną na wydruku 3. czy $aArray jest na pewno tablicą if ( is_array ($aArray ) && (count( $aArray ) > 0 )) { // Rozpoczęcie tabeli print ("<table border = \"1\">")..3. displayall. include( ". <html> <head> <title>Wyświetlenie wszystkich elementów formularza</title> </head> <body> <?php error_reporting( 255 ).global $HTTP_POST_VARS. } print ("</tr>"). HTTP POST i cookie odesłane przez przeglądarkę (cookie zostaną omówione w dalszej części tego rozdziału).4. Wydruk 3. Funkcja DisplayArray function DisplayArray( $aArray ) { // Upewniamy się. // Wyświetlenie wszystkich par klucz/wartość z tabeli foreach( $aArray as $aKey => $aValue ) { print( "<tr>" ). print ("</td>" ). ?> <br><br> <h2>Cała zawartość HTTP_POST_VARS</h2> <?php DisplayPostVars(). Jest to prosta funkcja wyświetlająca wszystkie elementy tablicy w tablicy HTML. DisplayArray( $HTTP_POST_VARS ).phtml. Obsługuje ona rekurencyjnie elementy tablicy. // Jeżeli bieżąca wartość jest tablicą // wywołujemy rekurencyjnie funkcję // w przeciwnym wypadku wyświetlamy wartość if (!is_array( $aValue )) { // jeżeli wartość jest pusta. Poniższy skrypt.3. Skrypt displayall. ?> <h2>Cała zawartość HTTP_GET_VARS</h2> <?php DisplayGetVars(). } print ("</table>").

1. Pisząc skrypt obsługujący te wartości należy pamiętać. ?> <br><br> </body> </html> Na rysunkach 3.DisplayCookieVars(). Zauważmy. Przykład wielowartościowyc h elementów formularza Rozdział 3 – Formularze i cookie 44 . korzystając z formularza z wydruku 2. jak się tego można było spodziewać. że element Submit jest zawsze umieszczany w tablicy HTTP_POST_VARS. że na rysunku 3. Address i Submit.2. tablicami. Wartości dwóch pierwszych elementów są.phtml. i 3. Rysunek 3.2. Wartością elementu Submit jest napis umieszczony na przycisku. tablica HTTP_POST_VARS zawiera trzy elementy: Colors. przedstawiono formularz wprowadzania danych i wyniki wysłania danych do skryptu displayall.1.

Jest ona dokładniej opisana w rozdziale 5 „Wysyłanie plików przez formularz”.2. Użycie rysunku jako przycisku wysłania danych Jeżeli projekt aplikacji WWW tak przewiduje.5.Strona HTML. Na przykład na wydruku 5 nazwą elementu rysunku jest SubmitImg. ale jeżeli używasz rysunku oprócz danych do serwera zostaną wysłane dodatkowo współrzędne x i y (względem lewego górnego rogu rysunku) punktu gdzie został kliknięty rysunek.phtml" method="post"> Nazwa użytkownika: <input type="text" name="Username"><br> Hasło: <input type="password" name="Password"><br> <input type="image" name="SubmitImg" src="submit.html --> <html> <head> <title>Użycie rysunku zamiast przycisku</title> </head> <body> <form action="displayall. Dla PHP nie ma znaczenia.Rysunek 3.gif"> </form> </body> </html> 45 PHP – Kompendium wiedzy . Przykład użycia rysunku w formularzu <!-. Mechanizm ten jest wygodny do tworzenia map obrazów po stronie serwera. Zmienne reprezentujące współrzędne będą się nazywały SubmitImg_x i SubmitImg_y. imgsubmit. Wydruk 3. PHP posiada obsługę przesyłania plików wbudowaną bezpośrednio w język. Nazwy zmiennych przechowujących współrzędne są tworzone poprzez dodanie _x i _y do nazwy elementu reprezentującego rysunek. możesz użyć rysunku w miejsce przycisku HTML wysyłającego dane formularza do serwera.phtml Użycie formularzy do przesyłania plików Większość nowoczesnych przeglądarek posiada zdolność przesyłania plików z dysku komputera użytkownika na serwer WWW. Wynik przesłania formularza wielowartościoweg o do displayall. czy jest to przycisk czy rysunek.

ale należy pamiętać. Kontrola taka jest zalecana w przypadku tworzenia wysoce interaktywnych aplikacji WWW. Zamiast tego można zastosować takie mechanizmy wprowadzania danych. Zamiast wszędzie korzystać ze zwykłych pól tekstowych należy znaleźć miejsca. gdzie można zastosować listę. Do kontroli poprawności używa się funkcji ereg() i eregi(). $aCode4 = "M6K 3E3". Kontrola danych za pomocą wyrażeń regularnych Prawdopodobnie najskuteczniejszym mechanizmem kontroli danych jest użycie wyrażeń regularnych i funkcji wyrażeń regularnych w PHP. to nie rób tego. $aCode2 = "83440-1607". Wyrażenia te są potężnym narzędziem. Ponieważ lepiej znam wyrażenia regularne w stylu POSIX. że przy przeszukiwaniu ignoruje ona wielkość liter. Poniższy przykład pokazuje zastosowanie wyrażeń regularnych do kontroli poprawności amerykańskiego kodu pocztowego oraz dat w formacie ISO (YYYY-MM-DD). są one używane we wszystkich przytoczonych tu przykładach. Wydruk 3. string ciag [. Skupimy się tutaj na wyrażeniach w stylu POSIX. że w przykładach tych jest sprawdzany jedynie format a nie wartości. ale nie zostaną wtedy przesłane dane na temat współrzędnych. które zmniejszają szansę pomyłki użytkownika. Zauważ. Kontrola poprawności danych formularza Część ta jest poświęcona kontroli poprawności danych formularza przez mechanizmy umieszczone na serwerze a nie na komputerze klienta. eregi_replace() oraz split(). że funkcje wyrażeń w stylu Perl są szybsze i mają większe możliwości. są dość skomplikowane w użyciu. Kontrola poprawności kodu pocztowego i daty ISO <html> <head> <title>Kontrola poprawności amerykańskiego kodu pocztowego i daty ISO</title> </head> <body> <?php $aCode1 = "83440". $aCode3 = "834". ale nie jest ona całkowicie pewna. kontrolę typów danych lub przeszukiwanie słowników w bazie danych. takie jak JavaScript mogą być wykorzystywane do kontroli poprawności elementów formularza przez wysłaniem ich do serwera.Niektóre przeglądarki posiadają mechanizm pozwalający wykorzystać klawisz Enter zamiast klikania w przycisk na formularzu. jeżeli nie musisz czegoś kontrolować. ale jeżeli wcześniej nie miałeś z nimi doświadczenia. ponieważ może być niedostępna w wielu przeglądarkach i systemach operacyjnych. PHP obsługuje dwa rodzaje wyrażeń regularnych — w stylu POSIX i Perl. wykorzystując wyrażenia regularne. ale wyrażenia w stylu Perl dają podobne możliwości. Gdy użyjemy rysunku zamiast przycisku. Nazwy funkcji wyrażeń w stylu Perl są poprzedzone przedrostkiem preg_ i są opisane w skorowidzu na końcu tej książki. ciągu do przeszukania oraz opcjonalnej tablicy. $aCode1 ) == True ) Rozdział 3 – Formularze i cookie 46 . array dopasowanie] ) Obie funkcje wymagają wzorca wyrażenia regularnego. Unikanie kontroli poprawności Chociaż kontrola poprawności jest ważna. array dopasowanie] ) int eregi( string wzorzec. jeżeli były one już kontrolowane na komputerze klienta. ereg_replace(). string ciag [. Ogólna składnia tych funkcji jest następująca: int ereg( string wzorzec. if ( ereg( $aCodeFormat. mechanizm ten nadal będzie działał. Na przykład zastosowanie listy rozwijalnej z miesiącami jest mniej pracochłonne niż kontrola poprawności wpisanych nazw. pole wyboru lub przyciski opcji. Języki skryptowe działające na kliencie. Funkcje wyrażeń regularnych w stylu POSIX to: ereg(). Każda funkcja zwraca true. która będzie zawierać dopasowania wzorca odnalezione w przeszukiwanym ciągu. Funkcja eregi() jest identyczna z ereg() poza tym. Dlatego dane muszą być kontrolowane na serwerze nawet. jeżeli wzorzec został odnaleziony w ciągu.6. eregi(). PHP pozwala na stosowanie kilku metod kontroli poprawności danych. $aCodeFormat = "[0-9]{5}(-[0-9]{4})?".

446". $aDate4 ) == True ) print( "'$aDate4' jest poprawnym formatem daty ISO<br>" ).56e18". takich jak liczby i ciągi. else print( "'$aDate2' nie jest poprawnym formatem daty ISO<br>" if ( ereg( $aDateFormat. $aCodeFormat. $aCodeFormat. "'$aCode4' nie jest poprawnym kodem pocztowym<br>" ). że zostały wprowadzone tylko liczby. 2000". $aDate3 ) == True ) print( "'$aDate3' jest poprawnym formatem daty ISO<br>" ). którzy nie znają wyrażeń regularnych mogą wybrać inne metody kontroli poprawności. ). $aDate1 ) == True ) print( "'$aDate1' jest poprawnym formatem daty ISO<br>" ). $aCode4 ) == True ) "'$aCode4' jest poprawnym kodem pocztowym<br>" ). 2000' nie jest poprawnym formatem daty ISO '0000-99-99' jest poprawnym formatem daty ISO Programiści programujący wcześniej w języku Perl i ci. $aCodeFormat. aby upewnić się. ). Wyniki działania skryptu z wydruku 6 są następujące: '83440' jest poprawnym kodem pocztowym '83440-1607' jest poprawnym kodem pocztowym '834' nie jest poprawnym kodem pocztowym 'M6K 3E3' nie jest poprawnym kodem pocztowym '2000-06-29' jest poprawnym formatem daty ISO '2000-7-4' jest poprawnym formatem daty ISO 'June 29. $aValue4 = "3 małe świnki". else print( "'$aValue1' nie jest liczbą<br>" ). $aCode3 ) == True ) "'$aCode3' jest poprawnym kodem pocztowym<br>" ). $aValue2 = "123. else print( "'$aDate4' nie jest poprawnym formatem daty ISO<br>" ?> </body> </html> ). "'$aCode3' nie jest poprawnym kodem pocztowym<br>" ). Metoda ta jest odpowiednia do kontrolo prostych typów.2}". "'$aCode2' nie jest poprawnym kodem pocztowym<br>" ). ). Kontrola poprawności za pomocą sprawdzania typów W niektórych przypadkach wystarczy sprawdzić typ wprowadzonej danej i nie przejmować się wprowadzoną wartością. $aDateFormat = "[0-9]{4}-[0-9]{1. else print( "'$aDate1' nie jest poprawnym formatem daty ISO<br>" if ( ereg( $aDateFormat. else print( "'$aDate3' nie jest poprawnym formatem daty ISO<br>" if ( ereg( $aDateFormat. $aCode2 ) == True ) "'$aCode2' jest poprawnym kodem pocztowym<br>" ). $aDate2 ) == True ) print( "'$aDate2' jest poprawnym formatem daty ISO<br>" ). będzie wystarczająca dla wielu aplikacji. opisane w następnych dwóch częściach. Jeżeli zostanie użyta w połączeniu z dodatkowym kodem kontroli poprawności. $aDate3 = "June 29. $aDate2 = "2000-7-4". ale również pozwala na nieco więcej. 47 PHP – Kompendium wiedzy . $aDate1 = "2000-06-29". if ( ereg( $aDateFormat.print( "'$aCode1' jest poprawnym kodem pocztowym<br>" ). else print( if ( ereg( print( else print( if ( ereg( print( else print( if ( ereg( print( else print( "'$aCode1' nie jest poprawnym kodem pocztowym<br>" ). $aDate4 = "0000-99-99". <html> <head> <title>Kontrola liczb przy użyciu kontroli typów</title> </head> <body> <?php $aValue1 = "123". if ( is_numeric( $aValue1 ) == True ) print( "'$aValue1' jest liczbą<br>" ). którzy używali już wyrażeń regularnych uważają taką kontrolę poprawności za łatwą i wydajną. Ci zaś.2}-[0-9]{1. Poniższy przykład sprawdza typy zmiennych. $aValue3 = "1.

if ( $aValidator->is_email( $aEmail3 ) == True ) print( "'$aEmail3' jest prawidłowym adresem email<br>" ). ?> </body> </html> Skrypt przedstawiony na wydruku 7 interpretuje pierwsze trzy wartości jako liczby natomiast ostatnią nie. Więcej na temat funkcji kontroli typów znajduje się przy opisie funkcji is_xxx() w części „Funkcje zmiennych” w skorowidzu funkcji na końcu książki. if ( $aValidator->is_email( $aEmail1 ) == True ) print( "'$aEmail1' jest prawidłowym adresem email<br>" ). $aPhoneNum2 = "+1 208-359-1540". */ $aEmail1 = "blake@intechra. Do kontroli poprawności przeznaczona jest klasa Validator zawierająca wiele funkcji upraszczających wiele zadań i oszczędzających czas. ?> Rozdział 3 – Formularze i cookie 48 .php3" ). Klasa Validator Jedną z najpiękniejszych cech oprogramowania typu open-source jest dostępność świetnych narzędzi uzupełniających podstawowy produkt.Validator.com". else print( "'$aEmail3' nie jest prawidłowym adresem email<br>" ).net". $aPhoneNum3 = "support@intechra. /* Funkcja is_email kontroluje nie tylko poprawność formatu adresu email ale również sprawdza. Witryna Webmasters Net (http://www. else print( "'$aValue3' nie jest liczbą<br>" ). W chwili pisania tego przykładu host 'invalidhost. is_url() i is_phone() przeznaczone do sprawdzania adresów e-mail. if ( is_numeric( $aValue3 ) == True ) print( "'$aValue3' jest liczbą<br>" ). Przykładowymi funkcjami kontroli poprawności są is_email().thewebmasters. if ( $aValidator->is_phone( $aPhoneNum1 ) == True ) print( "'$aPhoneNum1' jest prawidłowym numerem telefonu<br>" ). Dodatkowe oprogramowanie dla PHP można pozyskać z wielu źródeł. URL i numerów telefonów. $aPhoneNum1 = "(208) 359-1540". else print( "'$aPhoneNum2' nie jest prawidłowym numerem telefonu<br>" ). include( "./include/class. if ( $aValidator->is_phone( $aPhoneNum3 ) == True ) print( "'$aPhoneNum3' jest prawidłowym numerem telefonu<br>" ). Wydruk 3. else print( "'$aPhoneNum3' nie jest prawidłowym numerem telefonu<br>" ). if ( $aValidator->is_phone( $aPhoneNum2 ) == True ) print( "'$aPhoneNum2' jest prawidłowym numerem telefonu<br>" ). if ( $aValidator->is_email( $aEmail2 ) == True ) print( "'$aEmail2' jest prawidłowym adresem email<br>" ). else print( "'$aValue2' nie jest liczbą<br>" ). else print( "'$aEmail2' nie jest prawidłowym adresem email<br>" ). $aEmail2 = "john".. else print( "'$aPhoneNum1' nie jest prawidłowym numerem telefonu<br>" ). Więcej informacji na temat tej klasy i innych dostarczanych przez Webmasters Net znajduje się w części „PHP Tools and Extras” — ich witryny. $aEmail3 = "nobody@invalidhost. else print( "'$aValue4' nie jest liczbą<br>" ). else print( "'$aEmail1' nie jest prawidłowym adresem email<br>" ).net) zawiera nieco świetnych klas i modułów z kodem źródłowym. czy istnieje w Internecie podany host Oczywiście wymaga to podłączenia z Internetem. if ( is_numeric( $aValue4 ) == True ) print( "'$aValue4' jest liczbą<br>" ).8.com' nie był zarejestrowany.net".if ( is_numeric( $aValue2 ) == True ) print( "'$aValue2' jest liczbą<br>" ). Kontrola poprawności danych przy użyciu klasy Validator <?php error_reporting( 0 ). $aValidator = new Validator.

Jeżeli twoja aplikacja opiera swoje działanie na cookie. Jeżeli funkcja jest wywołana tylko z nazwą. Należy pamiętać o następujących pułapkach i częstych błędach użycia cookie: • Ustawione cookie nie będą widoczne w skrypcie do czasu jego powtórnego załadowania. Na wydruku 3. którą można uzyskać jako wynik funkcji mktime() lub time().= " o ". Cookie mogą przenosić wartości skalarne jak również tablice wartości. } // Ustawienie cookie ważnego przez dwa tygodnie $aTwoWeeks = time() + ( 60 * 60 * 24 * 14 ). ale nie wymagasz ich do prawidłowej pracy.= date( "d F Y". $aMessage . int bezpieczny ) Wszystkie argumenty funkcji poza nazwą są opcjonalne.html. $aValMessage . $aTwoWeeks ). jeżeli użytkownik ponownie obejrzy witrynę za pomocą innej przeglądarki. } else { $aMessage = "Nie byłeś tu przez ostatnie ". Sprawdź aplikację na możliwie dużej ilości przeglądarek. • Przeglądarki różnie obsługują cookie. Użycie cookie <?php // Sprawdzenie czy istnieje zmienna cookie $LastTime if ( !empty( $LastTime ) ) { $aMessage = "Ostatnia wizyta miała miejsce ". // sprawdzenie istnienia niezwykle ważnej tablicy z cookie $aValMessage = "". twoja aplikacja będzie działała z większością przeglądarek. $aMessage . PHP posiada tylko jedna funkcję przeznaczoną do tworzenia cookie. $CookieArray[0].= date( "h:i:s a". jak dzieje się to w przypadku metod GET i POST. funkcja setcookie() musi być wywołana przed wysłaniem jakichkolwiek danych do przeglądarki lub należy zastosować buforowanie wyjścia w celu opóźnienia wysyłania danych do przeglądarki do chwili zdefiniowania wszystkich cookie. Dowolna wartość numeryczna może zostać opuszczona podając wartość zero. $LastTime ). $aMessage .9. która jest dostępna pod adresem http://www. Dowolny z ciągów może zostać opuszczony podając pusty ciąg (""). Argument czas jest standardowym czasem z systemu Unix w postaci liczby. Poniższe dwa przykłady pokazują użycie funkcji setcookie(). niektórzy użytkownicy nie będą mogli jej używać. to cookie nie będzie dostępne. Oznacza to. ale tak jak w przypadku wszystkich narzędzi zewnętrznych należy sprawdzić. Jednak jeżeli korzystasz z cookie.com/newsref/std/cookie_spec. setcookie(). że jeżeli użytkownik obejrzy witrynę przy użyciu jednej przeglądarki i zostanie ustawione cookie. Jednak wielu użytkowników nie przyjmuje cookie wysłanych do przeglądarek z powodu plotek na temat ich wykorzystania.netscape. Parametr bezpieczny wskazuje. Cookie są plikami tekstowymi zapisanymi na komputerze klienta i są one ze swojej natury niewinne. time().Klasa Validator jest potężnym zestawem funkcji przyspieszających tworzenie oprogramowania. string ścieżka. " . int czas. 49 PHP – Kompendium wiedzy . Więcej ogólnych informacji na temat cookie można znaleźć w specyfikacji cookie firmy Netscape. Wydruk 3. if ( !empty( $CookieArray ) ) { $aValMessage = "Wartości: " . czy spełnia twoje wymagania.= "dwa tygodnie. cookie o podanej nazwie jest usuwane. $CookieArray[1]. że cookie może być przesyłane jedynie przez połączenie bezpieczne (HTTPS).". większość programistów WWW i użytkowników jest zaznajomiona z koncepcją cookie. Dowolne cookie odesłane do aplikacji przez przeglądarkę jest automatycznie konwertowane na zmienną PHP tak samo. Funkcja setcookie() jest zdefiniowana w sposób następujący: int setcookie( string nazwa. Ponieważ cookie są wysyłane jako część nagłówka HTTP. $aMessage . string wartość. • Każda przeglądarka przechowuje cookie niezależnie.= ". Wydruk 3. string domena.9 pokazuje jak ustawiać i wyświetlać cookie. setcookie( "LastTime". $LastTime ).10 pokazane jest jak używać buforowania wyjścia w połączeniu z funkcją setcookie(). To samo ograniczenie obowiązuje również dla funkcji header(). Cookie Z powodu trwającej debaty na temat użycia cookie.

ich tworzenie w PHP jest łatwe i proste. skrypt spowoduje błąd. W aplikacjach WWW nie ma niezawodnego mechanizmu kontroli danych po wyjściu z poszczególnych pól. </body> </html> <?php ob_end_flush(). w jakiej chciałeś obsługiwać cookie. Oznacza to. setcookie( "CookieArray[1]" ). że będą przetwarzane przez przeglądarkę. } // usunięcie niezwykle istotnej tablicy wartości setcookie( "CookieArray[0]" ). $aStartValue. time() + 60 ). że jeżeli istnieje błąd w danych. Ważne zagadnienia programowania dla WWW Część ta zawiera niektóre tematy. jakie muszą brać pod uwagę programiści przechodzący z pisania zwykłych aplikacji na aplikacje oparte o WWW. ?> </body> </html> Wydruk 3. ?> <html> <head> <title>Użycie cookie</title> </head> <body> <?php print( $aMessage . "anyvalue". czy należy używać cookie będzie nadal trwała. // dodanie niezwykle istotnej tablicy wartości setcookie( "CookieArray[0]". $aValMessage ). $aTwoWeeks ). jeżeli chciałeś usunąć cookie a następnie ustawić nowe o tej samej nazwie. więc cała kontrola poprawności jest przeprowadzana na serwerze.9. "<br><br>" . ?> Działa świetnie. Jeżeli funkcja ob_start() jest zakomentowana. Dalsze rozważania na temat cookie będą kontynuowane w rozdziale 7 „Sesje i stan aplikacji”. setcookie( "CookieArray[1]". $aStartValue = 0. Problemy te powstają zwykle w czasie przetwarzania i wykorzystywania danych przesłanych z formularza HTML. aby ustawić nową wartość a następnie usunąć poprzednią wartość. Proces ten jest pokazany na wydruku 3. Należy wywoływać setcookie() w takiej kolejności jak się spodziewasz. ?> Ostatnia uwaga na temat cookie W poprzedniej wersji PHP jeżeli chciałeś ustawić wiele cookie za pomocą jednego skryptu. */ ob_start().10. Mimo. W PHP4 zostało to usunięte. ?> <html> <head> <title>Użycie setcookie() wraz z buforowaniem wyjścia</title> </head> <body> <?php setcookie( "anyname". użytkownik nie będzie o nim wiedział aż do chwili Rozdział 3 – Formularze i cookie 50 . należało najpierw wywołać setcookie(). $aValMessage = "Wartości nie są dostępne!". Użycie setcookie() razem z buforowaniem wyjścia <?php /* Uruchomienie buforowania wyjścia. musiałeś wywoływać setcookie() w odwrotnej kolejności do tej. Obsługa nieprawidłowych danych Pierwszym problemem jest sposób obsługi nieprawidłowych danych. $aTwoWeeks ). że debata na temat tego. Na przykład. W tradycyjnych aplikacjach dane wprowadzone przez użytkownika są często kontrolowane natychmiast po ich wprowadzeniu. Pozwala to natychmiast informować o nieprawidłowych danych.$aStartValue } else { = $CookieArray[1] + 1. $aStartValue + 1.

$aValidPhone = $aValidator->is_phone( $Phone ). Drugą metodą obsługi nieprawidłowych danych jest ponowne pokazanie strony formularza z zainicjowanymi wszystkimi polami i zaznaczonymi nieprawidłowymi pozycjami.php3" ). przechodzimy do odpowiedniej strony header( "Location:thanks. */ include( ". $aEmailTextCol = "black". Niektóre przeglądarki nie utrzymują wartości formularza po użyciu przycisku Wstecz. przytoczymy tutaj dwa z nich. // na początku przestawiamy skrypt na zbieranie nowych danych. } } ?> <html> <head> <title>Inteligentna obsługa nieprawidłowych danych</title> </head> <body> <?php if ( empty( $Submit ) ) { ?> Proszę wprowadzić numer telefonu i adres email. Na wydruku 3. if ( $aValidEmail == False ) $aEmailTextCol = "red". $aCurEmailVal = $Email. Sprawdź dane oznaczone kolorem czerwonym. Jeżeli jednak tworzysz duży formularz nie należy używać tej metody. ale jest najprostszy do zrealizowania. if ( !empty( $Submit ) ) { /* Jeżeli zmienna $Submit jest zainicjowana jesteśmy tutaj po przesłaniu danych do skryptu. $aCurEmailVal = "". ale skutkuje powstaniem solidniejszej i bardziej użytecznej aplikacji. <br> <?php } else { // if ?> We wprowadzonych danych wystąpiły błędy. aby wrócił do poprzedniej strony i poprawił dane. $aPhoneTextCol = "black". Dlatego w trakcie tworzenia aplikacji musisz się zdecydować. Pierwszą metodą jest wypisywanie błędów i nakazanie użytkownikowi. $aValidator = new Validator. } else { // Dane nieprawidłowe. if ( $aValidPhone && $aValidEmail ) { // Dane są prawidłowe.html\n" )./include/class. Inteligentna obsługa nieprawidłowych danych <?php error_reporting( 0 ). Jeżeli do formularza wpisywane jest bardzo mało danych (jedno lub dwa pola) metoda ta będzie do zaakceptowania. ponieważ ten sam skrypt może być użyty do pobierania nowych danych.11 pokazane jest w jaki sposób można użyć jednego skryptu do zbierania i kontroli poprawności danych na prostym formularzu używanym do wpisywania adresów e-mail i numerów telefonów. Możesz utworzyć taki formularz przesyłając dane z formularza do tego samego skryptu.11.. if ( $aValidPhone == False ) $aPhoneTextCol = "red".Validator. Metoda taka wymaga bardziej zaawansowanego projektowania. ponieważ może ona wymagać ponownego wprowadzenia wszystkich danych.?>"> Numer telefonu:</font> <input type="text" name="Phone" 51 PHP – Kompendium wiedzy . $aCurPhoneVal = "". Próbujemy sprawdzić wartości zmiennych formularza.przesłania danych formularza. zmiany danych istniejących i kontroli poprawności tych danych. wyróżniamy je $aCurPhoneVal = $Phone. $aValidEmail = $aValidator->is_email( $Email ). Istnieje kilka sposobów reagowania na błędy. <?php } // end if ?> <form action="handle_errors. Wydruk 3.phtml" method="post"> <font color="<?php print( $aPhoneTextCol ). Według mnie jest to najmniej pożądany sposób reakcji na błędy. w jaki sposób reagować na błędy.

Czasami formatowane są liczby. <html> <head> <title>Pobieranie danych do wyświetlenia</title> </head> <body> <form action="safedisplay. Pamiętając o tym pomyśl o formularzu. strona jest ładowana po raz drugi. Formularz i skrypt na wydruku 3. Zwykle nie jest to niebezpieczne.phtml" method="post"> Wprowadź tekst:<br> <textarea cols="40" rows="6" name="TheText"></textarea> <br><br> Wybierz metodę filtrowania: <select name="FilterType" size="1"> <option value="0">brak</option> Rozdział 3 – Formularze i cookie 52 . W przypadku programowania dla WWW wyświetlanie danych wprowadzonych do formularza w postaci strony WWW jest sprawą krytyczną. na pewno nie będzie lubiana. Jeżeli któreś pole zawiera nieprawidłową wartość. która wymaga od użytkownika wprowadzania danych należy rozważyć użycie podobnej metody do obsługi błędnych danych.value="<?php echo $aCurPhoneVal. Metoda ta pozwala na szybką identyfikację przez użytkownika danych. Są to funkcje strip_tags() i htmlentities().?>"> Adres e-mail:</font> <input type="text" name="Email" value="<?php echo $aCurEmailVal. które wymagają poprawienia i nie wymaga ponownego wprowadzenia całej zawartości formularza. że stworzysz formularz w którym zapisywane będą: nazwa użytkownika. Dzieje się tak. Gdy użytkownik kliknie przycisk Wyślij. więc sprawdzana jest poprawność danych. ale tym razem zmienna $Submit nie jest pusta. PHP posiada kilka funkcji pomagających w tym zadaniu. które zostały podane w dodatkowym opcjonalnym parametrze.. i &gt. Załóżmy. nieprawidłowe dane są wyświetlane kolorem czerwonym. Po wprowadzeniu tekstu wyświetlasz komunikat w celu weryfikacji a następnie przetwarzasz ten komunikat. Wybór metody obsługi błędów może być kluczową decyzją przy projektowaniu aplikacji. która powoduje przekierowanie przeglądarki do nowej strony zawierającej podziękowanie. Dodatkowo.?>"> <br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> W skrypcie na wydruku 11. Jeżeli dostarczysz użytkownikom formularz a następnie będziesz wyświetlał wpisane dane. ale na pewno skutkuje różnymi efektami ubocznymi. ale tym razem pola mają wartości wprowadzone poprzednio przez użytkownika. Pomysłowi lub złośliwi użytkownicy mogą próbować przetestować twój serwer WWW dodając znaczniki HTML lub kod JavaScript w treści komunikatu. ale zwykle nie ma zbyt dużo kłopotu przy wyświetlaniu danych wprowadzonych przez użytkownika. Jeżeli twoja aplikacja będzie niewygodna lub wymagać będzie ponownego wprowadzania danych. Funkcja htmlentities() konwertuje specjalne znaki HTML na odpowiadające im symbole HTML. Jeżeli tworzysz aplikację WWW. gdy strona jest otwierana bezpośrednio.12. aby zaznaczyć wystąpienie błędu. aby wyświetlać wartości walutowe lub dodać separatory tysięcy. niektórzy użytkownicy będą dodawać znaczniki HTML.?>"> <br> <font color="<?php print( $aEmailTextCol ). adres e-mail oraz treść uwagi. Aby uniknąć tego problemu zawsze należy przetwarzać dane wprowadzone do formularza przed ich wyświetleniem. Funkcja strip_tags() usuwa wszystkie znaczniki z ciągu oprócz tych. Przedstawione metody nie są jedynymi stosowanymi do obsługi błędnych danych. wywoływana jest funkcje header(). ale ilustrują one podstawy tworzenia aplikacji WWW. w którym użytkownicy będą mogli wpisywać swoje uwagi. więc formularz jest wyświetlany z pustymi polami. Wydruk 3. Obróbka danych do wyświetlenia. ponieważ przeglądarka interpretuje cały tekst otrzymany z serwera WWW. Jeżeli oba pola mają poprawne dane. Na przykład znaki < i > są zastępowane przez &lt. formularz wywoływany jest ponownie. Obsługa i formatowanie wyświetlanych danych W zwykłej aplikacji wyświetlanie danych wprowadzonych przez użytkownika nie wymaga zwykle formatowania lub przetwarzania. aby sprawdzić co się stanie. zmienna $Submit jest pusta.12 pokazuje obróbkę danych do ponownego wyświetlenia.

4. i 3.3. Rysunek 3. Rysunek 3.3. pokazują wyniki filtrowania danych z formularza za pomocą funkcji odpowiednio strip_tags() i htmlentities(). case 2 : // htmlentities $aDisplayText = htmlentities( $TheText ). Rysunki 3.Skrypt safedisplay2. break. pokazują formularz wejściowy i wyniki działania skryptu. zawiera formularz wprowadzania danych.3. case 1 : // strip_tags $aDisplayText = strip_tags( $TheText ). } ?> <html> <head> <title>Bezpieczne wyświetlenie danych użytkownika</title> </head> <body> <?php print( $aDisplayText ). do 3. jeżeli nie ma filtrowania. pokazuje co się dzieje. switch ( $FilterType ) { case 0 : // brak $aDisplayText = $TheText. break.6. break.phtml --> <?php error_reporting( 255 ).6. Rysunek 3.5. Formularz wprowadzania danych 53 PHP – Kompendium wiedzy .<option value="1">strip_tags()</option> <option value="2">htmlentities()</option> </select> <br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> <!-. ?> </body> </html> Rysunki 3.

Wyświetlanie bez filtrowania Rysunek 3.Rysunek 3.4. Wyświetlanie ze strip_tags() Rozdział 3 – Formularze i cookie 54 .5.

która usuwa te dodatkowe znaki. tłum.Rysunek 3. Wyświetlanie z htmlentities() Jeżeli dokładnie przyjrzysz się tym rysunkom zauważysz. ale z dodatkowymi opcjami które powodują wywołanie funkcji strip_slashes() i nl2br().6.ini magic_quotes_gpc. magic_quotes_runtime i magic_quotes_sybase. Jeżeli jest ona uaktywniona. że HTML nie interpretuje znaku CR ani LF jako znaku podziału wiersza. jeżeli dane te będą zapisywane w bazie danych. która konwertuje znaki nowej linii na znaczniki <br>. są automatycznie poprzedzane ukośnikiem.Skrypt safedisplay2.phtml --> <?php 1 Znak o kodzie zero (przyp. Na przykład pojedynczy apostrof jest wyświetlany na stronie jako sekwencja \'. Aby wyświetlić taki ciąg. Na wydruku 13 znajduje się ten sam formularz i skrypt co na wydruku 12.) 55 PHP – Kompendium wiedzy . należy wywołać funkcję strip_slashes(). Ulepszona obróbka danych do wyświetlenia <html> <head> <title>Pobieranie danych do wyświetlenia</title> </head> <body> <form action="safedisplay2. Wydruk 3. Również znaki końca linii wprowadzone w polu tekstowym nie są uwzględniane w wyświetlanym tekście. że wystąpi on w bloku <pre></pre>. Jeżeli chodzi o problem ze znakami nowej linii.13. ponieważ nie będziesz musiał ręcznie oznaczać tych znaków w ciągu SQL. Jest to szczególnie przydatne. NUL1 i znaki backslash pochodzące z zewnętrznych źródeł. Pierwsze z zakłóceń jest powodowane przez dyrektywę konfiguracji --enable-magic-quotes oraz opcje pliku php.phtml" method="post"> Wprowadź tekst:<br> <textarea cols="40" rows="6" name="TheText"></textarea> <br><br> Wybierz metodę filtrowania: <select name="FilterType" size="1"> <option value="0">none</option> <option value="1">strip_tags()</option> <option value="2">htmlentities()</option> </select> <br><br> <input type="checkbox" name="DoSS"> strip_slashes()<br> <input type="checkbox" name="DoNB"> nl2br()<br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> <!-. że widać niespodziewane wyniki po wyświetleniu danych. chyba. należy pamiętać. wszystkie apostrofy. cudzysłowy. na przykład formularzy i bazy danych. PHP posiada funkcję nl2br().

switch ( $FilterType ) { case 0 : // brak $aDisplayText = $TheText.7. } if ( $DoSS == "on" ) $aDisplayText = stripslashes( $aDisplayText ). ?> <html> <head> <title>Bezpieczne wyświetlenie danych użytkownika</title> </head> <body> <?php print( $aDisplayText ). break. ?> </body> </html> Rysunek 3. Formularz wprowadzania danych Rozdział 3 – Formularze i cookie 56 . case 2 : // htmlentities $aDisplayText = htmlentities( $TheText ). if ( $DoNB == "on" ) $aDisplayText = nl2br( $aDisplayText ). case 1 : // strip_tags $aDisplayText = strip_tags( $TheText ).error_reporting( 0 ). break. break.

8. strip_slashes() i nl2br() Po wprowadzeniu zmian pokazanych na wydruku 3. W rozdziale tym omówiono również proces zapamiętywania i odczytywanie cookie na komputerze klienta. Jeżeli wcześniej miałeś doświadczenie jedynie ze zwykłymi aplikacjami. jak widać na rysunku 3. W rozdziale tym omówiono niektóre narzędzia umożliwiające obsłużyć nieprawidłowe dane i zabezpieczyć przed szkodliwymi danymi. że każda przeglądarka działa nieco inaczej. upraszcza on znacznie proces interakcji z formularzami HTML. Ważniejsze od prostego pobierania danych od użytkowników jest prawidłowa obsługa tych danych i zabezpieczanie serwera i użytkowników przed nieprawidłowymi lub niebezpiecznymi danymi. Podsumowanie Rozdział ten zawiera opis podstaw przetwarzania formularzy przy użyciu PHP.Rysunek 3.8. Szczegółowe omówienie tych problemów znajduje się w rozdziale 9 „Niezależność od przeglądarki”. 57 PHP – Kompendium wiedzy . musisz pamiętać o tych pułapkach stosowania przeglądarki jako warstwy prezentacji aplikacji. Wyświetlanie przefiltrowane przez strip_tags(). formularz wprowadzania danych i postać danych wynikowych jest taka.7. Wszystkie te tematy razem stanowią podstawę do tworzenia interaktywnych aplikacji WWW. i 3.13. Oprócz pamiętania o wspomnianych problemach należy również zwrócić uwagę. Ponieważ PHP został zaprojektowany jako język programowania dla WWW.

W przykładzie tym nie zostały wykorzystane wszystkie dostępne w PHP funkcje operujące na plikach. Powoduje to automatyczne zliczanie odwołań do strony. W aplikacjach opartych o sieć WWW stan musi być utrzymywany przez serwer WWW. Ponieważ aplikacja będzie działać w kontekście serwera WWW. czytania.1 pokazane zostało w jaki sposób można zrealizować liczniki dostępu do stron witryny. W chwili obecnej wystarczy wiedzieć. pamiętać o zagadnieniach bezpieczeństwa. W przypadku zwykłego programu. Ważne jest. Użycie plików do zliczania odwołań do stron witryny <?php /* Plik ten może być dołączany do dowolnego skryptu PHP. Operacje na plikach Wstęp Obsługa plików jest zawarta we wszystkich nowoczesnych językach programowania. Oczywiście istnieje wiele sytuacji gdy narzut czasowy wprowadzany przez bazę danych lub wymagania aplikacji powodują. użytkownik uruchamia go. że do utrzymywania stanu aplikacji i tworzenia innych mechanizmów przechowywania danych można użyć plików. Tworzy on zmienną globalną $aPageAccessCount. aby używając plików. W większości przypadków użycie bazy danych zamiast plików jest o wiele bardziej bezpieczne i praktyczne. pliki będą miały uprawnienia użytkownika przy pomocy którego uruchamiany jest serwer WWW. Do obsługi plików i innych obiektów systemu plików PHP posiada funkcje podobne do tych spotykanych w języku C. w funkcjach służących do odczytu i zapisu. // Sprawdzenie czy plik istnieje if ( is_file( $aLogFilePath ) == True ) { // Otwarcie i odczytanie pliku. . że równie łatwo można zapisać dane do pliku jak również wysłać je poprzez potok do innego programu. W czasie pracy programu stan aplikacji jest utrzymywany w pamięci. otwarcie. $aCountArray = array(). którego uprawnienia ograniczają dostęp przez aplikację do obiektów systemu plików. Szczegółowe przedstawienie zarządzania stanem aplikacji można znaleźć w rozdziale 7 „Sesje i stan aplikacji”. zapis i zamknięcie prostego pliku śladu. Tak jak C. UŻYCIE: Wystarczy dołączyć ten plik. $aLogFilePath = "/www/auto_logs/access. odczyt. Zdolność ta powoduje. jest sposób utrzymywania stanu aplikacji. Odczyt i zapis plików Jedną z głównych różnic przy pisaniu aplikacji opartych o sieć WWW w stosunku do zwykłych aplikacji.Rozdział 4. */ error_reporting( 0 ). wykonuje kilka komend i kończy działanie programu. Na wydruku 4.log". PHP używa uchwytów plików oraz pozwala na tworzenie uchwytów (pozwalających na operacje innymi typami strumieni danych. Wydruk 4. Bardziej szczegółowy opis wszystkich funkcji znajdują się w skorowidzu funkcji na końcu książki. ponieważ klientem jest zwykle prosta przeglądarka WWW. "r" ). która zawiera ilość odwołań do skryptu który dołącza ten plik. Do tego celu wykorzystane zostały podstawowe operacje na plikach. aby korzystając z plików nie naruszyć systemu bezpieczeństwa serwera WWW. Należy uważać. Zdolność do tworzenia. że pliki są jedynym sensownym rozwiązaniem. zapisu i innych operacji na plikach lub innych obiektach systemu plików jest niezbędna do zrealizowania obsługi sesji i serializacji.1. W przypadku Apache domyślnie jest to użytkownik nobody. takimi jak gniazda i potoki). Format pliku to oddzielone tabulatorami // pary opisujące kolejne skrypty: // ścieżka-do-skryptu licznik $aFile = fopen( $aLogFilePath.

możesz użyć tej tablicy do wyświetlenia liczników dla wszystkich stron witryny a nie tylko bieżącej strony.php" ). ?> <html> <head> <title>Strona testowa 1</title> </head> <body> Strona ta była oglądana <b> <?php print( $aPageAccessCount ). // Zapis całej tablicy do pliku $aFile = fopen( $aLogFilePath. W skrypcie tym sprawdzamy za pomocą funkcji is_file() czy istnieje plik śladu. Po wypełnieniu tablicy uaktualniany jest licznik odwołań do bieżącej strony (rozpoznawanej przy użyciu zmiennej globalnej PHP $PATH_TRANSLATED) i wartość ta jest przypisywana do zmiennej $aPageAccessCount.2 pokazane jest strona demonstrująca jak łatwo można użyć tego licznika. Na koniec cała tablica jest zapisywana do pliku śladu. Nie jest to efektywny sposób. $aCountArray[$PATH_TRANSLATED] = $aPageAccessCount. Bardziej efektywne jest odczytywanie i zapis tylko jednej wartości a nie całego pliku. który zwraca cytat dnia. znak tabulacji i wartość licznika. foreach ( $aCountArray as $aKey => $aValue ) { fputs( $aFile. 59 PHP – Kompendium wiedzy . Wydruk 4. Jeżeli chcesz. ?> </b> razy. że jest to bardzo nieefektywne rozwiązanie. $aLine ). } // Ustawienie globalnego licznika odwołań do strony // i uaktualnienie tablicy temp $aPageAccessCount = $aCountArray[$PATH_TRANSLATED] + 1. 1024 ).1 pokazujemy użycie jednego pliku do przechowywania liczników odwołań do dowolnej liczby stron witryny. Protokół quotd jest bardzo prosty. Jeżeli plik ten istnieje. Po zestawieniu połączenia serwer wysyła strumień danych tekstowych a następnie zamyka połączenie. Użycie skryptu z wydruku 4. </body> </html> Użycie gniazd PHP umożliwia dostęp do surowych gniazd TCP/IP. Na wydruku 4. "$aKey\t$aValue\n" ). POP3 i SMTP posiadają swoje implementacje w PHP. Z perspektywy klienta wystarczy jedynie zestawić połączenie. $aTempArray = explode( "\t". należy pamiętać. Niektóre z bardziej znanych protokołów TCP/IP. Na wydruku 4. ale pokazuje ideę takiego licznika. za pomocą których można komunikować się z innymi aplikacjami za pomocą dowolnego protokołu. Każda linia zawiera pełną ścieżkę dostępu do skryptu. "w" ). ?> Na wydruku 4.2. jego kolejne linie są odczytywane i analizowane. } } fclose( $aFile ). więc nie musisz w tych przypadkach używać surowych gniazd.while( !feof( $aFile ) ) { $aLine = fgets( $aFile. odczytać dane a następnie zakończyć połączenie. } fclose( $aFile ). if ( count( $aTempArray ) == 2 ) { $aCountArray[$aTempArray[0]] = $aTempArray[1]. na przykład HTTP. Jeżeli szukasz takiego mechanizmu do twojej witryny. Linia taka jest dzielona przy pomocy funkcji explode() na nazwę skryptu i wartość licznika a następnie wartości te są zapisywane w tablicy asocjacyjnej.1 <?php include( "auto_counter.3 pokazano sposób dostępu za pomocą gniazd do serwera quotd.

4. ?> </body> </html> Użycie potoków Tak jak w przypadku gniazd. 1024 ).php */ // ścieżka do programu whois $whois_prog = '/usr/bin/whois'. które jest dostępne w większości systemów Unix. } pclose( $aFile ). } fclose( $aFile ). Skrypt ten ilustruje również częstą praktykę używania tego samego skryptu do wyświetlenia formularza i przetworzenia jego danych. "r" ) ) { // odczytanie wszystkich danych z potoku while ( !feof( $aFile ) ) { $aLine = fgets( $aFile. } ?> <html> <head> <title>Whois: Uzycie potoków w PHP</title> </head> <body> <?php if ( $REQUEST_METHOD == 'POST' ) { // otwarcie potoku do polecenia whois if ( $aFile = popen( "$whois_prog $WhoisQuery". } ?> <form action="<?php echo $PHP_SELF ?>" method="post"> Wprowadź zapytanie <b>whois</b>: <input type="text" name="WhoisQuery"> <input type="submit" name="Submit" value="Submit"> </form> </body> </html> Rozdział 4 – Operacje na plikach 60 .4 pokazane jest użycie potoku do odczytania wyniku zapytania do polecenia whois. 1024 ). Potok może być użyty do odczytu danych wyjściowych z programu lub skryptu. print( "$aLine<br>" ). potoki są traktowane jak kolejny uchwyt pliku. Wydruk 4. } print( "<hr>" ). } else { echo "Nie mogę otworzyć $whois do odczytu!<br>". print( "$aLine<br>" ). Użycie gniazd <html> <head> <title>Przykład wykorzystania serwera QOTD: Użycie gniazd w PHP</title> </head> <body> <?php // otwarcie gniazda serwera qotd $aFile = fsockopen( "208. exit.129.36.Wydruk 4. Jedyną różnicą pomiędzy plikiem i potokiem jest to.3. Ten prosty skrypt i formularz pozwalają na wprowadzenie zapytania dla whois. Na wydruku 4. if ( !is_file( $whois_prog ) ) { // nie udało się znaleźć programu echo "Nie mogę znaleźć $whois_prog!<br>". // odczytanie wszystkich danych ze strumienia while ( !feof( $aFile ) ) { $aLine = fgets( $aFile. Skrypt przetwarzający zapytanie whois <?php /* whois. 17 ). że potok jest jednokierunkowym strumieniem danych.164".

?> <html> <head> <title>Użycie klasy File</title> </head> <body> Poniżej znajduje się lista plików w bieżącym katalogu. Klasa File dostępna z WebMasters Net (http://www. skrypt zamieszczony na wydruku 4. $nIndex < count( $aDirContents ).net) jest przydatnym narzędziem. print( "</pre>" )." ). for ( $nIndex = 0.6 wyświetla jego zawartość używając celu klasy File do odczytania jego zawartości.6.Klasa File W poprzednim rozdziale wspominaliśmy. $aFileClass = new File().File. na przykład gniazd i potoków. ?> </body> </html> Podsumowanie Zdecydowanie się na użycie plików w aplikacji opartej na WWW jest jedną z krytycznych decyzji w fazie projektowania aplikacji.<br><br> <?php $aFileClass = new File().php3" ). print( "$aCurFile</a><br>" ). 61 PHP – Kompendium wiedzy . Użycie klasy File do wyświetlenia zawartości bieżącego katalogu <?php include( "class. Noe wszystkie aplikacje używają plików. ale aby efektywnie korzystać z różnych typów strumieni danych. } ?> </body> </html> Wydruk 4. Opis operacji na plikach zawarty w tym rozdziale oraz opis formularzy zamieszczony w rozdziale poprzednim stanowią odpowiednią podstawę do następnego rozdziału.5 pokazany jest skrypt wyświetlający nazwy wszystkich plików w bieżącym katalogu w postaci łączy. „Wysyłanie plików przez formularz”./class.File.php3" ). gdy twoja aplikacja intensywnie wykorzystuje pliki. Klasa ta zawiera wiele często używanych funkcji PHP operujących na plikach i hermetyzuje kontrolę błędów. że do PHP dostępne są świetne narzędzia dodatkowe pochodzące z różnych źródeł. print( "<a href=\"disp_file. szczególne wtedy.5. print( nl2br( htmlentities( $aFileCont ) ) ). print( "<pre>" ).<br> Kliknij nazwę pliku aby zobaczyć ich zawartość. Gdy użytkownik kliknie łącze. należy poznać sposoby korzystania z uchwytów plików i funkcji operujących na plikach. $aDirContents = $aFileClass->get_files( ". Na wydruku 4. Wydruk 4. $aFileCont = $aFileClass->read_file( $fn ). ale również przedstawia dodatkową klasę ułatwiającą operacje na plikach. dzięki czemu możesz więcej czasu poświęcić logice aplikacji zamiast zajmować się pisaniem podstawowych konstrukcji kontroli błędów. $nIndex++ ) { $aCurFile = $aDirContents[$nIndex]. ?> <html> <head> <title>Użycie klsy File</title> </head> <body> <?php print( "The file <b>$fn</b>:<br><br>" ).phtml?fn=$aCurFile\">" ). Wyświetlenie zawartości pliku za pomocą klasy File <?php include( ".theWebMasters. Rozdział ten zawiera nie tylko opis podstawowych operacji na plikach i systemie plików.

1. Wydruk 5. Wydruk 5. jeżeli są one niezbędne do działania aplikacji. Pisząc skrypt obsługujący przesyłanie pliku należy pamiętać. • $thefile_type — Zmienna ta zawiera typ MIME przesyłanego pliku (o ile przeglądarka udostępnia taką informację). Jeżeli pozwolisz użytkownikom na wysyłanie plików za pomocą formularza. PHP posiada wbudowany mechanizm pozwalający na odebranie pliku wysłanego z przeglądarki zgodnej z RFC 1867. ponieważ wysyłanie plików wymaga poznania zarówno formularzy HTML. Jeżeli przesłany plik nie ma właściwego typu lub jest większy. tak jak jest to pokazane na Wydruku 5.Rozdział 5.2 zawiera kod obsługi przesyłania pliku poprzez formularz z Wydruku 1 i jeżeli plik jest rysunkiem (w formacie GIF lub JPEG) mniejszym od 100 kB. . Formularz HTML ze znacznikiem <INPUT> <html> <head> <title>Formularz do przesyłania plików</title> </head> <body> <form action="upload_single. • $thefile_size — Zmienna zawiera wielkość przesłanego pliku w bajtach.phtml" method="post" enctype="multipart/form-data"> Wyślij plik: <input type="file" name="thefile"><br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> Po wysłaniu danych formularza z wydruku 5. ale jeżeli masz zamiar przesyłać duże pliki należy się zastanowić nad zastosowaniem innego mechanizmu.1. Obsługa przesyłania plików w PHP jest bardzo łatwa. PHP tworzy automatycznie cztery zmienne globalne. Nazwy tych zmiennych są tworzone w oparciu o nazwę znacznika <INPUT> w formularzu.2.1. plik zostanie stracony. a przykład anonimowego FTP. jest on wyświetlany. że PHP automatycznie usuwa plik tymczasowy po zakończeniu skryptu. Większość nowoczesnych przeglądarek jest zgodnych z tym dokumentem. które opisują przesłany plik: • $thefile — Zmienna zawiera nazwę pliku tymczasowego w którym znajduje się plik przesłany na serwer. jak i funkcji systemu plików.1. Wysyłanie plików przez formularz Wstęp Poprzednie dwa rozdziały omawiały niezbędne podstawy dla tego rozdziału. wyświetlany jest komunikat błędu. • $thefile_name — Zmienna ta zawiera nazwę pliku na komputerze z którego został wysłany. Możesz również pomyśleć o stworzeniu dodatkowego mechanizmu przesyłania plików. musisz rozważyć dopuszczalne typy plików oraz ich wielkości. Znacznik <FORM> musi posiadać atrybut ENCTYPE ustawiony na multipart/form-data zamiast domyślnego application/x-www-form-urlencoded. zawiera prosty formularz HTML zawierający jeden znacznik <INPUT>. Skrypt na wydruku 5. ponieważ został on włączony do standardu HTML 3. więc jeżeli nie skopujesz go. Musisz również umieścić na formularzy znacznik <INPUT> typu file. Wysyłanie pojedynczego pliku Formularz przy pomocy którego można przesyłać pliki różni się kilkoma szczegółami od zwykłego formularza HTML. Mechanizm wbudowany w PHP działa świetnie dla małych plików.

Jeżeli nie został wybrany plik. przy pomocy wyrażenia dirname($PATH_TRANSLATED) odczytywany jest bieżący katalog na serwerze WWW.3 pokazany jest formularz identyczny z tym z wydruku 5. Następnie sprawdzane jest. PHP posiada mechanizm pozwalający na ograniczanie w skrypcie wielkości przesyłanych plików. Jednak przykład ten miał za zadanie pokazanie jak łatwo można obsłużyć za pomocą PHP operacje przesyłania pliku. if ( !empty( $thefile_name ) ) // nie wybrano pliku { if ( ( $thefile_type == "image/gif" ) || ( $thefile_type == "image/pjpeg" ) || ( $thefile_type == "image/jpeg" ) ) { if ( $thefile_size < ( 1024 * 100 ) ) { $aCurBasePath = dirname( $PATH_TRANSLATED ). Opuszczono również inne zagadnienia kontroli błędów.= "Plik nie jest typu gif ani jpeg". copy( $thefile. Ograniczenie wielkości przesyłanego pliku za pomocą MAX_FILE_SIZE <html> <head> 63 PHP – Kompendium wiedzy . $thefile_name. Zmienna $PATH_TRANSLATED jest zmienną PHP i zawiera pełną ścieżkę do bieżącego skryptu. Na wydruku 5. nie wzięto pod uwagę. Wydruk 5. $aNewName ). na przykład kontrolę poprawności wykonania funkcji copy. Jest to realizowane przez dodanie do formularza ukrytego pola o nazwie MAX_FILE_SIZE. docelowy katalog musi posiadać odpowiednio ustawione uprawnienia. Na koniec. że nie wszystkie przeglądarki wysyłają typu MIME pliku.= "Za duży plik !!!". } ?> </body> </html> W przykładzie zamieszczonym na wydruku 5.2. } ?> <html> <head> <title>Wyświetlenie przesłanego pliku</title> </head> <body> <?php if ( $aErrors != "" ) { print( "<b>Wystąpił błąd</b>: $aErrors<br>" ). print( "<img src=\"uppics/$thefile_name\" border=\"0\">" ). zmienna $thefile_name jest pusta.2. Dodając /uppics/ i oryginalną nazwę pliku na komputerze lokalnym. czy został wybrany plik do przesyłania. $aNewName = $aCurBasePath . że uprawnienia do katalogu muszą pozwolić na zapis przez użytkownika nobody. czy plik ma odpowiednią wielkość i typ MIME. } else { $aErrors . Korzystając z Apache w systemie Linux oznacza to. Jeżeli obie wartości zostaną zaakceptowane.= "Nie wybrano pliku".Wydruk 5. Funkcja dirname() zwraca nazwę katalogu z podanej ścieżki. } else { print( "Przesłany plik:<br><br>" ). Należy pamiętać.3. W przykładzie tym na początku sprawdzane jest. ale dodane zostało pole MAX_FILE_SIZE ograniczające wielkość przesyłanych plików do 100 kB. } } else { $aErrors .1. } } else { $aErrors . tworzymy nową ścieżkę. przesłany plik jest kopiowany z katalogu tymczasowego do katalogu określonego przez przed chwilą skonstruowaną ścieżkę. Obsługa przesyłania pliku <?php $aErrors = "". "/uppics/" . że aby operacja kopiowania się udała.

Jeżeli używasz Linuksa i Apache.ini opcję konfiguracji display_errors na Off. Jeżeli więc twoja aplikacja dopuszcza przesyłanie dużych plików. że jeżeli opcja konfiguracji display_errors ma wartość On (domyślnie) w przeglądarce będzie się pojawiał komunikat błędu. który znajduje się na końcu książki). do 2 megabajtów. // każdy przesłany plik należy skopiować Rozdział 5 – Wysyłanie plików przez formularz 64 .ini. Obsługa czterech przesyłanych plików <?php $aBasePath = dirname( $PATH_TRANSLATED ). nad jakim należy się zastanowić w trakcie pisania skryptu obsługi przesyłania plików jest to.phtml" method="post" enctype="multipart/form-data"> <INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="102400"> Wyślij plik: <input type="file" name="thefile"><br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> Pułapki PHP domyślnie ogranicza wielkość plików. musisz ustawić w pliku php. Wydruk 5. twoi użytkownicy mogą dosyć długo czekać zanim zobaczą komunikat o odrzuceniu przesyłanego pliku. jakie można przesyłać używając tego mechanizmu.conf (więcej szczegółów znajduje się w rozdziale o opcjach konfiguracji.<title>Formularz do przesyłania plików</title> </head> <body> <form action="upload_single. Jeżeli nie chcesz aby pojawiał się ten komunikat. Możesz następnie ustawić opcję log_errors na On a error_log na wartość odpowiednią dla twojego środowiska. Wartość ta może być zmieniona przez ustawienie wartości upload_max_filesize w pliku php.5. Poniższy przykład pokazuje użycie tablicy do przesłania czterech plików. Mimo tego. zmienna $thefile będzie miała wartość none. PHP generuje błąd. Aplikacja twoja może sprawdzać zmienne przesyłu plików i odpowiednio obsługiwać błędy. Innym problemem. przerywa przesyłanie i ustawia nazwę pliku na none. Jeżeli użytkownikowi nie uda się przesył pliku. a $thefile_name będzie zawierała odpowiednią wartość. ale akceptuje jedynie niektóre typy plików. ustawienie error_log na stderr spowoduje. że ta graniczna wielkość pliku jest ustawiana w celu chronienia serwera WWW. że zanim rozpocznie się wykonywanie skryptu musi zostać przesłany cały plik lub maksymalna określona ilość bajtów. Oznacza to. Ponieważ błąd przekroczenia wielkości przesyłanego pliku występuje przed wykonaniem jakiejkolwiek linii skryptu. że wszystkie błędy PHP trafią do dziennika błędów Apache. lub ustawienie dyrektywy w pliku Apache. nie ma możliwości przechwycenia generowanego ostrzeżenia generowanego przez mechanizm przesyłania plików.4. Przesyłanie czterech plików <html> <head> <title>Formularz do przesyłania plików</title> </head> <body> Proszę podać cztery pliki rysunków do przesłania: <form action="upload_multiple. Ta wielkość jest ważniejsza od zmiennej formularza MAX_FILE_SIZE.phtml" method="post" enctype="multipart/form-data"> Plik 1: <input type="file" name="thefiles[]"><br><br> Plik 2: <input type="file" name="thefiles[]"><br><br> Plik 3: <input type="file" name="thefiles[]"><br><br> Plik 4: <input type="file" name="thefiles[]"><br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> Wydruk 5. Przesyłanie wielu plików Jeżeli chcesz przesłać kilka plików używając jednego formularza możesz skorzystać z tablicy PHP do przesłania danych o przychodzących plikach. sieje ona zniszczenie w twoich aplikacjach. Gdy osiągnięta zostanie graniczna wielkość pliku (zarówno ustawiona w formularzu jak i globalne maksimum).

$aFileClass = new File(). W przykładzie tym przesłany plik jest kopiowany do nowego katalogu.// i zapamiętać ich nowe ścieżki do późniejszego wykorzystania for ( $nIndex = 0. Nawet pozwolenie na wyświetlenie przesłanych plików niesie ze sobą potencjalne zagrożenie.6. copy( $thefiles[$nIndex]. że można je bezpiecznie uruchomić. // skopiowanie przesłanego pliku $aCurBasePath = dirname( $PATH_TRANSLATED ).6. $aNewName = $aCurBasePath . $nIndex < count( $thefiles ). foreach( $aNewNames as $aNewName ) { print("<img src=\"uppics/$aNewName\" border=\"0\"><br><br>"). że pliki te zostaną właściwie obsłużone na serwerze. copy( $thefile. } } } ?> <html> <head> <title>Wyświetlanie przesłanego rysunku</title> </head> <body> <?php $aCount = count( $aNewNames ). print( "Przesłano <b>$aCount</b> rysunki:<br><br>" ). należy brać pod uwagę każdą ewentualność. if ( ( $aType == "image/gif" ) || ( $aType == "image/pjpeg" ) || ( $aType == "image/jpeg" ) ) { $aNewName = $aBasePath . $aNewNames[] = $thefiles_name[$nIndex]. W rzeczywistości 65 PHP – Kompendium wiedzy . print( "</pre>" ).php3" ). ale wyświetlając plik odczytywany i wysyłany do przeglądarki jest plik tymczasowy. } ?> </body> </html> Bezpieczeństwo Jeżeli dopuszcza się dostarczanie jakichkolwiek danych do aplikacji. Można je jedynie odebrać i wyświetlić w postaci czystego tekstu i nie można zakładać.File. Naruszenie bezpieczeństwa podczas obsługi przesłanych plików <?php include( "class. "/uploads/" . $aNewName ). ?> <html> <head> <title>Naruszenie bezpieczeństwa przy przesyłaniu pliku</title> </head> <body> <?php // wyświetlenie zawartości pliku print( "Plik <b>$aNewName</b>:<br><br>" ). $aFileCont = $aFileClass->read_file( $thefile ). Na przykład. Jeżeli pozwalasz na przesyłanie plików musisz się upewnić. "/uppics/" . $nIndex++ ) { if ( !empty( $thefiles_name[$nIndex] ) ) { $aType = $thefiles_type[$nIndex]. print( "<pre>" ). print( nl2br( htmlentities( $aFileCont ) ) ). Na wydruku 5. $thefiles_name[$nIndex]. $aNewName ). jeżeli tworzysz witrynę do której programiści mogą przesyłać własne skrypty nie należy pozwalać na wykonywanie tych skryptów na serwerze. Wydruk 5. pokazany jest prosty przykład w jaki sposób mechanizm wyświetlania plików może spowodować dziurę w systemie bezpieczeństwa. $thefile_name. ?> </body> </html> Jest to oczywiście wymyślony przykład.

Aby wykorzystać niedoskonałość skryptu ktoś może wpisać do przeglądarki nazwę skryptu i podać nazwę dowolnego pliku na serwerze. że nie wolno zakładać. że niektórzy użytkownicy mogą nie posiadać dostatecznie szybkiego łącza aby efektywnie korzystać z tego mechanizmu. Niektórzy użytkownicy będą chcieli rozmyślnie wykorzystać słabości aplikacji a inni nieświadomie spowodują jej awarię. Należy dokładnie przemyśleć wszystkie możliwe skutki uboczne pozwolenia na przesyłanie plików na serwer WWW.prawdopodobnie odczytasz i wyświetlisz plik znajdujący się na ścieżce zapamiętanej w $aNewName. ale należy pamiętać.com/sciezka/upload_flaw. że będzie on wykonywany na systemie Uniksowym): http://serwer. Dla potrzeb tej prezentacji poprzedni plik pokazuje w jaki sposób źle napisany skrypt narusza system bezpieczeństwa. Rozdział 5 – Wysyłanie plików przez formularz 66 . więc dobrym pomysłem jest zapewnienie jeszcze jednego sposobu na dostarczanie plików do aplikacji. Nawet mimo tego.phtml?thefile=/etc/passwd Można przetestować to na komputerze z Uniksem. W rozdziale o formularzach kładłem nacisk na to. Na końcu rozdziału znajduje się mała część ilustrująca w jaki sposób źle napisany skrypt może stworzyć dziurę w systemie bezpieczeństwa serwera. Dopuszczenie do przesyłania plików do aplikacji może być w wielu przypadkach użyteczne. Na przykład wprowadzenie takiego adresu URL spowoduje wyświetlenie zawartości pliku /etc/passwd (zakładając. Zostały przytoczone przykłady obsługi jednego pliku jak również tablicy plików. Podsumowanie W rozdziale tym pokazane zostały sposoby odczytywania i wykorzystania plików przesłanych przez przeglądarki zgodne z dokumentem RFC 1867. że serwer WWW pracuje jako użytkownik nobody. że wszyscy użytkownicy aplikacji będą używali jej zgodnie z twoimi zamiarami. Tak samo jest i teraz. plik /etc/passwd musi być możliwy do odczytania przez wszystkich użytkowników. że niebezpieczeństwo jest rzeczywiste.

relacje pomiędzy danymi. że czytelnicy znają podstawy SQL w stopniu wystarczającym do zrozumienia przykładów zamieszczonych na wydrukach. Pseudokod opisujący pobieranie danych z dowolnego systemu bazy danych przedstawiony jest na wydruku 6. PHP pozwala na dostęp do danych przy użyciu bogatego zestawu funkcji związanych z bazami danych. które również nie zostanie odpowiednio dokładnie opisane w tej książce. Wybrałem MySQL ponieważ jest to wydajna baza danych dostępna na zasadach licencji GNU General Public License (GPL) i jest powszechnie używana do współpracy z PHP. język SQL jest sam w sobie niezwykle bogatym i wydajnym narzędziem. wyślij_wyrażenie_SQL(). Wydruk 6. istnieje wspólny model dostępu do każdego z typów baz danych. Najlepiej posiłkować się dokumentacją odmiany SQL zaimplementowanej w używanej przez ciebie bazie danych. Nazwy funkcji związanych z MySQL rozpoczynają się od mysql_ i podobna zasada obowiązuje w przypadku innych baz (W skorowidzu funkcji na końcu książki znajduje się kompletna lista funkcji związanych z bazami danych). ponieważ do większości baz danych dostępne są sterowniki tego standardu. jak na przykład indeksowanie. Jest to spowodowane tym. Pseudokod opisujący pobieranie danych z bazy <?php połącz_z_Bazą(). Wprowadzenie Jak można wywnioskować na podstawie dokumentacji. PHP może zostać użyty do prawdopodobnie dowolnej istniejącej bazy danych. że każda z baz danych ma własny zestaw funkcji. . Funkcje baz danych Każda z obsługiwanych baz danych posiada własny zestaw funkcji PHP. obsługa transakcji. Współpraca z bazami danych Wstęp Jedną z najważniejszych cech nowoczesnych języków programowania lub narzędzi programistycznych jest zdolność współpracy z bazą danych.1. Dodatkowo. Obsługiwane są między innymi takie bazy danych: Adabas D InterBase Solid dBase mSQL Sybase Empress MySQL Velocis FilePro Oracle Unix dbm Informix PostgreSQL Mictosoft SQL Server ODBC Obsługując ODBC. autorzy PHP uważają obsługę baz danych za jedną z najważniejszych i najsilniejszych cech PHP. W rozdziale tym skupimy się na przykładach użycia MySQL i ODBC.1. wybierz_bazę(). kaskadowe operacje wykonywane na danych i wiele innych. że systemy zarządzania relacyjnymi bazami danych (SZRBD) posiadają wiele bardzo wydajnych i niezwykle użytecznych mechanizmów zarządzania danymi. Mimo. Przykłady ilustrują zastosowanie języka PHP i nie zawsze pokazują najlepsze zastosowania SQL oraz działania na bazach danych. Z powodu ogromnej ilości obsługiwanych baz danych jest niemożliwe szczegółowe omówienie obsługi każdej z nich w tej książce.Rozdział 6. Zakładamy w tym rozdziale. ODBC wybrałem.

PRIMARY KEY (id). Jeżeli używasz systemu działającego w oparciu o Win32.mysql. "user". Pobieranie danych z bazy danych MySQL <html> <head> <title>Pobieranie danych z MySQL</title> </head> <body> <?php // Ukrywamy komunikaty błędów i sami je obsługujemy $aDBLink = @mysql_connect( "db. "pass" ). dystrybucję binarną albo RPM. Użycie MySQL Po zainstalowaniu i uruchomieniu MySQL można rozpocząć pisanie skryptów PHP. Na tej witrynie znajduje się najnowsza wersja systemu oraz dokumentacja opisująca instalację i konfigurację MySQL w różnych środowiskach.com". print( "$aFName. $aPos = $aRow["position"]. last varchar(20). Rozdział 6 – Współpraca z bazami danych 68 . Skrypt zamieszczony na wydruku 6. ?> Następne dwie części zawierają szczegóły konfiguracji i użycia MySQL i ODBC. if ( !empty( $aDBLink ) ) { // wybór bazy danych MySQL if ( mysql_select_db( "mydb". najszybszą metodą pozyskania serwera jest ściągnięcie skompresowanej instalacji binarnej. // Wykonanie zapytania SELECT $aQResult = mysql_query( $aSQL.pobierz_wynik().2. if ( $aQResult == True ) { // Pobranie wiersza danych i wypisanie dwóch pól while ( $aRow = mysql_fetch_array( $aQResult ) ) { $aFName = $aRow["first"]. Przy użyciu tej metody instalowane są wszystkie elementy serwera. więc możesz od razu zaczynać pracę. $aPos<br>" ). UNIQUE id (id) ) Wydruk 6. PHP4 posiada wbudowaną obsługę MySQL. adress varchar(255). Tabela której będę używał w dwóch kolejnych przykładach została utworzona za pomocą następującego kodu SQL: CREATE TABLE employees ( id tinyint(4) DEFAULT '0' NOT NULL auto_increment. Jednak jeżeli korzystasz z wbudowanej obsługi MySQL. MySQL MySQL jest świetną bazą danych dla większości projektów. więc nie musisz ponownie kompilować PHP aby używać funkcji mysql_. $aDBLink ) == True ) { $aSQL = "select * from employees". które korzystają z danych umieszczonych w bazie danych. first varchar(20). na przykład mod_auth_mysql i mod_perl.2 pokazuje jak proste jest użycie MySQL do pobrania danych z bazy. możesz albo ściągnąć źródła MySQL.com.server. while ( istnieje_wiersz ) pobierz_wiersz(). Rozpoczynamy pracę z MySQL W zależności od twoich potrzeb i typu serwera. Najszybszą metodą zainstalowania MySQL na systemie Linux działającym na platformie Intel jest ściągnięcie pliku RPM i zainstalowanie go. $aDBLink ). musisz przekompilować PHP podając opcję konfiguracji --with_mysql=/ścieżka/do/mysql. zamknij_połączenie(). Oficjalną witryną MySQL jest http://www. nie można używać innych modułów odwołujących się do MySQL. Jeżeli potrzebujesz modułów używających MySQL. position varchar(50).

3. W przypadku powodzenia operacji zwraca identyfikator nowego rekordu a w przypadku błędu wartość ujemną wskazującą na przyczynę błędu. $aPos ) { // Przygotowanie wyrażenia SQL INSERT $aSQL = "insert into employees ( first. ADD TABLE lub dowolne inne zapytanie SQL. Funkcja mysql_fetch_array() zwraca wynik w postaci tablicy asocjacyjnej indeksowanej nazwami kolumn. które są używane do odczytania wynikowych danych. Skrypt korzysta z funkcji mysql_insert_id() w celu zrealizowania potwierdzenia operacji wstawienia danych. wynik funkcji jest identyfikatorem wyniku przekazywanym do funkcji mysql_result(). w naszym przypadku mydb. Następną czynnością wykonywaną przez skrypt jest wybranie odpowiedniej bazy danych. ". na przykład: INSERT.2. '$aLastName'. jeżeli zapytanie jest typu SELECT. Funkcje MySQL posiadają dodatkowo kilka cech. address. UPDATE. Wywołanie jednej z tych funkcji zwraca kolejny wiersz danych zwracanych przez zapytanie i przesuwa wewnętrzny wskaźnik do następnego wiersza. Funkcje mysql_fetch_array() i mysql_fetch_row() są podobne do siebie i zwracają jeden wiersz wyniku w postaci tablicy. } else { print( "Błąd wykonania zapytania<br>" ). a dostarcza o wiele więcej danych. Dostarczone są specjalizowane funkcje do tworzenia i usuwania baz danych oraz funkcje umożliwiające odczytanie struktury bazy danych.= "position ) values ( '$aFirstName'. Na przykład za pomocą funkcji mysql_list_tables() można uzyskać listę wszystkich tabel w bazie danych. mysql_fetch_object(). */ function InsertRecord( $aFirstName.2. Może być to dowolne zapytanie. Symbol @ umieszczony przed funkcją mysql_connect() powoduje zablokowanie wypisywania błędów i ostrzeżeń. W naszym przykładzie jest to zapytanie SELECT. Używając skryptu z wydruku 6. Wynik funkcji jest różny od zero w przypadku powodzenia i zero w przypadku błędu.serer. Wywołanie funkcji mysql_fetch_array() nie jest zauważalnie wolniejsze niż wywołanie mysql_fetch_row().} mysql_free_result( $aQResult ). który pozwala na wprowadzenie danych nowego pracownika do bazy używanej na wydruku 6. mysql_fetch_lengths(). mysql_fetch_array().2 jako podstawy. W naszym przykładzie używamy funkcji mysql_fetch_array() do odczytania wiersza z wynikowych danych a następnie wyświetlane są dane z odpowiednich pól. $aAddr. które nie są dostępne dla wszystkich baz obsługiwanych przez PHP. które powoduje pobranie rekordów z bazy danych. $aSQL . } } else { print( "Błąd wyboru bazy danych<br>" ). // Przyłączenie do serwera i wykonanie instrukcji INSERT 69 PHP – Kompendium wiedzy . Podczas testowania możesz opuścić ten symbol. $aLastName. last. i mysql_fetch_row(). funkcja zwraca False. ". ale w normalnej pracy należy go używać i stosować własne procedury obsługi błędów. Wywołanie funkcji mysql_fetch_row() zwraca tablicę indeksowaną liczbami. Jeżeli nie ma więcej danych. próbuje się on podłączyć do serwera bazy danych MySQL działającego na komputerze db. $aSQL . Jeżeli się to powiodło. Na wydruku 6. Jedną z moich ulubionych funkcji dla MySQL jest mysql_insert_id().com podając nazwę użytkownika i hasło.3 mamy formularz. przy pomocy funkcji mysql_query() zadawane jest zapytanie do bazy danych. można napisać wszystkie możliwe aplikacje oparte na bazie danych.= "'$aAddr'. Używając pól o atrybucie auto_increment można po prostu zapisać dane do tabeli a następnie odczytać unikalny identyfikator rekordu za pomocą funkcji mysql_insert_id(). '$aPos' )". Wydruk 6. } ?> </body> </html> Po uruchomieniu skryptu z wydruku 6. } } else { print( "Błąd przy podłączaniu do bazy danych<br>" ). Dodatkowo. Wstawianie rekordu do bazy danych MySQL <?php /* Funkcja InsertRecord Wstawia mowy rekord do tabeli employees.

Ten typ aplikacji powinien zawierać o wiele więcej kodu odpowiedzialnego za obsługę błędów. if ( $aQResult == True ) { $aResult = mysql_insert_id( $aDBLink ).$aDBLink = @mysql_connect( "db. } else { // print( "Błąd wykonania zapytania<br>" ). $aResult = -3. $aDBLink ) == True ) { $aQResult = mysql_query( $aSQL. } } else { // print( "Błąd przy podłączaniu do bazy danych<br>" ). "" ). if ( $aResult > 0 ) { print( "Dodano nowy wiersz. $aResult = -1. MySQL automatycznie generuje jednoznaczne wartości tego pola przy każdym wstawieniu rekordu.server. $Address.com". Realistycznie patrząc. $aResult = -2. Kod błędu = $aResult<br>" ). } ?> <html> <head> <title>Przykład MySQL: Wstawianie danych do bazy </title> </head> <body> <?php if ( $REQUEST_METHOD == 'POST' ) { // Nastąpiło przesłanie danych formularza $aResult = InsertRecord( $FirstName. W naszym przykładzie wartość ta jest odczytywana za pomocą funkcji mysql_insert_id(). ale dla naszych potrzeb kod ten nie został rozmyślnie wprowadzony. Rozdział 6 – Współpraca z bazami danych 70 . $LastName. } return $aResult. Zwraca on identyfikator nowego rekordu (wartość przypisywana przez MySQL do kolumny id) lub wartość ujemną oznaczającą jedną z trzech obsługiwanych sytuacji błędnych. "root". } print( "<hr>" ). $aDBLink ). } ?> Proszę wpisać dane nowego pracownika:<br> <form action="<?php echo $PHP_SELF ?>" method="post"> Imię: <input type="text" name="FirstName" maxlength="20"><br> Nazwisko: <input type="text" name="LastName" maxlength="20"><br> Adres: <input type="text" name="Address" maxlength="255"><br> Stanowisko: <input type="text" name="Position" maxlength="50"><br><br> <input type="submit" name="Submit" value="Wyślij"> </form> </body> </html> W skrypcie z wydruku 6. } } else { // print( "Błąd wyboru bazy danych<br>" ). if ( !empty( $aDBLink ) ) { if ( mysql_select_db( "mydb". $Position ). Więcej przykładów użycia baz danych w aplikacjach WWW można znaleźć w rozdziale 15 „Witryny oparte o bazę danych”. Przykład ten miał na celu pokazanie prostoty korzystania z baz danych w PHP. funkcja IndertRecord() zawiera całą logikę wstawienia nowego rekordu do bazy danych. ID = $aResult<br>" ). na przykład sprawdzanie pustych pól. } else { print( "Błąd funkcji InsertRecord.3. Ponieważ pole id w tabeli employees jest polem typu auto_increment. Znajdują się tam bardziej złożone przykłady zawierające obsługę błędów i skomplikowane zapytania.

2. Jeżeli twoja firma posiada system bazy danych inny niż MySQL.2. że najpierw musisz zainstalować program zarządzający sterownikami. Jeżeli jeszcze nie wybrałeś swojego systemu bazy danych. Oznacza to. następna część zawiera informacje na temat ODBC. Jest ona szybka. ale musi być w tym celu odpowiednio skonfigurowany.aplikacja PHP Rysunek 6. --with-iodbc oraz --with-openlink. która realizuje nasze żądanie. NA rysunku 6. kontaktuje się z zarządcą sterowników. Driver Manager . które pomogą podłączyć się do twoich istniejących danych. Na rysunku 6.zarządca sterowników Dodajemy The OOB driver . Sterownik ten pozwala na dostęp do baz danych zainstalowanych na różnych platformach za pomocą własnego modelu klient-serwer. Jest on dostępny na zasadach licencji GPL lub LGPL i jest bardzo łatwy do instalacji i konfigurowania. Sterownik OOB powoduje wzrost komplikacji struktury. Opcje te są lepiej opisane w skorowidzu na końcu książki. PHP Application . W PHP istnieją cztery opcje konfiguracji związane z ODBC: --with-unixODBC.klient OOB Network . W książce tej zostanie opisana instalacja i konfiguracja zarządcy sterowników unixODBC oraz sterownika ODBC-ODBC Bridge (OOB).sterownik OOB sterownik OOB OOB Client . że wszystkie odwołania do bazy danych wykonuje za pośrednictwem sterownika bazy danych.SZRBD korzystającej z PHP Ponieważ ODBC wymaga zastosowania zarządcy sterowników oraz sterownika odpowiedniej bazy danych. na przykład unixODBC.unixodbc. Driver Manager . na przykład odbc_connect(). W przypadku tworzenia aplikacji o wysokiej jakości koszt bazy nie jest jedynym czynnikiem jaki należy brać pod uwagę. spisz swoje wymagania i porównaj ze specyfikacją dostępnych systemów.MySQL jest wydajną bazą danych posiadającą funkcje wystarczające do tworzenia większości typów aplikacji WWW. ponieważ ODBC nie jest w chwili obecnej domyślną opcją. Istnieje kilka implementacji ODBC API dla systemów Uniksowych.sterownik do bazy danych aplikacji PHP DBMS . http://www.easysoft. ale posiada tak dużo zalet. ODBC tym różni się od MySQL i innych API baz danych tym. W systemie Windows ODBC jest zwykle instalowany razem z systemem.com/.zarządca sterowników Database Driver . --with-custom-ODBC.serwer OOB Driver Manager . PHP Application .org/). Aplikacja wywołując funkcję.zarządca sterowników Komponenty Database Driver . na przykład podzapytania.aplikacja PHP Rysunek 6.1. Jednak w czasie pisania tej książki MySQL nie zawierał mechanizmu transakcji. Zarządca ten jest odpowiedzialny za załadowanie odpowiedniego sterownika bazy danych i przekazanie do niego żądania. solidna i zawiera większość funkcji dostępnych w komercyjnych bazach danych. Niedostępne są również niektóre elementy SQL. Również każdy z używanych sterowników baz danych musi zostać zainstalowany i skonfigurowany. ODBC Open Database Connectivity (ODBC) to powszechnie stosowany interfejs API (application programming interface) służący do łączenia się z bazami danych. pokazane są powiązania pomiędzy komponentami aplikacji PHP opartej o ODBC.1. W rozdziale tym przykłady korzystają z implementacji ODBC unixODBC (http://www. a następnie sterownik do twojego systemu bazy danych.sieć OOB Server . Podstawy ODBC PHP może obsługiwać praktycznie każdą implementację ODBC. Sterownik bazy danych wywołuje odpowiednią funkcję bazy danych.sterownik do bazy danych 71 PHP – Kompendium wiedzy . Jest on oparty na specyfikacji Call Level Interface pochodzącym z X/Open oraz ISO/IEC i jako języka dostępu do danych używa SQL. który można uzyskać z Easysoft Limited. instalacja i konfiguracja ODBC jest nieco bardziej skomplikowana niż konfiguracja MySQL. że jest wart zainteresowania. zilustrowano sposób użycia sterownika OOB.

że używając OOB należy kolejno zainstalować klienta i serwer OOB na oddzielnych komputerach.DBMS . Wykonałem to uruchamiając program instalacyjny i wykonując wszystkie kroki w programie instalacyjnym. Źródła danych są mechanizmem specyficznym dla ODBC służącym do opisywania sposobu współpracy z systemem bazy danych. Instalowanie sterownika OOB W moim przypadku musiałem zainstalować serwer OOB na komputerze z Windows NT i skonfigurować go tak. Powodem wyłączenia wątków jest to. nie potrzebowałem aby unixODBC dodał swoje sterowniki wewnętrzne. kompilację PHP z obsługą unixODBC oraz instalowanie sterownika OOB. Użyta ścieżka musi być taka sama jak ścieżka użyta w opcji --prefix podczas kompilowania unixODBC. Proces ten był niespodziewanie łatwy. ponieważ nie mam na moim serwerze zainstalowanego środowiska XWindows. że masz zainstalowane wszystkie niezbędne kompilatory i narzędzia. wystarczy wyłączyć Apache. OOB wymaga utworzenia systemowego DSN a nie DSN użytkownika./configure --disable--drivers --disable-threads --prefix=/usr/local/unixODBC --disable-gui Ponieważ miałem już potrzebny sterownik.SZRBD Zaletą stosowania sterownika OOB jest to. W instalacji unixODBC znajduje się standardowy skrypt służący do konfigurowania środowiska kompilacji. Części te są przeznaczone dla użytkowników Linuksa i zakładamy. musisz również przekompilować Apache. Dla przykładu w moim testowym systemie zainstalowałem Oracle 8i na serwerze Windows NT i utworzyłem prostą bazę danych. Następnie w moim linuksowym serwerze WWW dodałem sterownik OOB. Rozdział 6 – Współpraca z bazami danych 72 . działającej na dowolnej platformie. Wyłączyłem również obsługę graficznego interfejsu użytkownika. W moim przypadku jest to /usr/local/unixODBC. Sterownika tego można używać do podłączania się do dowolnej bazy zgodnej z ODBC. Następnie ściągnąłem i zainstalowałem oprogramowanie klienta na serwerze z systemem Linux. Program ten zawiera plik pomocy opisujący sposób tworzenia systemowych DSN. Wszystko zadziałało bez problemów. musisz skompilować zarządcę sterowników. Odpowiednią opcją konfiguracji jest --with-unixODBC=/sciezka/do/unixODBC. Jeżeli statycznie łączysz PHP z Apache. W Windows tworzy się DSN poprzez program Źródła danych ODBC dostępny w Panelu sterowania. Dodatkowym utrudnieniem jest to. Kompilowanie PHP z obsługą unixODBC Po skompilowaniu i zainstalowaniu zarządcy sterowników unixODBC należy przekompilować PHP z włączoną obsługą unixODBC. Kolejne trzy części omawiają instalowanie zarządcy sterowników unixODBC. że moja instalacja PHP jest w postaci dynamicznie ładowanego modułu (--with-apxs) a Apache nie obsługuje domyślnie wątków. Skompilowanie tego modułu z obsługa wątków spowodowałoby awarię Apache w trakcie ładowania modułu. aby przyjmował żądania. zainstalować nowy moduł PHP i powtórnie uruchomić Apache. gdzie na podstawie konkretnej konfiguracji otrzymamy szczegółowy opis tego jak ściągnąć i zainstalować serwer i klienta OOB. Jeżeli korzystasz z dynamicznego łączenia. że potrafisz kompilować programy dla tego systemu oraz. Instalowanie i kompilowanie unixODBC Po ściągnięciu i rozpakowaniu plików unixODBC. że możesz dzięki niemu używać ODBC w aplikacjach działających na serwerze WWW i korzystać z danych z bazy danych działającej na innym komputerze (który może działać na innym systemie operacyjnym). Można również skorzystać z witryny Easysoft. Konfigurowanie OOB Po zainstalowaniu całego oprogramowania należy utworzyć nazwy źródeł danych (DSN) zarówno na kliencie jak i na serwerze. W celu skompilowania mojej konfiguracji PHP użyłem następujących opcji: . Na szczęście na witrynie Easysoft bardzo łatwo jest odszukać i załadować odpowiednie programy. ponieważ dostępny był program instalacyjny prowadzący użytkownika przez kolejne kroki procedury instalacyjnej.

$aQResult = @odbc_exec( $aDBLink.ini jest używany do opisu nazw sterowników i łączy nazwy z plikami sterowników.server. Swoje źródło skonfigurowałem następująco (serwer i hasło jest oczywiście zmyślone): [localdsn] Server=satabase.ini"). który jest odpowiednikiem ODBC skryptu umieszczonego na wydruku 6. "agdec" ).ini. Wydruk 6. while ( odbc_fetch_into( $aQResult. } odbc_free_result( $aQResult ). na wydruku 6. $aPos = $aRow[4].4 znajduje się skrypt.4 do pól tabeli odwołujemy się dla 73 PHP – Kompendium wiedzy .ini zawiera opis źródeł danych. Dodatkowo. Tabela używana w tym przykładzie jest odpowiednikiem używanej w poprzednim przykładzie. $aRowNum++. $aPos<br>" ). Jedyną zauważalną różnicą jest wywołanie putenv() na początku skryptu. &$aRow ) ) { $aFName = $aRow[1].ini i odbc.so Setup = /usr/local/easysoft/oob/client/libesoobsetup. Wywołanie to umieszcza w środowisku programu ścieżkę do pliku inicjalizującego ODBC. Na wydruku 6. Mimo. "prodplanner".com Driver=OOB Port=8888 Transport=tcpip LogonUser=prodplaner LogonAuth=password TargetDSN=LocalOracle TargetUser=prodplaner TargetAuth=password Korzystanie z ODBC Po zainstalowaniu i skonfigurowaniu wszystkich komponentów korzystanie z ODBC w PHP jest bardzo podobne do korzystania z MySQL. // Ukrywamy komunikaty błędów i sami je obsługujemy $aDBLink = @odbc_connect( "localdsn". } } else { print( "Błąd podłączenia do bazy danych<br>" ).2. $aRowNum = 1.Aby utworzyć DSN na Linuksie należy zmienić przy pomocy graficznego narzędzia unixODBC lub edytora tekstowego pliki odbcinst. jeżeli w ten sam sposób ustawiłeś środowisko serwera WWW. } ?> </body> </html> Wydruk 6.so FileUsage = 1 Plik odbc. $aSQL ). koncepcja jest nieomal identyczna. Nie jest to potrzebne. $aRowNum. Odczytywanie danych z bazy ODBC <html> <head> <title>Pobioeranie danych z bazy danych ODBC</title> </head> <body> <?php putenv("ODBCINI=/usr/local/unixODBC/etc/odbc. if ( !empty( $aDBLink ) ) { $aSQL = "select * from employees". Plik odbcinst.2. print( "$aFName.4. że nazwy funkcji są inne. if ( $aQResult == True ) { $aRow = array().4 jest właściwie taki sam jak wydruk 6. Mój plik wygląda następująco: [OOB] Driver = /usr/local/easysoft/oob/client/libesoobclient. } else { print( "Błąd wykonania zapytania<br>" ).

pokazany został sposób uproszczenia skryptu z wydruku 6. w której ustawiane są zmienne specyficzne dla twojego środowiska pracy. Jeżeli PHP będzie obsługiwał klasy abstrakcyjne. $aPos = $aDB->f( "position" ). var $Password = "". PHP Base Library (PHPLIB) jest dostępna pod adresem http://phplib. Uwaga na temat połączenia do baz danych W poprzednim przykładzie połączenie do baz danych było realizowane za pomocą podstawowych funkcji xxx_connect(). Skrypt z wydruku 6. więc użycie trwałych połączeń może mieć ogromny wpływ na ogólną wydajność aplikacji.5 definiowana jest klasa pochodna MySQLDBTest.uproszczenia za pomocą numer a nie nazwy. PHP ciągle dostarcza tego samego połączenia do kolejnych wywołań połączenia. Po utworzeniu połączenia za pomocą odpowiedniej kombinacji host-użytkownik-hasło.ini"). kursorów i wiele innych.inc" ). Jedna z najczęściej używanych bibliotek. Użycie połączenia trwałego poprawia wydajność aplikacji. więc może być ono wielokrotnie używane.inc" ). Wydruk 6. Poniższy wydruk ilustruje siłę modułu obsługującego bazy danych z pakietu PHPLIB.5 korzystający z Oracle i ODBC <?php putenv("ODBCINI=/usr/local/openlink/odbc. } // Tworzenie egzemplarza nowej klasy MySQLDBTest $aDB = new MySQLDBTest. Dostępne są funkcje ODBC zapewniające obsługę transakcji. Na wydruku 6. Poniższy wydruk pokazuje jak łatwo można zamienić skrypt z wydruku 6. while( $aDB->next_record() ) { $aFName = $aDB->f( "first" ). wiele innych. Pozwala to osiągnąć w wyniku kod. PHP posiada również zdolność tworzenia trwałych połączeń za pomocą funkcji pxxx_connect(). Wydruk 6.2 <?php include ( "db_mysql.163". var $Database = "mydb".6.2. var $User = "root". Klasy dostępu do bazy danych w PHPLIB tworzą warstwę abstrakcji dla kilku baz danych obsługiwanych przez PHP. Zawiera ona klasy dostęu do baz danych. dostępne są świetne biblioteki do wykorzystania przez programistów PHP. print( "$aFName. obsługi sesji. Oracle 8. Oracle 7. include( "db_odbc.5. } ?> Dostarczona przez PHPLIB klasa DB_Sql ukrywa w sobie szczegóły procesu łączenia i wyboru bazy danych oraz zawiera kod obsługi błędów. W skorowidzu funkcji na końcu książki znajdują wszystkie funkcje do obsługi ODBC. mSQL. więc programiści mogą łatwo zmieniać typ bazy danych bez konieczności nauki nowego zestawu funkcji lub wielu zmian w kodzie. Następnie tworzony jest obiekt tej klasy.de. // Dziedziczymy po klasie DB_Sql aby użyć jej z // naszą bazą MySQL class MySQLDBTest extends DB_Sql { var $Host = "208. narzędzi autoryzacji i wiele. w której zawarte są dane opisujące połączenie z MySQL. Użycie PHPLIB do powtórzenia wyników z wydruku 6. Warstwa ta zapewnia wspólny interfejs dla bazowych funkcji baz danych. na którym wykonywane są operacje. który jest łatwiejszy do czytania. W skrypcie umieszczonym na wydruku 6. aby zamiast z MySQL korzystał z Oracle poprzez sterownik ODBC.5. jest to idealny kandydat do takiej właśnie implementacji.129. Największa zaleta korzystania z klas PHPLIB ujawnia się. Zamiast tego powinna być tworzona klasa dziedzicząca po niej. W bazach danych utworzenie połączenia trwa zwykle długo (na przykład w Oracle). gdy zachodzi potrzeba wymiany bazy danych. utrzymania i uruchamiania. W czasie pisania książki PHPLIB obsługiwał MySQL.36.netuse. $aPos<br>" ). $aDB->query( "select * from employees" ). Sybase. Microsoft SQL Sever i bazy ODBC.5. PHPLIB Jak wspomniałem w poprzednich rozdziałach. // Dziedziczymy po klasie DB_Sql aby użyć jej z // bazą danych Oracle poprzez ODBC Rozdział 6 – Współpraca z bazami danych 74 . ponieważ sam PHP utrzymuje połączenie z bazą danych. Klasa DB_Sql nie jest przeznaczona do bezpośredniego używania. PostgreSQL.

Biblioteka ta zapewnia jednakowy interfejs dostępu do różnych baz danych. Przechowywanie danych z formularzy Omówienie formularzy HTML jest potrzebne w rozdziale dotyczących baz danych. Na przykład. Skrypt z wydruku 6.de/. $aPos = $aDB->f( "position" ). niektóre komunikaty błędów generowane przez bazę danych mogą zawierać takie informacje na temat używanej bazy danych. Dodatkowo. przyciski opcji i inne tego typ elementy pozwalają na dużą elastyczność i ograniczają możliwość błędu przy wprowadzaniu danych. Umieszczenie takiego zestawu opcji w bazie danych skutkuje w dłuższym okresie stworzeniem aplikacji łatwiejszej do zarządzania. Należy być przygotowanym na sytuacje. Tak jak opisano w rozdziale 3. tam gdzie jest to możliwe należy zastępować procedury kontroli danych przez takie mechanizmy. heterogenicznych środowiskach.netuse. Więcej informacji na temat klas zawartych w PHPLIB można odnaleźć na witrynie http://phplib. Pola wyboru. Każda z tabel zawiera identyfikator oraz nazwę. dane wpisane do formularza HTML muszą być sprawdzone przed ich zapisaniem do bazy danych. jak również w prostych instalacjach składających się z jednego serwera. PHP dostarcza wielu funkcji potrzebnych przy używaniu formularzy i baz danych. $aPos<br>" ). Tak jak we wszystkich aplikacjach.7 pokazane zostało tworzenie listy wyboru zawierającej kraje oraz stany USA. while( $aDB->next_record() ) { $aFName = $aDB->f( "first" ). W skrypcie tym używane są tabele us_states oraz world_countries. } // Tworzenie egzemplarza nowej klasy OracleDBTest $aDB = new OracleDBTest. Wydruk 6./db_mysql. co powoduje bardzo łatwe ponowne użycie istniejącego kodu.class OracleDBTest extends DB_Sql { var $Database = "localdsn". które ze swojej natury ograniczają pomyłki. var $User = "prodplanner". Użycie tabel słownikowych do generacji listy opcji <?php include ( ". Tworząc alternatywne mechanizmy wprowadzania danych należy pamiętać o możliwości korzystania z bazy danych przy tworzeniu początkowego zestawu danych. Na przykład na wydruku 6. $aDB->query( "select * from employees" ). cudzysłowy. Przykład ten pokazuje jedynie koncepcję. Skrypt z wydruku 6. W przy domyślnych ustawieniach PHP automatycznie oznacza we wszystkich zmiennych GET. print( "$aFName. Identyfikator jest przekazywany jako wartość formularza. Powoduje to. class MySQLDBTest extends DB_Sql 75 PHP – Kompendium wiedzy . var $Password = "agdec". ponieważ formularze są najczęściej używanym mechanizmem używanym do wprowadzania danych w aplikacjach WWW. że niektórzy użytkownicy mogą próbować wyszukać słabe punkty w aplikacji. że wartość przekazana z formularza jest od razu gotowa do użycia w zapytaniu SQL. musisz użyć funkcji addslashes() zanim skorzystasz w zapytaniu SQL z ciągu przekazanego z formularza. które będą wyświetlane muszą zostać przed wyświetleniem przetworzone za pomocą funkcji stripslashes().7.6 pobiera dane z bazy Oracle zainstalowanej na serwerze z Windows NT. Jak wspomniano w rozdziale 3.inc" ). ale znaczenie tej zmiany jest olbrzymie. } ?> Jedyną widoczną zmianą pomiędzy wydrukami 5 i 6 jest funkcja include(). POST i COOKIE apostrofy. Jeżeli zablokowałeś tą opcję. Mechanizmy kontroli poprawności danych były opisane w rozdziale 3. Oczywiście można wybrać stan w USA a następnie Afrykę południową. Aby zabezpieczyć się przed niektórymi typami ataków należy zawsze używać atrybutu maxlength w polach tekstowych oraz kontrolować typ i postać danych. ukośniki i znaki NUL. Wynikiem braku kontroli danych może być niezadowolenie użytkowników z aplikacji a nawet załamanie systemu bezpieczeństwa serwera.5 korzystał z danych z bazy MySQL działającej na tym samym komputerze co serwer WWW. których na pewno nie chciałbyś pokazywać użytkownikom. „Formularze i cookie”. wszystkie wartości. Z powodu prostoty projektu i implementacji PHPLIB może być on użyteczny dla programistów pracujących w złożonych.

"ZA" ) ). nie trzeba przeglądać wszystkich stron szukając odwołań. ?> </select> </td> </tr> <tr> <td> Wybierz kraj: </td> <td> <select name="world_country" size="1"> <?php print( GetGenOpts( "world_countries".= "<option value=\"$aID\" selected>$aName</option>". } function GetGenOpts( $aTableName. if ( $aID == $aCurSel ) { $aResult . jeżeli formularz jest użyty do edycji danych a nie do wprowadzania nowych danych. pokazany jest formularz.phtml" method="post"> <table> <tr> <td> Wybierz stan USA: </td> <td> <select name="us_state" size="1"> <?php print( GetGenOpts( "us_states". } } return $aResult.129. ponieważ w razie zmiany tej listy.163". $aDB = new MySQLDBTest. $aDB->query( $aSQL ). ?> </select> </td> </tr> </form> </body> </html> Na rysunku 6. Użycie tabel słownikowych pozwala również na natychmiastowe zmiany w aplikacji o ile zajdzie taka potrzeba. $aCurSel = "" ) { $aResult = "". Opcjonalny parametr $aCurSel może zostać użyty do określenia wybranej pozycji na formularzu. } ?> <html> <head> <title>Formularz wyboru stanu USA oraz kraju</title> </head> <body> <form action="some_place.3. $aID = $aDB->f( "ID" ). "". należy ją przechowywać w bazie danych zamiast statycznie definiować na stronie HTML. Jeżeli masz listę akceptowanych przez ciebie kart kredytowych.= "<option value=\"$aID\">$aName</option>".36. "ID" ) ). Rozdział 6 – Współpraca z bazami danych 76 . "root". Name from $aTableName order by Name".{ var var var var $Host $Database $User $Password = = = = "208. $aSQL = "select ID. Zamiast tego można po prostu zmienić wartości w tabeli bazy danych. while( $aDB->next_record() ) { $aName = $aDB->f( "Name" ). } else { $aResult . Funkcja GetGenOpts() może być użyta do tworzenia listy opcji z każdej tablicy posiadającej kolumny ID oraz Name. "mydb". Aplikacja zostanie natychmiast zmieniona się bez modyfikacji jednej linii kodu.

drop database”. ponieważ nie trzeba robić żadnych założeń dotyczących współbieżności a system bazy danych jest zwykle czymś więcej niż pośrednikiem służącym do odczytu i zapisu danych. Wynikowe wyrażenie SQL będzie następujące: select * from table where ID = 1. to jednak możesz odszukać podobne przykłady. Udostępniając aplikację.3. ktoś może wpisać do formularza napis „1. aby przykład ten spowodował jakiekolwiek szkody. spójrzmy na przykład aplikacji.Rysunek 6. lub uszkodzenie bazy danych. zawsze musisz zweryfikować poprawność danych. Środowisko takie jest bardzo wygodne. że jest nieprawdopodobne. Wszyscy. zanim trafią one do serwera bazy danych. Jeżeli umieścisz na formularzu pole tekstowe. Należy również przetestować aplikację za pomocą danych. Oczywiście. Spróbuj wprowadzić do pól tekstowych apostrofy oraz znaki backslash. drop database Mimo. tworzyłem w większości aplikacje Windows wykorzystywane przez jednego użytkownika. Wykorzystanie możliwości bazy danych Część ta nie jest związana bezpośrednio z wykorzystaniem baz danych z PHP — jest to dodatek poświęcony pisaniu aplikacji wykorzystujących bazy danych. Mimo. które mogą spowodować błąd. Zanim zacząłem pisać aplikacje dla WWW. w aplikacji nie powinny znajdować się pola umożliwiające wykonanie dowolnego zapytania SQL. powinieneś określić poziom wymaganego bezpieczeństwa i kontroli poprawności. Można również wpisać średnik i po nim wyrażenie SQL. więc można ją wkleić do wyrażenia SQL. Na przykład. powinni dokładnie przeczytać ten fragment i stosować go podczas pisania własnych aplikacji WWW korzystających z bazy danych. We wszystkich przypadkach bazy danych używał jeden użytkownik i działała na tym samym komputerze. że najlepszym zabezpieczeniem przed nieprawidłowymi danymi jest dobrze skonstruowany mechanizm wprowadzania danych. aby możliwy był dostęp do niej jedynie za pomocą aplikacji. Zawsze należy zabezpieczyć bazę danych w taki sposób. Dynamicznie generowany formularz do wprowadzania danych Kolejny raz musimy powtórzyć. które mogą spowodować naruszenie bezpieczeństwa. że przypadek ten jest dość nieprawdopodobny. nie możesz zapomnieć o bezpieczeństwie bazy danych. Może on znajdować się również w rozdziale poświęconym inżynierii programowania. którzy nie pisali zbyt wielu aplikacji w środowisku wielowarstwowym. W oparciu o typ tworzonej aplikacji. że wprowadzona_wartosc będzie jedną wartością. 77 PHP – Kompendium wiedzy . która pobiera identyfikator a następnie wykonuje wyrażenie SQL: select * from table where ID = wprowadzona_wartosc Spodziewasz się.

W jednym z ostatnich projektów musiałem posortować wiersze opisujące personel w oparciu o różnicę wieku licząc od określonej daty. czy serwer bazy danych i serwer WWW umieszczony jest na tym samym komputerze. Potrzebna jest zwykle nowoczesna baza danych. Jednym z najważniejszych problemów przypisaniu aplikacji dla WWW jest użycie właściwych narzędzi i właściwych ludzi do realizacji poszczególnych fragmentów projektu. która potrafi zarządzać współbieżnością. Wszystko czego potrzebujemy. Dalsze informacje na temat Rozdział 6 – Współpraca z bazami danych 78 . większość nowoczesnych baz danych posiada ogromną ilość funkcji. Podsumowanie Rozdział ten zawiera opis użycia baz danych razem z PHP. Dodatkowo każdej osobie przypisywana była wartość. Zamieszczona została również krótka dyskusja na temat inżynierii programowania i wykorzystaniu możliwości baz danych. przyjrzyj się dokładniej swojemu zapytaniu SQL. obliczana w oparciu o to jak blisko wiek osoby jest zbliżony do założonych wymagań wiekowych. powinieneś wszędzie tam gdzie jest to możliwe wykorzystywać siłę systemu zarządzania bazą danych. Jeżeli zdarzy ci się pisać kod formatujący. Następna duża część książki. ' '. to w pętli odczytać wyniki i wyświetlić je na ekranie. który pisał ten fragment. W mojej ostatniej stałej pracy trafiłem na świetny przykład. jak bardzo jej wiek jest zbliżony do 30 lat. Ponieważ PHP obsługuje wiele typów baz danych. który to mechanizm musi posiadać baza danych. skupiliśmy się na bazie MySQL oraz dostępowi poprzez ODBC. ale otrzymujemy wszystkie potrzebne dane bez potrzeby pisania dodatkowego kodu manipulującego wynikami: SELECT concat (firstname. Niezależnie od tego.W przypadku tworzenia aplikacji dla środowiska wielowarstwowego.nextval AS PRIMARY KEY. „Zarządzanie projektem przy tworzeniu aplikacji WWW” zawiera więcej informacji na temat inżynierii programowania dla aplikacji WWW. inne_pola FROM tabela Wyrażenie to opiera się na generatorze sekwencji do wygenerowania nowego klucza głównego. surneme) as fullname. Znaleziony przeze mnie kod wyglądał mniej więcej tak: wybierz wszystkie wiersze do kopiowania dla każdego wiersza inicjuj nowy ciąg zawierający wyrażenie INSERT wybierz nowy klucz główny w bazie danych jeżeli te dane powinny być skopiowane bez zmian skopiuj istniejące dane do wyrażenia INSERT w przeciwnym wypadku dodaj nowe wartości do wyrażenia INSERT wykonaj wyrażenie INSERT z wyrażenia koniec dla każdego wiersza Nie mam zamiaru śmiać się z programisty. Zadaniem było powielenie kilku wierszy danych z tabeli zmieniając w nowych wierszach zawartość kilku pól. Każdy. ale pokazuje w jaki sposób wykorzystując odpowiednio SQL można uniknąć pisania sporej ilości kodu oraz poprawić wydajność aplikacji. uprawnieniami użytkownika. Możesz skorzystać z wbudowanych funkcji bazy danych lub zastosować bardziej skomplikowany kod SQL do osiągnięcia oczekiwanych wyników. Fragment ten wymaga 1+ (2*ilość wierszy) odwołań do bazy danych. Cały fragment można zredukować do jednego wyrażenia SQL wykonywanego w całości przez bazę danych: INSERT INTO tabela SELECT sequence. baza danych pełni o wiele ważniejszą rolę. Na przykład. czy na osobnych maszynach. którego wiek był oddalony od założonego o więcej niż 10 lat otrzymywał tą samą ocenę. będącą liczbą od 0 do 10. (10-ABS((30-ROUND(((TO_DAYS(NOW()) . ROUND(MAX(0. Poniższe wyrażenie może wyglądać na dosyć skomplikowane.TO_DAYS(birthdate))/365))))))) AS age_dif FROM persons ORDER BY age_diff DESC Każdy z wierszy wyniku zawiera imię i nazwisko osoby oraz liczbę oznaczającą żądaną wartość. ale fragment ten prezentuje styl kodowania brute-force częsty u młodych lub niedoświadczonych programistów. musiałem określić pozycję rekordu osoby w oparciu o to. transakcjami i to odbierając wiele równoczesnych żądań w tym samym czasie. Na początku wyniku znajdą się osoby o wieku najbliższym 30 lat. Pierwsze wywołanie pobiera wszystkie wiersze i następnie dla każdego z nich jest potrzebne jedno wywołanie do wygenerowania nowego klucza głównego i jedno dla wykonania instrukcji INSERT. Oprócz wykonywania tych krytycznych funkcji. które pomagają w pisaniu aplikacji. filtrujący bądź sortujący dane pobierane z bazy danych.

użycia baz danych znajdują się w rozdziałach 15. Najobszerniejsze przykłady znajdują się w rozdziale 15 „Witryny oparte o bazę danych”. 16 i 17. 79 PHP – Kompendium wiedzy .

Serwer wykorzystuje ID do odczytania i odtworzenia wszystkich potrzebnych danych aplikacji. że zarówno przeglądarka jak i serwer WWW nie były projektowane do uruchamiania aplikacji WWW. w utrzymanie sesji jest zaangażowany zarówno serwer jak i klient. ale dostępne są również moduły zewnętrzne realizujące to samo zadanie. Stan programu jest zawsze znany. Gdy użytkownik kończy pracę. pokazany został schemat komunikacji pomiędzy klientem a serwerem WWW (w tym przypadku jest to serwer 1U produkowany przez Penguin Computing) w przypadku rozpoczynania sesji oraz wykorzystywania zmiennych. ponieważ cały model działania programu jest dosyć prosty: użytkownik uruchamia program. obsługa sesji w sieci WWW wymaga współpracy pomiędzy przeglądarką klienta i serwerem WWW. Podstawy mechanizmu sesji Jak napisałem we wprowadzeniu. Serwer korzysta z danych przekazanych mu przez klientów podczas kolejnych odwołań do stron do śledzenia i utrzymywania danych sesji. Gdy sesja zaczyna się.Rozdział 7. Jest to powodowane faktem.1. Następnie przeglądarka wysyła ID do serwera razem z każdym żądaniem przesłania strony. W PHP4 wbudowano funkcje do obsługi sesji. Sesje i stan aplikacji Wstęp W rozdziale 4 „Operacje na plikach” zostało przedstawione wykorzystanie plików do utrzymania stanu sesji. Ponieważ aplikacje WWW są ze swojej natury aplikacjami wielodostępnymi. Pod pojęciem klienta kryją się tutaj poszczególni użytkownicy. . W aplikacjach WWW zarządzanie danymi sesji jest bardziej złożone. Po zakończeniu aplikacji dane są usuwane z serwera. plikach oraz bazach danych wykorzystywanych przez program. Na rysunku 7. stan aplikacji nie zmieni się. Inną metodą jest napisanie w PHP własnego mechanizmu zarządzania sesjami. serwer WWW tworzy unikalny identyfikator sesji (ID) i przekazuje go do klienta. niezbędne dane są serializowane oraz zapisywane i sesja pracy programu się kończy. PHP pozwala na stosowanie kilka metod utrzymywania stanu sesji. Zwykle identyfikator ten jest przechowywany w cookie na komputerze klienta. ale nie zawiera on ogólnego opisu problemu utrzymywania stanu. wykonuje swoje zadania a następnie zamyka program. Jeżeli użytkownik chwilowo przełączy zadanie a następnie powróci do niego. W standardowych aplikacjach stan jest automatycznie utrzymywany w zmiennych przechowywanych w pamięci komputera.

$aAccount = "1016".phtml">Przejście do strony 2</a> </body> </html> Wydruk 7. który wykorzystuje zmienne sesji ze skryptu na wydruku 7. miejsce przechowywania zmiennych sesji na serwerze oraz częstotliwość usuwania przerwanych sesji. ?> <br><br> <a href="listing2. Uruchamianie sesji i inicjowanie zmiennych <?php session_start().2.Rysunek 7. Wykorzystując sesje w PHP należy wykonać następujące podstawowe operacje: 1. 81 PHP – Kompendium wiedzy . część ta zostanie podzielona na części o wzrastającym stopniu skomplikowania. 3. Rozpoczęcie sesji za pomocą session_start(). print( "Konto: $aAccount<br>" ). $aUser = "Cidnie". System zarządzania sesjami w PHP można w dużym stopniu konfigurować. Ponieważ dostępne jest wiele opcji konfiguracji. ?> <html> <head> <title>Podstawy sesji: Strona 1</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ).1 <?php session_start(). Funkcje obsługi sesji są dokładnie opisane w skorowidzu funkcji na końcu książki. Zarejestrowanie nazw zmiennych sesji za pomocą session_register(). Można zmienić sposób przesyłania identyfikatora sesji.1 i 7. "aAccount" ).2. Rozpoczęcie pracy z sesjami w PHP Wydruki 7. Na wydruku 7.1. jak łatwe jest użycie sesji w PHP wykorzystujące domyślne ustawienia. Wydruk 7. session_register( "aUser".1 zamieszczony jest skrypt inicjujący wszystkie zmienne sesji używane w aplikacji oraz łącze do skryptu z wydruku 7.1.2 pokazują. Wszystkie nazwy funkcji obsługi sesji rozpoczynają się od sesion_. 2.1. Użycie zmiennych sesji. Użycie zmiennych sesji z wydruku 7. Rozpoczynanie sesji oraz użycie zmiennych sesji Wbudowany w PHP mechanizm zarządzania sesjami W wersji 4 do PHP wprowadzono mechanizm zarządzania sesjami.

W domyślnej konfiguracji PHP używa cookie do przechowywania identyfikatora sesji. Po uruchomieniu poprzedniego przykładu odszukałem plik sess_e66b342b4e76889f8f25105db11820c6. pokazane są wyniki działania skryptów umieszczonych odpowiednio na wydrukach 1 i 2.2 Możliwe jest wyświetlenie bieżącego identyfikatora sesji wypisując na ekran zawartość zmiennej Dodatkowo. w domyślnej konfiguracji na Apache i Linuksa. Funkcje te muszą być wywoływane przed wysłaniem do przeglądarki jakichkolwiek informacji lub musi zostać włączone buforowanie danych wyjściowych.3. Pozostałe metody zostaną opisane później. PHP korzysta z identyfikatora sesji do odczytania wszystkich zmiennych sesji. Wynik działania skryptu z wydruku 7..aAccount|s:4:"1016". Gdy użytkownik kliknie łącze prowadzące do strony 2. Rozdział 7 – Sesje i stan aplikacji 82 . Wynik działania skryptu z wydruku 7. ?> </body> </html> Pierwszym krokiem skryptu z wydruku 7. $PHPSESSID.2. Na rysunkach 7. Chociaż można zmienić sposób przesyłania identyfikatora sesji. Rysunek 7.2.1 Rysunek 7.?> <html> <head> <title>Podstawy sesji: Strona 2</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). W skrypcie z wydruku 7. najprostszą metodą jest wykorzystanie domyślnego mechanizmu — cookie.1 jest uruchomienie sesji poprzez wywołanie funkcji session_start(). zostają zarejestrowane dwie zmienne. print( "Konto: $aAccount<br>" ). przeglądarka samoczynnie wyśle identyfikator sesji do serwera. który zawierał: aUser|s:6:"Cidnie".2 w trakcie wywołania funkcji session_start(). aUser oraz aAccount. i 7.3. dane sesji są przechowywane w katalogu /tmp w plikach o nazwach w postaci sess_$PHPSESSID. Funkcja session_start() posiada te same ograniczenia co funkcje set_cookie() i header(). Po rozpoczęciu sesji.

$aAccount = "1016". a aplikacja będzie źle działać.Domyślne ustawienia PHP dotyczące zarządzania sesjami są łatwe do użycia i wystarczają dla większości aplikacji WWW. "aAccount" ). więc jeżeli będziesz chciał wydrukować $SID zamiast nie otrzymasz takiego samego wyniku.1. Na wydruku 7. Pierwszą z metod jest ręczne przesyłanie identyfikatora sesji w postaci zmiennej GET lub POST. Stała ta jest zdefiniowana jako SessionName=SessionID. Jednak w niektórych przypadkach cookie mogą nie być pożądaną metodą przesyłania identyfikatora sesji. Ręczne przesyłanie identyfikatora sesji za pomocą metody GET <?php session_start(). który pokazuje w jaki sposób należy zmienić kod z wydruku 7. ?> <br><br> <a href="listing2. Przesyłanie identyfikatora sesji bez użycia cookie Jeżeli aplikacja absolutnie wymaga zastosowania zmiennych sesji. $aUser = "Cidnie". <?php session_start(). print( "Konto: $aAccount<br>" ).?> zakładając.3: <a href="listing2.3. Przetwarzanie względnych adresów URL przez PHP w celu przekazywania identyfikatora sesji SID. że kod jest taki sam jak na wydruku 7. Wydruk 7. poniższy kod jest semantycznie identyczny z odpowiednią linią z wydruku 7.phtml?<?=SID?>">Przejście do strony 2</a> </html> Należy zauważyć. ale nie pokazuje jak mechanizm ten wpływa na tworzenie aplikacji.3 może być zmieniony na nieco prostszy.phtml">Przejście do strony 2</a> 83 PHP – Kompendium wiedzy . możesz uaktywnić ten mechanizm kompilując PHP z opcją --enable-transsid. $aUser = "Cidnie". Następne dwie części zawierają omówienie sposobu rozwiązania tych problemów. Na wydruku 7. że niektórzy użytkownicy mają w swoich przeglądarkach włączoną obsługę cookie.3 pokazany jest skrypt. ?> <html> <head> <title>Automatyczne przesyłanie identyfikatora sesji: Page 1</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). pokazany na wydruku 7. Jeżeli chcesz przesyłać identyfikator sesji przy użyciu metod GET i POST.3 zastosowany został skrót <?=SID?>. $aAccount = "1016". do przesyłania identyfikatora sesji możesz użyć innego mechanizmu niż cookie. że SID jest stałą a nie zmienną. Zapis taki jest równoważny z <?php echo SID. W tym przypadku do adresu URL została doklejona stała PHP SID. Po przebudowaniu PHP kod z wydruku 7. Należy pamiętać. "=" .1. Jeżeli nie dodasz identyfikatora do jednego łącza. "aAccount" ). session_register( "aUser". session_register( "aUser".phtml?<?php echo session_name() . ?> <html> <head> <title>Ręczne przesyłanie identyfikatora sesji: Strona 1</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). że w czasie kompilacji PHP użyto opcji --enable-short-tags. poza łączem w trzecim wierszu od końca.4.4. który to mechanizm rozwiązuje ten problem za ciebie. SID zostanie utracony. Na szczęście PHP posiada opcję automatycznego przekształcania łączy. ?> <br><br> <a href="listing2. Wydruk 7. print( "Konto: $aAccount<br>" ). każde łącze i każdy formularz w aplikacji musi zawierać identyfikator sesji. Wydruk 7. a w przypadku niektórych dużych aplikacji WWW użycie plików na serwerze WWW może utrudniać skalowanie aplikacji.3 ilustruje mechanizm ręcznego przesyłania identyfikatora sesji w programie. Korzystając z tego mechanizmu. aby identyfikator sesji był przesyłany jako zmienna GET. session_id()?>"> Przejście do strony 2</a> Należy pamiętać.

phtml?MyVar=1234">Łącze 2</a> <br><br> <a href="http://www.</html> Różnica pomiędzy wydrukiem 3 i 4 jest taka. Jeżeli będziesz chciał użyć formularza korzystającego z metody GET.phtml?MyVar=1234&PHPSESSID=9771f86dc94e367cf1c62e0339d02c4b"> Łącze 2</a> <br><br> <a href="http://www. ?> <html> <head> <title>Uzupełnianie adresów URL</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). Pokazujemy również w jaki sposób PHP przetworzył łącza.phtml?PHPSESSID=9771f86dc94e367cf1c62e0339d02c4b">Łącze 1</a> <br><br> <a href="listing2. że na wydruku 7. ponieważ PHP potrafi również uzupełniać formularz tak. zostały do nich dołączone dane na temat sesji. chociaż strona ta znajduje się na tym samym serwerze. aplikacja nie będzie działała prawidłowo.phtml"> <input type="submit" name="Submit" value="Przycisk przesłania danych formularza"> </form> </html> Po uruchomieniu skryptu. że wydruk 7. że działa on jedynie dla metody POST. Gdy użytkownik kliknie łącze. tak samo jak w przypadku skryptu z wydruku 7.php.net/">Łącze 3</a> <br><br> <a href="http://localhost/listing2. Wydruk 7.1.3. Do przykładu został dołączony formularz. W tym przypadku jest to bezwzględny adres URL. $aUser = "Cidnie". Jedyną wadą tego mechanizmu jest to. Kod ten działa. Działanie takie było przewidziane. Oznacza to. ponieważ PHP szuka na stronie względnych adresów URL i dodaje do nich potrzebną wartość identyfikatora sesji. do przeglądarki został wysłany następujący kod HTML: <html> <head> <title>Uzupełnianie adresów URL</title> </head> <body> Użytkownik: Cidnie<br>Konto: 1016<br> <br><br> <a href="listing2. Przykłady automatycznego uzupełniania łączy przez PHP <?php session_start(). Rozdział 7 – Sesje i stan aplikacji 84 .net/">Łącze 3</a> <br><br> <a href="http://localhost/listing2. Łącze 4 pokazuje jak ostrożnym należy być używając funkcji automatycznego uzupełniania łączy. Łącze 3 nie jest oczywiście łączem względnym.4 nie ma odwołania do stałej SID w łączu. przeglądarka nie dodaje zmiennej PHPSESSID do ciągu zapytania (przetestowane na najnowszych wersjach Netscape i Internet Explorer). $aAccount = "1016". PHP uzupełnia jedynie adresy URL zapisane w postaci łączy względnych. następny skrypt zawiera kilka względnych łączy i kilka bezwzględnych. więc identyfikator sesji nie został dołączony.5.phtml">Łącze 4</a> <br><br> <form action="listing2. ale wynik jego działania jest różny z powodu zmiany konfiguracji. Można również zauważyć.4 jest praktycznie identyczny z wydrukiem 7. session_register( "aUser".phtml">Łącze 1</a> <br><br> <a href="listing2. print( "Konto: $aAccount<br>" ). "aAccount" ). że atrybut ACTION zostanie prawidłowo zmodyfikowany. Mimo.php.phtml">Łącze 4</a> <br><br> <form action="listing2. ?> <br><br> <a href="listing2. Aby to pokazać. aby zawierał on wartość identyfikatora sesji.phtml"><INPUT TYPE="HIDDEN" NAME="PHPSESSID" VALUE="9771f86dc94e367cf1c62e0339d02c4b"> <input type="submit" name="Submit" value="Przycisk przesłania danych formularza"> </form> </html> Ponieważ pierwsze dwa łącza są łączami względnymi. URL będzie zawierał ciąg PHPSESSID=xxx. że aplikacja korzystająca z formularzy również będzie prawidłowo działała.

że masz zainstalowaną właściwą wersję PHP. Funkcja jest wywoływana w celu zakończenia sesji. Dane te powinny być dokładnie takie same. Błąd ten poprawiono w wersji 4. Aby sprawdzić wpływ tego mechanizmu na wydajność stworzyłem przykładową stronę WWW oraz skrypt. Błąd w PHP Jak wspominaliśmy w tej części. PHP posiada mechanizm zapisywania zmiennych sesji w dowolnie wybrany sposób. gdzie będą zapisywane wartości samych zmiennych sesji. powinieneś również się zastanowić.save_path określonej w pliku php. lub ostatnią wartościa przekazaną do funkcji session_name(). który odczytywał ją z serwera i zapamiętywał czas potrzebny na jej odczytanie. Jeżeli chcesz korzystać z tej funkcji. Jeżeli zamierzasz skorzystać z automatycznego uzupełniania adresów. $mtime = $mtime[1] + $mtime[0].55 kB. $nIndex < 1000. $nIndex++) { $aData = file( $aFileName ). Dane przekazane do parametru value są danymi sesji w postaci serializowanej. które wymagały przepisania. Funkcja ta jest wywoływana w trakcie inicjalizacji sesji.1 poziom poprawek 2. $aTotTime = $aEndTime . string value ). Jeżeli wystąpi błąd. Zanotowano średnio 9% zysk wydajności w przypadku zablokowania opcji --enable-trans-sid. PHP wersja 4. } $aEndTime = getmicrotime().Przesyłanie identyfikatora sesji za pomocą metod GET i POST pozwala uniknąć niektórych problemów z cookie i jest łatwe do zrealizowania. Skrypt uruchamiałem z aktywną opcją --enable-trans-sid. oraz bez niej.name zdefiniowany w pliku php. Skrypt do sprawdzania wydajności <?php function getmicrotime() { $mtime = microtime(). $mtime = explode( " ". powinny zostać zwrócone w postaci serializowanej. return ($mtime). Zapisywanie zmiennych sesji w bazie danych Po wybraniu mechanizmu przesyłania identyfikatora sesji. Przykładowa strona zawierała 14 łączy z których 12 było łączami względnymi. należy zdecydować. powinieneś przeprowadzić własne testy sprawdzające wpływ zastosowanego mechanizmu na wydajność. ?> Test był uruchamiany wiele razy.ini. Wartościami domyślnymi są odpowiednio /tmp i PHPSESSID. } $aStartTime = getmicrotime(). że różnica taka może być w większości witryn mało znacząca. Strona miała wielkość 9. Jeżeli dane sesji nie są dostępne.phtml".aStartTime. print( "Czas całkowity: $aTotTime\n"). lub ostatnia wartość przekazana do funkcji session_save_path(). zawierał błąd w mechanizmie automatycznego uzupełniania adresów URL. $mtime). jak przekazane przez PHP do funkcji write(). • bool open( string save_path. string sess_name ).2. Funkcje te wraz z ich parametrami są przedstawione poniżej. upewnij się. powinna zostać zwrócona wartość False. Funkcja jest używana do odczytania zawartości sesji. Mimo. Jeżeli istnieją dane sesji. • bool write( string sess_id. jaki wpływ będzie to miało na wydajność aplikacji. Funkcja jest wywoływana w przypadku konieczności zapamiętania danych sesji. PHP musi przecież podczas każdego uruchomienia strony odszukać wszystkie łącza na stronie i zmienić URL. powinien zostać zwrócony pusty ciąg (""). Do napisania dowolnego mechanizmu obsługi sesji wystarczy zdefiniować sześć funkcji i zarejestrować je w PHP. Wydruk 7. może ona być ważna w przypadku silnie obciążonych witryn.ini.0. • mixed read( string sess_id ). Można jej użyć do wstępnej inicjalizacji sesji. • bool close().0. Zanim zastosujesz któreś z rozwiązań.6 do odczytania strony kolejno 1000 razy. Użyłem skryptu z wydruku 7. Pierwszy argument jest ścieżką podaną w jako wartość zmiennej konfiguracji session. 85 PHP – Kompendium wiedzy . Drugi argument jest nazwą sesji określoną przez parametr session.6. aby obliczyć średnią różnicę czasów wykonania. $aFileName = "http://localhost/ch07/listing5. for ($nIndx = 0.

php" ).php bool destroy( string sess_id ). Do zilustrowania tego mechanizmu przygotowany został skrypt na wydruku 7. "mysess_read". ?> • Aby pokazać w jaki sposób PHP wywołuje nowe funkcje. Powinna usunąć wszystkie dane związane z sesją. • bool gc( int max_lifetime ). Usuwanie niepotrzebnych danych sesji jest omówione w następnej części rozdziału. $aUser = "Katie".". $aAccount = "2026".7. ?> <html> <head> <title>Własny mechanizm obsługi sesji</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). które jedynie wypisują swoją nazwę i parametry wywołania. Jest ona wywoływana z częstotliwością określoną przez parametr konfiguracji session. użyjemy skryptu z wydruku 7.Funkcja jest wywoływana podczas wywołania w skrypcie funkcji session_destroy(). $aSessionName )<br>" ). $aSessionName ) { print( "mysess_open( $aSavePath./mysession. który zawiera 7 funkcji obsługi zmiennych. Podczas swojego działania powinna usunąć wszystkie dane nie używane przez max_lifetime sekund. "mysess_destroy". Dodatkowo ustawiłem wartość session. Funkcja jest przeznaczona do usuwania nieużywanych danych sesji. Funkcja read() z tego skryptu zwraca dla celów testowych wartości dwóch zmiennych sesji. ?> </body> </html> Rozdział 7 – Sesje i stan aplikacji 86 . Po tej operacji PHP będzie wywoływało wszędzie tam gdzie jest to potrzebne nowe funkcje. print( "Konto: $aAccount<br>" ). więc funkcja czyszczenia pamięci jest wywoływana na początku każdej sesji. } session_set_save_handler( "mysess_open".aAccount|s:4:\"1016\". } function mysess_close() { print( "mysess_close()<br>" ).gc_probability. $aVal ) { print( "Wywołanie mysess_write!\n\nWłaśnie tutaj!\n\n" ). "mysess_gc" ).7.php <?php include( ". return "aUser|s:6:\"Cidnie\". return True.8. Po utworzeniu funkcji obsługi sesji należy zarejestrować je za pomocą funkcji session_set_save_handler(). return True. return True. "mysess_write". return True. } function mysess_gc( $aMaxLifetime ) { print( "mysess_gc( $aMaxLifetime )<br>" ). session_start(). Funkcja ta jest wywoływana w czasie rozpoczynania sesji. <?php function mysess_open( $aSavePath.8. } function mysess_read( $aKey ) { print( "mysess_read( $aKey )<br>" ). Zdefiniowany przez użytkownika mechanizm obsługi sesji: mysession. } function mysess_write( $aKey. print( "Konto: $aAccount<br>" ). $aVal )<br>" ). Wydruk 7. } function mysess_destroy( $aKey ) { print( "mysess_destroy( $aKey )<br>" ). print( "mysess_write( $aKey. return True. print( "Użytkownik: $aUser<br>" ). Wydruk 7.gc_probability na 100. "mysess_close". Testowanie mysession.

to dane sesji będą nieosiągalne.4. stworzenie prawdziwego mechanizmu obsługi sesji będzie dosyć łatwe.9. Na przykład w przypadku serwera Xitami działającego na Windows widoczne były wszystkie spodziewane dane. pole data/czas do zapamiętywania czasu ostatniej zmiany oraz dane w postaci pola tekstowego typu BLOB. Trzeba powiedzieć. 87 PHP – Kompendium wiedzy . Awaria ta będzie wynikała z tego. var $User = "root". W wyniku tego przekierowania nie można wysłać żadnych danych do przeglądarki zarówno w funkcji write(). Następny wydruk zawiera prosty przykład użycia bazy danych MySQL do przechowywania danych sesji. Wynik działania skryptu mysession. Oznacza to. jakiego się spodziewałem. Obsługa sesji przy użyciu bazy danych MySQL <?php include ( "db_mysql. Po dokładniejszym sprawdzeniu odkryłem. INDEX (LastUpdated ) ). Jeżeli wszystkie dane sesji będą przechowywane w bazie danych. że ten efet może nie powtórzyć się w przypadku użycia innej platformy i serwera. Jak można zauważyć dodałem nawet dodatkową instrukcję print() aby dokładniej sprawdzić co się stało. że w którymś momencie wyjście zostało tymczasowo przekierowane z stdout na stderr. Pole LastUpdated posiada indeks w celu poprawienia wydajności w trakcie odzyskiwania nieużytków. var $Database = "mydb". Wydruk 7. W celu poprawienia czytelności kodu.9. że zapisywanie danych aplikacji na serwerze WWW może ograniczać skalowalność aplikacji. Do przechowywania danych sesji korzystamy z tabeli zdefiniowanej w następujący sposób: CREATE TABLE Sessions ( SessionId char(32) not null. LastUpdated datetime not null. ale należy pamiętać. // Specjalizacja klasy DB_Sql do wykorzystania na naszym // serwerem bazy danych MySQL class MySQLDB extends DB_Sql { var $Host = "localhost". użycie plików do obsługi sesji może spowodować załamanie aplikacji. Idea ta może być z początku mało zrozumiała. DataValue text. Wynik w przeglądarce jednak nadal nie był prawidłowy. a kolejne żądanie będzie przekazane do serwera dwa. ponieważ sposób obsługi standardowego wyjścia danych i błędów może być inny. wynik nie był taki. powinieneś przechowywać je w bazie danych a nie w pliku. PRIMARY KEY (SessionID). Problem ten jednak nie wpływa na właściwy system obsługi sesji. Jeżeli początkowe dane zostaną zapisane na serwerze pierwszym. przykład korzysta z klasy DB_Sql pochodzącej z pakietu PHPLIB omówionej w rozdziale 6 „Współpraca z bazami danych”. że wynik działania obu funkcji znajduje się w pliku error_log serwera Apache. Po poznaniu zasady działania mechanizmu.inc" ). Tabela ta zawiera pole do przechowywania identyfikatora sesji. Jeżeli chcesz używać zmiennych sesji. jak i close(). zmienne sesji będą dostępne dla wszystkich serwerów WWW w klasterze. Cały kod funkcji obsługi sesji zamieszczony jest na wydruku 7. że każde żądanie może być kierowane do innego serwera w klastrze. Jeżeli aplikacja zostanie rozdzielona na kilka serwerów WWW i zastosowany zostanie mechanizm równoważenia obciążenia pomiędzy serwerami.php Gdy uruchomiłem ten skrypt.Rysunek 7. W przeglądarce nie było informacji na temat wywołania funkcji write() i close().

} function mysess_destroy( $aKey ) { $aDB = new MySQLDB. W funkcji mysess_read() do bazy jest kierowane zapytanie mające za zadanie odczytać dane związane z identyfikatorem sesji. NOW(). } function mysess_read( $aKey ) { $aDB = new MySQLDB. mysess_write(). czy istnieje już odpowiedni rekord w bazie danych. return "". ". ?> Kod z wydruku jest całkiem prosty jak na tak dużą zmianę mechanizmu obsługi sesji. $aSessionName ) { // nie trzeba nic robić return True. $aDB->query( $aSQL ). } else { // Wstaw wiersz dla bieżącej sesji aby uprościć funkcję write $aSQL = "insert into Sessions values ( '$aKey'. } } function mysess_write( $aKey. } function mysess_gc( $aMaxLifetime ) { $aDB = new MySQLDB.= "LastUpdated=NOW() where SessionID='$aKey'". Wszystkie dane sesji są przechowywane w jednej tabeli. $aSQL . Funkcja mysess_gc() usuwa wszystkie wiersze. } function mysess_close() { // nie trzeba nic robić return True.= ".UNIX_TIMESTAMP(LastUpdated) > $aMaxLifetime". Jeżeli nie ma jeszcze rekordu w bazie. return True. $aData = $aDB->f( "DataValue" ). "mysess_gc"). $aDB->query( $aSQL ). $aData = addslashes( $aVal ). mysess_destroy() oraz mysess_gc(). $aSQL = "delete from Sessions where UNIX_TIMESTAMP(NOW()) ". Funkcje i mysess_close() nie są w tym przypadku używane. Funkcja mysess_destroy() usuwa rekord związany z identyfikatorem sesji. '' )". $aSQL = "update Sessions set DataValue='$aData'. Jeżeli dane te zostaną odnalezione — są zwracane. a po zakończeniu sesji nie trzeba niczego usuwać. mysess_open() <?php Rozdział 7 – Sesje i stan aplikacji 88 . return True. Funkcja mysess_write() za każdym wywołaniem uaktualnia pola DataValue oraz LastUpdated. których wartość pola LastUpdated wskazuje że nie rekord nie był uaktualniany przez ostatnie $aMaxLifetime sekund. } function mysess_open( $aSavePath. "mysess_read". $aDB->query( $aSQL ). Interesującymi funkcjami są mysess_read(). $aSQL . return True. ponieważ nie są potrzebne. return $aData. $aSQL = "delete from Sessions where SessionID = '$aKey'". więc wartości przekazane do mysess_open() nie są używane. "mysess_write". "mysess_destroy". $aVal ) { $aDB = new MySQLDB.var $Password = "root". Poniższy kod pokazuje sposób wykorzystania mechanizmu sesji partego o bazę danych. } session_set_save_handler("mysess_open". tworzony jest nowy rekord z pustym polem DataValue i zwracany jest pusty ciąg (""). $aDB->query( $aSQL ). Powodem takiego działania jest to. że gdy później będą zapisywane dane sesji nie będzie konieczności sprawdzania. $aSQL = "select DataValue from Sessions where SessionID='$aKey'". if ( $aDB->num_rows() == 1 ) { $aDB->next_record(). "mysess_close". $aDB->query( $aSQL ).

Jeżeli wywołasz funkcje session_set_save_handler(). Powinna zawierać jedynie znaki alfanumeryczne. session_start(). session_save_path() i session_id() mogą być użyte do odczytywania lub ustawiania odpowiednio. • session. $aAccount = "1016". Ustawienie jej wartości na files powoduje zapisywanie danych sesji w pliku na serwerze WWW. wartość opcji jest niejawnie przestawiana na user. Opcja ta może być odczytywana lub zmieniana w czasie pracy za pomocą funkcji session_module_name(). Wartością domyślną jest php. ze musisz korzystać z dzielenia ich przy pomocy tych funkcji powinieneś poważnie rozważyć zastosowanie sugestii zamieszczonych w części „Inżynieria programowania a sesje”. co oznacza. że 1% uruchomień sesji powoduje wykonanie funkcji usuwania nieużytków.php" ).?> <br><br> <a href="mysql_session_mgmt2. print( "Konto: $aAccount<br>" ). Możliwe są wartości files. ścieżki zapisu i identyfikatora. PHP zawiera rozwiązania pozwalające na dowolną implementację takiego mechanizmu. Opcja określa prawdopodobieństwo w procentach uruchomienia funkcji gc (usuwania nieużytków) podczas obsługi żądania. że aplikacja posiada własny mechanizm obsługi.include( ". Opcja pozwala na zdefiniowanie nazwy programu obsługi używanego do serializacji i deserializacji danych. session_module_name(). Wartością domyślną jest 1. Ustawienie na user. Opcja określa nazwę sesji. Funkcje session_name(). • session. bieżącej nazwy sesji. "aAccount" ). Dostępny jest wewnętrzny format PHP (o nazwie php) oraz WDDX (o nazwie wddx). • session. Wartością domyślną jest /tmp./mysql_session. nazwy modułu. $aUser = "Cidnie". • session. W pliku php. Wartością domyślną jest 0. Jeżeli potrzebujesz w swojej aplikacji zastosować zmienne sesji. Ponieważ często niemożliwe jest określenie.ini znajdują się następujące opcje konfigurujące mechanizm sesji: • sessions. ?> <html> <head> <title>Obsługa sesji z wykorzystaniem MySQL: Strona pierwsza</title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). W przykładzie tym można zastosować kilka optymalizacji i usprawnień ulepszających działanie. Jeżeli twoja zmienna posiada tak dużo zmiennych sesji. Wartością domyślną jest files. WDDX jest dostępny jedynie po skompilowaniu PHP z obsługą WDDX. user i mm. oznacza.serialize_handler. Jeżeli do PHP – Kompendium wiedzy 89 .save_path.gc_maxlifetime).phtml?<?=SID?>">Przejście do następnej strony</a> </body> </html> Poprzedni przykład pokazuje jak łatwo można utworzyć i używać własny mechanizm przechowywania danych sesji w PHP. które nie były uaktualniane przez określony czas (patrz session.auto_start. Wartość mm powoduje korzystanie z wspólnej pamięci serwera WWW. Jeżeli używasz wbudowanego mechanizmu przechowywania danych. ale przykłady mają za zadanie pokazać ogólną ideę. Usuwanie nieużytków polega na usuwaniu zmiennych sesji zapisanych na serwerze WWW. czy moduł sesji automatycznie uruchamia sesję na początku strony. • session. • session. Miałem kłopot wymyślić projekt.name. Opcja określa. PHP wywołuje funkcję usuwania nieużytków usuwającą zmienne sesji. Opcja określa argument przekazywany do funkcji obsługi sesji. w którym byłaby zalecana zmiana tych parametrów w czasie pracy. Wartością domyślną jest PHPSESSID.lifetime. Pozwala określić w sekundach czas ważności cookie wysyłanego do przeglądarki. Opcja ta pozwala na zdefiniowanie nazwy programu obsługi używanego do zapisywania i odczytywania danych związanych z sesją.save_handler. Domyślną wartością jest 0 (wyłączony). umieszczony w dalszej części rozdziału. używaną również jako nazwa cookie.gc_probability. Wartość 0 oznacza „do zamknięcia przeglądarki”. Inne funkcje i opcje dotyczące sesji PHP posiada jeszcze kilka nie omówionych jeszcze funkcji obsługi sesji. jest to nazwa katalogu gdzie są tworzone pliki. session_register( "aUser". kiedy sesja się zakończyła.

których można uniknąć stosując tą opcję. które będą używały mechanizmu sesji.przesyłania identyfikatora sesji używane są metody GET i POST. PHPLIB była jedną z pierwszych (i prawdopodobnie najbardziej znaną) bibliotek klas zawierających obsługę sesji w PHP. ponieważ powoduje on.use_cookies. var $Database = "mydb". Opcja określa ilość sekund.referer_check. Mimo. Domyślnie jest to 1 (włączone). Obsługa sesji w PHPLIB jest oparta w całości o kod PHP. Mogą to być /dev/random lub /dev/urandom. że korzysta on z cookie do przechowywania identyfikatora sesji na komputerze klienta. • session. że PHPLIB można rozszerzyć w sposób. czy identyfikatory sesji odwołujące się do zewnętrznych witryn są usuwane. Używana jest jedna z klas pochodnych po klasach CT_xxx. które należy odczytać z pliku określonego w poprzedniej opcji.inc" ). PHPLIB wymaga również. include( "session. Wydruk 7. Domyślnie jest to 0 (wyłączone). więc jest możliwa do rozbudowy i konfiguracji poprzez dziedziczenie i rozbudowę klasy bazowej. użytkownicy nie zdając sobie sprawy ze skutków mogą publikować identyfikator sesji. które mogą być bardzo użyteczne w naszych aplikacjach. include( "ct_sql. • session. Prawdopodobnie nie chcesz. Powodem tego jest możliwość zapisania jako zakładki adresu URL. Obsługa sesji w PHPLIB <?php include( "page. Wydruk 7. Domyślnie jest ustawiona na 0. Sytuacja taka może prowadzić do problemów z bezpieczeństwem serwera. Projektując aplikację korzystającą ze zmiennych sesji należy rozważyć wszystkie dostępne opcje. dostępne we wielu systemach Unix. ponieważ użytkownicy mogą wyłączyć obsługę cookie.inc" ).10 zawiera skrypt ilustrujący użycie PHPLIB do zapisu zmiennych sesji w bazie MySQL.entropy_length. PHP zapewnia ogromną elastyczność przy obsłudze sesji. Opcja pozwala na podanie ścieżki do zewnętrznego źródła (pliku). • session. może to spowodować poważne problemy. oraz która z „funkcji” PHPLIB jest używana na stronie. który pozwala na przechowywanie zmiennych sesji w praktycznie dowolnym miejscu. include( "db_mysql. Jeżeli identyfikator sesji jest przesyłany w adresie URL. Polecam metodę przesyłania identyfikatora sesji w adresie URL. Domyślnie jest to 1440 sekund (24minuty). Powoduje to.gc_maxlifetime. Posiada ona również niektóre opcje inicjalizacji. Przykład ten jest identyczny z przedstawionym na wydruku 7. Opcja określa. który posiada dołączony identyfikator sesji. Inne metody przesyłania identyfikatora sesji wymagają więcej pracy. // Specjalizacja klasy DB_Sql do połączenia z // naszym serwerem MySQL class MySQLDB extends DB_Sql { var $Host = "localhost". Opcja pozwala na zdecydowanie czy do przechowywania identyfikatora sesji na komputerze klienta używane będą cookie. Koncepcyjnie jest ona podobna do rozwiązania zastosowanego w PHP4. ponieważ metoda ta wymaga podjęcia decyzji na temat stron. ale korzystne jest wcześniejsze planowanie. Obsługa sesji w PHPLIB oparta jest o klasę kontenerową zdefiniowaną w PHPLIB.9. Opcja pozwala określić ilość bajtów. należy zwiększyć tą wartość. że użycie cookie wydaje się najprostszym rozwiązaniem.10. • session. Użycie PHPLIB do obsługi sesji W rozdziale 6 „Współpraca z bazami danych” przedstawialiśmy PHPLIB. aby funkcje obsługi strony sygnalizowały początek i koniec strony. które będzie używane jako dodatkowe źródło entropii do generowania identyfikatorów sesji. Rozdział 7 – Sesje i stan aplikacji 90 . przeznaczonych do obsługi przechowywania zmiennych sesji.inc" ). • session. oprócz tego. po których dane są uważane za „nieużytki” i usuwane.inc" ). var $User = "root". że ręczne przesyłanie identyfikatora sesji jest o wiele prostsze niż w przypadku projektu pokazanego w tym rozdziale.entropy_file. W zależności od aplikacji możesz wydłużać lub skracać ten czas. jako świetną bibliotekę zawierającą niektóre zaawansowane funkcje do tworzenia aplikacji opartych o PHP. aby użytkownicy po dłuższym czasie kontynuowali starą sesję. Polecam również użycie projektu witryny opartego na szablonach (szczegóły w rozdziale 12 „Oddzielanie kodu HTML od PHP”).

Tak jak PHP posiada on mechanizmy zapewniające zapisywanie danych sesji w liku. } class MySqlSession extends Session { var $classname = "MySqlSession". sid). var $lifetime = 0. $aAccount = "1016". Jedynym dodatkowym wymaganiem jest wywołanie w skrypcie funkcji page_close() do zaznaczenia końca skryptu. Podstawowe funkcje klasy Session w PHPLIB są praktycznie identyczne z możliwościami wbudowanego mechanizmu PHP. Tak jak we wbudowanym mechanizmie sesji PHP. $sess->register( "aAccount" ). Po utworzeniu klas pochodnych PHPLIB wykorzystuje funkcję page_open() do dodania „funkcji” sesji do bieżącej strony. // użycie cookie sesji var $that_class = "MySQLCt".10 jest nieco bardziej skomplikowany.phtml">Następna strona</a> </body> </html> <?php page_close(). // język aplikacji // domyślnie polski 91 PHP – Kompendium wiedzy . Pierwsza klasa pochodna. MySQLCt jest klasą pochodną po klasie kontenerowej CT_Sql. PRIMARY KEY (name. ale doświadczeni programiści na pewno zauważą. changed varchar(14) not null. $aUser = "Cidnie". name varchar(32) not null. $sess->register( "aUser" ). ?> <br><br> <a href="phplib_session_mgmt2. pamięci współdzielonej oraz tabeli bazy danych. // obsługa przechowywania var $mode = "cookie". Poniższy kod pokazuje przykład takiego pliku inicjalizującego: <?php global $lang. że jest on bardzo łatwo rozszerzalny poprzez dziedziczenie bazowych klas obsługi sesji. Kolejna klasa. która jest wykorzystywana w kolejnych wywołaniach obsługi sesji. var $database_class = "MySQLDB". ?> PHPLIB jest niezmiernie elastycznym narzędziem do zarządzania danymi sesji. print( "Konto: $aAccount<br>" ). MySQLSession rozszerza bazową klasę Session i ustawia klasę MySQLCt jako klasę zapisującą wszystkie dane sesji. $lang = "pl". val text. która jest używana do zrealizowania dostępu do tabel. Zawiera ona odwołanie do klasy MySQLDB. PHPLIB posiada również narzędzia do tworzenia klas kontenerowych używanych do zapisywania zmiennych sesji na dowolnie wymyślonym serwerze. która jest podstawową klasą kontenerową zapewniającą zapisywanie danych w bazach danych SQL. var $database_table = "active_sessions". Kod z wydruku 7. Po utworzeniu klasy rejestrowane i wykorzystywane są zmienne sesji.var $Password = "root". Tabela bazy danych wymagana przez mechanizm obsługi sesji w PHPLIB posiada następującą strukturę: CREATE TABLE active_sessions ( sid varchar(32) not null. Ostatnia klasa. } class MySQLCt extends CT_Sql { var $classname = "MySQLCt". ?> <html> <head> <title>Obsługa sesji w PHPLIB: Pierwsza strona </title> </head> <body> <?php print( "Użytkownik: $aUser<br>" ). MySQLDB jest klasą niezbędną do nawiązania połączenia z naszym serwerem bazy danych. PHPLIB pozwala na wykorzystanie cookie lub zmiennych GET i POST do przesyłania identyfikatora sesji. // nazwa używanego kontenera } page_open( array( "sess" => "MySqlSession" ) ). Dodatkową funkcja PHPLIB jest możliwość dostarczania pliku inicjalizującego używanego do inicjalizacji zmiennych sesji na początku każdej sesji. Wywołanie tej funkcji powoduje utworzenie globalnej zmiennej $sess. $sess->register("lang"). KEY changed (changed) ).

jak zmienne globalne przy pisaniu tradycyjnych aplikacji. Czasami niektóre dane są tak często używane w aplikacji. ?> // waluta aplikacji // domyślnie złotówki // utworzenie obiektu wózka na zakupy // zdefiniowanego w local. każda strona biorąca udział w sesji musi załadować wszystkie zmienne sesji nawet. Lista ta wskazuje powody rozważane użycia zmiennych globalnych przy programowaniu zwykłych aplikacji. Dane globalne. często są nadużywane w takim samym stopniu. w których należy skorzystać ze zmiennych sesji. Może być to duże zbiory danych używane w całej aplikacji.global $cur. • Zastępowanie nazwanych stałych. pełna). • Eliminowanie wędrujących danych. gdy nie korzysta z żadnej. że po zdefiniowaniu w aplikacji zmiennych sesji. Rozwiązanie to jest proste do zrealizowania i nie wymaga żadnych dodatkowych narzutów wprowadzanych przez przedstawione w tym rozdziale narzędzia obsługi sesji.inc // zarejestrowanie obiektu Mimo. może być przydatny dostęp do całego kodu źródłowego PHP. $sess->register("cart"). Dodatkowo przesyłanie wartości identyfikatora otwartym tekstem może powodować naruszenie bezpieczeństwa. na przykład aby wykonać niektóre optymalizacje. że powodem użycia zmiennej globalnej mogą być następujące przypadki: • Przechowywanie wartości globalnych. Są one elastyczne i łatwe do użycia. to dane odzwierciedlające stan całej aplikacji. jak decyzja użycia zmiennej globalnej. na przykład tryb pracy (wersja próbna. które nie posiadają wbudowanego mechanizmu sesji. ale decyzja użycia zmiennej sesji powinna być oparta na tych samych kryteriach. Bądź ostrożny przy uznawaniu zmiennej za zmienną sesji. na przykład tabele słownikowe. Wybór niewłaściwego narzędzia na początku całego procesu może być kosztowne i prowadzić w dłuższej perspektywie do problemów z konserwacją i rozwojem aplikacji. Mając tą wartość możesz odczytać z bazy danych wszystkie potrzebne na stronie dane. Gdy procedury w takim łańcuchu nie korzystają z takich danych. W wielu wypadkach jedyną daną. Tak jak w przypadku wszystkich innych aspektów projektowania aplikacji należy wykona dokładną analizę potrzeb aplikacji i na jej podstawie wybrać właściwy schemat zarządzania sesjami. Należy pamiętać. Należy również Rozdział 7 – Sesje i stan aplikacji 92 . Czasami wartości są przekazywane do procedury tylko po to. ale tak jak wszystkie inne narzędzia programistyczne powinny być używane ostrożnie i według projektu. $cart = new Shop_Cart. jest klucz główny lub identyfikator. Steve McConnell. ponieważ wydaje się występować w każdej procedurze i na każdej stronie witryny WWW. Tworzenie własnego mechanizmu sesji W niektórych przypadkach w aplikacji może nie być potrzebny kompletny mechanizm sesji. Inżynieria programowania a sesje Zmienne sesji mogą być niezmiernie istotne we wielu aplikacjach WWW. Projektując aplikację WWW należy szczegółowo rozważyć wszystkie zastosowania. są one nazywany danymi wędrującymi. jaką musimy przesyłać pomiędzy stronami. • Uproszczenie użycia bardzo często używanych danych. Możesz również stosować PHPLIB do realizowania sesji w starszych wersjach PHP. zastosowanie to nie jest dopuszczalne. że występują w liście parametrów każdej procedury. autor książki „Code Complete” (Microsoft Press. przesyłanie identyfikatora wymaga nieco dokładniejszego projektowania aplikacji. aby mogły być przekazane do kolejnej. 1993) uważa. Ponieważ PHP posiada stałe. że PHP posiada wbudowany mechanizm sesji zbliżony do rozwiązania zastosowanego w PHPLIB. $cur = "PLN". global $cart. Ponieważ zmienne sesji są bardzo łatwe do użycia. więc korzystając z tej metody zaleca się używanie odpowiedniej mechanizmu szyfrowania. $sess->register("cur"). Z drugiej strony. Takie podejście najczęściej prowadzi do nadużywania danych globalnych i zmiennych sesji. Decyzja użycia zmiennej sesji powinna być oparta na takich samych przesłankach. W takich przypadkach bardziej efektywne będzie przesyłanie identyfikatora pomiędzy stronami aplikacji za pomocą zmiennych GET i POST.

Na przykład. Jeżeli pierwotny użytkownik uaktualnił tabelę uprawnień w czasie. jest to świetny kandydat na zmienną sesji. ponieważ programista nie ładuje jawnie zmiennych sesji. nie było by problemu. którym pierwsi użytkownicy ufali. jeżeli aplikacja korzysta z logowania użytkowników. są one automatycznie odczytywane z trwałego nośnika. • Czy zmienna ta jest unikalna dla tej sesji? Jeżeli jest to na pewno dana związana z sesją. Takie niefortunne działanie było spowodowane tym. ale dobrze zaprojektowanej bazy danych. doradca miał dostęp tylko do danych zleconych w trakcie rozpoczynania sesji. W jednym z moich ostatnich kontraktów natrafiłem na świetny przykład nieprawidłowego użycia zmiennych sesji. jeżeli tworzysz wózek na zakupy. W trakcie projektowania należy rozważyć wszystkie alternatywne sposoby uzyskana tego samego efektu. aby wyeliminować odwołania do baz danych (aby przyspieszyć ładowanie strony) przy pobieraniu danych o uprawnieniach. Większość aplikacji WWW wymaga zastosowania tylko kilku zmiennych sesji. Dodatkowo. Za każdym razem. Jednak ktoś zdecydował. • Czy dana jest dana kluczową? Pytanie to jest związane z pierwszym. prawdopodobnie nie potrzebujesz zmiennej sesji. są spowolnione przez proces ładowania zmiennych sesji. lista ta była uaktualniana (wraz z tabelą uprawnień). że pierwszy programista nie zapewnił realizacji dwóch celów. że nawet strony. że zapewniają one wygodniejszy dostęp do danych związanych z sesją. gdy doradca otwierał w programie zbiór danych. zapamiętaj ją w zmiennej sesji. Drugi cel nie został spełniony. musiał na początku wybrać zbiór danych do oglądania. aby nie korzystać z bazy danych do sprawdzania uprawnień i w zmiennej sesji przesyłana była lista zleconych identyfikatorów danych. Następnie. Jeżeli aplikacja korzysta ze zmiennych sesji do przechowywania identyfikatora użytkownika. którym dane były udostępniane byli doradcami. Gdy użytkownik udostępniał dane doradcy. Jeżeli te identyfikatory byłyby jedynymi zmiennymi sesji. w którym tabela z danymi jest połączona z tabelą z uprawnieniami. ponieważ programista nie wiedział czy używać danych z bazy danych czy ze zmiennych sesji. Po pierwsze. jest o wiele bardziej efektywne. ale powinny być używane rozważnie. gdy element danych był pobierany z bazy. Gdy doradca logował się do aplikacji. musisz prawdopodobnie przechowywać jego identyfikator w zmiennej sesji. W aplikacji użytkownicy mogli utworzyć zbiór danych i udostępnić je do modyfikacji przez innego użytkownika. zmienne sesji zostały zastosowane.unikać użycia zmiennych sesji jedynie dlatego. Spowoduje to usunięcie ogromnej ilości kodu i wyeliminuje konieczność przechowywania listy uprawnień w danych sesji. Jednak jeżeli aplikacja korzysta z kilku trwałych wózków na zakupy w których użytkownik może przechowywać zamówienie w czasie kilku sesji. które zawierały identyfikator konta doradcy. dane o tym były zapisywane w bazie danych. ponieważ doradca nie powinien go widzieć Jak wspominaliśmy w rozdziale 6 „Współpraca z bazami danych”. Głównym problemem powodowanym przez takie podejście były kłopoty z synchronizacją danych. które wymagają tych informacji. jego identyfikator był poszukiwany w zawartości zmiennej sesji zamiast w bazie danych. Po drugie. unikaj przechowywania innych danych 93 PHP – Kompendium wiedzy . ponieważ programista nie korzystał w pełni z wydajności bazy danych. Tabela uprawnień zawierała identyfikator pierwotnego użytkownika i doradcy oraz identyfikator danych udostępnianych przez użytkownika. oraz identyfikator przeglądanych danych klienta. W aplikacji były ustawiane zmienne sesji. Na wszystkich stronach aplikacji dane o uprawnieniach są ładowane z serwera WWW i po zakończeniu strony ponownie zapisywane. rozwijanie aplikacji według tego modelu było frustrujące. postaw sobie następujące pytania: • Czy ta zmienna jest używana w całym programie? Jeżeli ta wartość jest używana na każdej stronie aplikacji. Na przykład. Proces ten powoduje. gdy doradca był zalogowany w aplikacji. Użytkownicy. Gdy chcesz zastosować zmienną sesji. Pierwszy cel nie został zrealizowany. Poprzedni przykład kodu może być zastąpiony zapytaniem. Ładowanie danych uprawnień z bazy danych jedynie na stronach. Zmienne sesji są niezmiernie potrzebne przy programowaniu aplikacji WWW. zmienne sesji były używane do uproszczenia sprawdzania uprawnień w kodzie strony. należy wykorzystywać możliwości bazy danych do poprawienia wydajności aplikacji. dobrze jest przechowywać identyfikator użytkownika w zmiennej sesji. które nie korzystają z uprawnień. Na wielu stronach kod wyglądał następująco: WYIERZ wszystkie potrzebne dane z konta pierwotnego użytkownika DLA KAŻDEGO WIERSZA JEŻELI identyfikator tego wiersza znajduje się na liście uprawnień w zmiennej sesji wyświetl lub wykorzystaj dane W PRZECIWNYM WYPADKU ignoruj ten wiersz.

Podsumowanie W PHP dostępne jest kilka świetnych narzędzi do stworzenia mechanizmu sesji. Należy wybrać mechanizm. jeżeli aplikacja personalizuje strony. Przechowuj w sesji identyfikator i wykorzystaj kilka funkcji odczytujących dane potrzebne do personalizacji. Struktura taka nie tylko eliminuje powtórzenia danych. Zmienne sesji nie powinny zastępować innych mechanizmów przechowywania danych. w razie potrzeby skorzystaj z identyfikatora do odczytania potrzebnych danych. że użytkownik przegląda witrynę i przeprowadza jakieś operacje niekoniecznie oznacza. ale również pozwala użytkownikowi na zmianę swoich ustawień w jednej sesji i natychmiastowe odzwierciedlenie tego w drugiej równoległej sesji. Sesje są świetnym narzędziem. ale nieprawidłowo używane mogą doprowadzić do stworzenia aplikacji pełnej błędów i trudnej do utrzymania. Zamiast tego. ale często jest pomijane z powodu łatwości używania zmiennych sesji. • Czy aplikacja na pewno potrzebuje zmiennych sesji? Pytanie to może wydawać się oczywiste. To. Na przykład. Jeżeli odpowiedź na te pytania nie zgadza się z zasugerowanymi odpowiedziami. który najlepiej pasuje do potrzeb i którego zastosowanie będzie przynosiło owoce w dłuższym czasie a nie tylko będzie miał krótkoterminowy wpływ na kodowanie aplikacji. należy rozważyć zastosowanie innych metod przechowywania danych.związanych z użytkownikiem w zmiennej sesji. Rozdział 7 – Sesje i stan aplikacji 94 . że potrzebna jest sesja. która posiada trudne do zidentyfikowania błędy. nie przechowuj zmiennych potrzebnych do tego celu w sesji. Nieprawidłowe użycie zmiennych sesji może doprowadzić do stworzenia aplikacji trudnej do rozwijania.

Wydruk 8.htaccess jest mniej efektywne od wykorzystania standardowych plików konfiguracyjnych. ale jedynie w oparciu o serwer Apache na Linuksie (Windows i IIS również umożliwiają uwierzytelnianie.phtml">Przejdź do strony administratora</a> </body> </html> Wydruk 8. W tym rozdziale zajmiemy się uwierzytelnianiem opartym na mechanizmach serwera. Uwierzytelnianie Wstęp W poprzednim rozdziale „Sesje i stan aplikacji” omówione zostały sposoby śledzenia użytkowników witryny WWW w celu zapewnienia ciągłości pracy aplikacji. Na przykład może być niezbędne stworzenie zbioru stron przeznaczonych do administracji witryną. Strony te nie mogą być dostępne dla wszystkich użytkowników. że użytkownicy maja wystarczające uprawnienia do pracy w aplikacji. więc kliknięcie tego łącza spowoduje. Odpowiednie dyrektywy konfiguracji mogą znajdować się w pliku httpd. Jeżeli masz dostęp do plików konfiguracyjnych Apache powinieneś skorzystać z nich zamiast z pliku . Jednak jeżeli witryna jest umieszczona na dzierżawionym serwerze.Rozdział 8.2. pokazane na rysunku 8. Większość serwerów WWW posiada narzędzia przeznaczone do autoryzacji użytkowników w oparciu o uprawnienia i pliki serwera.htaccess. prawdopodobnie nie będziesz mógł zmienić plików konfiguracyjnych i zrestartować serwera WWW w celu pobrania zmienionej konfiguracji. Prosta strona HTML z łączem do stron administracyjnych <html> <head> <title>Proste uwierzytelnianie Apache</title> </head> <body> <a href="admin/index. Korzystanie z pliku . ale nie zostanie ono tutaj opisane). Dyrektywy konfiguracji Apache włączające podstawowe uwierzytelnianie AuthUserFile /www/auth_users AuthName Adminstrative . Wykorzystanie mechanizmu uwierzytelniania dostarczanego przez serwer WWW jest zwykle szybkim i efektywnym sposobem zrealizowania takiego mechanizmu.htaccess i innych plików konfiguracyjnych serwera Apache nie dowiedzą się tutaj zbyt wiele nowego.1.htaccess. Na wydruku 8. że przeglądarka wyświetli standardowe okno uwierzytelniania. Osoby znające dyrektywy uwierzytelniania Apache oraz przeznaczenie plików . Wydruk 8.2 zawiera dyrektywy konfiguracji Apache które powodują wyświetlenie okna logowania. Istnieją różne schematy uwierzytelniania przeznaczone do różnych zadań.conf lub . za pomocą których można przeglądać i zmieniać wybrane elementy witryny. Strona administracyjna znajduje się w katalogu wymagającym uwierzytelniania. Aby zrealizować takie założenia możesz przenieść wszystkie strony administracyjne do osobnego podkatalogu w drzewie katalogów witryny WWW oraz zmienić konfigurację Apache tak. Ten rozdział poświęcony będzie sposobom upewnienia się. Podstawowe uwierzytelnianie w Apache Rozdział ten rozpoczniemy omówieniem podstawowego schematu uwierzytelniania dostępnego w serwerze WWW Apache oraz problemami związanymi z tą metodą. ponieważ jest on odczytywany za każdym żądaniem pliku z katalogu zawierającego plik .1 zamieszczony jest wydruk prostej strony HTML zawierającej łącze do podkatalogu ze stroną administracyjną.1.htaccess w chronionym katalogu. W dalszej części rozdziału przedstawiony zostanie również mechanizm niezależny od serwera i platformy. aby dostęp do stron znajdujących się w tym katalogu wymagały autoryzacji. Nawet w prostej witrynie może być potrzebne ograniczenie dostępu do niektórych stron. ale administrator musi mieć do nich dostęp z dowolnej przeglądarki.

Wydruk 8. Okno dialogowe uwierzytelniania w przeglądarce Więcej informacji na temat użycia uwierzytelniania Apache można znaleźć w Sieci oraz we wielu świetnych książkach poświęconych serwerowi Apache.2. gdy chcesz chronić wszystkie strony i inne zasoby znajdujące się we fragmencie drzewa Rozdział 8 – Uwierzytelnianie 96 . których możesz użyć w aplikacji w celu odczytania danych autoryzacji. Wyświetlanie zawartości zmiennych autoryzacji <html> <head> <title>Strona administratora</title> </head> <body> <h1>Witamy na stronie administratora</h1> <?php print( "PHP_AUTH_USER: $PHP_AUTH_USER<br>" ).AuthType Basic <Limit GET> require valid-user </Limit> Rysunek 8. Jeżeli serwer zaakceptuje uwierzytelnianie. Zmienne autoryzacji w PHP Schemat autoryzacji Apache zapewnia podstawowy stopień bezpieczeństwa witryny. Przeglądarka wysyła wprowadzone dane do serwera podczas żądania sprowadzenia wszystkich kolejnych stron aż do zakończenia pracy przeglądarki.3 zawiera stronę wyświetlająca dane autoryzacji. Ten rodzaj uwierzytelniania wymaga współpracy pomiędzy przeglądarką i serwerem. pokazana jest zawartość tej strony po przejściu do niej poprzez łącze znajdujące się na stronie z wydruku 8. chroniony zasób jest udostępniony użytkownikowi. serwer WWW wysyła żądanie 401 do przeglądarki a przeglądarka odpytuje użytkownika i odsyła wprowadzone przez niego dane do serwera. Jest on szczególnie użyteczny w sytuacjach.3. Na rysunku 8.1.2.1. PHP posiada zmienne globalne. print( "PHP_AUTH_PW: $PHP_AUTH_PW<br>" ). ?> </body> </html> Rysunek 8. Mechanizm ten wygląda następująco: gdy użytkownik musi zostać autoryzowany. Możesz skorzystać ze zmiennych $PHP_AUTH_USER oraz $PHP_AUTH_PW do odczytania nazwy użytkownika i hasła. Wydruk 8.

usuwania użytkowników. Wydruk 8. if ( !$aHTPasswd->EXISTS ) { print( "Błąd autoryzacji<br>" ). co pozwoli na stworzenie narzędzia WWW do dodawania i usuwania użytkowników. $aHTPasswd = new Htpasswd("/www/auth_users"). Wydruk 8. Wydruk 8. czy została wywołana w wyniku żądania POST.5 zawiera pierwszą część skryptu. exit.php3" ). Ograniczeniem stosowania tej metody jest konieczność dodawania i usuwania użytkowników poprzez wykonanie odpowiednich poleceń na serwerze.6 i 8.4.net/) stworzyli dwie klasy służące do zarządzania użytkownikami i grupami plików dla celów podstawowego uwierzytelniana. zmiany hasła.5. Sprawdzanie poprawności autoryzacji użytkownika za pomocą klasy Htpasswd <html> <head> <title>Szybkie sprawdzenie użytkownika z uzyciem klasy Htpasswd</title> </head> <body> <?php include( ". jak można wykorzystać tę klasę do autoryzacji użytkownika. sprawdzania poprawności użytkownika oraz zmiany jego nazwy.Htpasswd.theWebmasters. Przykład korzysta z tego samego pliku. który został użyty w poprzednim przykładzie. przy użyciu bardzo małej ilości kodu. Użycie klasy Htaccess do zarządzania użytkownikami <?php include( ".5. } else { print( "phpbook nie jest prawidłowym użytkownikiem<br>" ). 8.Htpasswd. $aHTPasswd = new Htpasswd("/www/auth_users").4 pokazany został przykład. można przy użyciu PHP stworzyć narzędzie administracyjne upraszczające zarządzanie użytkownikami. } if ( { $REQUEST_METHOD == 'POST' ) switch ( $acttype ) { 97 PHP – Kompendium wiedzy . w jaki sposób można połączyć wszystkie te operacje w jednym formularzu. Na wydruku 8.7 zawierają skrypty pokazujące. Skrypt ten jest podobny do wielu przytoczonych do tej pory przykładów. } else { if ( $aHTPasswd->verifyuser( "phpbook". Skrypty na wydruku 8./class. które przesyłają dane do samego siebie i są używane zarówno do wyświetlania jak i do zmiany danych.htaccess przy użyciu PHP Jeżeli podstawowe uwierzytelnianie serwera WWW jest wystarczające w tworzonej aplikacji. W następnej części zostanie opisane w jaki sposób można wykorzystać PHP do aktualizacji pliku haseł. Do manipulacji standardowym plikiem Apache htpasswd można wykorzystać klasę Htpasswd. Programiści zespołu The Webmasters Net (http://www. "phpbook" ) ) { print( "phpbook to prawidłowy użytkownik<br>" ). Przy pomocy tej klasy można napisać obszerne narzędzie do administracji użytkownikami.php3" ). Aktualizacja pliku . if ( !$aHTPasswd->EXISTS ) { print( "Błąd krytyczny<br>" ). którzy będą mogli operować użytkownikami bez konieczności udostępniania im bezpośredniego dostępu do serwera./class. } } ?> </body> </html> Klasę Htpasswd można również wykorzystać do dodawania nowych użytkowników. Można udostępnić to narzędzie zaufanym osobom. które będzie pomocne przy zarządzaniu mechanizmem podstawowego uwierzytelniania serwera.katalogów witryny. Jest ona używana do inicjalizacji skryptu i określenia czy strona jest oglądana pierwszy raz.

break. $ChangePass ). } } ?> Jeżeli skrypt ten zostanie wywołany w wyniku żądania POST. która realizuje wysłanie danych formularza do odpowiedniej strony. Oczywiście. case 'rename' : $aUserName = $aHTPasswd->USERS[$CurUserRow]["user"]. Zmienna posiada pięć możliwych wartości: none. Dla wszystkich przycisków znajdujących się na formularzu zdefiniowana jest odpowiednia akcja. Strona z formularzem HTML <body> <form action="<?=$PHP_SELF?>" method="post" name="mainform" id="mainform"> <input type="hidden" name="acttype" value="none"> <h1>Prosty program zarządzający użytkownikami</h1> <h2>Dodanie użytkownika</h2> Nazwa nowego użytkownika: <input type="text" name="NewUserName"><br> Hasło: <input type="password" name="NewUserPass"><br> <input type="button" value="Dodaj" onClick="DoSubmit( 'add' ).7. print( "<b>Nazwa użytkownika zmieniona z $aUserName na $RenameName</b><br>" ).6. print( "<b>Dodano użytkownika $NewUserName</b><br>" ). delete. case 'add' : $aHTPasswd->addUser( $NewUserName. } //--> </script> </head> Ostatnia część skryptu pokazana na wydruku 8. Wydruk 8. Wydruk 8. add.value = aType. $aHTPasswd->renameUser( $aUserName.submit(). print( "<b>Usunięto użytkownika $aUserName</b><br>" ). break. rename oraz changepass. na podstawie wartości zmiennej formularza podejmowana jest decyzja co do kolejnej akcji. $RenameName ). Ustawianie zmiennej $acttype $acttype <html> <head> <title>Prosty program zarządający użytkownikami</title> <script language="JavaScript"> <!-function DoSubmit( aType ) { document.mainform.mainform. Każdy przycisk na formularzu zawiera atrybut onClick. Do ustawiania ukrytej zmiennej formularza $acttype wykorzystujemy JavaScript. Kod PHP jest jedynie używany do wstawiania istniejących użytkowników do listy SELECT. document. break. aby program mógł być normalnie używany niezbędne jest dodanie kodu kontroli poprawności. $aHTPasswd->deleteUser( $aUserName ). że wszystkie potrzebne dane są prawidłowo wypełnione."> <hr> <h2>Zmiana użytkownika</h2> <table> <tr> <td> <select name="CurUserRow" size="10"> <?php $nIndex = 0. $NewUserPass ).7 jest po prostu stroną HTML zawierającą formularz. W skrypcie założono. } ?> Rozdział 8 – Uwierzytelnianie 98 . case 'changepass' : $aUserName = $aHTPasswd->USERS[$CurUserRow]["user"]. break. $nIndex++. W zależności od wyboru użytkownika podejmowana jest odpowiednia akcja. $aHTPasswd->changePass( $aUserName. który powoduje wywołanie przedstawionej funkcji JavaScript.acttype. case 'delete' : $aUserName = $aHTPasswd->USERS[$CurUserRow]["user"].case 'none' : break. W następnej części skryptu ustawiana jest zmienna $acttype. print( "<b>Zmieniono hasło dla użytkownika $aUserName</b><br>" ). foreach( $aHTPasswd->USERS as $aUser ) { print( "<option value=\"$nIndex\">$aUser[user]</option>" ).

"> <br><br> Zmiana nazwy zaznaczonego użytkownika: <input type="text" name="RenameName"><input type="button" value="Zmiana nazwy" onClick="DoSubmit( 'rename' ). Rysunek 8.3. Jak mówiliśmy wcześniej. W niektórych przypadkach może być wymagane zabezpieczenie tylko niektórych stron aplikacji lub nie jest możliwa modyfikacja odpowiednich plików na serwerze WWW."><br><br> Zmiana hasła dla zaznaczonego użytkownika: <input type="password" name="ChangePass"><input type="button" value="Zmiana hasła" onClick="DoSubmit( 'changepass' ). skrypt ten nie jest kompletnym narzędziem zarządzającym użytkownikami. Program zarządzający użytkownikami w działaniu Podstawowe uwierzytelnianie za pomocą PHP Poprzednie dwie części opisywały podstawowe uwierzytelnianie serwera Apache do ochrony fragmentów witryny WWW (zwykle katalogów).</select> </td> <td> Usunięcie zaznaczonego użytkownika: <input type="button" value="Usuń" onClick="DoSubmit( 'delete' ). W takim przypadku możesz wykorzystać PHP do wysyłania odpowiednich nagłówków do serwera i w ten sposób bezpośrednio żądać autoryzacji.3. Można również skorzystać z dostarczanej przez The Webmasters Net klasy Htgroup do tworzenia i zarządzania grupami użytkowników. a jedynie pokazuje sposób wykorzystania klasy Htpasswd. 99 PHP – Kompendium wiedzy ."><br><br> </td> </tr> </table> </form> </body> </html> Na rysunku 8. pokazana jest strona bezpośrednio o dodaniu użytkownika scott.

PHPLIB pozwala na stworzenie autoryzacji opartej na uprawnieniach. Schemat autoryzacji PHPLIB jest uruchamiany podczas wywołania funkcji PHPLIB page_open() i zażądanie „własności” sess.8.inc. Głównym powodem użycia tego typu implementacji jest zwiększenie elastyczności aplikacji. Następna metoda jest bardziej niezależna od platformy i posiada bardziej elastyczne podejście do uwierzytelniania. PHP posiada wystarczająco dużo narzędzi i elastyczności aby można było napisać dowolny system autoryzacji użytkowników. } ?> Skrypt ten na początku pracy sprawdza. to wartości zmiennych $PHP_AUTH_USER i $PHP_AUTH_PW są porównywane z prawidłową nazwą użytkownika i hasłem aplikacji. echo "Nie udało się zalogowanie do systemu. Mechanizm uwierzytelniania realizowany przez PHPLIB jest w wielu punktach podobny do mechanizmu obsługi sesji. Kompletny system uwierzytelniania oparty o PHP Wykorzystanie metody autoryzacji opisanej w poprzedniej części jest łatwe i proste. Gdy zostanie zażądana ta własność.0 401 Unauthorized" ). należy albo wysyłać dane nagłówków przed wysłaniem jakichkolwiek danych strony. Rozdział 8 – Uwierzytelnianie 100 .php <?php $aDoAuth = True. if ( isset( $PHP_AUTH_USER ) ) { if ( ( $PHP_AUTH_USER == "ryan" ) && ( $PHP_AUTH_PW == "dentist" ) ) { // prawidłowa nazwa użytkownika i hasło $aDoAuth = False. która nie polega na wywołaniach HTTP 401 z serwera. Poprzednia metoda jest oparta o możliwość obsługi przez przeglądarki wywołań HTTP 401 ale metoda ta posiada wiele ograniczeń.8 zamieszczony jest prosty skrypt żądający autoryzacji. więc będzie go można łatwo dodawać do wszystkich stron wymagających autoryzacji. Zamiast tego należy wykorzystać bazę danych lub usługę katalogową (na przykład LDAP) lub nawet pliki zawierające dane uwierzytelniania. Większość programistów WWW wykorzystywało już pliki . Poniższa implementacja wykorzystuje klasę Auth z PHPLIB. Jeżeli tak. Jedną z zalet takiego podejścia jest możliwość odwołania uwierzytelnienia użytkownika poprzez ponowne wysłanie nagłówka HTTP 401. auth_include.\n". Jeżeli porównanie nie uda się skrypt wysyła do przeglądarki nagłówek HTTP 401. Prawdziwy system uwierzytelniania nie powinien mieć zaszytych nazw użytkowników i haseł w samym skrypcie. Skrypt auth_include. W tej części skupimy się na implementacji. Wydruk 8. exit. zanim można będzie ją wykorzystać. Jeżeli nie korzystamy z mechanizmów przeglądarki przy wyświetlaniu okna uwierzytelniania. który powoduje wyświetlenie okna autoryzacji. wymuszających na przeglądarce wyświetlenie okna uwierzytelniania. albo korzystać z buforowania wyjścia.htaccess do zabezpieczania katalogów. Można to wykorzystać do ponownego logowania użytkownika po określonym czasie bezczynności lub do chronienia różnymi hasłami różnych części aplikacji. ale przez o wymaga sporo zachodu. nie ma potrzeby wysyłania do przeglądarki nagłówka autoryzacji. Skrypt ten jest w postaci pliku dołączanego. musimy sami tworzyć formularz HTML służący do pobierania danych niezbędnych dla naszej aplikacji. } } if( $aDoAuth == True ) { Header( "WWW-Authenticate: Basic realm=\"My Realm\"" ). Na wydruku 8. albo do przerwania uwierzytelniania przez użytkownika. Dodatkowo. Jest to ekstremalnie solidna i elastyczna implementacja. Jeżeli sprawdzenie to się powiedzie. Do działania wymaga on sesji PHPLIB. Header( "HTTP/1. Proces ten jest powtarzany aż do podania właściwych danych autoryzacji. czy ustawiona jest zmienna $PHP_AUTH_USER. więc do każdej strony można przypisać wymagany poziom uprawnień dla każdego z użytkowników. więc sposób ten jest zwykle dobrze znany.Tak jak w przypadku wysyłania innych danych nagłówka. Dołączenie tego pliku na początku dowolnego skryptu powoduje konieczność autoryzacji użytkownika skryptu. Jednak po jej zaprogramowaniu jest świetnym zamiennikiem metody opisanej w poprzedniej części.

// wybór kontenera var $allowcache_expire = 0.inc" ). NOT NULL. include( "ct_sql. include( "auth.inc" ). Na rysunku 8. include( "db_mysql. var $database_class = "MySQLDB".inc" ).PHPLIB sprawdza zalogowanie użytkownika.9. } class MySQLCt extends CT_Sql { var $classname = "MySQLCt"./sample_lform.= "'$FirstName' ) and ( SurName = '$SurName' )". var $lifetime = 20. 101 PHP – Kompendium wiedzy . NOT NULL. SurName) Wydruk 8. var $Database = "mydb". } class Sample_Auth extends Auth { var $classname = "Sample_Auth".inc" ). pokazana jest interakcja pomiędzy klientem.inc" ). var $lifetime = 0. Tabela użyta do autoryzacji jest zdefiniowana następująco: CREATE TABLE MyAuth ( FirstName varchar(20) SurName varchar(30) password varchar(20) PRIMARY KEY (FirstName. Strona ta pobiera dowolne dane. Następnie PHPLIB wywołuje dostarczoną przez użytkownika funkcję sprawdzającą uprawnienia użytkownika.htinc" ). serwerem WWW (i tym razem jest to 1U z Penguin Computing) oraz aplikacją PHP.4. var $User = "root". include( "session. // Obsługa przechowywania var $mode = "cookie". } function auth_validatelogin() { global $FirstName. na wydruku 8.9 pokazane są klasy zdefiniowane przez użytkownika niezbędne do stworzenia klasy Auth i klas ją wspomagających (Klasy sesji i bazy danych są identyczne jak te. Jeżeli użytkownik nie podawał wcześniej danych autoryzacji. których używaliśmy w rozdziale 7). PHPLIB wyświetla stronę a w przeciwnym wypadku następuje ponowne uwierzytelnianie. $Password. class MySQLDB extends DB_Sql { var $Host = "localhost". PHPLIB wyświetla zdefiniowaną przez użytkownika stronę. Rysunek 8. Przygotowanie klas używanych przez klasę PHPLIB Auth <?php include( "page. jakich aplikacja wymaga do prawidłowej autoryzacji użytkownika. } class MySqlSession extends Session { var $classname = "MySqlSession". // użycie cookie sesji var $that_class = "MySQLCt". $aSQL = "select * from MyAuth where ( FirstName = ". W naszym przypadku dane autoryzacji znajdują się w tabeli bazy danych MySQL. // 20 minut (0 == ciągle) function auth_loginform() { include( ". Interakcja w schemacie autoryzacji PHPLIB Z powodu elastyczności jaką zapewnia PHPLIB wymagane jest wykonanie kilku niezbędnych kroków zanim użyjemy naszej klasy autoryzacji. ). Jeżeli funkcja ta zaakceptuje użytkownika. $SurName. var $database_table = "active_sessions".4. Po pierwsze. $aSQL . var $Password = "root". NOT NULL. $aDB = new MySQLDB.

ale zwykle dołączenie pliku jest łatwiejsze. Funkcja auth_loginform() jest wywoływana. } else { return False. </td> </tr> <?php } ?> </table> Rozdział 8 – Uwierzytelnianie 102 . $aCurSurName = "". gdy klasa Auth wymaga uwierzytelnienia użytkownika. $aCurFirstName = "". global $SurName.10 pokazany jest plik użyty w tym przykładzie. spróbuj jeszcze raz. if ( !empty( $FirstName ) ) { $aCurFirstName = $FirstName. $aDB->query( $aSQL ). Na wydruku 8.= "and ( Password = '$Password' )". Możesz użyć instrukcji print() do stworzenia formularza HTML potrzebnego do zalogowania. Zdefiniowane są odpowiednie funkcje auth_loginform() i auth_validatelogin().htinc) <?php global $FirstName.10. } } } ?> Klasa Sample_Auth dziedzicząca po klasie bazowej Auth zapewnia działanie specyficzne dla bieżącej aplikacji.$aSQL . } if ( !empty( $SurName ) ) { $aCurSurName = $SurName. if ( $aDB->num_rows() > 0 ) { return $FirstName. } ?> <html> <head> <title>Formularz autoryzacji dla PHPLIB</title> </head> <body> <form action="<?=$this->url()?>" method="post"> <table> <tr> <td> Imię: </td> <td> <input type="text" name="FirstName" value="<?=$aCurFirstName?>"> </td> </tr> <tr> <td> Nazwisko: </td> <td> <input type="text" name="SurName" value="<?=$aCurSurName?>"> </td> </tr> <tr> <td> Hasło: </td> <td> <input type="password" name="Password"> </td> </tr> <tr> <td colspan="2"> <input type="submit" name="Submit" value="Log In"> </td> </tr> <?php if ( !empty( $FirstName ) ) { ?> <tr> <td colspan="2"> <br><br> Podane dane są nieprawidłowe.. Przykładowy formularz logowania (sample_lform. Wydruk 8.

= "and ( Password = '$Password' )". } else { return False. header ("Pragma: no-cache"). W kontekście tej strony zmienna $this wskazuje na bieżący obiekt klasy pochodnej po Auth. header ("Cache-Control: no-cache"). Aby to zrobić wywołuje ona zdefiniowaną przez użytkownika funkcję auth_validatelogin(). d M Y H:i:s") . $Password. Jeżeli nie ma pasującego rekordu. gdy wyświetlamy formularz po nieudanej autoryzacji użytkownika W tym przypadku klasa Auth ponownie wyświetla formularz logowania. Dane formularza są wysyłane do strony określonej przez $this->url().11 pokazujemy funkcję użytą w naszym przykładzie. Auth sprawdza ponownie dane autoryzacji. $aDB = new MySQLDB. Następnie strona wyświetla trzy pola tekstowe do wprowadzenia imienia. if ( $aDB->num_rows() > 0 ) { return $FirstName.11. Funkcja auth_validatelogin() function auth_validatelogin() { global $FirstName.phtml">Wylogowanie</a></li> 103 PHP – Kompendium wiedzy . Wydruk 8. ?> <html> <head> <title>Przykład użycia klasy PHPLIB Auth</title> <META HTTP-EQUIV="Expires" CONTENT="-1"> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> </head> <body> <h2>Strona główna</h2> Posiadasz uprawnienia do oglądania tej strony! <ul> <li><a href="test_auth_phplib. $aSQL = "select * from MyAuth where ( FirstName = ".phtml">Strona druga</a></li> <li><a href="test_auth_phplib3.php" ). zdefiniowanych w formularzu logowania.</form> </body> </html> Strona ta jest zaprojektowana jedynie do wyświetlania przez klasę Auth. page_open( array( "sess" => "MySqlSession". $aSQL .= "'$FirstName' ) and ( SurName = '$SurName' )". "auth" => "Sample_Auth" ) ). Na wydruku 8. Jeżeli odnaleziony zostanie rekord w tabeli opisujący bieżącego użytkownika. zwracana jest wartość False. $aDB->query( $aSQL ). header ("Last-Modified: " . Na koniec definiujemy ostrzeżenie jakie zobaczy użytkownik gdy poda niewłaściwe dane. nazwiska i hasła użytkownika. header ("Expires: Mon. Gdy dane formularza zostaną przesłane do oryginalnej strony.phtml">Strona trzecia</a></li> <li><a href="test_auth_phplib_logout. $SurName.phtml">Strona główna</a></li> <li><a href="test_auth_phplib2. Na wydruku 8. Wydruk 8. funkcja auth_validatelogin() zwraca imię użytkownika (oczywiście użycie imienia jako identyfikatora użytkownika nie było by zbyt dobrym pomysłem)./auth_phplib. $SurName i $Password. Funkcja url() zwraca stronę. czy zmiene formularza mają jakieś wartości.12.12 pokazana została typowa strona WWW wykorzystująca o autoryzacji klasę Auth. Prosta strona wykorzystująca klasę Auth <?php // bez buforowania (z witryny php. wymagających autoryzacji. gmdate("D. na której był użytkownik zanim obiekt klasy interweniował i wywołał naszą stronę autoryzacji. Ostatnia strona z listy zapewnia wylogowanie użytkownika. $aSQL . Może to się zdarzyć. " GMT"). Wartości zmiennych formularza są przenoszone do pól formularza FirstName i SurName jedynie z grzeczności (ale użytkownik nie musi ponownie wpisywać tych danych). } } Funkcja odwołuje się do zmiennych globalnych $FirstName. SurName i Password.net) include( ". Ich wartości są wyszukiwane w tabeli MySQL zawierającej trzy kolumny: FirstName. W przykładzie wyświetlane są cztery łącza do innych podobnych stron. Na początku sprawdza. 26 Jul 1997 05:00:00 GMT").

Kilka wierszy w tym przykładzie nie jest związane z mechanizmem uwierzytelniania. Podczas testowania tego przykładu nie stwierdziliśmy żadnych problemów w IE 5. ?> Pierwsza strona dołącza prosty plik uwierzytelniania a następnie wywołuje funkcję PHPLIB page_open(). oraz możliwość łatwego wylogowania użytkownika. powinieneś w fazie projektowania określić specyficzne wymagania tej aplikacji. w zależności od wymagań aplikacji. page_close(). a wymusza ona ponowne wywołanie autoryzacji użytkownika na następnej stronie. która zapisuje dane sesji. Na końcu strony wywoływana jest funkcja page_close(). Ostatnia metoda. WebTV i Opera. Szczególne kłopoty sprawia Microsoft Internet Explorer. Niektóre mechanizmy uwierzytelniania nie posiadają wystarczającej elastyczności. Zmienne uwierzytelniania są przesyłane pomiędzy stronami przy pomocy mechanizmu sesji. że przeglądarka nie będzie przechowywała strony w buforze. czy są już zalogowani. którzy nie będą wiedzieli. wymagająca użycia klas PHPLIB jest bardziej złożona. Kod ten jest dosyć ważny. Strona Wylogowanie. ale o wiele bardziej elastyczna i całkowicie przenośna pomiędzy serwerami WWW i systemami operacyjnymi. pozwalającym na stworzenie własnego mechanizmu uwierzytelniania. Rozdział 8 – Uwierzytelnianie 104 .5. Umieszczenie w aplikacji systemu zabezpieczeń wydaje się bardziej efektywne. wszystkich wersjach Netscape. PHPLIB jest niezwykle elastycznym narzędziem. Jeżeli aplikacja wymaga jakiegoś typu uwierzytelniania użytkowników. Podsumowanie W tym rozdziale zostało omówionych wiele aspektów uwierzytelniania użytkowników w aplikacjach PHP. więc podjęto szczególne środki zapewniające prawidłowe działanie przykładów. szczególnie dla początkujących użytkowników.</ul> </body> </html> <?php page_close(). Można stworzyć skomplikowane lub proste schematy uwierzytelniania. którzy mogą być zaskoczeni systemowymi oknami dialogowymi. ?> Funkcja $auth->logout() może być wywołana w dowolnym momencie. Pierwsze kilka omówionych metod jest mocno zależne od platformy. Druga i trzecia strona jest funkcjonalnie identyczna z pierwszą. Zaletą tego podejścia jest możliwość tworzenia własnych formularzy logowania. zawiera na dole strony następujący kod wymuszający wylogowanie użytkownika: <?php $auth->logout(). porównywanie wpisanych danych z danymi przechowywanymi na dowolnym nośniku informacji. która uaktywnia sesję i mechanizm uwierzytelniania. ale są łatwe do implementacji. Przy pomocy tego rozdziału można skojarzyć twój potrzeby z oferowanymi przez poszczególne metody możliwościami. ponieważ buforowane strony mogą mylić użytkowników. Jak wcześniej wspomnieliśmy. Wywołania funkcji header() oraz znaczniki <META> zapewniają. Inne mogą nie zapewniać dostatecznego poziomu bezpieczeństwa.

40. ale jest zbyt prosta. która jest zoptymalizowana do wyświetlania stron w określonej przeglądarce. Jeżeli wystarczy ci proste rozpoznanie typu przeglądarki. Można wykorzystać tę informację do wyświetlenia odpowiedniego komunikatu. można wykorzystać bezpośrednio zmienną $HTTP_USER_AGENT. } else { print( "Przeglądarka MS Internet Explorer!<br>" ). należy tak napisać aplikację. if ( $aPos === False ) { print( "To <b>nie</b> jest MS Internet Explorer!<br>" ). czy przeglądarka klienta to Internet Explorer. że większość nowoczesnych przeglądarek będzie wyświetlało aplikacje w podobny sposób. niektóre wersje Internet Explorera zawierały następujące ciągi user agent: • Microsoft Internet Explorer/4. "MSIE" ) . Przykład opiera się na tym. Na przykład. że zwracana nazwa przeglądarki w większości wersji Internet Explorera zawiera fragment MSIE. W czasie pisania aplikacji dla WWW. aby obsługiwać ogromną ilość prawidłowych ciągów user agent. interfejs użytkownika nie jest już tak niezmienny. Niezależność od przeglądarki Wstęp Podczas pisania standardowych aplikacji interfejs użytkownika jest tworzony dla potrzeb aplikacji i zwykle jest on przeznaczony dla jednej platformy. rozpoczynając od stworzenia własnego rozwiązania do użycia narzędzi firm trzecich.305beta (Windows 95)[en] . zawsze istnieją różnice.1. PHP pozwala na kilka metod wykrywania rodzaju przeglądarki. Jeżeli aplikacja wymaga jakiejś własności przeglądarki. lub przekierować użytkownika do innej części witryny. Wydruk 9. } ?> </body> </html> W przykładzie tym sprawdzamy. Metoda ta sprawdza się w niektórych przypadkach. aby sprawdzała typ użytej przeglądarki i odpowiednio reagowała. Rozpoczynamy Na najbardziej podstawowym poziomie. Mimo. Ciąg ten jest wysyłany przez przeglądarkę do serwera wraz z każdym żądaniem. W rozdziale tym przedstawimy przykłady wielu metod. ponieważ może być on odtwarzany przez różne typy przeglądarek na różnych platformach. Kilka przeglądarek zmieniło format tego ciągu podczas jednej ze zmiany wersji. Nie przewiduje się niespodziewanych zmian tego interfejsu w czasie działania programu w zależności od użytkownika. PHP pozwala na odczytanie typu przeglądarki poprzez zmienną globalną $HTTP_USER_AGENT.1. Wyświetlanie podstawowych danych na temat przeglądarki <html> <head> <title>Szybkie sprawdzenie typu przeglądarki</title> </head> <body> <?php $aPos = strpos( $HTTP_USER_AGENT. który używa aplikacji. Na przykład.Rozdział 9. jeżeli potrzebujesz dokładnej informacji o przeglądarce. sposób wykrycia przeglądarki Internet Explorer przy użyciu porównywania ciągów zamieszczony jest na wydruku 9. więc rozpoznanie określonej przeglądarki może być problematyczne. z których będziesz mógł wybrać odpowiednią dla twojej aplikacji. Tworzenie aplikacji niezależnej od przeglądarki wymaga możliwości wykrywania typu przeglądarka i wykorzystywania jej możliwości.

ini. $aArray = file( ". więc zdefiniowana jest pewnego rodzaju struktura. przy użyciu metody udokumentowanej w http://www. (wspomnianej już wcześniej) wymaga kilku zmian aby działał z PHP 4. • • Wewnętrzne funkcje PHP Rozpoznawanie typu serwera ma zwykle służyć do poznania możliwości przeglądarki. Każda z sekcji odwołuje się do sekcji wyższego dostępny bez rzędu. Aby . Istnieje tak wiele kombinacji przeglądarek. konfiguracji } fclose ($aNewFile ).ini. Na wydruku 9.2 pokazany jest przykład użycia funkcji get_browser(). że plik browser. { $aNewFile = strtolower( $aLine ).php. Te informacje nie są zawarte w ciągu informacji o przeglądarce. ponieważ nie wszystkie nazwy zapisane są małymi literami.0 z poprawką 2.net/./browscap. Aby użyć funkcji get_browser() należy ściągnąć z W czasie pisania książki podejmowane były dodatkowe ulepszenia do istniejącej w sieci plik PHP funkcji get_browser(). że PHP nie potrafi pe.02. $aNewFile = fopen( ". że dokładne rozpoznanie choć jednego przeglądarki staje się problematyczne. plik browscap. że w czasie odczytu pliku PHP http://www.ini" ). Jednak po wprowadzeniu browscap. trudno jest stworzyć ogólne rozwiązanie tego problemu. wersji.0. czy przeglądarka obsługuje określone możliwości. Update a. "w" ). Następna część omawia rozwiązanie tego problemu w oparciu o PHP.ini upraszcza proces rozpoznawania możliwości przeglądarki i rozszerza jego zakres.Mozilla/2. o wiele bardziej skomplikowany problem jest związany z samą struktura W czasie pisania pliku.ini. MSIE 3. Wykorzystanie funkcji get_browser() wraz z plikiem browscap. platform i języków. Typowo. ponownym uruchomieniu serwera WWW będzie można korzystać z danych zawartych w pliku. Odszukaj opcję fputs( $aNewFile.ini na małe litery: zainstalowaniu w <?php serwerze WWW. który jest Pierwszą z nich jest dodanie pustej linii na końcu pliku. MSIE 5. W rzeczywistości znajomość jedynie typu przeglądarki nie jest tak ważne.0 (compatible. ciąg identyfikacyjny przeglądarki jest zmieniany do właściwej Rozdział 9 – Niezależność od przeglądarki 106 Dodatkowe informacje na temat Browscap . $aNewLine ).0)[en] Różnice w zawartości tego ciągu powodują. witryn w Sieci. Odkryłem. Następnie. Z powodu ogromnej ilości kombinacji przeglądarek i platform.ini". jak się tego spodziewamy. należy zmienić foreach( $aArray as $aLine ) plik php. Zamiast tego lepiej wiedzieć. że wszystkie wywołania funkcji ją ścieżkę do pliku get_browser() muszą zawierać wywołanie funkcji strtolower(). W czasie pisania książki plik browscap./browscap.cysca konwertuje jego zawartość na małe litery. Po takich zmian funkcja get_browser() działa tak.ini jest zwykłym plikiem konfiguracyjnym w którym każda książki plik był sekcja reprezentuje określoną przeglądarkę. Drugim. Tym sposobem w sekcji opisującej żadnych opłat z nową przeglądarkę zdefiniowane są tylko nowe możliwości a istniejące wcześniej znajdują witryny cię w opisie starszej przeglądarki.com/browscap odszukać nadrzędnej sekcji.ini zawierał ponad 2100 różnych przeglądarek. Na szczęście PHP zawiera kilka metod dokładniejszego rozpoznania serwera za pomocą funkcji get_browser(). Bez dodatkowego znaku końca linii dostępny z wielu w trakcie uruchamiania PHP generowany jest błąd składni. AOL 3. Windows NT 5. Po jego rozwiązać ten problem wykonałem prosty skrypt konwertujący wszystkie linie pliku ściągnięciu i browscap. Konwersja ta powoduje. browscap i zmień ?> na pełną Skutkiem ubocznym takiej zmiany jest to. na przykład JavaScript lub ramki. że sprawdzanie ich zawartości staje się nieporęczne.ini dostępny z firmy cyScape browscap. Problem wynika z tego. Windows 95)[en] Mozilla/4.0. Tak jak opisane zostało we wskazówce „Dodatkowe informacje na temat Browscap” pierwszym krokiem powinno być przekonwertowanie zawartości $HTTP_USER_AGENT na małe litery.0 (compatible.

} ?> </body> </html> Na rysunku 9.ini. } } else { print( "<i>brak danych przeglądarki</i><br>" ).postaci przed wywołaniem funkcji get_browser().2. echo ("<b>$key=</b> $aValue<br>"). 107 PHP – Kompendium wiedzy . $aUserAgent = eregi_replace( "\[[a-z]{2. $aUserAgent = strtolower( $HTTP_USER_AGENT ). Użycie funkcji get_browser() <?php function GetMassagedUA() { global $HTTP_USER_AGENT. if ( strpos( $aUserAgent. $value ) = each ($array) ) { $aValue = stripslashes( $value ).2. } return $aUserAgent. która występuje w pliku browscap.7. print( "<h2>$aUserAgent</h2>" ). } ?> <html> <head> <title>Możliwości przeglądarki</title> </head> <body> <h1>Możliwości przeglądarki</h1> <?php $aUserAgent = GetMassagedUA().}\]". if ( count( $array ) > 1 ) { while ( list( $key. '*' ) === False ) { $aUserAgent . Do zamiany określenia języka (na przykład [en]) na gwiazdkę. Wydruk 9. $aUserAgent ). $array = (array) get_browser( $aUserAgent ). "*". w przeglądarce Netscape 4. używana jest funkcja eregi_replace().= '*'.

wszystkie możliwości są wyświetlane poprzez rzutowanie zwracanego obiektu na tablicę i przeglądanie kolejnych par klucz-wartość. } ?> <html> <head> <title>Obsługa ramek?</title> </head> <body> <?php $aUserAgent = GetMassagedUA(). $aBrowsCap = get_browser( $aUserAgent ). Można również sprawdzić kolejno każdą z możliwości korzystając bezpośrednio z obiektu i używając zapisu $obiekt->możliwość. "*". } return $aUserAgent. print( "<h2>$aUserAgent</h2>" ).2. if ( strpos( $aUserAgent.7 Lista dostępnych możliwości pokazuje potęgę funkcji get_browser(). W kodzie zamieszczonym na wydruku 9.3. $aUserAgent ). $aUserAgent = strtolower( $HTTP_USER_AGENT ).1 wykonywanego w przeglądarce Netscape 4.= '*'.}\]". Użycie get_browser() do sprawdzenia obsługi ramek <?php function GetMassagedUA() { global $HTTP_USER_AGENT. $aUserAgent = eregi_replace( "\[[a-z]{2. if ( $aBrowsCap->frames == 1 ) { print( "Przeglądarka obsługuje ramki<br>" ). Wynik działania skryptu z wydruku 9. Rozdział 9 – Niezależność od przeglądarki 108 . '*' ) === False ) { $aUserAgent . } else { print( "Przeglądarka nie obsługuje ramek<br>" ).3 pokazujemy przykład sprawdzenia. czy przeglądarka obsługuje ramki.Rysunek 9. Na wydruku 9. Wydruk 9.2.

również niesie ze sobą kłopoty. Wpisana jest tutaj również ścieżka bez określenia pliku (/home/blake/bhawk).jar:/home/blake/java/servlet. Pewność działania funkcji wymaga.path w pliku php. lub jako Java bean dla innych platform. Taj jak w przypadku każdej innej klasy Java należy podać położenie pliku z klasami Javy korzystając ze zmiennej java. Niezbędne jest również zainstalowanie maszyny wirtualnej Java (JVM) na serwerze.servlet. Wywołanie funkcji phpinfo() powoduje wyświetlenie dużej ilości danych w postaci tabel HTML.jar. lub inny kod Java na serwerze. w następnej części opisane zostanie narzędzie jednej z firm. jeżeli wykorzystujesz serwer z Windows. Na przykład nasz plik browscap.ini wymaga sporo czasu. Rysunek 9.} ?> </body> </html> Funkcja get_browser() dostarcza dużo informacji i jest dobra na początek. pokazana jest ta część informacji.megginson. dostępny z firmy cyScape jest świetnym narzędziem do wykrywania możliwości serwera. Potrzebny będzie na przykład dostęp do klasy javax.class.jar:/homeblake/php4. Poniżej znajduje się przykład: java. Ścieżka ta powinna wskazywać na katalog. gdy aplikacja wymaga rozpoznania typu przeglądarki w czasie pracy. Jeżeli twoja aplikacja wymaga dokładnego wykrywania możliwości bieżącej przeglądarki. należy sprawdzić konfigurację za pomocą funkcji phpinfo()./bhawk4j. aby mógł skorzystać z BrowserHawk.3. ale nie jest domyślnie włączona. należy skonfigurować PHP. że uaktualnienie i rozesłanie pliku browscap.jar:/home/blake/bhawk/ lib/bhawk4j..class./sax2.02. Obsługa języka Java jest dostępna w PHP4. które świetnie spełnia swoje zadanie. Jednak posiada ona kilka znaczących ograniczeń. Problem tkwi w tym. Na wydruku 9.jar. która wskazuje na dostępność Javy.jar:/home/blake/java/sax2. Po ściągnięciu i zainstalowaniu wymaganych klas Javy.com/SAX/..0. Po ustawieniu wszystkich tych elementów konfiguracji i przekompilowaniu PHP z obsługą Javy. aby plik browscap.ini.jar i .path=/usr/share/kaffe/Klasses. Wiele dystrybucji Linuksa zawiera JVM i w wielu przypadkach pakiet ten jest instalowany automatycznie.ini był często uaktualniany./servlet.ini nie pozwalał na prawidłowe rozpoznanie przeglądarek Internet Explorer 5. dostępnego w Internecie. Jednym z nich jest Simple API for XML (SAX) dostępny pod adresem http://www.. Jest on dostępny w formie obiektu COM. która określa położenie plików licencyjnych i danych pakietu BrowserHawk. że klasy wymagane przez BrowserHawk są dostępne dla PHP w katalogach . . w tym w najnowszych JVM pochodzących od różnych dostawców.5 i Opera 4. Wymagane moduły servletów można znaleźć we wielu miejscach. Jak wspomniałem wcześniej.jar:/home/blake/bhawk: Zapis taki wskazuje. PHP musi być przekompilowane z opcją konfiguracji -with-java.HttpServlet.1pl2/ext/java/php_java. Wynik działania funkcji phpinfo() pokazujący dostępność Javy 109 PHP – Kompendium wiedzy .ini. w którym został zainstalowany BrowserHawk. Aby wykorzystać Java bean. aby podążać za zmianami w najnowszych dostępnych przeglądarkach. BrowserHawk Komponent BrowserHawk®. Dodatkowo komponent BrowserHawk wymaga kilku dodatkowych modułów.http. użycie pliku browscap.3.

String getBrowser() Zwraca ogólną nazwę przeglądarki.browserhawk.lang. double getAOLVersion() Zwraca numer wersji przeglądarki AOL. Boolean getCompressGZip() Sprawdza. zamieszczone są metody odczytujące informacje na temat możliwości przeglądarki dostępne w BrowserHawk. Wydruk 9. czy przeglądarka obsługuje cookie. W tabeli 9. czy przeglądarka jest szperaczem sieciowym lub innym programem wykorzystywanym do indeksowania zawartości witryny. java.String getFileUpload() Sprawdza. Boolean getDHML() Sprawdza. $aBrowserInfo = $aBrowserHawk->getBrowserInfo( "$HTTP_USER_AGENT" ). // Czy przeglądarka obsługuje ActiveX? if ( $aBrowserInfo->getActiveXControls() == True ) { print( "Przeglądarka obsługuje kontrolki ActiveX<br>" ).4. Typ Metoda Zastosowanie Boolean getActiveXControls() Sprawdza.cyscape.BrowserHawk" ). na przykład Netscape lub IE (Internet Explorer). czy przegladarka obsługuje Channel Definition Format (CDF) używany do prenumerowania zawartości WWW z możliwością automatycznej aktualizacji. Boolean getBeta() Sprawdza. czy przeglądarka jest w wersji beta. który pokazuje w jaki sposób stworzyć obiekt BrowserHawk i wykorzystać go do odczytania kilku podstawowych danych o przeglądarce. czy przeglądarka obsługuje kontrolki ActiveX. Na wydruku 9. wykorzystanie komponentów BrowserHawk jest łatwe. Boolean getCookies() Sprawdza. czy przeglądarka obsługuje Rozdział 9 – Niezależność od przeglądarki 110 . int getAuthenticodeUpdate() Zwraca numer wersji Authenticode obsługiwanego przez przeglądarkę. Boolean getCrawler() Sprawdza. java. czy przeglądarka obsługuje skrypty DHTML().4 pokazujemy w jaki sposób można sprawdzić obsługę ActiveX i tak samo łatwo można sprawdzić każdą z właściwości BrowserHawk. } else { print( "Przeglądarka nie obsługuje kontrolek ActiveX<br>" ). Boolean getBackgroundSounds() Sprawdza. Boolean getAOL() Sprawdza.Po skonfigurowaniu obsługi Javy i BrowserHawk w PHP. } ?> </body> </html> Na wydruku 9. Przykład wykorzystania BrowserHawk <html> <head> <title>Przykład wykorzystania BrowserHawk</title> </head> <body> <h1>Przykład wykorzystania BrowserHawk</h1> <?php print( "<h2>$HTTP_USER_AGENT</h2>" ). czy użytkownik witryny korzysta z przeglądarki firmowanej przez America Online (AOL) (na sieci AOL). $aBrowserHawk = new Java( "com. czy przeglądarka potrafi odgrywać dźwięk w tle. czy przeglądarka przyjmuje dane w skompresowanym formacie GZip. Boolean getCDF() Sprawdza.1.4 znajduje się kod.lang.

Zwraca wyższą część numeru wersji przeglądarki.lang. czy użytkownik jest połączony poprzez serwer Proxy. o ile występują. Zwraca kompletną wersje przeglądarki zawierającą wyższą i niższą część numeru oraz litery.String int double java. Zwraca numer wersji JavaScript obsługiwanego przez przeglądarkę. Sprawdza. mouseover. czy przeglądarka obsługuje ramki.String Boolean java. Sprawdza. czy przeglądarka obsługuje applety Java. Zwraca bardziej ogólne dane (w porównaniu do getOSDetails()) na temat platformy użytkownika.lang. czy przeglądarka potrafi wyświetlać kolorowy tekst. Sprawdza. czy przeglądarka obsługuje efekt JavaScript. Zwraca wybrany przez użytkownika język.String Boolean Boolean java.Boolean Boolean Boolean java. Zwraca szczegóły na temat systemu operacyjnego (OS) systemu użytkownika. Zwraca literę niższej części numeru przeglądarki. Sprawdza. czy przeglądarka obsługuje JavaScript. czy przeglądarka obsługuje format rysunków PNG (Potrable Network Graphics). Sprawdza. czy użytkownik korzysta z sieci Microsoft Network (MSN).String getProxy() getSSL() getSSLActive() getSSLCipherSuite() możliwość przesyłania plików do serwera (przeglądarki zgodne z RFC 1867). Dostępny jedynie w przypadku PHP – Kompendium wiedzy 111 . o ile występuje. Sprawdza. jeżeli obsługuje HDML (poprzednik WAP). czy przeglądarka obsługuje protokół SSL (Secure Socket Layer). czy użytkownik jest połączony poprzez aktywne połączenie SSL. Sprawdza.String getGold() getHDML() getIPAddr() getJavaApplets() getJavaScript() getJavaScriptVer() getLanguage() getMajorver() getMinorver() getMinorverlet() getMouseOver() getMSN() getOSDetails() getPDA() getPlatform() Boolean getPNG() Boolean Boolean Boolean java. Sprawdza.lang.lang. Zwraca niższą część numeru wersji przeglądarki.lang. Sprawdza. Sprawdza. Zwraca True.String getFontColor() getFontSize() getFrames() getFullversion() Boolean Boolean java. czy przeglądarka potrafi wyświetlać różne wielkości tekstu. czy jest to wersja Gold przeglądarki Netscape Navigator.lang. Sprawdza.lang. Sprawdza. Zwraca True. jeżeli przeglądarką jest urządzeniem PDA na przykład PalmPilot. Zwraca zestaw szyfrowania SSL dla bieżącej sesji. Zwraca adres IP klienta.String Boolean Boolean double java.

Niektóre zaawansowane funkcje raportujące nie mogą być wykorzystane. Aplikacja będzie nadal działała prawidłowo. czy przeglądarka obsługuje bezpośrednie wyświetlanie plików XML. Boolean getTableBGImage() Sprawdza. czy przeglądarka obsługuje kaskadowe arkusze stylu (CSS). niż jest to stosowane w innych metodach.String getWAPDeviceModel() Zwraca model urządzenia WAP. double getVersion() Zwraca wersję przeglądarki. Jeżeli aplikacja opiera się na dostarczaniu danych specyficznych dla przeglądarki lub polega na bardzo specyficznych własnościach przeglądarki. BrowserHawk zapewnia najlepsze rozpoznawanie przeglądarki. Boolean getWAP() Zwraca True dla urządzeń obsługujących WML i WAP (Wireles Application Protocol). że jest on zaprojektowany dla użytkowników JSP. java. o ile jest wykorzystywana.Link. Boolean getTableBGColor() Sprawdza. czy przeglądarka obsługuje wyświetlanie tabel. Boolean getWin16() Sprawdza. który jest umieszczony w ciągu identyfikacyjnym przeglądarki.String getWAPGateway() Zwraca szczegóły bramy UP. Boolean getStyleSheets() Sprawdza. W dokumentacji znajduje się informacja. Boolean getVBScript() Sprawdza. Boolean getXML() Sprawdza. o ile jest znany. Jedyną wadą przy używaniu komponentu BrowserHawk jest to. jaką może obsłużyć urządzenie. Sprawdza wielkość klucza SSL obsługiwaną przez przeglądarkę. BrowserHawk uaktualnia swoją bazę danych w razie potrzeby.lang.lang. niezależnie od ciągłych zmian w technologiach przeglądarek. java.String getWAPSubscriberID() Automatycznie ustawiany na identyfikator abonenta dla użytkownika WAP. na przykład telefony komórkowe z WAP. standardowe obiekty zwracają wystarczająco dużo danych dla większości zastosowań i są stale aktualne dla najnowszych przeglądarek. int getVersionpos() Zwraca pozycję w numerze wersji przeglądarki. czy przeglądarka pracuje w 16 bitowym systemie operacyjnym Windows.1. Mimo to. BrowserHawk jest również zaprojektowany. aby sprawdzał o wiele więcej własności przeglądarki. niż można to zrobić korzystając z browscap.lang. java. Przewagą użycia komponentu BrowserHawk nad innymi metodami opisanymi w tym rozdziale jest jego dokładność i elastyczność. czy przeglądarka obsługuje ustawianie kolorów dla poszczególnych komórek tabeli HTML. int getWAPMaxDeckSize() Zawiera przybliżoną maksymalna ilość bajtów. więc niektóre metody mogą nie być bezpośrednio dostępne poprzez PHP. czy przeglądarka obsługuje ustawianie rysunków tła dla poszczególnych komórek tabeli HTML. ponieważ opierają się na obiektach specyficznych dla JSP. int getSSLKeySize() Rozdział 9 – Niezależność od przeglądarki 112 . Boolean getTables() Sprawdza. czy przeglądarka obsługuje VBScript.aktywnej sesji SSL. że rozpoznaje on około 9 razy więcej przeglądarek. Dostępne jedynie w przypadku aktywnego połączenia SSL. jak na przykład Windows 3.

Wydruk 9.browserhawk. aby użytkownicy mogli zrozumieć dlaczego wykonanie operacji się nie powiodło. Wybierając taki mechanizm należy zwrócić uwagę. Wydruk 9.BrowserHawk" ).<br><br> proszę przesłać pliki pocztą na adres files@my. Warunkowe dostarczanie treści w zależności od możliwości przeglądarki <?php $aBrowserHawk = new Java( "com. Brak innych własności może całkowicie zatrzymać aplikację. takie jak animowane podpowiedzi. <?php } ?> </form> </body> </html> Jeżeli przeglądarka posiada obsługę wysyłania plików. Należy po prostu zapewnić możliwie największą dostępną ilość funkcji. $aBrowserInfo = $aBrowserHawk->getBrowserInfo( "$HTTP_USER_AGENT" ).BrowserHawk" ). zależy ona od wymagań stawianych aplikacji. lub obsługa kaskadowych arkuszy stylów nie są krytyczne. wyświetlany jest napis informujący użytkownika o możliwości przesłania pliku za pomocą poczty elektronicznej.domain. Niektóre możliwości przeglądarki i własności aplikacji. że operacja się nie udała. skrypt ten wyświetla formularz wysyłania pliku.com.Wykorzystanie danych o przeglądarce Pierwszym zadaniem podczas tworzenia aplikacji niezależnej od przeglądarki jest rozpoznanie możliwości przeglądarki użytkownika. $aBrowserInfo = $aBrowserHawk->getBrowserInfo( "$HTTP_USER_AGENT" ).cyscape.5. aby użytkownicy aplikacji uważali ją za przyjazną.6 pokazano przykład takiego działania. zamieszczony został przykład w jaki sposób można zrealizować elegancką obsługę braku wymaganej własności przeglądarki. Projekt aplikacji powinien zawierać listę wymaganych własności przeglądarki i zapewniać elegancką obsługę sytuacji. Większość ludzi nie chce widzieć komunikatów typu „Twoja przeglądarka nie obsługuje RFC 1867”. Jeżeli aplikacja może działać pomimo tego.png". O wiele ważniejszym krokiem jest zadecydowanie w jaki sposób zostaną wykorzystane te dane. Na wydruku 9. Na wydruku 9.phtml" method="post" enctype="multipart/form-data"> <?php if ( $aBrowserInfo->getFileUpload() == True ) { ?> <input type="file" name="File"><br><br> <input type="submit" name="Submit" value="Wyślij"> <?php } else { ?> Przeglądarka nie obsługuje wysyłania plików. Dodatkowo. gdy nie można skorzystać z którejś z wymaganych własności.cyscape. W rzeczywistości mechanizm taki jest niezbędny. Jeżeli przeglądarka nie obsługuje tej funkcji.browserhawk.6. na przykład zdolność przeglądarki do nawiązania połączenia szyfrowanego SSL lub obsługa wysyłania plików. } else { $aImage = "Logo. można spróbować warunkowo dostarczać niektórych elementów w zależności od zdolności przeglądarki do ich wyświetlania. Eleganckie zakończenie aplikacji w przypadku braku obsługi przesyłania plików <?php $aBrowserHawk = new Java( "com.gif".5. ?> <html> <head> <title>Wysyłanie pliku</title> </head> <body> <h1>Wysyłanie pliku</h1> <form action="someurl. } ?> <html> <head> <title>Nasze logo</title> </head> <body> <h1>Nasze logo</h1> 113 PHP – Kompendium wiedzy . nie wyświetlaj ponownie tego komunikatu. if ( $aBrowserInfo->getPNG() == True ) { $aImage = "Logo. Tak jak w przypadku innych decyzji podejmowanych w czasie projektowania.

Dodatkowo mechanizm ten wymaga. aby każda strona posiadała kilka równoległych stron przeznaczonych dla odpowiednich typów przeglądarek. aby wykrywał przeglądarki działające na komputerach typu PDA lub inne specyficzne typy przeglądarek. przekierowanie do standardowych stron header( "Location: http://mysite. wygląd strony nie będzie odpowiedni dla bieżącego typu przeglądarki. Systemy takie mają zwykle ograniczoną wielkość ekranu i zwykle mniej możliwości wyświetlania różnych czcionek.<img src="<?=$aImage?>" width="180" height="70" alt="" border="0"> </body> </html> Skrypt ten wyświetla grafikę w formacie PNG jeżeli przeglądarka potrafi wyświetlić ten format. ale ilustruje podstawową zasadę działania. Zamiast wykorzystywać zmienne do wysyłania różnych danych. <?php $aBrowserHawk = new Java( "com.browserhawk. Wadą takiego rozwiązania jest to. że jeżeli użytkownik wyśle znajomemu łącze do strony przeznaczonej dla innej przeglądarki niż używa ten znajomy. które będą opisane w rozdziałach 13 i 14. użytkownicy przeglądarek WebTV są kierowani na odpowiednio zoptymalizowane strony. Dlatego trzeba inaczej projektować taką witrynę aby poprawić widoczność wszystkich elementów. w przeciwnym wypadku wysyłany jest rysunek w formacie GIF.cyscape. Inni użytkownicy są kierowani do zwykłego zestawu stron przeznaczonych dla innych typów przeglądarek. Poniższy kod jest prostym przykładem sposobu implementacji takiego przypadku. Na przykład można stworzyć witrynę zoptymalizowaną dla oglądania jej przez przeglądarki WebTV. W czasie projektowania aplikacji należy poznać ograniczenia różnych przeglądarek. Tego typu mechanizm może być zaimplementowany przy użyciu systemu szablonów. Przykład ten może być rozszerzony.BrowserHawk" ). w oparciu o wymagania projektu należy wykorzystać narzędzia do wykrywania przeglądarki i włączania niektórych funkcji. Podsumowanie Wykrywanie możliwości przeglądarki może być niezmiernie ważne dla wielu aplikacji WWW. aplikacja może skorzystać z informacji o możliwościach przeglądarki do wyświetlenia całkowicie innej sekcji witryny. Następnie. Lepszym rozwiązaniem przy tworzeniu stron specyficznych dla przeglądarki jest wyłączenie kluczowych różniących się elementów i umieszczenie ich w osobnych plikach dla każdego typu przeglądarki. $aBrowserInfo = $aBrowserHawk->getBrowserInfo( "$HTTP_USER_AGENT" ). gdy funkcja jest niedostępna.com/main/\n" ). gdy przeglądarka wyświetla niezrozumiały komunikat błędu w przypadku. Wprowadzenie takiego projektu jest nieporęczne dla dużych witryn. że jest to główna strona witryny. zanim zatwierdzimy realizację specyficznych funkcji. Tam też przytoczymy przykłady implementacji takiego scenariusza.com/webtv/\n" ). if ( $aBrowserInfo->getBrowser() == "WebTV" ) { // Przeglądarka WebTV. przekierowanie do stron zoptymalizowanych dla WebTV header( "Location: http://mysite. Rozdział 9 – Niezależność od przeglądarki 114 . Należy unikać sytuacji. Zakładamy. } else { // To nie jest przeglądarka WebTV. Należy dążyć do zapewnienia zestawu funkcji niezależnych od używanego typu przeglądarki. Przykład ten jest prosty. } ?> W przykładzie tym.

Z powodu ogromnego zainteresowania jakie wzbudziło programowanie aplikacji WWW. na przykład ASP i JSP.Rozdział 10. testowania modułów oraz uruchamiania. Dane z firm TRW i IBM wskazują. ponieważ zakłada się. 1993). Niespodziewanie. ponieważ można uniknąć ogromnej pracy przy uruchamianiu aplikacji. Inżynieria programowania a uruchamianie W rozdziale 3 „Formularze i cookie” doszliśmy do wniosku. inne natomiast zostały stworzone jedynie w celu tworzenia interaktywnych aplikacji WWW. Po zdefiniowaniu zadań . Uruchamianie Wstęp Uruchamianie aplikacji WWW jest równie krytycznym procesem jak uruchamianie innych typów aplikacji. Tak samo. szczególnie gdy nie masz odpowiednich uprawnień do administracji serwerem WWW. Kolejne części zawierają przegląd każdego z tych kroków i zakładają. Wstępny podział aplikacji na moduły może uprościć ten proces. Pierwsza część rozdziału zawiera przypomnienie zasad inżynierii programowania. do tego nowego środowiska programowania należy zaadaptować wszystkie istniejące zasady inżynierii programowania. Problemem jest to. W dużych projektach takie planowanie może zająć tygodnie lub miesiące. że kod przeszedł wszystkie wcześniejsze wymagane kroki. Dodatkowo. Uruchamianie jest koniecznie ostatnie na tej liście. Projekt aplikacji WWW musi być tak samo dokładnie przemyślany. że wprowadzenie zmian do aplikacji w początkowym okresie programowania (przed fazą programowania) jest 10 do 200 razy tańsze niż wprowadzanie tych samych zmian na końcu tego procesu (McConnell. Narzędzia te zostały stworzone na podstawie istniejących już narzędzi. W zależności od projektu. W tym rozdziale zaprezentowane zostaną porady i narzędzia. ponieważ zbyt dużo czasu spędzonego przy uruchamianiu jest zwykle powodowane błędami przy tworzeniu projektu. oraz wymyślenie możliwie wielu możliwych rozwiązań przed rozpoczęciem pisania kodu. Jest ona dołączona do tego rozdziału. pisanie lepszego (bardziej defensywnego) kodu powoduje ogromne zmniejszenie czasu straconego w czasie uruchamiania. że można uniknąć sprawdzania poprawności niektórych danych w przypadku zastosowania lepszego mechanizmu wprowadzania danych. W aplikacji WWW modułami takimi mogą być współpraca z bazą danych. Tworzenie świetnej aplikacji wymaga właściwego projektu. które mogą usprawnić uruchamianie aplikacji. Prawdopodobnie brak ten jest spowodowany potrzebą zaistnienia na rynku jako pierwsze narzędzie lub z faktu. powstało wiele narzędzi (między innymi PHP) do tworzenia takich aplikacji. W każdym z tych przypadków kluczowe jest przemyślenie wymagań aplikacji. że może być trudno zdalnie uruchamiać program. narzędzia spełniające zasady inżynierii programowania są tu w mniejszości. niektóre części rozdziału są przypomnieniem zasad inżynierii programowania. jak projekt każdej innej aplikacji. obsługa stanu. Projekt aplikacji Identyfikacja wstępnych założeń aplikacji przed napisaniem jakiegokolwiek kodu jest krytyczna w przypadku każdego projektu. że pierwszymi projektantami nowej technologii nie byli bardziej zaawansowani programiści. id. W małych projektach mogą zostać zapisane na skrawku papieru w przeciągu kilku minut. jeżeli jej projekt jest odpowiednio przygotowany. zgodności z standardami tworzenia oprogramowania. identyfikacja wymaganych funkcji aplikacji może wymagać wykonania sporej pracy. sprawdzania oprogramowania. Niezależnie od powodu. autoryzacja użytkownika. że posiadasz pewną wiedzę inżynierii programowania.

Dobrym pomysłem może być stosowanie tzw. Wymyśl alternatywny plan na wypadek. że ten czas jest zużywany na projektowanie wysokiego poziomu. że PHP może działać na wielu serwerach WWW i platformach systemowych. Mimo. Zdefiniuj konwencję nazywania plików i katalogów.: nIlosc to zmienna przechowująca liczby całkowite. Następnie. W 2 Przypis tłumacza. Oprócz zdefiniowania wymagań funkcjonalnych aplikacji. jeżeli aplikacja ma być wysoce dynamiczna. Trzeba pamiętać. Nawet małe aplikacje programowane przez jednego programistę mogą korzystać z odpowiednio stosowanego zbioru standardów programowania. Pozwalają również mniej doświadczonym programistom na korzystanie z wiedzy bardziej doświadczonych kolegów. Tworzenie zastępników takiego kodu jest łatwe do zaimplementowania i w dłuższym okresie czasu umożliwia łatwiejsze utrzymanie aplikacji. każda z takich kombinacji posiada indywidualne cechy. jak na przykład konwencje nazw plików i katalogów mogą mieć ogromne znaczenie przy konserwacji kodu2. jednak inne. oraz czy niektóre moduły należy zakupić. a bIstnieje to zmienna logiczna. Ilość funduszy dostępnych na początku projektu rzadko jest dobrym powodem wyboru platformy. gdzie nazwa zmiennej zaczyna się od liter określających jej typ. Przegląd oprogramowania Przegląd oprogramowania dostarcza możliwości zrealizowania kilku celów za jednym razem. komentowania oraz konwencje układu. Są również jednym z bardziej efektywnych metod zapewnienia odpowiedniej jakości oprogramowania. przeglądy takie zwiększają w dużych projektach ogólną wydajność zespołu. czy też pisać je od początku. możesz nie i mieć wystarczająco dużo czasu. na przykład układ kodu. 35% dla testowania funkcji oraz 45% dla testowania integracyjnego. notacji węgierskiej. sTytul zawiera ciąg znaków. W zależności od harmonogramu projektu. Ten wynik należy zestawić z jedynie 25% prawdopodobieństwem dla testowania modułów. Jeżeli przewidujesz występowanie zmian. które moduły aplikacji zostaną stworzone przy pomocy gotowych narzędzi pochodzących od zewnętrznych dostawców. są mniej ważne. należy zaprojektować organizację kodu. Na przykład.poszczególnych modułów należy w razie potrzeby podzielić je na mniejsze fragmenty i zapisać przeznaczenie każdego fragmentu. ponieważ nowoczesne edytory potrafią przeformatować kod. do projektowania szczegółów implementacji również potrzebny jest czas. przegląd oprogramowania pozwala na sprawdzenie kodu z standardami kodowania. na przykład jak będą zorganizowane pliki kodu. Należy poświęcić nieco czasu na zdefiniowanie powodów. Właściwe zaprojektowanie aplikacji wymaga czasu. Z powodu luźnego traktowania typów w PHP szczególnie ważne wydaje się odpowiednie nazywanie zmiennych. W przypadku dobrego systemu faza projektowania zajmuje 20 do 30 procent czasu tworzenia systemu (McConnell. Dodatkowo. czy osobno. Taki standard obejmuje sposoby nazywania. W małych aplikacjach dobrą strategią jest podział modułów na pliki kodu bądź klasy obiektowe. Taki typ projektowania jest istotny szczególnie. Na koniec należy zadecydować. może być to krytyczne zagadnienie. gdy korzystasz przy tworzeniu aplikacji z narzędzi pochodzących z innych źródeł lub oprogramowania w wersji beta. Rozdział 10 – Uruchamianie 116 . Należy tu pomyśleć o rodzaju stosowanego systemu zarządzania relacyjną bazą danych (SZRBD) i innych mniej oczywistych elementach. gdy istnieje duże prawdopodobieństwo zmian. np. napisz aplikację lokalizującą zmiany w kilku modułach a buforującą resztę. Decyzja „tworzyć czy kupić” jest dosyć skomplikowana. jak radzić sobie ze zmianami. Dodatkowo należy pomyśleć. Definiowanie standardów programowania Zdefiniowanie standardów programowania ułatwia długoterminowe utrzymanie projektów o dowolnej wielkości. należy rozważyć architekturę systemu. co uprości identyfikację kodu. czy serwer WWW i baza danych będą pracować na tym samym komputerze. Niektóre z nich. Jednak możesz również nie mieć wystarczająco dużo czasu na stworzenie ich od początku. Wybór bazy danych jest równie istotny. Analizy przeglądów oprogramowania stosowanych przy tworzeniu prawdziwych aplikacji pokazały. Aby zmniejszyć wpływ tej decyzji na projekt można stworzyć własne funkcje pośrednie ukrywające implementację. W zależności od wielkości i charakteru aplikacji. 1993). że pozwalają na wykrywanie błędów z prawdopodobieństwem pomiędzy 55 a 60%. aby dostatecznie przetestować dostępne narzędzia. dla których należy wybrać określony sprzęt i serwer.

Każdy. Przegląd projektu pozwala na identyfikację jego wad w momencie. Na przykład w przypadku. ale każdy z programistów powinien być odpowiedzialny za dostarczenie testerom dostatecznie dużo danych. Można wykorzystać kilka metod realizacji przeglądu. Uruchamianie powinno być gruntownym procesem przeznaczonym do identyfikacji źródła problemu. aby ich praca była efektywna. Przegląd powinien być przeprowadzany zarówno podczas testowania jak i podczas implementacji. programowania i część testowania. Najważniejsze jest. Zwykle część kodu jest przekazywana dwóm lub więcej osobom. które niezależnie pracując identyfikują błędy. Większe projekty mogą zawierać ludzi. W zależności od rozmiaru i organizacji projektu użycie jednej z metod ma przewagę nad inną. ze właściwe stosowanie zasad inżynierii może ograniczyć nakład pracy wymagany przy uruchamianiu. Rozwiązywanie problemów powinno brać pod uwagę priorytety. przeprowadzenie przeglądu kodu jest najbardziej efektywną metodą identyfikacji problemów w projekcie bądź implementacji. Każdy twórca kodu powinien również być odpowiedzialny za testowanie swoich modułów na poziomie funkcji lub strony. mogą powstać sugestie na temat sposobu jego usunięcia. Tak jak w przypadku innych projektów. aby pamiętać. W przypadku formalnej inspekcji kodu. Znalezienie źródła problemu powoduje stworzenie kompletnego rozwiązania zamiast obchodzenia problemu. możesz skorzystać z zatrudnienia osoby. Następna część zawiera opis kilku technik i narzędzi specyficznych dla aplikacji PHP. kilku członków zespołu zbiera się razem w celu odszukania błędów. ale nie zapewni trwałego rozwiązania. Gdy zidentyfikowany zostanie błąd. kto bierze udział w testowaniu powinien znać źródło problemu w momencie. Prowadzący spotkanie prowadzi je do przodu i pilnuje. aby jedynym tematem była identyfikacja błędów. ale muszą zostać odpowiednio udokumentowane. ponieważ zmiany mogły wprowadzić nowe błędy. testowanie modułów oraz testowanie integracyjne. czasami czasowe rozwiązania mogą być wystarczające. W przypadku przeglądu ogólnego grupa programistów nieformalnie dyskutuje na temat kodu zadając pytania. W zależności od natury problemu. ponieważ w momencie. a nie pracy grupowej. Testowanie każdego modułu powinno być odpowiednio zaplanowane. W małych projektach testowanie może wymagać jedynie wymyślenia kilku prostych przypadków użycia aplikacji a następnie sprawdzenie każdego przypadku. Testowanie Zwykle testowanie nie jest pomijane. Nie powinno być prostym łataniem. Z testami związany jest określony zbiór oczekiwań i wymagań. Niektóre z nich są formalną inspekcją kodu inne przeglądem ogólnym lub czytaniem kodu. Formalna inspekcja kodu nie powinna zawierać dyskusji na temat rozwiązań. Uruchamianie Uruchamianie jest ostatnim etapem w procesie tworzenia aplikacji. gdy stwierdza się usunięcie problemu. Czytanie kodu poświęcone jest jedynie dla kodu programu. Niezależnie od wybranej metody. Wynik ich pracy jest przekazywany autorowi kodu. 1993). gdy pracujesz sam lub w małym zespole. Wszystkie zmiany wprowadzone do kodu w trakcie procesu uruchamiania powinny zostać ponownie przetestowane na wszystkich poziomach testowania. ale głównym celem jest nadal jego identyfikacja. ale często jest przeprowadzane przypadkowymi metodami. gdy ich usuwanie jest najprostsze i najtańsze. które naprawi błędne przypadki. W tej książce prawdopodobnie nie zostanie opisane wszystko na temat prawidłowej inżynierii programowania. gdy następuje uruchamianie powinny być ukończone procesy projektowania. Uruchamianie może być przeprowadzane w trakcie każdej z fazie testowania jako część tego procesu. że inżynieria programowania jest równie ważna w aplikacjach WWW jak w pozostałych aplikacjach oraz o tym.niektórych przypadkach powodują one 80 do 90% spadek awarii oraz 10 do 25% wzrostu wydajności (McConnell. która wykona taki przegląd metodą czytania kodu. którzy zajmują się jedynie testowaniem. testowanie aplikacji WWW powinno zawierać testowanie na różnych poziomach: testowanie funkcji. 117 PHP – Kompendium wiedzy .

gdy jego wartość wynosi False. assert. że PHP nie podstawi zbyt wcześnie wartości zmiennej w miejsce jej nazwy. Na wydruku 10. Opcje asercji w pliku php.quiet_eval) lub opcje przekazane jako parametr wywołania funkcji assert_options() definiują akcję jaką podejmuje funkcja assert().2. W PHP do funkcji assert() można przekazać zarówno ciąg jak i wartość Boolean. Użycie funkcji assert() do kontroli poprawności parametrów wejściowych <?php function ArrayAverage( $aArray ) { $aTotal = 0. jak i bez nich. Tabela 10. // Apostrofy ozanczają ciąg nie interpretowany przez PHP assert( 'is_array( $aArray )' ). wewnętrznym sprawdzaniu stanu procedur w trakcie procesu programowania. Takie programowanie polega na odpowiednim komentowaniu błędów.1 spodziewa się jako parametru tablicy wartości numerycznych (liczb lub ciągów zawierających liczby) i zwraca średnią z wartości w tablicy. więc jeżeli wykorzystywane są zmienne należy zapewnić. Do sprawdzania stanu funkcji. ale powinno być zgodne ze standardami. programiści powinni opisywać przeznaczenie funkcji. Należy zwrócić uwagę.1 jest zamieszczony na wydruku 10. Jeżeli przekazany został ciąg. assert.ini (assert.Programowanie defensywne Zanim zaczniesz uruchamiać program. Użycie funkcji ArrayAverage() <?php include( ". klasy lub dołączanego pliku oraz zawsze komentować niejasne fragmenty kodu. prowadzące do napisania kodu zawierającego dużo mniej błędów. Funkcja assert() jest zaprojektowana jedynie do wykorzystywania w czasie tworzenia programu i nie powinna być używana w czasie normalnej pracy. } ?> Funkcja ArrayAverage() umieszczona na wydruku 10.2. powinieneś podjąć kroki. posiada funkcję assert(). Jako minimum. Wydruk 10.1 zamieszczone są różne opcje asercji./arrayfunc. assert_callback (null) Nazwa funkcji użytkownika wykonywanej w przypadku nieudanej asercji.callback i assert. że do assert() można przekazać ciąg. Wydruk 10. Aby tego uniknąć należy używać ciągów w apostrofach.php" ).warning. Opcje asercji i ich opis Opcja Domyślnie Opis assert_active 1 Włącza wykonywanie assert(). Aplikacja powinna działać identycznie z wywołaniami funkcji assert(). Funkcja assert() oblicza wartość przekazanego parametru i podejmuje określone akcje w przypadku. tak jak wiele języków wysokiego poziomu.1 pokazany został przykład użycia funkcji assert() do kontroli poprawności parametrów wejściowych. assert_quiet_eval 0 Wyłącza raportowanie błędów w czasie obliczenia wyrażenia asercji. Testowy skrypt dla funkcji z wydruku 10.1. czy tablica zawiera wartości numeryczne. Sposób komentowania jest indywidualny dla każdego programisty.bail.active. assert. } return ( $aTotal / count( $aArray ) ). Taki sposób programowania jest nazywany programowaniem defensywnym. assert_warning 1 Wyświetla ostrzeżenie PHP przy każdej nieudanej asercji. foreach( $aArray as $aElement ) { assert( 'is_numeric( $aElement )' ). ?> <html> <head> <title>Testowanie asercji</title> </head> <body> Rozdział 10 – Uruchamianie 118 . $aTotal += $aElement. Wyrażenie assert() jest wykorzystywane do kontroli poprawności parametru przekazanego do funkcji a później do sprawdzania. PHP.1. W tabeli 10. assert_bail 0 Kończy wykonanie w przypadku nieudanej asercji. jest on wykonywany jako blok kodu PHP. który jest wykonywany jako kod PHP.

2. 5 ) ) = $aResult<br>" ). powoduje to. 2 ). "5. że ponieważ PHP wewnętrznie wymusza typy zmiennych. Istnieje jeszcze jedna funkcja pomagająca w programowaniu defensywnym. \"5. Przyjemną cechą asercji jest to. ?> </body> </html> Testowy skrypt wywołuje funkcję ArrayAverage() cztery razy. Funkcja ta jako argumentu wymaga liczby całkowitej określającej poziom raportowania błędów. 4. False) lub ustawić odpowiednio dyrektywę konfiguracji. 5 ) ). 2. że gdy assert. więc można podać zestaw kilku ustawień. \"4\".5". "cat". 5)) udaje się bez żadnych ostrzeżeń (poza generowanymi przez asercje). natomiast ostatnie dwa razy przekazane wartości są nieprawidłowe. 3. print( "ArrayAverage( array( 1. "4". Poprzedni przykład wyorzystywał domyślne ustawienia asercji. 2. Rysunek 10. Testowanie funkcji ArrayAverage() Podejmowane przez funkcję assert() działania zależą od ustawień asercji. "cat". Argument ten jest traktowany jako maska bitowa. Należy zauważyć. Pierwsze dwa razy przekazywane są właściwe wartości. 3. 4. gdzie asercje są aktywne. PHP posada zestaw stałych używanych razem z tą funkcją.active jest ustawione na False. 5 ) ). 2. $aResult = ArrayAverage( array( 1. $aResult = ArrayAverage( 1.5\". 2 ) = $aResult<br>" ).1. \"cat\". print( "ArrayAverage( 1. Są one następujące: Wartość Nazwa E_ERROR 1 E_WARNING 2 E_PARSE 4 E_NOTICE 8 E_CORE_ERROR 16 E_CORE_WARNING 32 E_COMPILE_ERROR 64 E_COMPILE_WARNING 128 E_USER_ERROR 256 E_USER_WARNING 512 119 PHP – Kompendium wiedzy . print( "ArrayAverage( array( 10. przestają one działać.1. pokazany jest wynik działania skryptu. że wywołanie ArrayAverage(array(1. 5 ) ).1. 4. Aby zmienić tą opcję należy albo wywołać funkcję assert_options( ASSERT_ACTIVE. 2. $aResult = ArrayAverage( array( 10.<?php $aResult = ArrayAverage( array( 1.1. 4. 5 ) ) = $aResult<br>" ). print( "ArrayAverage( array( 1. 4. 3. 3. error_reporting(). 5 ) ) = $aResult<br>" ). Na rysunku 10. Wykorzystując opcję konfiguracji można instalować aplikację w środowisku z wyłączonymi asercjami a pracować na innym.

problem przestanie być niewinny. error_reporting( E_ALL ).3 zamieszczony jest przykład kodu generujący ostrzeżenia w przypadku ustawienia maksymalnego poziomu raportowania błędów. Jak można zauważyć. "city" => "Rexburg". ustawienie bardziej restrykcyjnego poziomu raportowania błędów może spowodować wykrycie błędów w kodzie. "<br>" ).E_USER_NOTCE 1024 Dodatkowo istnieje również stała E_ALL. "country" => "US" ). "county" => "Madison".2. Na wydruku 10. "county" => "Madison". $aArray[state] . pokazane są wyniki działania tego przykładu. "<br>" ). Na wydruku 10. $aArray[state] . "country" => "US" ). Tworząc aplikację powinno się przestawić poziom raportowania błędów na E_ALL. W tym przypadku problem może wydawać się niewinny. $aArray[state] . "<br>" ). print( "aArray[state] = " . ?> </body> </html> Rysunek 10. Drugi przykład użycia funkcji error_reporting() oraz stałej <?php // Stan działania aplikacji define( state. która uaktywnia wszystkie informacje o błędach. ?> </body> </html> Na rysunku 10.3.3. // standardowy poziom raportowania błędów print( "aArray[state] = " .4. co spowoduje wyświetlanie wszystkich informacji o błędach w kodzie.2. // Pozostały kod używający stałej state ?> <html> <head> <title>Poziomy raportowania błędów</title> </head> <body> <?php $aArray = array( "state" => "Idaho". Wynik działania skryptu error_reporting() Rozdział 10 – Uruchamianie 120 . error_reporting( E_ALL ).4 pokazujemy skrypt z taką właśnie stałą. Wyniki jego działania są widoczne na rysunku 10. 3 ). ale jeżeli zdefiniujemy stałą o nazwie state reprezentującą stan działania aplikacji. Wydruk 10. print( "aArray[state] = " . Przykład użycia funkcji error_reporting() <html> <head> <title>Poziomy raportowania błędów</title> </head> <body> <?php $aArray = array( "state" => "Idaho". Ustawienie to jest również ważne w trakcie dołączania do aplikacji zewnętrznej biblioteki. Przy standardowych ustawieniach skrypt nie powoduje wyświetlenia żadnego komunikatu. które mogą spowodować różne efekty uboczne w czasie tworzenia aplikacji. // domyślny poziom raportowania print( "aArray[state] = " . Wydruk 10. "city" => "Rexburg". "<br>" ). $aArray[state] .

że PHP nie wyświetla błędów w przeglądarce a zamiast tego kieruje wszystkie błędy do pliku stderr.assumed 'state' in c:\helion\php4devguide\site\ch10\error_reporting. możesz ustawić poziom raportowania błędów na maksymalny w trakcie rozwijania aplikacji i na minimalny na serwerze produkcyjnym. Jednak osobiście uważam.3. że w przeglądarkach użytkowników nie pojawiają się ostrzeżenia i komunikaty błędów. On i stderr. że najlepiej ustawić na serwerze produkcyjnym poziom raportowania na maksimum. string cel [. nie były generowane żadne ostrzeżenia i program wykonywał się nieomal bezbłędnie.phtml on line 12 Następnym krokiem podczas programowania defensywnego może być napisanie własnego mechanizmu rejestrującego. możesz skorzystać z innej lokalizacji dziennika. W zależności od twojego środowiska.3 po skonfigurowaniu PGP w sposób wspomniany powyżej. Jeżeli używasz Apache. plikiem stderr dla Apache jest dziennik błędów. PHP – Kompendium wiedzy 121 . Tabela 10.phtml on line 17 [06-Dec-2001 20:54:53] PHP Warning: Use of undefined constant state . Powoduje to. Gdy zostanie wykonany skrypt z wydruku 10. Takie ustawienie powoduje. log_errors i error_log na odpowiednio Off. ale skierować strumień błędów do pliku dziennika. Jeżeli chcesz. Prototyp funkcji error_log() wygląda następująco: int error_log(string komunikat.phtml on line 12 [06-Dec-2001 20:54:49] PHP Warning: Undefined offset: 3 in c:\helion\php4devguide\site\ch10\error_reporting_2. 1 Komunikat jest wysyłany pocztą elektroniczną na adres podany w parametrze cel.2. świetnie działający nagle przestał działać. gdy poziom raportowania błędów był ustawiony na standardowy poziom. int typ [. Wartości parametru typ Wartość Opis 0 Parametr komunikat jest wysyłany do systemowego mechanizmu rejestrowania PHP przy użyciu mechanizmu rejestrowania zapewnianego przez system operacyjny lub pliku — w zależności od ustawienia zmiennej konfiguracji error_log. co w funkcji mail(). komunikat. Można to zrealizować ustawiając zmienne konfiguracji display_errors. aby uniknąć występowania błędów w przyszłości.phtml on line 17 [06-Dec-2001 20:54:03] PHP Warning: Use of undefined constant state .2.assumed 'state' in c:\helion\php4devguide\site\ch10\error_reporting. Przykład ten pokazuje zalety zastosowania ustawienia poziomu raportowania błędów na maksimum. jeżeli stała taka byłaby zdefiniowana w dołączanym pliku. na ekranie nie pojawią się ostrzeżenia. Drugi z parametrów określa gdzie zostanie zapisany komunikat.phtml on line 12 [06-Dec-2001 20:54:45] PHP Warning: Use of undefined constant state . Jednak po dodaniu w drugim przykładzie stałej.phtml on line 17 [06-Dec-2001 20:54:51] PHP Warning: Undefined offset: 3 in c:\helion\php4devguide\site\ch10\error_reporting_2. PHP posiada funkcję error_log() przy pomocy której można dodawać własne zapisy do pliku śladu aplikacji. Wszystkie wyświetlane ostrzeżenia powinny zostać zlikwidowane. string naglowki]]) Pierwszy parametr. W dowolnych miejscach aplikacji możesz sprawdzać stan niektórych funkcji lub raportować błędy wewnętrzne i kontynuować pracę. Problem taki może być bardzo trudny do odszukania.assumed 'state' in c:\helion\php4devguide\site\ch10\error_reporting. zawiera zapisywane dane. Jedynie ten typ zapisu wykorzystuje parametr naglowki.Rysunek 10. Lista prawidłowych wartości parametru typ znajduje się w tabeli 10. a w pliku dziennika błędów Apache znajdą się następujące pozycje: [06-Dec-2001 20:53:22] PHP Warning: Undefined offset: 3 in c:\helion\php4devguide\site\ch10\error_reporting_2. Wynik działania drugiego skryptu error_reporting() W obu przykładach. Do obsługi tego typu komunikatu wykorzystywana jest ta sama funkcja wewnętrzna.

com\r\n" ). powodując eliminację niektórych błędów i przeoczeń już w fazie programowania. Inne typy komunikatów działają w sposób opisany w tabeli. case E_WARNING: $aErrorType = "E_WARNING". // Wysłanie błędu przez e-mail error_log( "MÓJ BŁĄD: wystąpił błąd!". $aErrorStr. W tym przykładzie błąd ten wysyłany do dziennika błędów Apache. $aFile. Prototyp takiej funkcji wygląda następująco: function ErrorCallBack( int nr_bledu. Opcja ta jest dostępna jedynie w przypadku. "/tmp/error. ale nie pozwala na obsługę błędów generowanych przez PHP. Jak pokazane zostało na końcu poprzedniego przykładu. Wykorzystanie set_error_handler() <?php function myErrorHandler( $aErrorNo. // nie powinien wystąpić break.6 zamieszczony jest przykład sposobu rejestrowania i użycia funkcji obsługi błędów. $aLine. Na szczęście PHP pozwala w inny sposób obsługiwać takie przypadki.6. </body> </html> 2 Pierwsze wywołanie funkcji error_log() zapisuje komunikat błędu w systemowym dzienniku błędów. Na wydruku 10. gdy włączone jest uruchamianie zdalne.net". Drugie wywołanie skutkuje wysłaniem poczty elektronicznej do odbiorcy określonego w parametrze cel. "From: error_logger@myhost. Funkcja set_error_handler() wymaga podania jednego argumentu — nazwy funkcji obsługi błędów. aby spełniał wymagania stawiane przez aplikację. Użycie funkcji error_log() <html> <head> <title>Rejestrowanie błędów</title> </head> <body> <?php // Zapisanie błędu do dziennika systemowego error_log( "MÓJ BŁĄD: wystąpił błąd!". że zdalne uruchamianie nie jest jeszcze dostępne. Nie pozwala również na przechwytywanie komunikatów generowanych przez funkcje assert(). // Zapisanie błędu w pliku śladu aplikacji error_log( "MÓJ BŁĄD: wystąpił błąd!". Funkcja set_error_handler() pozwala zarejestrować funkcję w PHP. Informacje zawarte w dodatkowych nagłówkach są utworzone przy użyciu tych samych zasad. Wydruk 10. Wykorzystanie tego mechanizmu nie jest w dosłownym znaczeniu uruchamianiem. "app_errors@intechra.Komunikat jest wysyłany poprzez połączenie PHP używane do uruchamiania zdalnego. Rozdział 10 – Uruchamianie 122 . funkcja error_log() pozwala na skonstruowanie prostego mechanizmu rejestrowania własnych błędów występujących w aplikacji. ale jego zastosowanie może zaoszczędzić czas spędzony przy właściwym uruchamianiu. string ciag_bledu.5. Kod źródłowy zawierał komentarz informujący. Jak wcześniej wspomniałem. w tym przypadku /tmp/error. ?> Wystąpiły błędy. która będzie wywoływana za każdym razem. Wydruk 10.log. W czasie pisania książki typ 2 nie był dostępny. unikanie uruchamiania programu poprzez tworzenie poprawnego kodu jest o wiele cenniejsze od najlepszych narzędzi używanych przy uruchamianiu.log" ). co w przypadku funkcji mail(). gdy wygenerowany zostanie komunikat błędu. array kontekst) Na wydruku 10. int nr_lini. Ostatnie wywołanie powoduje dodanie komunikatu błędu do pliku. 1. Własna obsługa błędów Tak jak prawie każdy element PHP mechanizm obsługi błędów możesz dostosować do własnych potrzeb. 3 Komunikat jest dołączany na koniec pliku o nazwie cel. $aContext) { switch ( $aErrorNo ) { case E_ERROR: $aErrorType = "E_ERROR". 3. string nazwa_skryptu.5 pokazany jest przykład użycia funkcji error_log(). W tym przypadku parametr cel określa nazwę komputera lub adres IP oraz opcjonalnie numer portu używanego do odbierania informacji uruchamiania. 0 ).

case E_CORE_WARNING: $aErrorType = "E_CORE_WARNING". error_reporting( E_ALL ). $aArray[state] . ?> </body> </html> W skrypcie na wydruku 10. która wyświetla komunikaty błędów w obramowanej tabeli zawierającej jedną komórkę. case E_PARSE: $aErrorType = "E_PARSE". Po zainstalowaniu funkcji obsługi.4. case E_USER_ERROR: $aErrorType = "E_USER_ERROR". } set_error_handler( "myErrorHandler" ). case E_CORE_ERROR: $aErrorType = "E_CORE_ERROR". "<b>$aErrorType</b>: <i>$aErrorStr</i><br>" ). "county" => "Madison". "city" => "Rexburg".6 została zdefiniowana funkcja obsługi błędów myErrorHandler(). skrypt powoduje dwa błędy. // nie powinien wystąpić break. // nie powinien wystąpić break. Rysunek 10. case E_COMPILE_WARNING: $aErrorType = "E_COMPILE_WARNING".3. // nie powinien wystąpić break. break. co pomaga w odróżnieniu komunikatu błędu od reszty kodu HTML. Drugi błąd (ostrzeżenie) jest identyczny jak błąd pokazany na wydruku 10. "country" => "US" ).4. "<br>" ). break. break. case E_COMPILE_ERROR: $aErrorType = "E_COMPILE_ERROR". pokazany został wynik działania skryptu. } print( print( print( print( "<table border=\"1\"><tr><td>" ). default: $aErrorType = "UNKNOWN ERROR TYPE". // nie powinien wystąpić break. break. Działanie funkcji set_error_handler() 123 PHP – Kompendium wiedzy . "</td></tr></table>" ). case E_USER_WARNING: $aErrorType = "E_USER_WARNING". ?> <html> <head> <title>Własna obsługa błędów</title> </head> <body> <?php trigger_error( "Test błędów". // nie powinien wystąpić break. Pierwszy jest generowany przy użyciu funkcji PHP trigger_error(). E_USER_ERROR ). case E_USER_NOTICE: $aErrorType = "E_USER_NOTICE".break. break. $aArray = array( "state" => "Idaho". case E_NOTICE: $aErrorType = "E_NOTICE". "w pliku $aFile linia $aLine<br>" ). print( "aArray[state] = " . Na rysunku 10.

że wywołanie takie zwróci jedynie nazwę bieżącej funkcji obsługi. to dodatkowo oprócz zwracania nazwy.2. $Asercja ) Uwaga na temat assert_options() W PHP do wersji 4. Aby to zrealizować należy skorzystać z funkcji assert_options(). <?php assert( "1 == 2" ). Obsługa tego typu błędów przez użytkownika nie jest bezpieczna. ?> </body> </html> Kod z wydruku jest podobny do tego z wydruku 10. // wyłączenie normalnych ostrzeżeń assert_options( ASSERT_WARNING. że w dokumentacji napisano. w tym nazwę skryptu.2. funkcja użyta w tym przykładzie posiada pięć parametrów. 0 ). $aAssertion ) { print( "<table border=\"1\"><tr><td>" ). Mimo. Wywołanie asercji powoduje wyświetlenie jednokomórkowej tabeli. pokazany został przykład zdefiniowania i użycia funkcji wywoływanej przez assert(). "MyACallback" ). function MyACallback( $aFileName. Wydruk 10. w celu odczytania ustawionej funkcji obsługi. Na rysunku 10. E_CORE_ERROR.7. $NrLinii. print( "</td></tr></table>" ). Z tego powodu w kodzie funkcji obsługi błędów z wydruku 10. pokazany jest wynik działania skryptu z wydruku 10. E_COMPILE_ERROR oraz E_COMPILE_WARNING. Wykorzystanie funkcji wywoływanej przez callback() <?php error_reporting( E_ALL ). Uwaga na temat set_error_handler() Funkcja set_error_handler() jest dostępna w PHP od wersji 4. pojawiły się komentarze „nie powinien wystąpić”. że nie jest wywoływana później funkcja assert_options() w celu sprawdzenia nazwy zarejestrowanej funkcji. Rozdział 10 – Uruchamianie 124 .6.6. Jeżeli nie zostanie opcja ASSERT_WARNING. Wcześniejsze wersje miały tylko dwa parametry: typ komunikatu i komunikat.Używając funkcji set_error_handler() należy pamiętać.7. Dlatego jeżeli chcesz użyć funkcji assert() z funkcją obsługi upewnij się. Będą one opisane w następnej części rozdziału. ?> <html> <head> <title>Własna obsługa asercji</title> </head> <body> Nieudana asercja.6 nie są wykorzystane dane na temat kontekstu. } // zarejestrowanie funkcji obsługi assert_options( ASSERT_CALLBACK.0.2 włącznie. Funkcja obsługująca nieudane asercje jest zdefiniowana w następujący sposób: function AssertCallback ($NazwaPliku. print( "w pliku $aFileName w linii $aLineNum<br>" ). Również funkcja assert() pozwala na zdefiniowanie wywoływanej funkcji.0. Dane te zawierają nazwy i wartości zmiennych istniejących w skrypcie w momencie wystąpienia błędu.7.1. Błąd ten został zauważony i poprawiony w wersjach PHP powyżej 4. Dodatkowo. w funkcji assert_options() występował mały błąd. Występował on w przypadku wywołania funkcji w postaci assert_options(ASSERT_CALLBACK).0. $aLineNum. W skrypcie z wydruku 10. E_CORE_WARNING. oprócz informacji zdefiniowanych przez użytkownika wyświetlony zostanie standardowy komunikat PHP.5. print( "<b>assert()</b> nieudane: <i>$aAssertion</i><br>" ). Na wydruku 10. że PHP nie przekazuje do funkcji obsługi błędów typu E_ERROR. numer linii i dane kontekstu. bieżące ustawienie funkcji obsługi było czyszczone. Parametry te są dostępne dopiero w wersji 4.0. E_PARSE.

W następnej części połączymy wszystkie przedstawione do tej pory techniki.log. Jest on tak utworzony.IP=myserver. if ( $aMyDebugType & MYDEBUG_DISPLAYFILE ) { // jeżeli nie można zapisać do pliku sladu // poinformuj o tym uzytkownika i wyłączyć zapis do pliku if ( CheckFileSanity( $aMyDebugFile ) == False ) { error_log( "MyDebug nie udało się otworzyć pliku $aMyDebugFile". plik konfiguracyjny Apache może zawierać kod podobny do następującego: SetEnv MYDEBUG_CONFIG FILE=/tmp/mydebug.8. $aMyDebugType &= ~MYDEBUG_DISPLAYFILE. Oprócz tego. 0 ). która nie została przeniesiona do PHP 4. że może być łatwo dołączony do dowolnego skryptu PHP. 125 PHP – Kompendium wiedzy . "a" ). MyDebug. które automatycznie łączą różne typy danych o błędach.php i będzie on określony jako moduł MyDebug. Motywacją do napisania tego fragmentu był brak dostarczanych przez PHP narzędzi. ale na razie muszą wystarczyć podstawowe techniki obsługi błędów opisane w tym rozdziale. } if ( $aMyDebugType & MYDEBUG_DISPLAYIP ) { $aSocketHandle = fsockopen( "udp://$aMyDebugIP". $aMyDebugPort ). } // Teraz rejestrujemy funkcje obsługi i funkcje porządkujące set_error_handler( "MyErrHandler" ). } } if ( $aMyDebugType & MYDEBUG_DISPLAYFILE ) { $aFileHandle = fopen( $aMyDebugFile. Pozwalał on przesyłać dane za pomocą protokołu TCP/IP do innego komputera. więc zostanie omówiony we fragmentach.8.5. "MyAssertHandler" ). Zaawansowana obsługa błędów Po omówieniu technik obsługi błędów możemy rozpocząć tworzenie ogólnego narzędzia do obsługi błędów. 0 ). Dołączanie modułu MyDebug ParseConfig( getenv( "MYDEBUG_CONFIG" ) ).8. Po dołączeniu pliku wykonywany jest kod pokazany na wydruku 10.com:5400. Wydruk 10. Moduł ten znajduje się w jednym pliku. Przykład przytoczony w tej części jest niezwykle długi. assert_options( ASSERT_CALLBACK. co w efekcie pozwoli lepiej uruchamiać programy w całym cyklu produkcyjnym. register_shutdown_function( "MyDebugShutdown" ). MAIL=mydebug@intechra. Na przykład. Pozwala on dzięki temu pisać kod łatwiejszy do uruchamiania i późniejszego utrzymania.net. Użycie funkcji zdefiniowanej dla assert() PHP posiada elastyczny mechanizm obsługi błędów. PHP 3 posiadał możliwość zdalnego uruchamiania. powoduje przetworzenie ciągu konfiguracji MyDebug. który jest przechowywany w zmiennej środowiska serwera. assert_options( ASSERT_WARNING. Opcja ta prawdopodobnie niedługo się pojawi.Rysunek 10. Pierwsza linia z wydruku 10.

Jeżeli moduł MyDebug nie może zapisać danych do pliku. ale nie zawsze jest aktywny proces nasłuchu.log). W tym przypadku moduł będzie zapisywał błędy do pliku (/tmp/mydebug.9 pokazana jest funkcja kończąca program. że można ustawiać zmienne środowiska. $aCallType = MY_DEBUG_INTERNAL. $aErrType = 0. $aMyDebugType. Główna funkcja obsługi błędów to przedstawiona na wydruku 10. MYDEBUG_ASSERTCALLBACK ). funkcje te są wywoływane w tej samej kolejności. PHP przekaże je do funkcji końcowej. gdy zapisywanie jest aktywne na serwerze produkcyjnym. Zmienna MYDEBUG_CONFIG definiuje miejsca.11. ale moduł MyDebug pozwala na stosowanie wielu jednoczesnych miejsc zapisu błędów. $aLine. Wydruk 10. Następnie otwierane są wszystkie potrzebne pliki i gniazda. $aErrorNo. $aDisplayType <= MYDEBUG_DISPLAYIP. poprzez pliki konfiguracyjne serwera WWW i są one dostępne w kodzie PHP. Funkcję kończącą może zarejestrować dowolny skrypt.10. $aAssertion ) { MyDebug( "asercja( $aAssertion ) nieudana". $aErrorStr. Przykład ten pokazuje. Ostatnią operacją jest zarejestrowanie funkcji wywoływanej po zakończeniu programu. funkcja MyDebug(). } if ( $aMyDebugType & MYDEBUG_DISPLAYIP ) { fclose( $aSocketHandle ). $aLineNum. PHP pozwala na rejestrowanie wielu funkcji kończących. Ponieważ kolejność ta nie została udokumentowana.com:5400). gdzie MyDebug będzie zapisywał błędy. $aContext ). Można przekazać dodatkowe argumenty do funkcji register_shutdown_function(). Funkcja MyDebug() // Funkcja MyDebug jest główną funkcją obsługi function MyDebug( $aMessage. co pozwala na eleganckie zakończenie działania modułu. aby mieć pewność. która może również zostać wywołana bezpośrednio ze skryptu. $aErrContext = array() ) { global $aMyDebugType. Funkcja ParseConfg() analizuje ciąg konfiguracji i ustawia odpowiednie zmienne globalne. $aFile. Choć ten fakt nie jest odnotowany w dokumentacji. $aLineNum. } // Funkcja obsługi dla funcji assert_options() function MyAssertHandler( $aFileName. skrypty twoje nie powinny polegać na kolejności wykonywania funkcji kończących lub musisz sam to przetestować. for ( $aDisplayType = MYDEBUG_DISPLAYFILE. Na wydruku 10. wysyłał na adres e-mail (mydebug@intechra.10. $aFile. obsługuje on błędy za pomocą funkcji z wydruku 10. } Obie funkcje przekazują parametry do głównej funkcji obsługi błędów. Należy również pamiętać. Po przeanalizowaniu ciągu konfiguracyjnego sprawdzane są wszystkie pliki używane do zapisu. zapisywanie do niego jest wyłączane. MYDEBUG_ERRCALLBACK. $aFileName. if ( $aMyDebugType & MYDEBUG_DISPLAYFILE ) { fclose( $aFileHandle ). Po skonfigurowaniu modułu MyDebug. że w funkcji końcowej nie można wysyłać żadnych danych do przeglądarki. co zostały zarejestrowanie. które są wykonywane w czasie kończenia pracy skryptu. $aFile. $aDisplayType++ ) { Rozdział 10 – Uruchamianie 126 . Własność ta jest użyteczna szczególnie wtedy.Ta opcja konfiguracji jest specyficzna dla modułu MyDebug i nie jest dostępna jako standardowa część Apache czy PHP. Wydruk 10. Następnie moduł MyDebug rejestruje funkcje obsługi błędów i asercji. } } Funkcja ta zamyka wymagane pliki oraz gniazdo sieciowe. $aLine. co nie wymaga istnienia procesu nasłuchu. $aSocketHandle. że można do nich zapisywać dane. Gniazdo jest otwierane używając UDP.9. $aContext) { MyDebug( $aErrorStr. $aLine. Funkcja kończąca program function MyDebugShutdown( ) { global $aFileHandle. W normalnej pracy wybiera się zwykle jedną z metod zapisu błędów. Funkcje obsługi błędów // Funkcja obsługi ustawiana przez set_error_handler() function MyErrHandler( $aErrorNo.11.net)oraz do gniazda UDP (myserver. Wydruk 10.

Funkcje formatujące z wydruku 10. } fputs( $aFileHandle. 127 PHP – Kompendium wiedzy . jeżeli pomyśli się o efektywności każdej z tych opcji. break. Każda funkcja formatująca użyta w module MyDebug posiada mechanizm zamiany wewnętrznego numeru błędu na postać czytelną dla człowieka. $aDisplayType ). Następnie wywołuje funkcje MyDebugOutput() (wydruk 10. $aFile. $aDisplayType ) { global $aFileHandle.= "Dane kontekstu:\n{$aContext}\n". break. ". case MYDEBUG_DISPLAYEMAIL: $aMsg = "$aType: '$aMessage' wystąpił w $aFile w linii $aLine.11 zostaną omówione później.13. ". Funkcja FormatType() /* Funkcja formatuje typ komunikatu w oparciu o to gdzie będzie wyświetlony */ function FormatType( $aCallType. } } Funkcja MyDebugOutput() wysyła dane do właściwych miejsc.13 formatuje kod typu błędu.com\r\n"). Wydruk 10.12. $aMyDebugEmail. switch( $aDisplayType ) { case MYDEBUG_DISPLAYFILE: $aMsg = "$aType: '$aMessage' wystąpił w $aFile w lini $aLine. Wydruk 10. case MYDEBUG_DISPLAYIP: $aMsg = "$aType|$aMessage|$aFile|$aLine|$aContext^^". fputs( $aSocketHandle. $aMsg ). $aSocketHandle. $aMessage. $aMsg ). break. $aContext. $aLine. } else { $aContext = "". "From: mydebug@host. $aContext. $aDisplayType ). $aMessage. if ( $aContext != "" ) { $aMsg . if ( $aContext != "" ) { $aMsg . } mail($aMyDebugEmail. $aMsg. } } } Funkcja MyDebug() formatuje różne parametry w zależności od typu medium zapisu (plik. $aMessage. Jest ona zaskakująco prosta. $aMessage = FormatMsg ( $aCallType.if ( $aDisplayType & $aMyDebugType ) { $aType = FormatType( $aCallType. $aDisplayType ). $aDisplayType ) { switch( $aDisplayType ) { case MYDEBUG_DISPLAYFILE: case MYDEBUG_DISPLAYEMAIL: switch ( $aCallType ) { case MYDEBUG_INTERNAL: return "INTERNAL".= "\n". $aDisplayType ). e-mail lub TCP/IP). } else { $aMsg . Funkcja MyDebugOutput() function MyDebugOutput( $aType. } else { $aMsg . if ( $aCallType == MYDEBUG_ERRCALLBACK ) { $aContext = FormatContext( $aErrContext.12). } MyDebugOutput( $aType. Na przykład funkcja FormatType() przedstawiona na wydruku 10.= "Dane kontekstu:\n{$aContext}\n". "Raport MyDebug". która wysyła dane do prawidłowego miejsca. $aFile. $aErrType. $aLine.= "\n".

= " )$aDelim". W zależności od miejsca wystąpienia błędu. w tym zmienne środowiska i zmienne GET i POST. kontekst lokalny może zawierać sporo danych.) dołączyliśmy moduł MyDebug oraz ustawiliśmy zmienną konfiguracji na zapisywanie do pliku tekstowego. Wszystkie te zmienne znajdą się w danych kontekstu. return $aString. Funkcja zamieszczona na wydruku 10. nie jest przeprowadzane formatowanie.= "$aVarName = array( ". przekształcając je na postać czytelną dla człowieka. } } Jeżeli dane są wysyłane poprzez TCP/IP. Analiza danych kontekstu Funkcja formatuje typ komunikatu w oparciu o to gdzie będzie wyświetlony. $aString . break. kontekst będzie zawierał jedynie zmienne lokalne funkcji. &$aString. Jeżeli błąd wystąpi w głównej części skryptu. } else { $aString . FormatContext(). case MYDEBUG_ASSERTCALLBACK: return "ASSERT CALLBACK".phtml w lini 16. Funkcja rekurencyjna przegląda tablice zmiennych kontekstu i zapisuje każdą parę nazwa-wartość do wynikowego ciągu. case MYDEBUG_ERRCALLBACK: return "ERROR CALLBACK". $aDelim ).break. Dane te są przesyłane w postaci tablicy asocjacyjnej z nazwami zmiennych i ich wartościami. Funkcja ta jest wywoływana jedynie wtedy. Jeżeli błąd wystąpi w funkcji. jedynie wynikiem wystąpienia ostatniego błędu w skrypcie: ERROR CALLBACK: 'Typ błędu PHP: E_USER_ERROR . Analiza tych danych wymaga wykorzystania funkcji rekurencyjnej. } } } /* Funkcja FormatContext() ustawia kilka parametrów i wywołuje funkcję rekurencyjną FormatContextR(). $aString. Dane kontekstu: a = 1 b = 2 aArray = array( 0 = spring. Jedyną funkcją formatującą. W innym wypadku numer typu jest zamieniany na czytelny ciąg. $aString. Jeżeli napotkana zostanie tablica." ).2 = autumn. Skrypt testowy <?php Rozdział 10 – Uruchamianie 128 . break. $aDelim ) { foreach( $aErrContext as $aVarName => $aVarValue ) { if ( is_array( $aVarValue ) == True ) { $aString . $aDisplayType ) { // od tej pory wszystkie wyświetlane typy // otrzymują ten sam ciąg kontekstu $aString = "". } function FormatContextR( $aErrContext.error in sum' wystąpił w c:\helion\php4-devguide\site\ch10\test_mydebug.= "$aVarName = {$aVarValue}{$aDelim}". w zasięgu znajdą się wszystkie zmienne globalne. Sam numer typu jest wysyłany do zdalnego komputera. Po jego uruchomieniu na końcu pliku śladu znalazł się ciąg błędu. Do skryptu testującego (wydruk 10. Poniższy tekst nie jest całym plikiem. ) Wydruk 10. rekurencyjnie jest wywoływana funkcja FormatContextR(). gdy błąd zostanie obsłużony przez funkcję zarejestrowaną za pomocą set_error_handler(). } break. Dane kontekstu udostępniane przez PHP zawierają wszystkie zmienne będące w zasięgu w momencie wystąpienia błędu.15. $aDelim = "\n". case MYDEBUG_DISPLAYIP: return $aCallType. FormatContextR( $aErrContext. break. analizuje dane kontekstu. FormatContextR( $aVarValue. Wydruk 10.14.14.15. jest funkcja formatująca kontekst błędu. która jest wyraźnie inna.1 = summer.3 = winter. ponieważ w kontekście mogą znajdować się tablice. Inne funkcje konwertujące użyte w MyDebug działają podobnie. ". Funkcja oparta o funkcję rekurencyjną FormatContextR */ function FormatContext( $aErrContext.

/mydebug. ?> <html> <head> <title>Test modułu MyDebug</title> </head> <body> Nieudana asercja. Wynik funkcja sum() nie jest nigdzie używany. które pozwalają na uniknięcie możliwie dużo pracy przy uruchamianiu. "summer". "county" => "Madison". Aby pokazać elastyczność tego modułu. sum( 1.include_once( ". ale jest ona umieszczone w tym skrypcie. trigger_error( "error in sum". "country" => "US" ). Moduł MyDebug jest napisany całkowicie w PHP dodając do niego niezwykle użyteczne funkcje (kompletne źródła modułu MyDebug są dostępne wraz z wszystkimi przykładami kodu z tej książki). poza generowaniem błędów. które są dostępne we wielu nowoczesnych językach 129 PHP – Kompendium wiedzy . print( "<br><br>aArray[state] = " . aby pokazać jak wywołanie funkcji wpływa na dane kontekstu przekazywane przez PHP. co pozwoli na wykorzystanie tej opcji w środowisku produkcyjnym. Jest to prosta aplikacja Delphi. Podsumowanie W tym rozdziale przedstawione zostały informacje na temat technik programowania defensywnego. pokazana została ta aplikacja po odebraniu kilku komunikatów wygenerowanych przez PHP. Na przykład. która odczytuje pakiety UDP przychodzące do portu 5400. Nie wszystkie narzędzia programowania dla WWW są tak elastyczne. podobnego do tych. $aArray = array( "state" => "Idaho". 2 ). Rysunek 10. "city" => "Rexburg".6. Po odczytaniu danych formatuje linie i wyświetla je. Moduł ten nie jest kompletny i może być rozwijany na wiele sposobów. $b ) { $aArray = array( "spring". ale można wykorzystać pocztę elektroniczną do raportowania jedynie krytycznych błędów i ostrzeżeń. E_USER_ERROR ). E_USER_ERROR ). trigger_error( "Błąd testowy". "<br>" ). "winter" ). napisana została aplikacja Windows. że jest on niezwykle rozszerzalny.php" ). która realizuje proces nasłuchu portu TCP/IP i wyświetla przychodzące dane. że wszystkie te opcje są zrealizowane całkowicie w PHP.15. Linie z opisem błędu zamieszczone bezpośrednio przed wydrukiem 15 są wygenerowane przy wywołaniu funkcji sum(). wykorzystanie poczty elektronicznej do raportowania błędów jest niezwykle nieefektywne. Niezmiernie istotny jest fakt.6. Na rysunku 10. nie robi nic. "autumn". Aplikacja nasłuchu dla MyDebug Jednym z powodów atrakcyjności języka PHP jest to. ?> </body> </html> Skrypt testowy przedstawiony na wydruku 10.<br><br> <?php function sum( $a. $aArray[state] . W chwili obecnej PHP nie posiada programu do uruchamiania skryptów. } assert( "1 == 2" ).

Opisany został jeden z modułów. 1993. Bibliografia Steve McConnell.programowania. Code Complete. aby spełniał wymagania prawie każdego programisty. Seattle: Microsoft Press. Rozdział 10 – Uruchamianie 130 . Jednak przy odrobinie pomysłowości i wykorzystując rozszerzalność PHP. który zapewnia elastyczną obsługę błędów i może być modyfikowany i rozszerzany tak. można stworzyć świetne narzędzia do uruchamiania aplikacji.

na przykład tworząc oddzielne pliki z kodem źródłowym (pliki dołączane) lub tworząc klasy obiektowe. jeżeli nie zostanie zastosowane odpowiednie planowanie. że tworzenie kodu do ponownego wykorzystania jest integralną częścią całego procesu produkcji oprogramowania i że wszyscy programiści zgadzają się z tą ideą. który uprości jego wykorzystanie w przyszłości. Taka elastyczność pozwala programistom na przenoszenie do sieci WWW istniejących aplikacji bez konieczności całkowitego przepisywania kodu. Gdy planowane jest ponowne wykorzystanie kodu. • Upewnienie się. Zalety ponownego użycia nie są natychmiast widoczne. jakie należy wziąć pod uwagę: • Zaangażowanie kierownictwa w proces ponownego wykorzystania kodu. 1996). Mając to na uwadze. Zalety te nie będą wykorzystane. oraz przytoczone zostanie kilka przykładów kodu PHP nadającego się do powtórnego wykorzystania. W PHP kod nadający się do powtórnego wykorzystania można tworzyć przy pomocy kilku metod. że dany fragment kodu będzie wykorzystywany w przyszłości. Kluczem do sukcesu jest tworzenie kodu nadającego się do powtórnego użycia. 1996). należy napisać go i udokumentować w sposób zgodny z najlepszymi zaleceniami stosowanymi w zespole. Należy unikać używania danych lub założeń specyficznych dla projektu. Użycie hermetyzacji i technik ukrywania danych da w efekcie maksymalne zwiększenie wydajności i efektywności ponownie wykorzystanego kodu. W rozdziale tym omówione zostanie wykorzystanie w projektach PHP kodu napisanego w innych językach programowania. Wybór plików dołączanych lub podejścia obiektowego nie wpływa zbytnio na ogólne założenia. częściej należy dzielić grupy funkcji na oddzielne moduły lub klasy. ale wiele firm zauważyło około 58% wzrost wydajności rocznie w przeciągu czterech lat (McConnell. • Skupienie się na tworzeniu małych. . który jest odpowiednio zorganizowany i dobrze udokumentowany. Ponieważ PHP pozwala na dołączanie zewnętrznych plików oraz na tworzenie klas. że przy pisaniu aplikacji w przyszłości będą potrzebne podobne fragmenty. precyzyjnych modułach kodu.Rozdział 11. W tym rozdziale ponowne wykorzystanie kodu zostanie krótko omówione z perspektywy inżynierii programowania. że używane moduły kodu stanowią podstawę kolejnych aplikacji i w dłuższym czasie polepszają wydajność zespołu programistów. Jeżeli wiadomo. Poniżej przedstawione zostały niektóre ważne zagadnienia. ponieważ tworzenie takiego kodu zajmuje często dużo więcej czasu i jest bardziej kosztowne w porównaniu do tego samego kodu do jednokrotnego użycia (McConnell. ponowne wykorzystanie kodu jest dosyć proste. Ponowne wykorzystanie kodu Wstęp Podczas tworzenia dowolnej aplikacji niezmiernie ważne jest wykorzystanie istniejących modułów kodu. Tworząc kod należy mieć na uwadze. Nowe fragmenty kodu często są tworzone w sposób ułatwiający ich ponowne wykorzystanie. a zamiast tego tworzyć moduł w sposób. Ponowne wykorzystanie kodu a inżynieria programowania Ponowne wykorzystanie kodu nie polega jedynie na integracji istniejącego kodu z nowym produktem. ważne są efekty długoterminowe. • Tworzenie kodu do ponownego wykorzystania przy użyciu możliwie najlepszych standardów programowania i dokumentacji. Pierwszym powodem jest to.

php" ). "8-15-1992" ) ). 0. Omówione zostaną teraz niektóre techniki dostępne w PHP. na końcu książki. $aDateStr1 ). przedstawiono przykład takiego problemu i sposób jego rozwiązania. Wydruk 11. Wydruk 11. który można wykorzystać. return GetFormattedNumber( $aTimeDiff / ( 60 * 60 * 24 ) ). 0. assert( 'count( $aDateArray2 ) == 3' ). $aDateStr2 ) { $aDateArray1 = explode( "-". które upraszczają proces dołączania. Plik dołączany date_funcs. print( " gości " ). ?> <html> <head> <title>Problem z wielokrotnym dołączaniem plików</title> </head> <body> <?php $aNumVisitors = 14500. HTML lub ich kombinacji. Skrypt wykorzystujący oba pliki dołączane <?php include( ". Jeżeli przenosi się zwykłą aplikację biurową do sieci. assert( 'count( $aDateArray1 ) == 3' ). $aDateArray2[0]. print( "w przeciągu ostatnich " ). } ?> Wydruk 11. dostępne są funkcje include_once() i require_once()./format_funcs. include( ".'. Z tego powodu została przygotowana podstawa do tworzenia narzędzi dla PHP tworzonych przez różne firmy. prawdopodobnie istnieje wtedy kod. // Zwraca ilość dni pomiędzy datami // jako sformatowany ciąg w postaci mm-dd-rrrr function GetDateDiff( $aDateStr1.1.php <?php include_once( ". $aDateArray2[2] ). $aDateArray2[1]. print( "Witrynę odwiedziło " )." ).2. print( GetFormattedNumber( $aNumVisitors ) ). Niektóre z nich zostały wspomniane w poprzednich rozdziałach i są wymienione na liście zasobów internetowych. $aTime1 = mktime( 0. wykorzystuje funkcje z obu poprzednich plików dołączanych.php <?php function GetFormattedNumber( $aNum ) { return number_format( $aNum./date_funcs./format_funcs.$aTime2 ). Używane już we wcześniejszych przykładach. funkcje te pozwalają na dołączanie czystego kodu PHP. print( " dni.3. $aDateArray1[0]. o których należy pamiętać przy projektowaniu aplikacji.php" ). $aDateArray1[1]. Najbardziej oczywistą metodą ponownego wykorzystania kodu PHP jest użycie funkcji include() lub require() do dołączenia istniejącego kodu. $aTimeDiff = abs( $aTime1 . Ponieważ PHP jest niezwykle rozszerzalny. Jednak ponowne wykorzystanie kodu może jedynie wymagać przewidywania przyszłych projektów. Plik dołączany format_funcs. PHP PHP zawiera kilka narzędzi ułatwiających ponowne wykorzystanie kodu.3. 0. 0. Niektóre z tych metod zostaną opisane w późniejszych częściach. lub przepisuje się z innego języka na PHP. '. $aDateArray1[2] ). ?> </body> </html> Rozdział 11 – Ponowne wykorzystanie kodu 132 .1. $aDateArray2 = explode( "-". Na wydruku 11.2. print( GetDateDiff( "9-21-2000". istnieje wiele metod użycia obcego kodu w aplikacjach opartych o PHP. ' ' ). Zaczynając od wersji PHP 4.php" ). Funkcje te eliminują problem występujący przy wielokrotnym dołączaniu do skryptu tego samego pliku. } ?> Skrypt z wydruku 11. $aTime2 = mktime( 0.Ponowne użycie istniejącego kodu Z powodu natury projektów internetowych. w firmie może nie istnieć zbyt wiele fragmentów kodu do wykorzystania. i 11. $aDateStr2 ). 0.

/format_funcs.php" ). "8-15-1992" ) ). Wydruk 11. możesz rozważyć dołączenie tego kodu do twojej instalacji PHP. który ma być przeniesiony do środowiska WW. print( "Witrynę odwiedziło " ). ale nie opiszemy tutaj tego procesu. Skrypt wykorzystujący include_once() <?php include_once( ". Ponieważ PHP obsługuje dołączanie modułów oraz programowanie obiektowe. oprocentowanie (i) oraz czas (l) */ double _fin_mpmt (double p.php dołącza również plik format_funcs.3 wynika z tego. można utworzyć obiekty PHP używające implementacji w C++. że plik dołączany date_funcs. C/C++ PHP jest napisany w C i C++.5. Jeżeli posiadasz istniejący kod projektu w C lub C++. ?> </body> </html> Funkcje require() i require_once() działają podobnie. Funkcje w C do konwersji na PHP /* _fin_mpmt: oblicza miesięczną spłatę kredytu w oparciu o kwotę kredytu (p). Dodatkowo PHP obsługuje tworzenie klas obiektowych. print( " gości " ). Oprócz tego. Pierwsze dwie funkcje zwracają pojedyncze wartości oznaczające odpowiednio ratę miesięczną i sumę wszystkich rat. print( " dni." ). print( "w przeciągu ostatnich " ). że mamy trzy funkcje zamieszczone na wydruku 11. double i.4. double n.Problem występujący w skrypcie z wydruku 11. Na przykład CyberCashTM Merchant Control Kit został napisany w C a jego funkcje są dostępne w PHP jako funkcje cybercash_xxx(). które można ponownie wykorzystywać lub rozszerzać. Wydruk 11.5 i chcemy na ich podstawie utworzyć wewnętrzne funkcje PHP.php.php on line 2 Na wydruku 11. Z tego powodu możliwa jest integracja istniejącego kodu C/C++ bezpośrednio w PHP. rozszerzalność PHP pozwala na wykorzystanie innego istniejącego kodu. Używając tych danych można wygenerować harmonogram amortyzacji. Skupmy się teraz na tworzeniu wbudowanych funkcji PHP opartych o istniejące funkcje w C.php" ). Funkcje te są wykorzystywane do obliczania płatności hipotecznych i tworzenia tabel amortyzacji w USA. że wymaga to sporo pracy i w efekcie może być mniej efektywne. Ten mechanizm dołączania plików pozwala na tworzenie własnych bibliotek często używanych funkcji oraz wykorzystanie kodu od zewnętrznych dostawców. niż proste przepisanie kodu na PHP. j = i / (12 * 100). ?> <html> <head> <title>Problem z wielokrotnym dołączaniem plików</title> </head> <body> <?php $aNumVisitors = 14500. n = l * 12. Załóżmy. Ostatnia funkcja zwraca tabelę wartości reprezentujących wartość odsetek miesięcznych w racie. include_once( ". Tak naprawdę wiele z rozszerzeń PHP jest bezpośrednio przeniesiona z C lub C++.4. double l) { double j. print( GetFormattedNumber( $aNumVisitors ) ). naturalnie pozwala na tworzenie kodu wielokrotnego użycia. print( GetDateDiff( "9-21-2000". Można zamiast tego napisać funkcje mapujące dla metod istniejących obiektów C++./format_funcs. Jeżeli istniejący kod jest napisany w C++./date_funcs. W poprzednich rozdziałach zostały pokazane przykłady rozszerzania klas pochodzących z od różnych dostawców. Po uruchomieniu skryptu generowany jest komunikat błędu: Fatal error: Cannot redeclare getformattednumber() in . pokazane zostało jak łatwo można rozwiązać ten problem korzystając z funkcji include_once(). Należy jednak pamiętać. 133 PHP – Kompendium wiedzy .

double interest. h. int nIndex. 1. double length ) Parametr assign-params powoduje. tworzony jest nowy katalog ext/fin_funcs. double length ) double fin_total ( double principle.m4 jest pokazany poniżej (komentarze zostały usunięte): PHP_ARG_ENABLE(fin_funcs. Testowy moduł rozszerzenia jest uaktywniany za pomocą dyrektywy konfiguracji --enable-fin_funcs. Uruchom skrypt buildconf w głównym katalogu PHP. że pliki szkieletowe i konfiguracyjne są prawidłowe. l ). double i. [ --enable-fin_funcs Enable fin_funcs support]) if test "$PHP_FIN_FUNCS" != "no". czy rozszerzenie jest aktywne w PHP. Uruchom skrypt configure i dodaj obsługę nowego rozszerzenia. więc natychmiast po uruchomieniu tego narzędzia i poprawieniu pliku config. } /* _fin_total: oblicza całkowitą kwotę spłat w czasie trwania kredytu w oparciu o kwotę kredytu (p). q = q . Skrypt testowy wykrywający. oprocentowanie (i). co zostanie opisane później. double *pIntPmt) { double n. Aby dodać funkcje finansowe do PHP należy uruchomić build_skel w następujący sposób: . Dla funkcji finansowych użyjemy następującej zawartości pliku prototypów: double fin_mpmt ( double principle. czy rozszerzenie działa jest podobny do następującego: Rozdział 11 – Ponowne wykorzystanie kodu 134 ./build_skel --extname=fin_funcs --proto=/sciezka/do/fin_funcs.php) aby sprawdzić. 2. [ ]) PHP_EXTENSION(fin_funcs. Pierwsza zmiana musi zostać wprowadzona do pliku config. c = m . 4. } /* _fin_table: oblicza miesięczne odsetki używane w planie amortyzacji dla kredytów w oparciu o kwotę (p). W pliku tym zawarty jest opis omawiający wymagane zmiany. l) * l * 12. Plik ext/fin_funcs/config. Po uruchomieniu skryptu w sposób przedstawiony powyżej.proto --assign-params Parametr extname jest nazwą nowego rozszerzenia PHP. oprocentowanie (i) i czas (l) */ double _fin_total (double p. whether to enable fin_funcs support. double i. i inne ustawienia generacji kodu. Wykonaj skrypt testowy z katalogu z rozszerzeniem (fin_funcs. Plik prototypów powinien zawierać prototypy funkcji PHP. m. nIndex++ ) { h = q * j. j. 3. można wykonać następujące czynności: 1. $ext_shared) fi Funkcja build_skel tworzy plik źródłowy w C. n = l * 12. then AC_DEFINE(HAVE_FIN_FUNCS. double interest.h. (n * -1)))))). Więcej szczegółów można uzyskać uruchamiając skrypt build_skel bez parametrów. Program ten znajduje się w katalogu ext dystrybucji PHP zawierającej pliki źródłowe. } W dystrybucji PHP dostarczany jest program o nazwie build_skel. i. j = i / (12 * 100). Skompiluj PHP. Inne dostępne parametry pozwalają kontrolować wygląd dokumentacji.(pow(( 1+j ).4m. który zawiera wymagane funkcje i dołączone pliki nagłówków. } return . i. nIndex < n.m4 można skompilować PHP z obsługą nowych rozszerzeń.c. który służy do tworzenia zbioru szkieletowych plików konfiguracji dla nowych rozszerzeń PHP. double length ) array fin_table ( double principle. który zawiera pliki rozszerzeń wymagane przez PHP. i czas (l) */ void _fin_table ( double p. q = p. double l.return ( p* ( j/( 1 . pIntPmt[nIndex] = h. double l) { return _fin_mpmt( p. double interest. natomiast proto jest nazwą pliku zawierającego prototypy tworzonych funkcji. q. że pliki szkieletowe dołączają parametry o prawidłowych typach. Aby upewnić się. for (nIndex = 0. m = _fin_mpmt( p. c.

if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3. principle = Z_DVAL_PP(principle_arg).6. **length_arg. interest. } /* }}} */ /* {{{ proto array fin_table(double principle. double length) */ PHP_FUNCTION(fin_mpmt) { zval **principle_arg. &interest_arg.<?php if (extension_loaded( "fin_funcs" )) { // Wykonaj jedną z funkcji } else { print( "moduł fin_funcs niedostępny<BR>" ). double aRetVal. Funkcje finansowe dodane do PHP /* {{{ proto double fin_mpmt(double principle. &principle_arg. Należy zauważyć. &length_arg) == FAILURE){ WRONG_PARAM_COUNT. **interest_arg. Wydruk 11. aRetVal = _fin_total( principle. **interest_arg. convert_to_double_ex(length_arg). convert_to_double_ex(interest_arg). length = Z_DVAL_PP(length_arg). interest = Z_DVAL_PP(interest_arg). convert_to_double_ex(length_arg). double interest. &interest_arg. aby zawierał implementację każdej z funkcji. double aRetVal. double length. RETVAL_DOUBLE( aRetVal ). double principle. aRetVal = _fin_mpmt( principle.c. double interest. nIndex. **length_arg. } convert_to_double_ex(principle_arg). We wielu przypadkach wymaga to jedynie dołączenia oryginalnych nagłówków i wywołaniu oryginalnych funkcji. double length. double interest. convert_to_double_ex(interest_arg). double length) */ PHP_FUNCTION(fin_table) { zval **principle_arg. } convert_to_double_ex(principle_arg). if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3. length ). &principle_arg. double principle. 135 PHP – Kompendium wiedzy . **interest_arg. double *pIntPmts. że skrypt build_skel wygenerował większość kodu w ciele każdej funkcji. double principle. Kod dodany ręcznie zaznaczony jest czcionką pogrubioną. length ). W przykładzie z funkcjami finansowymi. RETVAL_DOUBLE( aRetVal ). } ?> Po skonfigurowaniu PHP.6. double length) */ PHP_FUNCTION(fin_total) { zval **principle_arg. double interest. **length_arg. principle = Z_DVAL_PP(principle_arg). interest = Z_DVAL_PP(interest_arg). length = Z_DVAL_PP(length_arg). aby korzystał z nowego rozszerzenia. &length_arg) == FAILURE){ WRONG_PARAM_COUNT. należy jeszcze uaktualnić plik extension. double interest. } /* }}} */ /* {{{ proto double fin_total(double principle. int n. double length. funkcje są zdefiniowane w sposób pokazany na wydruku 11. double interest. interest.

nindex < n. Na wydruku 11. </td> <td> Podstawa </td> <td> Odsetki </td> </tr> <?php $nIndex = 1. if (array_init(return_value)== FAILURE ) { php_error( E_ERROR. Implementacja funkcji fin_table() pokazuje kilka technik ważnych dla programowania dla PHP. natomiast efree() zapewnia. ?> <table border="1"> <tr> <td> Rata nr. $Interest. "</b><br>" ). pIntPmts = emalloc( sizeof( double ) * n ). } convert_to_double_ex(principle_arg). nIndex++ ) add_next_index_double( return_value. convert_to_double_ex(length_arg).7 pokazujemy przykład użycia nowego rozszerzenia.if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3. Wydruk 11. number_format( $aMontlyPayment. przydział pamięci jest przeprowadzany za pomocą funkcji emalloc(). length. $aArray = fin_table( $Amount. "</b><br><br>" ). "</b><br>"). interest = Z_DVAL_PP(interest_arg). $aMontlyPayment = fin_mpmt( $Amount. principle = Z_DVAL_PP(principle_arg). 2 ) . Wymaga to nieco więcej pracy od dwóch pierwszych funkcji. convert_to_double_ex(interest_arg). n = (int)length * 12. wartości z tablicy C są kopiowane do nowej tablicy PHP. } /* }}} */ W pierwszych dwóch funkcjach do implementacji rozszerzenia wymagane było napisanie jednie trzech linii kodu. Na koniec tymczasowa tablica jest niszczona i funkcja się kończy. Użycie funkcji finansowych dodanych do PHP <html> <head> <title>Kalkulator kredytowy</title> </head> <body> <?php if ( $REQUEST_METHOD == 'POST' ) { print( "Kwota pożyczki: <b>" . number_format( $Amount ) . że PHP wykona normalny proces odzyskiwania nieużytków. print( "Suma rat: <b>" . $Interest. pIntPmts ). $Term ). pIntPmts[nIndex]). Po wywołaniu funkcji wbudowanej. jak inne wewnętrzne funkcje PHP. Pierwsza linia jest deklaracją zmiennej. print( "Czas spłaty: <b>$Term lat</b><br><hr>" ). druga wywołuje wewnętrzną funkcję obliczającą wartość a trzecia ustawia zwracaną wartość. mogą być one wywoływane identycznie. number_format( fin_total( $Amount. &interest_arg. Po pierwsze. &length_arg) == FAILURE){ WRONG_PARAM_COUNT. $Term ). Ostania funkcja jest utworzona w taki sposób. aby zwracała tablicę PHP. 2 ) . Po wbudowaniu tych funkcji w PHP.7. } else { for ( nIndex = 0. _fin_table( principle. &principle_arg. "fin_table: nie udało się utworzyć tablicy"). zwracana wartość jest deklarowana przy pomocy wywołania funkcji array_init() jako tablica PHP. Następnie przy pomocy pętli przebiegającej po kolejnych komórkach tablicy i kolejnych wywołań funkcji add_next_index_double(). interest. print( "Oprocentowanie: <b>{$Interest}%</b><br>" ). Rozdział 11 – Ponowne wykorzystanie kodu 136 . print("Rata miesięczna: <b>" . length = Z_DVAL_PP(length_arg). $Interest. ale wyniki tej pracy są znaczące. $Term ). W implementacji fin_table() pamięć jest przydzielana dla tablicy tymczasowej zawierającej wartości wygenerowane przez funkcję C _fin_table(). } efree( pIntPmts ).

5%): </td> <td> <input type="text" name="Interest"> </td> </tr> <tr> <td> Czas spłaty (w latach): </td> <td> <input type="text" name="Term"> </td> </tr> <tr> <td colspan="2"> <input type="submit" name="Submit" value="Wyślij"> </td> </tr> </table> </form> </body> </html> Skrypt ten wyświetla formularz do wprowadzenia danych kredytu.foreach( $aArray as $aIntPmt ) { $aPrinciple = number_format( $aMontlyPayment . oprocentowanie i czas spłaty </td> </tr> <tr> <td> Kwota: </td> <td> <input type="text" name="Amount"> </td> </tr> <tr> <td> Oprocentowanie ("7. 2 ). $aIntPmt = number_format( $aIntPmt. } ?> </table> <?php } ?> <form action="<?=$PHP_SELF?>" method="post"> <table> <tr> <td colspan="2"> To jest prosty kalkulator rat kredytu. pokazany jest fragment strony będącej wynikiem typowego wykonania programu. Po wywołaniu go poprzez wywołanie HTTP POST. Na rysunku 11. Wprowadź kwotę pożyczki. a następnie wysyła je do samego siebie. wywoływane są funkcje finansowe i wyświetlane wyniki ich działania.5" == 7. 2 ). 137 PHP – Kompendium wiedzy .1.$aIntPmt. ?> <tr> <td> <?=$nIndex?> </td> <td> <?=$aPrinciple?> </td> <td> <?=$aIntPmt?> </td> </tr> <?php $nIndex++.

jeżeli masz dużą bibliotekę kodu C/C++ pochodzącą z istniejących aplikacji i zamierzasz przenieść je do środowiska WWW. Możliwość używania klas Javy została wprowadzona w PHP4. Na przykład implementacja bezpiecznych gniazd zapewnia możliwości. aby móc skorzystać z tego potężnego narzędzia. Rozważając integrację istniejącego kodu C/C++ z PHP należy wziąć pod uwagę. jeżeli posiadasz PHP statycznie włączone w Apache.Rysunek 11. Inną możliwością wykorzystania istniejącego kodu C/C++ jest jego skompilowanie i wykonywanie na serwerze WWW poprzez PHP. powoduje to konieczność ciągłej konserwacji istniejącej witryny. Opcja ta działa. Jeżeli serwer Apache nie posiada obsługi dynamicznych modułów. musisz przekompilować PHP w celu dodania obsługi Javy. Rozdział 11 – Ponowne wykorzystanie kodu 138 . „Niezależność od przeglądarki” przedstawiony został opis połączenia Javy z PHP. Zaletą tego rozwiązania jest możliwość ponownego wykorzystania dobrze przetestowanego kodu oraz dobra wydajność skompilowanego kodu. Java W rozdziale 9. W podręczniku PHP znajdziemy. że nie można wykorzystać opcji konfiguracji --with-java. jeżeli PHP jest uruchamiany jako program CGI lub dynamicznie włączany moduł Apache. Dodatkowo kroki podjęte w czasie integracji muszą być w części powtórzone dla każdej nowej wersji PHP. funkcje napisane w C lub C++ mogą realizować funkcje. że koszt integracji może być wyższy od kosztu przepisania kodu na PHP. należy go wcześniej przekompilować. Dodatkowo. oferowanych przez wielu niezależnych dostawców. Przytoczony wcześniej przykład może być łatwo przepisany na PHP i zajmie to mniej czasu. których nie da się napisać wyłącznie w PHP. więc należy przekompilować PHP. Z powodów bezpieczeństwa nie zaleca się korzystania z PHP w postaci CGI.1. dostępne jest wiele klas i modułów klas Javy. Dodawanie obsługi Javy w PHP na *niksach Jeżeli korzystasz z PHP na platformie *nix. Jeżeli zamierzasz zawsze korzystać z najnowszej wersji PHP. PHP posiada prosty mechanizm integracji istniejącego kodu z nowymi aplikacjami. które nie mogą być w chwili obecnej zrealizowane przy pomocy funkcji PHP. Metoda ta zostanie opisana w dalszej części rozdziału. Z powodu popularności Javy. Wykorzystanie nowych funkcji finansowych Jak wspomniano wcześniej. Obsługa Javy nie jest włączona domyślnie do PHP.

/configure --enable-module=so --enable-rule=SHARED_CORE --prefix=/www make make install Po przekompilowaniu Apache można uaktywnić obsługę Javy w PHP za pomocą następującego skryptu. Następnie należy dodać odpowiednio sekcję z opcjami konfiguracji.1.0. który będzie potrzebny do skompilowania PHP.class. Należy również ustawić kilka opcji konfiguracji Javy w pliku php.class. 139 PHP – Kompendium wiedzy . W Windows sekcja ta powinna wyglądać podobnie do następującej: [java] java.net. Należy doda linię ładującą rozszerzenie (extension=php_java. której chcesz używać. Dołączanie obsługi Javy w PHP dla Windows Zamiast kompilowania specjalnej wersji PHP dla Windows.php.path="D:\php4\php_java. Powinieneś sprawdzić która wersja JDK (Java Development Kit) jest zainstalowana na serwerze.jar:/home/blake/php4.jar:/home/blake/bhawk:/home/blake/java/num berspeller. który można załadować z witryny www.library="D:\Program Files\JavaSoft\JRE\1.library.Poniższy skrypt powoduje przekompilowanie Apache tak. że będzie uruchomiony z głównego katalogu instalacji PHP. że będzie on uruchomiony z głównego katalogu instalacji Apache. w pliku php./configure --with-apxs=/www/bin/apxs --with-java . W skrypcie tym zakładamy.2.betabeans.jar.dll" W przypadku systemów *nix. Opcje konfiguracji Javy Niezależnie od platformy. jeżeli obsługa Javy jest aktywna w PHP.ini.de. Po zakończeniu kompilacji można sprawdzić konfigurację PHP za pomocą funkcji phpinfo(). wykorzystanie RTF pozwala użytkownikowi na dostarczanie plików bez niebezpieczeństwa bezpośredniego dodawania kodu HTML do witryny.jar:/home/blake/java/sax2.home="D:\Program Files\JavaSoft\JRE\1.. Funkcja ta może być wykorzystywana we wielu aplikacjach.ini musisz podać lokalizację klas Javy lub plików JAR. Ponieważ RTF obsługuje różne czcionki i układy. make clean .home=/usr/lib/kaffe java.0. musisz dodać kilka opcji konfiguracji do pliku php.library=/www/libexec/libkaffevm. z których można skorzystać za pomocą języka obsługującego API.jar:/home/blake/bhawk/lib/bhawk4j.path=/usr/share/kaffe/Klasses. Następnie należy uaktualnić plik php. Można to zrobić przy pomocy java -showversion. Moduł ten posiada prosty interfejs używany do konwertowania plików RTF na standardowy HTML.dll).dll do katalogu systemowego.path=/usr/lib/kafee:/home/blake/php-4.jar java. Należy to wykonać dla każdej używanej klasy Javy.path zawiera pełną ścieżkę do plików implementacji.class.p12/ext/java/php_java. W Windows 95 jest to zwykle \windows\system a Windows NT \winnt\system32. sekcja ta jest następująca: [java] java. aby korzystał z dynamicznie ładowanych modułów oraz tworzy właściwie skonfigurowany skrypt apxs.ini. Tak jak jest to w przypadku każdego języka umożliwiającego tworzenie komponentów. Zakładamy w nim.so Po skonfigurowaniu obsługi Javy..1p12/modules java. java.ini.jar:/home/blake/java/servlet. dla Javy dostępne jest wiele narzędzi.3" java. rozszerzenie Javy jest dostępne do pobrania z www. Są one kluczowe do prawidłowego działania Javy na każdej platformie.jar" java.so). Należy pobrać odpowiedni plik rozszerzenia i skopiować php_java. Pierwsza jest linia z dołączeniem rozszerzenia (extension=libphp_java. make make install Opcja --with-java może zawierać ścieżkę oznaczającą katalog instalacji używanej maszyny wirtualnej Javy.) którego możemy użyć do sprawdzenia siły i elastyczności modułu. w których użytkownicy mogą wysyłać takie pliki.jar:/home/blake/java/scrooge.3\bin\hotspot\jvm. Jak widać na zamieszczonych opcjach konfiguracji. Pozostałe opcje zostaną omówione później. Moduł Scrooge zawiera przykładowy plik RTF (pokazany na rysunku 11.D:\PHP4 book\other\RTF2HTML\lib\Scrooge_09b7. Jednym z dostępnych komercyjnie modułów Javy jest konwerter RTH na HTML Scrooge. make clean .

} } ?> <FORM METHOD="POST" ACTION="<?=$PHP_SELF?>" enctype="multipart/form-data"> Przesyłanie pliku: <INPUT TYPE="file" NAME="rtffile"><br><br> <INPUT TYPE="submit" NAME="submit" value="Wyślij"> </FORM> </BODY> </HTML> Skrypt ten zawiera formularz przesyłania pliku. W skrypcie z wydruku 11. print( $aOutput ).Scrooge"). $aArray) ). oraz listę dostępnych metod i właściwości.8. Dołączona dokumentacja zawiera nazwę klasy Javy. $aOutput = $aR2H->convert( implode( "". Rozdział 11 – Ponowne wykorzystanie kodu 140 . } else { print ("Wybrany plk nie jest plikiem <b>RTF</b>. Przykładowy plik RTF modułu Scrooge Użycie modułu Scrooge jest łatwe i proste. $sR2H->setOptWrapHTML( False ). za pomocą którego użytkownik może przesłać plik RTF. $aArray = file ( $rtffile ). Użycie modułu Javy Scrooge <HTML> <HEAD> <TITLE>Konwersja RTF na HTML</TITLE> </HEAD> <BODY> <?php if ($REQUEST_METHOD == 'POST' ) { if ( ( $rtffile_type == "text/richtext" ) || ( $rtffile_type == "application/rtf" ) ) { // utworzenie obiektu Scrooge $aR2H = new Java ("de.<BR>").betabeans.2. Wydruk 11.Rysunek 11.scrooge.8 pokazane jest wykorzystanie tego modułu. Po przesłaniu danych formularza sprawdzany jest typ pliku i jeżeli jest prawidłowy tworzony jest obiekt Scrooge.

<br> Użyte <?=$aUsedK?> KB. przedstawiony jest wynik uzyskany z przykładowego pliku RTF. if ( $aProgFile = popen( $aFreeProg . i 11. Implementacja COM w PHP ewoluowała z opartego o funkcje API w wersji 3. $aLines[$nIndex++] = $aLine. $aTotalK = number_format( $aArray[1] ).<br> Wolna pamięć <?=$aFreeK?> KB. tablica jest konwertowana na ciąg. $aArray = split( "[ ]+". Użycie serwera konwersji walut Cloanto <html> <head> <title>Użycie potoków</title> </head> <body> <?php $aFreeProg = '/usr/bin/free'.2]. $aCount = count( $aLines ).<br> <?php } else 141 PHP – Kompendium wiedzy .3. więc nie jest potrzebna dodatkowa konfiguracja. 1024 ). while ( !feof( $aProgFile ) ) { $aLine = fgets( $aProgFile. a następnie używając funkcji implode().5. Wydruk 11. Obiekt ten pozwala na przeliczanie walut pomiędzy sobą i posiada wewnętrzną bazę danych kursów.4. Baza ta jest automatycznie uaktualniana.9. Wynik przetworzenia przykładowego pliku RTF na kod HTML Java jest tylko jednym z języków umożliwiających tworzenie komponentów. Standardowa instalacja PHP dla Windows posiada obsługę COM. dostępny z witryny http://cloanto. $aLines = array().9. pokazują formularz z cenami w dwóch różnych walutach. "r" ) ) { $nIndex = 0. Obiekt ten posiada bogaty zestaw metod. które można wykorzystać w środowisku PHP. $aTotal = $aLines[$aCount . Na wydruku 11. if ( !is_file( $aFreeProg ) ) { print( "Nie można znaleźć programu na serwerze<br>" ). ?> Całkowita ilość dostępnej pamięci <?=$aTotalK?> KB. } else { $aLines = array().Przesłany plik jest odczytywany do tablicy za pomocą funkcji file(). który jest przekazywany do obiektu Scrooge. Zwracaną wartością jest ciąg zawierający kod HTML utworzony na podstawie przesłanego pliku. W części tej omówimy serwer konwersji walut Cloanto Currency Server. zamieszczony jest przykład wykorzystania tego obiektu. Wynikowy kod HTML jest wysyłany do przeglądarki. $aFreeK = number_format( $aArray[3] ). Rysunki 11.3. do implementacji obiektowej w PHP 4. Na rysunku 11. więc dyskusja ta odnosić się będzie do PHP działającego na serwerze pracującym pod kontrolą systemu Windows. " -t". $aTotal ). więc można użyć tego modułu w międzynarodowej aplikacji handlu elektronicznego w celu umożliwienia wyświetlania cen w lokalnej walucie. } pclose( $aProgFile ).com. że użycie COM w PHP jest bardzo naturalne. nie potrafię uruchomić tego przykładu Rysunek 11. Powoduje to. Następna część opisuje użycie obiektów COM w PHP. COM COM jest z natury oparty o Windows. ale bardzo łatwo można użyć podstawowych funkcji w środowisku testowym. $aUsedK = number_format( $aArray[2] ).

która eliminuje frustrujące pomyłki w liczeniu cen. Po przesłaniu danych formularza skrypt wykorzystuje serwer Cloanto do przeliczenia cen na wybraną walutę. Wykorzystując serwer Cloanto wraz z wykrywaniem typu przeglądarki można przeliczać ceny na lokalną walutę bez potrzeby pytania użytkownika o jej nazwę.9. Obiekt ten jest używany do uzyskania listy krajów.5. Przykład użycia serwera Cloanto. Rozdział 11 – Ponowne wykorzystanie kodu 142 . Dodatkowo dostępny jest formularz do wyboru lokalnej waluty.{ print ( "Nie można użyć programu na serwerze<br>" ). współczynników wymiany oraz wykonuje przeliczanie na bieżąco.4. wyświetlana waluta: dolary amerykańskie Rysunek 11. Przykład użycia serwera Cloanto. Jeżeli tworzona jest aplikacja handlu elektronicznego. przy pomocy tego obiektu można dodać niezwykle przydatną dla użytkowników funkcję. utworzona jest prosta tabela cen dla trzech różnych towarów. wyświetlana waluta: forinty węgierskie W skrypcie umieszczonym na wydruku 11. } } ?> </body> </html> Rysunek 11.

Skrypt otwiera potok. } } ?> </body> </html> Skrypt ten otwiera potok do standardowego programu free. if ( !is_file( $aFreeProg ) ) { print( "Nie można znaleźć programu na serwerze<br>" ). Ponieważ tematem tego rozdziału jest integracja. $aTotal ). $aArray = split( "[ ]+". Technika ta może być użyta dla każdego programu. } pclose( $aProgFile ). $aLines[$nIndex++] = $aLine. 1024 ). Skrypt odczytuje z potoku kolejne wiersze wyniku i wyświetla je w przeglądarce.<br> Wolna pamięć <?=$aFreeK?> KB. Na wydruku 11. W zależności od zwracanych danych może być niezbędna bardziej zaawansowana analiza. Inne metody Prawdopodobnie posiadasz istniejący kod. że można w ten sposób użyć nieomal każdej komendy bezpośrednio z PHP – Kompendium wiedzy 143 . dostępne jest wiele komponentów dla wszystkich typów projektów. którego nie da się wykorzystać przy użyciu żadnej z przedstawionych metod. dostępnego na większości systemów *nix. $aLines = array(). $aTotal = $aLines[$aCount .10. pokazany został przykład odczytywania bieżącej ilości użytej pamięci w systemach *nix.2]. Użycie potoków do integracji PHP z istniejącymi skryptami lub programami wykonywalnymi <html> <head> <title>Użycie potoków</title> </head> <body> <?php $aFreeProg = '/usr/bin/free'. Używając obsługi COM w PHP można z łatwością wykorzystać istniejący kod we własnych projektach. nadal można go wykorzystać w PHP. na przykładzie programu whois. } else { $aLines = array(). Jeżeli tak się stanie. najlepszą metodą wykorzystania programów na serwerze będzie skorzystanie z funkcji popen() do uruchamiania programów i skryptów oraz przechwytywania ich wyników. " -t". ale podstawowa idea jest ta sama. PHP posiada kilka funkcji służących do uruchamiania programów i skryptów na serwerze. ?> Całkowita ilość dostępnej pamięci <?=$aTotalK?> KB.Z powodu dużej ilości programistów Windows oraz dojrzałości modelu COM. który powoduje uruchomienie programu. W przypadku systemów Unix oznacza to. Technika ta była przedstawiona w rozdziale 4 „Operacje na plikach”. $aTotalK = number_format( $aArray[1] ). $aFreeK = number_format( $aArray[3] ). da się go zastosować w skrypcie. Wydruk 11.10. $aCount = count( $aLines ). który zwraca wyniki na standardowe wyjście. while ( !feof( $aProgFile ) ) { $aLine = fgets( $aProgFile. if ( $aProgFile = popen( $aFreeProg . Jeżeli kod ten jest skryptem (na przykład skryptem Perla) lub można go skompilować do postaci wykonywalnej. "r" ) ) { $nIndex = 0.<br> Użyte <?=$aUsedK?> KB.<br> <?php } else { print ( "Nie można użyć programu na serwerze<br>" ). $aUsedK = number_format( $aArray[2] ). Program zwraca dane na temat ilości dostępnej pamięci w komputerze.

można znaleźć odpowiednie rozwiązanie. że uruchamianie programów wymaga znacznej ilości zasobów serwera. Pozwala to łatwo zrealizować odczytanie statusu systemu. Seattle: Microsoft Press. można otrzymać aplikację łatwiejsza w konserwacji i skalowaniu. Bibliografia Steve McConnell. Używając tych komponentów można znacznie zmniejszyć czas potrzebny na napisanie programu. Należy jednak zaznaczyć. zwracanie danych lub inne operacje. Z powodu olbrzymiej ilości istniejących komponentów (zarówno COM jak i Javy) może się okazać. że aplikacja będzie powolna i trudna do skalowania. Rozdział 11 – Ponowne wykorzystanie kodu 144 . pozwala to na szybkie prototypowanie. że większość projektowanej aplikacji jest już napisana. Podsumowanie W PHP nie brakuje możliwości ponownego użycia kodu. Jeżeli trzeba przenieść istniejący kod do PHP.PHP. Pozwala to na szybsze rozpoczęcie testowania funkcji aplikacji minimalizując ilość koniecznych prac programistycznych. Rapid Development. Planując tworzenie biblioteki kodu w PHP przeznaczonej do wielokrotnego użytku lub przenosząc istniejący kod do aplikacji WWW. 1996. Używając ich mądrze. co może powodować. przed zastosowaniem wcześniej opisanych metod.

Jeżeli zmiany te są ograniczone do jednej warstwy. warstwa aplikacji (biznesowa) oraz warstwa bazy danych. podczas trwania projektu aplikacji dla WWW mogą pojawić się żądania wprowadzenia zmian. Gdy tworzenie interfejsu i kodu jest rozdzielone pomiędzy zespołami lub osobami. W praktyce nadal jest to trudne. np. 1993).Rozdział 12. które pozwala na łatwiejsze użycie istniejących modułów. programiści tworzą logikę aplikacji a projektanci baz danych projektują i uruchamiają infrastrukturę bazy danych. Wprowadzenie Programowanie dla WWW jest często nazywane tworzeniem aplikacji wielowarstwowej. Programowanie dla WWW. Jedynymi fragmentami tworzonymi przez inne osoby są emblematy. Celem tego rozdziału jest pokazanie sposobów tworzenia aplikacji odpornych na zmiany w późnych stadiach rozwoju. że nie będzie konieczne ponowne kodowanie. Najważniejszym zadaniem przy projektowaniu wielowarstwowym jest logiczne oddzielenie warstw a nie ich fizyczna implementacja. • Możliwość przeniesienia bądź replikacji określonych warstw na inny sprzęt w celu zapewnienia skalowania bądź nadmiarowości. dostępne dla większości programistów. Każda z tych warstw może być fizycznie oddzielona od drugiej. . które mogą być używane w dowolnych aplikacjach. ponieważ stosowane są tutaj oddzielne logiczne warstwy. Na przykład: graficy i projektanci przygotowują stronę graficzną aplikacji. • Możliwość zmian w warstwie bez potrzeby modyfikacji innych. Nawet w małych jednoosobowych projektach oddzielenie HTML od logiki aplikacji powoduje. prawa autorskie lub mogą być modułami kodu. Często używanymi nazwami warstw są: warstwa prezentacji. możliwe jest. Modularność więcej wnosi do łatwości utrzymania aplikacji niż strukturalność i jest najważniejszym czynnikiem zapobiegania konieczności tworzenia poprawek do aplikacji mających za zadanie usuwanie błędów. W programowaniu tradycyjnym projekt modularny jest zwykle postrzegany jako tworzenie modułów kodu. że standardowe aplikacje wykorzystują standardowe narzędzia tworzenia interfejsu użytkownika. Oddzielanie kodu HTML od PHP Wstęp Przy projektowaniu zwykłych aplikacji zwykle nie bierze się pod uwagę oddzielania tworzenia interfejsu użytkownika od tworzenia części wykonawczej programu. ale wiele małych zmian ogranicza się do pojedynczej warstwy. Według badań 89% użytkowników kodu zgłaszało poprawienie możliwości utrzymania aplikacji modularnej. Tak jak w przypadku wszystkich aplikacji. że konserwacja aplikacji jest prostsza i bardziej efektywna. moduły mogą zawierać dane będące częścią interfejsu. a w rozległych testach programiści osiągali o 15% lepsze wyniki pracując nad programem modularnym niż nad niemodularnym (McConnell. Dodatkowo oddzielenie interfejsu użytkownika od logiki aplikacji jest jedną z technik programowania modularnego. rysunki przycisków i podobne elementy wpływające na graficzny wygląd produktu. W przypadku projektowania dla WWW. pozwala na zastosowanie o wiele bogatszego interfejsu użytkownika i przez to bardzo często wymaga zatrudnienia projektantów specjalizujących się w tworzeniu strony graficznej aplikacji. oddzielenie kodu i HTML staje się naturalne a integracja wyników pracy ważna. Jest to spowodowane tym. Głównymi zaletami podejścia wielowarstwowego przy tworzeniu aplikacji WWW są: • Możliwość przydzielenia zadań osobom najlepiej przygotowanym do ich realizacji.

Dodatkowo w tym rozdziale jak również w rozdziale 14 „Witryny oparte o szablony”. ale również procedury przechowywane w bazie danych. Dla przykładu. W książce A Methodology for Client/Server and Web Application Development Roger Fournier sugeruje. oddzielenie modułów kodu od modułów interfejsu może być zrealizowane bezpośrednio przy pomocy narzędzi języka. Rozdział 12 – Oddzielanie kodu HTML od PHP 146 . } else { $aSQL = "SELECT * FROM Answers WHERE (QuestionID=$aQuestionID)". Motywacja Pierwszą motywacją dla oddzielenia elementów HTML od kodu jest umożliwienie ponownego wykorzystania kodu oraz jego łatwiejszej konserwacji. 1998). ale w efekcie można otrzymać aplikację łatwiejszą do zrozumienia i konserwacji. dołączone są kompletne przykłady zastosowania tych technik.php3" method="POST"> <?php if (!empty( $UserID )) { ?> <input type="Hidden" name="UserID" value="<?php print($aUserID ). } $aDB->SetSQL( $aSQL ). tworzone i testowane a następnie udostępniane dla całej korporacji. Niektóre przykłady w kolejnych częściach pokazują techniki jakich należy unikać. Część ta opisuje kilka sposobów zrealizowania tego zadania. ?> </b> <form action="response.1. W kolejnych częściach zostanie opisane kilka metod implementacji tych metod. W przypadku tworzenia kodu prawdziwego kodu technika ta jest niewygodna i powoduje powstanie trudnych do analizy skryptów.Jak wspomniano w poprzednim rozdziale. PHP i HTML w jednym skrypcie <?php if ( $aShowForm == True ) { ?> <p> <font face="Arial" size="3"> <b> <?php print( $aQuestion ). wyzwalacze i zdalne procedury (Fournier. Wydruk 12.1 zawiera fragment strony WWW ze zintegrowanym kodem PHP i HTML. Oddzielenie i integracja przy użyciu wbudowanych funkcji PHP Ponieważ PHP zawiera bogaty zestaw funkcji i narzędzi. HTML i PHP były wymieszane w celu otrzymania krótkich i prostych przykładów. Komponenty te powinny zawierać nie tylko moduły kodu. że wspólne fragmenty lub moduły aplikacji zawsze powinny być najpierw projektowane. skrypt z wydruku 12. W wszystkich przykładach umieszczonych do tej pory w książce. tworzenie aplikacji modularnej wymaga dodatkowych prac projektowych i podjęcia odpowiednich decyzji. ?>"> <?php } ?> <ul> <font face="Arial" size="2"> <!--wyświetl możliwe odpowiedzi--> <?php if ( $aQuestionID != -1 ) { if ($aSortOrd != 0 ) //Sortowanie alfabetyczne { $aSQL = "SELECT * FROM Answers WHERE (QuestionID=$aQuestionID) ORDER BY Text". ?>"> <?php } ?> <?php if ($aQuestionID != -1 ) { ?> <input type="Hidden" name="QuestionID" value="<?php print($aQuestionID ).

Fragment z nagłówkiem HTML require().Oprócz tego. jak i wyglądu strony bez wpływania na inne elementy. aby nie popsuć kodu podczas wprowadzania zmian. że projektanci uaktualnią wygląd przycisków nawigacji i muszą być one umieszczone w witrynie.4 pokazano sposób integracji tych segmentów z dynamicznie tworzonym fragmentem strony. Wydruk 12. Problemy z utrzymaniem tego typu skryptów wykraczają jednak poza podstawowe problemy z czytelnością kodu.2. zlokalizowanie bloków kodu może być trudne. Na wydruku 12.jpg" width="250" height="68" alt="" border="0"> <h1>Nowości wydawnictwa Helion</h1> Mimo. Wydruk 12. 147 PHP – Kompendium wiedzy . Teraz zostaną zademonstrowane dostępne w PHP metody integrowania oddzielnych modułów kodu i projektu. a programiści mogą być zmuszeni uaktualniać fragmenty kodu jedynie w celu zmiany wyglądu. W obu przypadkach wynikiem są opóźnienia w projekcie. jeżeli zainwestowano w projekt interfejsu.0 Transitional//EN"> <html> <head> <title>Nowe książki wydawnictwa Helion</title> </head> <body> <img src="logo. jest to bardzo prosty przykład.3. które są używane przez moduły kodu PHP w czasie ich wykonywania. </p> </body> </html> Wydruk 12.2 i 12.0 Transitional//EN"> <html> <head> <title>Nowe książki wydawnictwa Helion</title> </head> <body> <img src="logo. załóżmy. pokazuje on w jaki sposób można użyć funkcji include() w celu integracji HTML i kodu. Nawet pomocą edytorów wyróżniających składnię. Dodatkowo.jpg" width="622" height="106" alt="" border="0"> <h1>Nowości wydawnictwa Helion</h1> Wydruk 12. co ułatwia tworzenie efektywnych i łatwych do modyfikacji aplikacji. Jeżeli twoja firma zamierza dostarczać wysokiej jakości i łatwe do konserwacji aplikacje WWW. 2001 Helion. Na przykład. Można tego uniknąć stosując lepsze praktyki projektowe.1 pokazuje jak skomplikowana może stać się strona HTML z wbudowanym PHP. Równie trudno jest wprowadzać zmiany zarówno do kodu. tworzenie stron za pomocą przedstawionej metody nie powinno być stosowane.4. Implementacja Najprostsza metodą integracji osobnych modułów jest wykorzystanie funkcji PHP include() lub Metoda ta wymaga umieszczenia elementów projektu HTML w osobnych plikach. nie należy tego marnować tworząc aplikację utrudniającą wprowadzanie prostych zmian. Wszystkie prawa zastrzeżone. Przykład ten pokazuje wartość oddzielenia kodu od HTML.3 umieszczone są fragmenty projektu strony rozdzielonej na nagłówek i stopkę. Jeżeli projekt nagłówka lub stopki ulegnie modyfikacji. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4. należy zmienić jedynie pliki HTML. Odpowiedź na pytanie kto powinien wprowadzić zmiany jest trudna. Na wydruku 12. ponieważ projektanci mogą nie mieć wystarczająco dużo doświadczenia. Skrypt łączący kod z projektem <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4. Fragment ze stopką HTML <br><br><br> <hr> <p> &copy. że przykład jest niekompletny.1 pokazany jest wygląd wynikowej strony w przeglądarce. Na przykład na wydruku 12.

Użycie własnych funkcji dołączania plików pozwala na to.6. można również wykorzystać standardowe funkcje obsługi plików dostępne w PHP w celu odczytania plików HTML i dołączenia ich do strony.5. Metoda ta pozwala na większą kontrolę nad obsługą plików.5. Stopka HTML <p class="copyright"> &copy.0 Transitional//EN"> <html> <head> <title>Nowe książki wydawnictwa Helion</title> <link rel="STYLESHEET" type="text/css" href="css1. Dla celów tej demonstracji utworzone zostały dwa osobne pliki CSS.7. Łączenie HTML i kodu PHP przy użyciu include() Zamiast funkcji include() lub reqiure().jpg" width="622" height="106" alt="" border="0"> <h1>Nowości wydawnictwa Helion</h1> Wydruk 12.1. natomiast na wydruku 12. Dodatkowo użyte zostały kaskadowe arkusze stylów (CSS) w celu zapewnienia większych możliwości zmiany wyglądu strony. Rozdział 12 – Oddzielanie kodu HTML od PHP 148 . } $aFileArray = file( $aFileName ). Nagłówek HTML <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4. Wszystkie prawa zastrzeżone. aby w plikach HTML nie było żadnego kodu PHP.7 znajduje się warstwa logiczna strony. w tym odszukiwanie plików i obsługę błędów.Rysunek 12. Na wydruku 12. Wydruk 12. Kolejne wydruki zawierają bardziej szczegółowy przykład wykorzystania poprzedniej techniki wykorzystując funkcje obsługi plików zamiast funkcji include(). 2001 Helion. Skrypt aplikacji PHP <?php function MyIncludeFile( $aFileName ) { if ( !is_file( $aFileName ) ) { // przekierunkowanie na stronę błędu exit. </p> </body> </html> Wydruk 12.6. i 12. ponownie jest umieszczony nagłówek i stopka. foreach( $aFileArray as $aLine ) { print( "$aLine" ).css"> </head> <body> <img src="logo.

"<p>$aSynopsis</p>" ). var $Database = "mydb". var $User = "root". i 12.html" ). } // Tworzenie obiektu klasy news_db i odczytanie wiadomości $aDB = new news_db.inc" ).</a>" ). var $Password = "root". ?> "<h2>$aTitle</h2>" ).html" ). Aplikacja ta wykorzystuje małą bazę danych do przechowywania tekstów wiadomości. że w tekście strony PHP znajduje się kilka podstawowych znaczników HTML. Mimo. Dodatkowo ważna jest elastyczność rozwiązania wykorzystującego pliki CSS.} } MyIncludeFile( ". "<br><br><hr>" ). Tak jak w poprzednich przykładach./db_mysql.. $aSynopsis = $aDB->f( "synopsis" ). "<h4>autor: $aAuthor</h4>" ). include( ". ich użycie jest ograniczone a sposób ich interpretacji jest kontrolowany przez CSS. $aDB->query( "select * from news order by date desc limit 5" ). "<a href=\"full_story.phtml?news_id=$aNewsID\">pełny tekst./header_2. $aTitle = $aDB->f( "title" ). Wygląd kompletnej strony jest pokazany na rysunkach 12. $aAuthor = $aDB->f( "author" ).. print( print( print( print( print( } MyIncludeFile( "./footer_2. Zawartość i struktura bazy danych nie jest istotna. ponieważ jest to przykład rozdzielania kodu oraz technik jego integracji. // tworzenie klasy news_db class służące do odczytu wiadomości class news_db extends DB_Sql { var $Host = "localhost".3. 149 PHP – Kompendium wiedzy .2. w przykładzie tym wykorzystane są klasy obsługi baz danych PHPLIB. while( $aDB->next_record() ) { $aNewsID = $aDB->f( "news_id" ).

2.Rysunek 12. Przykłado wa aplikacja z pierwszym arkuszem stylów Rozdział 12 – Oddzielanie kodu HTML od PHP 150 .

podział odpowiedzialności pomiędzy projektantami i programistami oraz ułatwiają konserwację aplikacji. Przykłado wa aplikacja z pierwszym arkuszem stylów Czego należy unikać Korzystając z tej metody należy unikać mieszania kodu programu i HTML. który generuje kod HTML.Rysunek 12. 151 PHP – Kompendium wiedzy . że za zmiany projektu witryny odpowiada programista PHP.3. Również jeżeli przesyłany jest identyfikator sesji lub inny identyfikator specyficzny dla aplikacji. które nie spełniają prawdziwych potrzeb. powoduje to. Czasami programiści przesadzają w swoim zapale pisania kodu i tworzą mechanizmy. Należy unikać kodu PHP. trzeba dynamicznie generować wszystkie łącza. a dołączane pliki PHP — jedynie kod PHP. Utrudnia to również wprowadzanie hurtowych zmian w wyglądzie całej witryny WWW. niezbędne będzie dołączenie części znaczników HTML do kodu PHP. Celem oddzielenia HTML od PHP jest uproszczenie aplikacji. Celem oddzielenia HTML od PHP może być całkowite oddzielenie projektu od logiki aplikacji. na przykład może być to generowany dynamicznie znacznik łącza. Choć pozwala to na pisanie kodu PHP nie zawierającego znaczników HTML. Jednak czasami trzeba dynamicznie wygenerować niektóre znaczniki HTML. Ułatwia to rozdzielenie odpowiedzialności programistów PHP i projektantów interfejsu. Podsumowanie: Oddzielanie i integracja przy wykorzystaniu funkcji PHP Tworząc mechanizm oddzielania kodu PHP od HTML należy pamiętać o najważniejszych celach takiego działania. Używając przedstawionych technik i wykorzystując przy projektowaniu pliki CSS. cel ten jest nieomal osiągnięty. Dołączane pliki HTML powinny zawierać jedynie kod HTML. W tych przypadkach jeżeli wykorzystywana będzie opisana technika integracji.

Utworzenie obiektu klasy FastTemplate. Użycie metody assign() do skojarzenia wartości do zmiennych szablonu. BODY_COLOR. cała warstwa projektu interfejsu aplikacji może być modyfikowana niezależnie od logiki aplikacji. $aBodyText = "Bardzo krótka zawartość strony. Przykładowy plik szablonu znajduje się na wydruku 12.0 Transitional//EN"> <html> <head> <title>{TITLE}</title> </head> <body bgcolor="{BODY_COLOR}"> {BODY} <hr> <font size="1"> {COPYRIGHT} </font> </body> </html> Przykładowy szablon pokazany na wydruku 12. W prostych aplikacjach plik szablonu może być wykorzystywany dla wszystkich stron witryny. } ".W następnej części zatytułowanej „Wykorzystanie systemu szablonów” opisuję szczegóły metody umożliwiającej całkowite oddzielenie kodu PHP od HTML. Jest to zalecana metoda. Przykładowy szablon FastTemplate <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.net. Tak jak przy wszystkich dotychczasowych technikach projektowania. Uruchomienie metody parse() do przetworzenia pliki szablonu i przypisania wartości do zmiennych. które można załadować z witryny www. Podstawowym założeniem jest podział strony na jeden lub więcej szablonów projektowych.9. for ( $nIndex = 1.thewebmasters. $aTemplate = new FastTemplate( ". Użycie metody define() do przydzielenia plikom szablonów unikalnych nazw. FastTemplate Mimo." ). $nIndex++ ) { $aBodyText . FastTemplate jest łatwy do użycia i istnieje specjalna dokumentacja dla początkujących. zmienne te mogą być ustawione bezpośrednio z kodu. że każdy może zbudować własny system szablonów.tpl' ) ).8. BODY i COPYRIGHT. Wydruk 12. 2. W szablonach FastTemplate zmienne są umieszczane w nawiasach klamrowych ({}).8. W najprostszym przypadku.php" ). które są łączone z dynamiczną zawartością generowaną przez kod PHP. aby osiągnąć zamierzony wynik wykorzystując szablony. Użycie metod FastPrint() lub fetch() do wypisania lub odczytania przetworzonego pliku szablonu.FastTemplate. Wykorzystanie systemu szablonów System szablonów jest mechanizmem przeznaczonym do całkowitego oddzielenia elementów projektu HTML od kodu PHP.8 zawiera cztery zmienne FastTemplate: TITLE. W bardziej skomplikowanych. $aTemplate->define( array( 'basic' => 'sample_1.9.= "$nIndex ". 5. w sposób pokazany na wydruku 12. 3. Rozdział 12 – Oddzielanie kodu HTML od PHP 152 . 4. Oczywistą zaletą wykorzystania szablonów jest umożliwienie doświadczonym projektantom HTML na całkowite panowanie nad wszystkimi aspektami projektu. Aby rozpocząć pracę z FastTemplate należy utworzyć plik szablonu. dostępne jest świetne narzędzie o nazwie FastNet. Wydruk 12. ponieważ cały HTML może być pod opieką projektantów. Następnie w kodzie należy wykonać następujące kroki: 1. Gdy wszystkie znaczniki HTML zostaną usunięte z kodu. $nIndex <= 10. zwykle z rozszerzeniem tpl. może być użyte bardzo wiele szablonów. wymagane są dodatkowe prace projektowe oraz skuteczne wprowadzenia ich w życie. Skrypt aplikacji <?php include( "class.

$aTemplate->FastPrint( 'PAGE' ).phtml">początek</a><br><br> <a href="about.phtml">o nas</a><br><br> <a href="links. wszystkie prawa zastrzeżone' ) ). zmiennym FastTemplate przypisywane są wartości. a następnie jej zawartość wysyłana jest do przeglądarki. Rysunek 12. Wynik przetwarzania prostego szablonu Po przetworzeniu szablonu przez obiekt FastTemplate. Następnie plikowi umieszczonemu na wydruku 12. ?> Pierwszym krokiem jest utworzenie obiektu klasy FastTemplate. W kilku kolejnych liniach generowany i zapamiętywany jest również test strony oraz wykorzystując metodę assign(). oraz główny plik szablonu zamieszczone odpowiednio na wydrukach 10 i 11. muszą im zostać przypisane wartości. $aTemplate->parse( 'PAGE'.4.Panel nawigacji --> <a href="index. Wydruk 12. Główny plik szablonu (body. wygenerowane zostaną następujące ostrzeżenia: [Wed Sep 12 19:42:38 2001] [error] [FastTemplate] Warning: no value found for variable: {PAGE_HEADER} [Wed Sep 12 19:42:38 2001] [error] [FastTemplate] Warning: no value found for variable: {PAGE_CONTENT} [Wed Sep 12 19:42:38 2001] [error] [FastTemplate] Warning: no value found for variable: {YEARS} 153 PHP – Kompendium wiedzy .4. zawierają swoje zmienne FastTemplate i aby szablony działały prawidłowo. W naszym przykładzie został wykorzystany bieżący katalog „. wynik jest zapisany w zmiennej. Wynik pokazany jest na rysunku 12. Konstruktor wymaga jednego argumentu — ścieżki do pliku szablonu. Nowymi plikami są: plik z danymi o prawach autorskich.$aTemplate->assign( array( 'TITLE' => 'Prosty przykład'. 'basic' ).Główna sekcja tekstu --> {PAGE_CONTENT} </td> <td width="125" valign="top"> <!-.10.8 zostaje nadana nazwa basic. 'BODY' => $aBodyText. która może zostać wydrukowana lub zachowana dla innych celów. Szablon z prawami autorskimi (copyright.tpl) <table width="100%"> <tr> <th colspan="3"> {PAGE_HEADER} </th> </tr> <tr> <td colspan="3"> &nbsp.tpl) &copy. lub zmienna ta może być użyta w kolejnym szablonie.Tutaj reklamy i inne --> </td> </tr> </table> Każdy z dodatkowych plików szablonów. </td> </tr> <tr> <td align="center" valign="top"> <!-.”. Dodatkowe informacje na temat praw autorskich mozna znaleźć <a href="legal. Na koniec Szablon jest przetwarzany i zapamiętywany w zmiennej PAGE. Wydruk 12. Wszystkie prawa zastrzeżone. 'BODY_COLOR' => 'white'.phtml">łącza</a><br><br> </td> <td width="90%" valign="top"> <!-. Jeżeli nie zostanie przypisana zmienna FastTemplate.11. które zostały do tej pory pokazane. {YEARS} Helion.phtml">tutaj</a>. 'COPYRIGHT' => 'Helion 2001. Ostatnia opcja pozwala na zagnieżdżanie plików szablonów.

FastTemplate.= "$nIndex ". $aTemplate->FastPrint( 'PAGE' ). zmiennym tym należy przypisać wartości. $aYears = "$aStartYear".tpl'. => => => => => 'Lepszy przykład'. $aTemplate->parse( 'PAGE'.12. $aNowYear = $aNow["year"]. $nIndex". Rozdział 12 – Oddzielanie kodu HTML od PHP 154 . $aBodyText $aTemplate->parse( 'BODY'. $aTemplate->define( array( 'basic' 'copyright' 'body' => 'sample_1. Wartość zmiennej YEARS jest generowana automatycznie.tpl'. ?> W przykładzie tym zdefiniowano dwa dodatkowe pliki szablonów nadając im nazwy copyright i body. => 'body. $nIndex <= $aCurrentYear. return $aNowYear. 'copyright' ). Zamiast tego zmienne te otrzymują wartości przy wywołaniu metody parse() na końcu tego skryptu. $aYears. że w tym rozdziale zmienne BODY i COPYRIGHT nie są ustawiane w metodzie assign().tpl' ) ).5. } $aTemplate = new FastTemplate( "." ).Dodając nowe pliki szablonów należy również zmienić główny plik PHP. Należy zauważyć. $nIndex++ ) { $aBodyText . 'Lepszy przykład'. 'basic' ). Wynik działania tego skryptu jest pokazany na rysunku 12. $aCurrentYear = GetCurrentYear(). } $aTemplate->assign( array( 'TITLE' 'BODY_COLOR' 'YEARS' 'PAGE_HEADER' 'PAGE_CONTENT' ) ). for ( $nIndex = $aStartYear + 1. ". $aBodyText = "Bardzo krótka zawartość strony. $nIndex++ ) { $aYears . } $aStartYear = 1997.php" ). Zagnieżdżone pliki szablonów <?php include( "class. Ponieważ te pliki szablonów zawierają własne zmienne FastTemplate. 'body' ). function GetCurrentYear( ) { $aNow = getdate(). $nIndex <= 10.12 pokazany jest nowy skrypt PHP używający zagnieżdżonych szablonów. Wydruk 12. Na wydruku 12. for ( $nIndex = 1. $aTemplate->parse( 'COPYRIGHT'. więc dane o prawach autorskich są zawsze aktualne.= ". 'white'. => 'copyright. Zmienna $aBodyText posiada identyczną wartość jak w poprzednim przykładzie.

jpg" width="250" height="68" alt="" border="0"> <h1>Nowości wydawnictwa Helion</h1> </td> </tr> <tr> <td> <br><br> {NEWS_ITEMS} </td> </tr> <tr> <td> <br> <p class="copyright"> {COPYRIGHT} </p> </td> </tr> </table> </body> Wydruk 12. w kodzie tym wykorzystana zostanie siła klasy FastTemplate.. zamieszczony jest skrypt generujący stronę z nowościami. wykorzystany w poprzednim przykładzie. Szablon elementu wiadomości (ft_news_item.15. Na wydrukach 12.13.15 umieszczony jest kod HTML szablonów tworzących podstawowy układ strony. W przykładzie tym użyty jest szablon zawierający prawa autorskie. 12. za pomocą którego można tworzyć bogate i złożone projekty interfejsu. Aby lepiej zilustrować tą technikę w kolejnym przykładzie wrócimy do przykładu aplikacji dostarczającej najnowszych wiadomości. 155 PHP – Kompendium wiedzy .css"> </head> {NEWS_BODY} </html> Wydruk 12.0 Transitional//EN"> <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="css2.14 i 12.tpl) <body> <table width="640" border="0" align="center"> <tr> <td> <img src="logo.13. ale większość kodu pochodzi z poprzednich przykładów.. Wynik działania zagnieżdżonych szablonów FastTemplate Klasa FastTemplate jest potężnym narzędziem.14. Podstawowy szablon dla aplikacji dostarczającej wiadomości (ft_news_base.</a> <br><br><hr> Na wydruku 12. Szablon treści w aplikacji wiadomości (ft_news_body. Wydruk 12. Skrypt ten jest bardziej skomplikowany niż w poprzednim przykładzie. Zamiast wykorzystywać do tego celu pliki dołączane.tpl) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.5.tpl) <h2>{NEWS_TITLE}</h2> <h4>autor: {NEWS_AUTHOR}</h4> <p>{NEWS_SYNOPSIS}</p> <a href="{FULL_STORY_URL}">więcej.Rysunek 12. treść i element wiadomości.16.

$aTemplate->parse( "NEWS_BODY"." ). $aDB->query( "select * from news order by date desc limit 5" ).inc" ). ponieważ ostrzeżenie generowane przez FastTemplate zostaną omówione później. ?> => => => => $aTitle. $aTitle = $aDB->f( "title" ). var $User = "root".16. } $aTemplate = new FastTemplate( ". $aYears = "$aStartYear". } // Tworzenie klasy news_db do pobrania wiadomości class news_db extends DB_Sql { var $Host = "localhost". "base" ). $aCurrentYear = GetCurrentYear(). // Tworzenie obiektu klasy news_db i generowanie elementów wiadomości $aDB = new news_db.FastTemplate. $aSynopsis. include( ". $aURL ) ). => "Nowości wydawnictwa Helion" ) ). var $Password = "root". a obsługa bazy danych z poprzedniej realizacji aplikacji wiadomości. YEARS i TITLE reprezentujące odpowiednio rok praw autorskich i tytuł strony. error_reporting( E_ALL & ~E_NOTICE ).Wydruk 12.php" ).= ". Rozdział 12 – Oddzielanie kodu HTML od PHP 156 . $nIndex++ ) { $aYears . że na początku skryptu wyłączone zostały ostrzeżenia PHP. Zauważmy.tpl". "copyright.tpl" ) ). // generowanie roku dla treści praw autorskich $aStartYear = 1997. "ft_news_item. $aTemplate->parse( "BASE"./db_mysql. $aAuthor. "copyright" ). $aAuthor = $aDB->f( "author" ). W przykładzie tym funkcja generująca rok dla tekstu o prawach autorskich pochodzi z poprzednich przykładów. $aSynopsis = $aDB->f( "synopsis" ). } $aTemplate->assign( array( "YEARS" "TITLE" => $aYears. Na początku skryptu inicjowane są dwie główne zmienne FastTemplate. function GetCurrentYear( ) { $aNow = getdate(). Kolejną główną funkcją skryptu jest dynamiczne dodawanie kolejnych wiadomości. while( $aDB->next_record() ) { $aNewsID = $aDB->f( "news_id" ). $aTemplate->assign( array( "NEWS_TITLE" "NEWS_AUTHOR" "NEWS_SYNOPSIS" "FULL_STORY_URL" $aTemplate->parse( "NEWS_ITEMS". ". return $aNowYear. $aTemplate->FastPrint( "BASE" ). W każdym przebiegu pętli przetwarzany jest szablon item i dodawany do zmiennej FastTemplate NEWS_ITEMS. $aTemplate->define( array( "base" "body" "item" "copyright" => => => => "ft_news_base. $nIndex".phtml?news_id=$aNewsID".tpl". $nIndex <= $aCurrentYear. Zostało to zrealizowane przez pobranie pięciu najnowszych wiadomości z bazy danych i wypisanie ich przy pomocy pętli. W skrypcie tym zdefiniowane zostały cztery pliki szablonów. var $Database = "mydb".item" ). $aNowYear = $aNow["year"]. $aURL = "full_story. "ft_news_body. } $aTemplate->parse( "COPYRIGHT". "body" ). for ( $nIndex = $aStartYear + 1. Główny skrypt aplikacji <?php include( "class.tpl".

że zmienna NEWS_ITEMS nie jest zainicjowana. powinno być w tym momencie dosyć oczywiste. że wykorzystanie systemu szablonów wymaga nieco innego myślenia w trakcie projektowania. Szablon nawigacji <?php include( "class. 'navi' ). Zaawansowane techniki użycia FastTemplate W poprzednich rozdziałach dwa zagadnienia były z rozmysłem odsuwane aż do tego rozdziału.tpl) <a href="{HREF_INDEX}">początek</a> <a href="{HREF_NEWS}">nowości</a> <a href="{HREF_LINKS}">łącza</a> Właściwe adresy URL dla łączy mogą być tak generowane. } $aTemplate = new FastTemplate( ".phtml'. Pierwsze zostało wspomniane w rozdziale 7. 'HREF_LINKS' => MyGenURL( 'HREF_LINKS' ) ) ). że system szablonów może być alternatywną metodą dostarczania zawartości zależnej od typu przeglądarki. Wydruk 12. ?> 157 PHP – Kompendium wiedzy .18. } return $aBaseURL .FastTemplate. takich jak treść kolejnych wiadomości.18 zamieszczony jest skrypt generujący dynamiczne adresy URL dla poprzedniego szablonu. break. że elementy projektu strony mogą być tworzone i zmieniane niezależnie od kodu aplikacji. case 'HREF_LINKS' : $aBaseURL = 'links.phtml'. „Sesje i stan aplikacji”. default : $aBaseURL = 'badlink. Na wydruku 12. Po poznaniu podstawowych założeń używanie FastTemplate staje się niezwykle naturalne.) przed nazwą szablonu. break. gdzie znalazła się sugestia.phtml'. break. Wydruk 12. Wykorzystując szablony projekt może zawierać dynamiczne łącza URL generowane w kodzie PHP.php" ). w którym mówiono o lepszych sposobach przenoszenia identyfikatora sesji w aplikacji.phtml'. Poprzedni przykład pokazuje w jaki sposób można wykorzystać klasę FastTemplate do generowania powtarzających się elementów. Inną zaletą wykorzystania takich adresów jest łatwa modyfikacja położenia stron w czasie pracy aplikacji. case 'HREF_NEWS' : $aBaseURL = 'news. Po ustawieniu w pętli wartości zmiennej NEWS_ITEMS przetwarzana jest reszta szablonów a następnie drukowana strona. $aTemplate->parse( 'NAVI'.17. Drugie znalazło się w rozdziale 9." ). function MyGenURL( $aLinkName ) { switch( $aLinkName ) { case 'HREF_INDEX' : $aBaseURL = 'index.Dodawanie to jest zrealizowane poprzez dodanie kropki (. $aTemplate->assign( array( 'HREF_INDEX' => MyGenURL( 'HREF_INDEX' ). $aTemplate->define( array( 'navi' => 'navi. break.17. Dlatego właśnie w pierwszym przebiegu pętli FastTemplate generuje ostrzeżenie wskazujące. Oczywistą zaletą klasy FastTemplate jak również innych systemów szablonów jest to. Szablon nawigacji (navi. przesyłanie identyfikatora sesji. Mimo. session_start(). session_name() . $aTemplate->FastPrint( 'NAVI' ). lub inny specyficzny dla aplikacji. W tej części skupimy się na tych dwóch zagadnieniach. 'HREF_NEWS' => MyGenURL( 'HREF_NEWS' ). „Niezależność od przeglądarki”. jest ono warte zainteresowania. session_id(). Podobna konstrukcja może być wykorzystana do tworzenia wierszy tablicy lub listy łączy.tpl' ) ). aby zawierały identyfikator sesji. "=" . Pierwsze zagadnienie. Podstawowy przykład szablonu nawigacyjnego zamieszczony jest na wydruku 12.

com/shockwave/download/index.com/pub/shockwave/cabs/flash/swflash.0" WIDTH=320 HEIGHT=240> <PARAM NAME=movie VALUE="flash_menu.swf"> <PARAM NAME=quality VALUE=high> <PARAM NAME=bgcolor VALUE=#FFFFFF> <EMBED src="Track As Menu. $aTemplate->FastPrint( "BASE" ). $aTemplate->parse( "NAVI".21. Menu HTML (html_menu. Pozwala to unikać brzydkich komunikatów „HTTP 404: Page Not Found” spotykanych we wielu aplikacjach WWW. w jaki sposób można umieszczać na stronie menu zrealizowane w programie Macromedia FlashTM.21. $aTemplate->assign(array("TITLE" => "Przykład działania zależnego od przeglądarki")). ?> Przykład ten pokazuje.tpl".tpl) <OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download. Problemem z przekierowaniem jest to. W rozdziale 9.php" ). "base" ). pokazany jest główny szablon strony.phtml">początek</a> <a href="news.tpl) <a href="index.0 Transitional//EN"> <html> <head> <title>{TITLE}</title> </head> <body> {NAVI} </body> </html> Wydruk 12.0. if ( $aHasFlash == True ) { $aNaviFile = "flash_menu.FastTemplate.cab#version=5.macromedia.0. Wydruk 12.. natomiast wydruk 12. Rozdział 12 – Oddzielanie kodu HTML od PHP 158 .20.22 zawiera skrypt PHP. Przykład umieszczony na wydrukach 19. Oczywiście powinna zostać wykorzystana prawdziwa funkcja wykrywająca. "navi" ). Pobiera ona symboliczną nazwę łącza i zwraca prawdziwą lokalizację strony wraz z dołączonymi danymi sesji.phtml">łącza</a> Wydruk 12.macromedia.tpl".19. Skrypt <?php include( "class. Wydruk 12. podobna do tej zamieszczonej na witrynie firmy Macromedia. "base" => "base_basic. Funkcja taka ma dodatkową możliwość obsługi nieznanych nazw łączy. pokazuje w jaki sposób można zintegrować treści zależne od typu przeglądarki z szablonami. to strony zależne od możliwości przeglądarki. $aTemplate->define( array( "navi" => $aNaviFile.Funkcja MyGenURL() jest głównym elementem skryptu. gdy używana przeglądarka potrafi je wyświetlić i zwykłe menu HTML w przypadku korzystania z innych przeglądarek. że użytkownik może wysłać łącze do strony do osoby używającej innej przeglądarki.19.phtml">wiadomości</a> <a href="links. Podstawowy szablon strony (base_basic. i 12.tpl) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4. że zmienna $aHasFlash jest ustawiana przez // prawdziwą funkcję wykrywania Flash-a $aHasFlash = False. Używając szablonów preferowana jest pierwsza metoda.. Na wydruku 12. $aTemplate->parse( "BASE". W oparciu o specyficzne potrzeby witryny można pomysłowo rozdzielać wiele aspektów projektu w zależności od możliwości używanej przeglądarki i wykorzystać system szablonów do dostarczenia najlepszej zawartości dla każdej z przeglądarek. i 22. Menu oparte o Flash (flash_menu. } $aTemplate = new FastTemplate( ". Wykorzystanie szablonów do dostarczania treści zależnych od przeglądarki również jest korzystne.swf" quality=high bgcolor=#FFFFFF WIDTH=320 HEIGHT=240 TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www. 20." ).tpl" ) ).20. zasugerowane były metody warunkowego dołączania plików lub przekierowania użytkownika do katalogu odpowiadającego używanej przeglądarce. 21.22.cgi?P1_Prod_Version=ShockwaveFlash"></EMBED> Wydruk 12. // zakładamy. } else { $aNaviFile = "html_menu.

rozdział ten ma podłoże czysto osobiste. ponieważ warstwa prezentacji jest odpowiedniej jakości a ja nie muszę jej tworzyć ani zmieniać samemu. więc w mojej firmie poświęciłem sporo czasu na znalezienie sposobu na dołączenie projektów profesjonalnych projektantów z moimi aplikacjami. Wykorzystuję klasę FastTemplate w nieomal wszystkich moich obecnych projektach. Seattle: Microsoft Press.Podsumowanie Oddzielanie elementów projektu aplikacji WWW od jej logiki powoduje promowanie projektowania modularnego i dzięki temu zwiększenie możliwości ponownego wykorzystania kodu oraz jego łatwiejszej konserwacji. że nigdy nie będę projektantem graficznym ani artystą. Code Complete. Bibliografia Roger Fournier. Pozwala to osiągnąć ogólną poprawę witryny. 1993. który pozwala na pełne oddzielenie wszystkich elementów projektu od kodu. Steve McConnell. Tak zupełnie na marginesie. New Jersey: Prentice Hall PTR. Z powodu elastyczności PHP cel modularnego tworzenia witryn WWW może być osiągnięty wieloma sposobami. 159 PHP – Kompendium wiedzy . A Mehodology for Client/Server and Web Application Development. Jakiś czas temu zdałem sobie sprawę. Zalecaną w tym rozdziale metodą jest wykorzystanie systemu szablonów. 1998. Pozwala ona moim projektantom łatwo stworzyć pliki szablonów stron wykorzystując nawiasy klamrowe do zaznaczenia elementów i pozwala mi na projektowanie w pełni funkcjonalne oraz szybkie zmiany w logice aplikacji.

Rozdział 13. Fajny PHP
Wstęp
W przypadku języka tak potężnego i rozszerzalnego jak PHP, trudno jest poszufladkować wszystkie fajne rzeczy, jakie można zrobić przy jego pomocy. Rozdział ten zawiera opis niektórych z nich. Tematy tu omawiane są albo zagadnieniami, które musiałem kiedyś zaprogramować, albo odpowiedziami na pytania często pojawiające się na listach dyskusyjnych poświęconym PHP. Rozdział ten nie opisuje oczywiście wszystkich rozszerzeń i własności PHP, ale opisuje niektóre z nich, które nie zostały opisane w innych częściach książki.

Wysyłanie do przeglądarki plików innych niż HTML
Ogólnie mówiąc, PHP jest wykorzystywany do wysyłania plików HTML do przeglądarki, ale może być on również użyty do automatyzacji ściągania plików, lub dostarczania innych typów plików do przeglądarki. Na przykład można umożliwić użytkownikom na zapisanie fragmentu zawartości bazy danych w formacie tekstowym, na przykład takim jak CSV. Przykład ten ilustruje sposób, w jaki można umożliwić użytkownikom zapisanie fragmentu tabeli bazy danych. Na wydruku 13.1. umieszczono skrypt pobierający dane z bazy danych, formatujący je oraz wysyłający je do przeglądarki. Wydruk 13.1. Wysyłanie CSV do przeglądarki
<?php include_once( "db_mysql.php" ); // Tworzenie klasy pochodnej po DB_Sql służącej do pobrania danych pracownika class employee_db extends DB_Sql { var $Host = "localhost"; var $Database = "mydb"; var $User = "root"; var $Password = "root"; } $aSQL = "select * from employees ";

$aDB = new employee_db; $aDB->query( $aSQL ); /* metoda metadata() bardzo zależy od wersji MySQL przykład ten może nie działać dobrze na wszystkich wersjach MySQL */ $aMetaData = $aDB->metadata(); $aData = ""; $aNumFields = count( $aMetaData ); for ( $nIndex = 0; $nIndex < $aNumFields; $nIndex++ ) { $aData .= "\"" . $aMetaData[$nIndex]["name"] . "\","; } // usunięcie ostatniego znaku w ciągu (,) i znaku końca linii (\n) $aData = substr( $aData, 0, strlen( $aData ) - 1 ) . "\n"; while ( $aDB->next_record() ) { $aLine = ""; for ( $nIndex = 0; $nIndex < $aNumFields; $nIndex++ ) { $aLine .= "\"" . $aDB->f( $nIndex ) . "\","; } // usunięcie ostatniego znaku w ciągu (,) i znaku końca linii (\n) $aLine = substr( $aLine, 0, strlen( $aLine ) - 1 ); $aLine .= "\n";

$aData .= $aLine; } header( "Content-length: " . strlen( $aData ) ); header( "Content-type: application/octetstream" ); header( "Content-disposition: inline; filename=\"employees.csv\"" ); print( $aData ); ?>

Pierwszą czynnością realizowaną przez skrypt jest zdefiniowanie klasy pochodnej po klasie DB_Sql pochodzącej z PHPLIB, która jest używana do uruchomienia zapytania na bazie danych. Więcej informacji na ten temat znajduje się w rozdziale 6. „Współpraca z bazami danych”. Następnie wykonywane jest zapytanie i pobierane z niego są metadane. Metadane zawierają ilość pól oraz nazwę każdego ze zwracanych pól. Dane te są potrzebne do skonstruowania pierwszej linii pliku CSV. Zwykle CSV zawiera wiersz nagłówka zawierający nazwy pól, a następnie umieszczone są wiersze danych. Każde pole w CSV jest umieszczone w cudzysłowach i oddzielona są od siebie przecinkami. Każdy wiersz kończy się znakiem nowej linii. Po dodaniu wiesza nagłówka, skrypt przebiega po kolejnych rekordach wyniku i konstruuje z nich sformatowane wiersze CSV. Następnie do przeglądarki wysyłane są trzy wiersze nagłówka HTML. Pierwszy zawiera wielkość wysyłanego pliku, Następna zawiera typ zawartości pliku. Jest ona ważna, ponieważ przeglądarka wykorzystuje te dane do rozpoznania, w jaki sposób powinna traktować przesyłane dane. Jeżeli linia ta zawierała by text/html, przeglądarka próbowała by wyświetlić przychodzące dane w postaci HTML. Ponieważ typem tym jest w tym przypadku application/octetstream, przeglądarka nie próbuje wyświetlić tych danych, a zamiast tego pozwala zapisać je na dysku. Ostatni wiersz wskazuje przeglądarce, że dane są wysyłane razem z nagłówkami oraz sugeruje nazwę dla zapisywanego pliku. Na rysunku 13.1. pokazane jest okno dialogowe wyświetlane przez Internet Explorer po uruchomieniu tego skryptu. Pierwsze dwie linie tego pliku umieszczone są na wydruku 13.2., natomiast na rysunku 13.2. widać wygląd tego pliku w programie Microsoft Excel. Rysunek 13.1. Okno dialogowe Zapisz jako

161

PHP – Kompendium wiedzy

Rysunek 13.2. Plik CSV w Excelu

Wydruk 13.2. Surowy plik CSV
"id","first","last","address","position" "1","Bob","Smith","Poziomkowa 16, Miastko","Szef marketingu"

Innym częstym zastosowaniem przesyłania zawartości innej niż HTML do przeglądarki, jest wysyłanie plików graficznych. Na przykład możesz mieć aplikację, która zapisuje małe rysunki w bazie danych. Następnie można przy pomocy PHP zapisywać je oraz pobierać i wyświetlać. Poniższy wydruk pokazuje w jaki sposób można pobierać rysunki poprzez formularz HTML, zapisywać je w bazie danych, a następnie wyświetlać je na innej stronie. Na wydruku 13.3. znajduje się formularz HTML używany do przesyłania rysunków, natomiast wydruk 13.4. zawiera skrypt zapisujący rysunki do bazy danych. Tabela MySQL używana do przechowywania rysunków zdefiniowana jest następująco:
CREATE TABLE pictures ( picture_id int(11) DEFAULT '0' NOT NULL, name varchar(30) NOT NULL, date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, pic_data mediumblob NOT NULL, pic_size int(11) DEFAULT '0' NOT NULL, pic_type varchar(30) NOT NULL, PRIMARY KEY (picture_id) );

Wydruk 13.3. Formularz przesyłania plików
<html> <head> <title>Przesyłanie rysunków</title> </head> <body> <form action="upload_pic.phtml" method="post" enctype="multipart/form-data"> <table> <tr> <td colspan="2"> Proszę wybrać plik z rysunkiem (jpeg lub gif) do przesłania, oraz podać jego nazwę. </td> </tr> <tr> <td> Plik rysunku: </td> <td> <input type="file" name="PicFile"> </td> </tr> <tr> <td> Nazwa rysunku: </td> <td> <input type="text" name="PicName" maxlength="30">

Rozdział 13 – Fajny PHP

162

</td> </tr> <tr> <td colspan="2"> <input type="submit" name="Submit" value="Wyślij"> </td> </tr> </table> </form> </body> </html>

Wydruk 13.4. Zapisywanie przesłanego pliku w bazie danych
<?php include_once( "db_mysql.php" ); // Utworzenie podklasy DB_Sql do zapisywania i odczytu rysunków class pictures_db extends DB_Sql { var $Host = "localhost"; var $Database = "mydb"; var $User = "root"; var $Password = "root"; } $aErrors = False; if ( !empty( $PicFile_name ) ) // nie wybrano pliku { if ( ( $PicFile_type == "image/gif" ) || ( $PicFile_type == "image/pjpeg" ) || ( $PicFile_type == "image/jpeg" ) ) { $aFile = fopen( $PicFile, "rb" ); $aFileContents = addslashes( fread( $aFile, filesize( $PicFile ) ) ); fclose( $aFile ); $aDB = new pictures_db(); $aSQL = "select ( max( picture_id ) + 1 ) as new_id from pictures"; $aDB->query( $aSQL ); if ( $aDB->next_record() ) { $aNewID = $aDB->f( "new_id" ); } if ( empty( $aNewID ) == True ) { $aNewID = 1; } $aSQL = "insert into pictures ( picture_id, name, date, pic_data, "; $aSQL .= "pic_size, pic_type ) values ( $aNewID, '$PicName', "; $aSQL .= "NOW(), '$aFileContents', '$PicFile_size', '$PicFile_type' )"; print( $aSQL ); $aDB->query( $aSQL ); if ( $aDB->Errno != 0 ) { $aErrors = True; } } else { $aErrors = True; } } else { $aErrors = True; } if ( $aErrors == False ) { header( "Location: upload_ok.html\n" ); } else { header( "Location: upload_failed.html\n" ); } ?>

Skrypt ten ponownie wykorzystuje klasę PHPLIB do obsługi odwołań do bazy danych. Na początku sprawdzane jest, czy plik jest właściwego typu. Następnie plik jest umieszczony w zmiennej i przygotowany do 163 PHP – Kompendium wiedzy

umieszczenia w bazie danych poprzez użycie funkcji addslashes(). Następnie z tabeli pobierany jest nowy identyfikator i dane są umieszczane w bazie danych. Na końcu skryptu przeglądarka jest kierowana do odpowiedniego pliku w zależności od tego, czy operacja się powiodła czy nie. Aby wyświetlić rysunek, wykorzystujemy kod z wydruków 5. i 6. Na wydruku 13.5. umieszczona jest prosta strona HTML powodująca wyświetlenie jednego, określonego rysunku. Wydruk 13.6. zawiera skrypt wyświetlający rysunki. Wydruk 13.5. Strona HTML powodująca wyświetlenie rysunku z bazy danych
<html> <head> <title>Wyświetlenie rysunku</title> </head> <body> <img src="show_pic.phtml?ID=1" border="0" alt=""> </body> </html>

Wydruk 13.6. Skrypt wyświetlający rysunki
<?php include_once( "db_mysql.php" ); // Utworzenie podklasy DB_Sql do zapisywania i odczytu rysunków class pictures_db extends DB_Sql { var $Host = "localhost"; var $Database = "mydb"; var $User = "root"; var $Password = "root"; } $aDB = new pictures_db(); $aSQL = "select * from pictures where ( picture_id = $ID )"; $aDB->query( $aSQL ); if ( $aDB->next_record() ) { header( "Content-length: " . $aDB->f( "pic_size" ) ); header( "Content-type: " . $aDB->f( "pic_type" ) ); print( $aDB->f( "pic_data" ) ); } else { // Nie znaleziony rysunek, obsługa błędu! Header( "HTTP/1.0 404 Not Found" ); } ?>

Mimo, że dziwny wydaje się znacznik <IMG> wskazujący na skrypt PHP, nie ma jednak żadnej różnicy. Ważny kod znajduje się w skrypcie PHP, gdzie ustawiany jest właściwy typ zawartości dla rysunku z bazy danych. Skrypt powoduje pobranie odpowiedniego rysunku z bazy danych i przesłanie danych. Jeżeli identyfikator rysunku ($ID) nie zostanie odnaleziony w bazie danych, skrypt zwraca standardowy kod błędu HTTP 404. Ponieważ PHP pozwala na wysłanie dowolnych nagłówków HTTP, można w ten sposób przesyłać dowolną zawartość. Elastyczność ta pozwala na łatwe tworzenie aplikacji o dużych możliwościach.

Skrypty automatyzujące
PHP nie jest jedynie językiem programowania dla WWW, który do działania wymaga serwera WWW, ale jest on językiem skryptowym, który może zostać do dowolnych zadań programowych. Ponieważ jest on tak bogaty w funkcje, może być wykorzystany do automatyzacji zadań, które mogą być trudne do zrealizowania w standardowych językach programowania powłoki lub plikach wsadowych. Dodatkowo, ponieważ PHP jest dostępny na wielu platformach, te same skrypty mogą być użyte na wielu platformach. Wykorzystanie PHP jako osobnego narzędzia skryptowego wymaga skompilowania wersji CGI PHP. Jest to opsane w rozdziale 1., „Kompilacja i instalowanie PHP 4”. Mając dostępną wersję CGI można uruchomić dowolny skrypt PHP z linii poleceń. Poniższy przykład pokazuje wykorzystanie PHP do generowania plików stref DNS co jest przydatne w przypadku obsługi wielu stref. Rozdział 13 – Fajny PHP 164

Wydruk 13.7. Baza do obsługi DNS
CREATE TABLE Domains ( domain_id int(11) NOT NULL, name varchar(250) NOT NULL, soa_server_id int(11) DEFAULT '1' NOT NULL, cname_list varchar(250) NOT NULL, mail_server_id int(11) DEFAULT '1' NOT NULL, ip_address_id int(11) DEFAULT '1' NOT NULL, incl_zone_file tinyint(4) DEFAULT '1' NOT NULL, created_date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, PRIMARY KEY (domain_id), KEY name (name), UNIQUE name_2 (name), KEY created_date (created_date) ); CREATE TABLE IPAddressess ( ip_address_id int(11) NOT NULL, value carchar(15) NOT NULL, PRIMARY KEY (ip_address_id), KEY value (value) ); CREATE TABLE MailServers ( mail_server_id int(11) NOT NULL, name varchar(250) NOT NULL, PRIMARY KEY (mail_server_id), KEY name(name) ); CREATE TABLE NameServers ( name_server_id int(11) NOT NULL, name varchar(250) NOT NULL, PRIMARY KEY (name_server_id), KEY name(name) ); CREATE TABLE SOAServers ( soa_server_id int(11) NOT NULL, name varchar(250) NOT NULL, PRIMARY KEY (soa_server_id), KEY name(name) );

Baza danych jest wykorzystywana do przechowywania danych niezbędnych do utworzenia plików strefy oraz innych plików konfiguracyjnych niezbędnych do działania serwera DNS. Poniżej pokazany jest jeden rekord z tabeli Domains:
INSERT INTO Domains VALUES( '4', 'intechra.net', '1', 'www, secure, mail', '1', '1', '1', '2000-08-25 13:29:37');

Wiersz ten zawiera dane DNS na temat domeny intechra.net. Chociaż rekord ten nie jest sam szczególnie użyteczny, to jednak połączony z innymi powiązanymi tabelami pozwala uzyskać informacje na temat adresów IP, serwerów pocztowych oraz serwerów SOA. Używając wszystkich tych danych oraz skryptu PHP można niezmiernie uprościć proces uaktualniania serwera DNS. Poniższe siedem wydruków zawiera elementy głównego skryptu. Wydruki 8. do 13. są plikami szablonów używanych do generowania plików wynikowych. Przykład ten korzysta z klasy FastTemplate opisanej w rozdziale 12. „Oddzielanie kodu HTML od PHP”. Wydruk 13.8. Główny szablon dla pliku strefy DNS (dns_primary.tpl)
$TTL 86400 {DOMAIN}. IN SOA {SOA_SERVER}. {ADMINISTRATOR}. ( {SERIAL} ; nr seryjny 10800 ; odswieżanie 3600 ; ponowna próba 604800 ; wygaśnięcie 86400 ; domyślny TTL ) {NAMESERVERS} {DOMAIN}. IN A {IPADDRESS} {CNAME_RECORDS} {DOMAIN}. IN MX 10 {MAIL_SERVER}. {DOMAIN}. LOC 43 49 57.551 N 111 46 38.071 W 1480.7m

Wydruk 13.9. Szablon nazw hostów DNS (zastępuje CNAME_RECORDS z wydruku 13.8.) (dns_secondary.tpl)
{CNAME} IN CNAME {DOMAIN}.{CRLF}

Wydruk 13.10. Szablon serwerów nazw DNS (zastępuje NAMESERVERS z wydruku 13.8.) (dns_nservers.tpl)
{DOMAIN}. IN NS {NAMESERVER}.{CRLF}

Wydruk 13.11. Główny szablon dla pliku named.conf (named_primary.tpl) 165 PHP – Kompendium wiedzy

acl trustedslaves { ns1.nameserver.com;ns2.nameserver.com; }; options { directory "/var/named"; recursion yes; fetch-glue no; allow-query { any; }; }; zone "." { type hint; file "cache.db"; }; {ZONES}

Wydruk 13.12. Pomocniczy szablon dla pliku named.conf (zastępuje ZONES z wydruku 13.11.) (named_secondary.tpl)
zone "{DOMAIN}" { type master; file "{DOMAIN_FILE}"; notify yes; allow-transfer { trustedslaves; }; };

Wydruk 13.13. Szablon dla pliku podrzędnych DNS (named_slaves.tpl)
zone "{DOMAIN}" { type slave; file "{DOMAIN_FILE}"; masters { master.com; }; };

Szablony te tworzą szkielet niezbędny do utworzenia wszystkich plików konfiguracyjnych dla serwera nazw BIND. Pierwsze trzy generują osobne pliki stref, które mogą posiadać różną liczbę serwerów nazw i definicji nazw komputerów. Pozostałe są używane do utworzenia pliku named.conf oraz pliku podrzędnego, wykorzystywanego w podrzędnym serwerze nazw. Skrypt pokazany na wydruku 13.14 odczytuje z bazy danych dane DNS i generuje wszystkie pliki konfiguracyjne. Wydruk 13.14, Skrypt DNS
<?php include( "./class.FastTemplate.php" ); include( "./db_mysql.php" ); // db_mysql.inc o zmienionej nazwie // tworzenie klasy obsługi bazy danych dla aplikacji class genapps_db extends DB_Sql { var $Host = "localhost"; var $Database = "mydb"; var $User = "root"; var $Password = "root"; } // katalog dla plików wynikowych $aPath = "./dns_output"; $tpl = new FastTemplate( "." ); $tpl->define( array( named_main => "named_primary.tpl", named_zones => "named_secondary.tpl", named_slaves => "named_slaves.tpl", dns_main => "dns_primary.tpl", dns_cnames => "dns_secondary.tpl", dns_nservers => "dns_nservers.tpl" )); // pobierz listę serwerów nazw i zapamiętaj do późniejszego wykorzystania $aNSDB = new genapps_db(); $aSQL = "select * from NameServers"; $aNSDB->query( $aSQL ); // pobierz wszystkie dane strefy $aDB = new genapps_db(); $aSQL = "select A.name, A.cname_list, A.incl_zone_file, B.name as soa_server, C.name as "; $aSQL .= "mail_server, D.value as ip_address from Domains A, SOAServers B, "; $aSQL .= "MailServers C, IPAddressess D where ( A.soa_server_id = B.soa_server_id)"; $aSQL .= "and ( A.mail_server_id = C.mail_server_id ) and "; $aSQL .= "( A.ip_address_id = D.ip_address_id )"; $aDB->query( $aSQL ); while ( $aDB->next_record() ) { $aDomainName = strtolower( $aDB->f( "name" ) ); $aCNames = $aDB->f( "cname_list" ); $aSoaServer = $aDB->f( "soa_server" ) ; $aMailServer = $aDB->f( "mail_server" ); $aIPAddress = $aDB->f( "ip_address" ); $aInclZoneFile = $aDB->f( "incl_zone_file" ); $tpl->assign( array( DOMAIN => $aDomainName, ADMINISTRATOR => "admin." . $aSoaServer, SERIAL => date( "Ymd" ) . "00", MAIL_SERVER => $aMailServer, SOA_SERVER => $aSoaServer, IPADDRESS => $aIPAddress, CRLF => "\n" ) ); /* nazwy hostów (rekordy CNAME) są przechowywane w liście rozdzielanej przecinkami w bazie danyche. Dzielenie listy i tworzenie linii dla każdego elementu */ $tpl->clear( CNAME_RECORDS );

Rozdział 13 – Fajny PHP

166

$tpl->fetch( DNS_MAIN ) ). "w" ). foreach( $aCNameList as $aCName ) { $aCName = trim( $aCName ). $tpl->assign( array( CNAME => $aCName ) ).dns_cnames"). "dns_main"). $tpl->parse( SLAVES. Przykładowy plik strefy pokazany jest na rysunku 13. print( "Główny plik 'named. $tpl->fetch( SLAVES ) ). $aCNames ).named_zones' ). } $tpl->parse( NAMED_CONF.$aCNameList = explode( ". fclose( $aFile ). print( "Plik domeny 'named. $aFile = fopen( "$aPath/named. print ("Plik domeny '$aDomainFile' został utworzony\n" ). 'named_main' ). fwrite( $aFile. 167 PHP – Kompendium wiedzy . } // dodanie linii serwerów nazw do pliku strefy $tpl->clear( NAMESERVERS ). } $aDomainFile = $aDomainName . $aFile = fopen( "$aPath/named.4. gdy pole 'incl_zone_file' w bazie danych ma wartość '!' */ if ( $aInclZoneFile == "1" ) { $tpl->parse( DNS_MAIN.".. } /* dodanie biżącej nazwy domeny do głównego i pomocniczego pliku konfiguracyjnego */ $tpl->assign( array( DOMAIN_FILE => $aDomainFile ) ).named_slaves' ). $tpl->fetch( NAMED_CONF ) ). ". ".db". $tpl->parse( ZONES. $aFile = fopen( "$aPath/$aDomainFile". while ( $aNSDB->next_record() ) { $tpl->assign( array( NAMESERVER => $aNSDB->f( "name" )) ). i 10. Jest on utworzony za pomocą szablonów z wydruków 8. $tpl->parse( NAMESERVERS. "w" ). 9.slave". fclose( $aFile ).dns_nservers" ). ?> Skrypt ten odczytuje kolejne pozycje w tabeli Domains i tworzy plik strefy. fclose( $aFile ). /* plik strefy jest tworzony tylko wtedy.slave' utworzony\n" ). '. fwrite( $aFile. $aNSDB->seek( 0 ) .conf". fwrite( $aFile. ". $tpl->parse( CNAME_RECORDS.conf' utworzony\n" ). "w" ). '.

Pakiet ten zawiera dokumentację i przykłady użycia WDDX.4. PHP może być wykorzystany do wykonania wielu złożonych zadań. Aby uruchomić ten skrypt pod Windows lub na systemach Unix należy użyć polecenia php create_dns. W celu stworzenia tych plików do odczytania zapamiętanego tekstu wykorzystana została metoda FastTemplate fetch().org. Ponieważ PHP jest kompletnym językiem skryptowym. Obsługa WDDX może być uaktywniona w PHP poprzez podanie opcji konfiguracji --enable-wddx i ponowne skompilowanie PHP. na przykład pakietu FastTemplate. łatwo wymieniać pomiędzy sobą dane. można wykorzystać WDDX do współdzielenia przez partnerów danych z bazy danych. na przykład cron. Dla przykładu. SDK dla WDDX można ściągnąć z witryny www.php. przy jego pomocy można napisać dowolne narzędzia automatyzujące złożone zadania. monitorowanie sieci lub aplikacji i wiele innych. kompilując PHP z obsługą WDDX umożliwia się serializację danych w postaci pakietów WDDX oraz deserializację pakietów danych WDDX do struktur danych Rozdział 13 – Fajny PHP 168 . Postęp wykonywania skryptu jest pokazywany na standardowym wyjściu. WDDX WDDX (Web Distributed Data Exchange) to bezpłatna. a pliki wynikowe są tworzone w katalogu określonym na początku skryptu. Celem WDDX jest zapewnienie spójnego interfejsu danych dla informacji przekazywanych pomiędzy aplikacjami sieciowymi. Użyty z mechanizmami automatycznego uruchamiania programów.conf.wddx. Przykładowy plik strefy DNS Dodatkowo tworzony jest odpowiednio sformatowany plik named. Tworzenie plików konfiguracyjnych dla dowolnych programów może być bardzo łatwo wykonane przy użyciu systemu szablonów. składowanie i uaktualnianie bazy danych. Ponieważ PHP jest niezwykle elastyczny. oparta na XML technologia pozwalająca aplikacjom WWW działających na dowolnych platformach.Rysunek 13. Patrząc na najbardziej podstawowym poziomie. może być on użyty do napisania skryptów do takich zadań jak: wysyłanie masowej poczty.

"aAge" ). "aArray" ). } function Initialize() { SetupProductsList().17 Użycie WDDX do manipulacji danymi na kliencie <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="css2. Pakiet danych WDDX zawiera wszystkie dane niezbędne do odtworzenia zmiennych za pomocą funkcji wddx_deserialize(). nIndex++ ) { aValue = aProducts. $aAge = 25.16.0'><header><comment>products</comment></header><data><struct><var name='aFirstName'><string>Arian</string></var><var name='aAge'><number>25</number></var><var name='aArray'><array length='3'><string>red</string><string>green</string><string>blue</string></array></var></struct></data></wd dxPacket> W przedstawionym przykładzie funkcja wddx_packet_start() tworzy nowy pakiet WDDX. wddx_add_vars( $aPacketID.15.ARECORDS[nIndex]. aName = aProducts. natomiast wydruk 13. obj_name) { var result = "". zawiera skrypt PHP wykorzystujący ten szablon.16. "aFirstName" ). gdzie jest używany przez JavaScript.PHP.DESCRIPTION.PRODUCT_ID. aNumProds = aProducts. w kolejnym przykładzie pakiet WDDX jest wysyłany do strony WWW. // Czyszczenie listy produktów // dodanie produktu do listy for ( var nIndex = 0. "blue" ). Na wydruku 13.18.js" LANGUAGE="JavaScript"></SCRIPT> <script language="JavaScript"> <!-function show_props(obj.Dołączenie obsługi obiektu WddxDeserializer ---> <SCRIPT SRC="wddxDes. "green". } return result. for (var i in obj) { result += obj_name + ". Aby to zilustrować. skrypt z wydruku 13.js" LANGUAGE="JavaScript"></SCRIPT> <!--. wddx_add_vars( $aPacketID.Dołączenie obsługi WDDX / Javascript ---> <SCRIPT SRC="wddx. $aWDDXPacket = wddx_packet_end( $aPacketID ).css"> <!--. Aby pokazać jak można wykorzystać WDDX w systemie używającym kilku języków programowania. ?> </body> </html> Wydruk 13. w polach tekstowych tylko do odczytu uaktualniana jest cena i waga wybranego produktu.15. 169 PHP – Kompendium wiedzy . Wykorzystanie WDDX <html> <head> <title>Przykład użycia WDDX</title> </head> <body> <?php $aFirstName = "Arian". oraz wypisuje zawartość pakietu. tworzy kilka zmiennych i serializuje je w pakiet danych WDDX. Wydruk 13. Wydruk 13.ARECORDS[nIndex]. $aArray = array( "red". pokazany jest szablon HTML. print( $aWDDXPacket ).deserialize( '{PRODUCTS_WDDX}' ).17. $aPacketID = wddx_packet_start( "products" ). Wynik serializacji pokazany jest na wydruku 13. aProducts = MyDeser. nIndex < aNumProds. Gdy użytkownik wybierze z listy nazwę produktu.ARECORDS. Następnie do tego pakietu dodawane są trzy zmienne PHP i pakiet jest zamykany. Pakiet WDDX <wddxPacket version='1.length." + i + " = " + obj[i] + "\n". wddx_add_vars( $aPacketID. } function SetupProductsList() { MyDeser = new WddxDeserializer. Przykład ten pokazuje w jaki sposób można manipulować danymi na kliencie przy pomocy JavaScript. Dane WDDX reprezentują informacje o towarach: nazwę. cenę i wagę.

Funkcja SetInfo() jest wywoływana po zmianie przez użytkownika wybranego elementu w liście rozwijalnej.MainForm. Uaktualnia ona wartości wyświetlane w polach tekstowych cena i waga. if ( RowNum > -1 ) { document. Pierwsza funkcja. Ta funkcja z kolei wywołuje funkcję SetupProductsList() a następnie dodaje nazwy i identyfikatory produktów do listy rozwijalnej. aby zobaczyć jego cenę i wagę.Weight.MainForm.ARECORDS[RowNum].value = aProducts. które zostały odczytane z bazy danych przez PHP."> <option></option> <option></option> </select> </td> <td> <input type="text" name="Price" readonly> </td> <td> <input type="text" name="Weight" readonly> </td> </tr> </table> </form> </body> </html> Szablon ten intensywnie wykorzystuje JavaScript.18. document. // Dodanie nowego obiektu do listy SELECT document. false. show_props() jest jedynie funkcją testującą używaną przy wyświetlaniu właściwości obiektu.value = aProducts. } function SetInfo() { // ustawienie ceny i wagi zaznaczonego produktu var RowNum = document. </td> </tr> <tr> <td colspan="3"> &nbsp. Po deserializacji pakietu danych WDDX obiekt JavaScript aProducts zawiera wszystkie dane produktów.MainForm. </td> </tr> <tr> <th> Towar </th> <th> Cena </th> <th> Waga </th> </tr> <tr> <td> <select name="Product_List" size="1" onChange="SetInfo(). true ). Funkcja Initialize() inicjuje stronę i jest wywoływana automatycznie przez zdarzenie strony onLoad.Price.ARECORDS[RowNum]. aValue.Product_List.WEIGHT.PRICE. } } //--> </script> </head> <body onload="Initialize()"> <form action="" name="MainForm" id="MainForm"> <table> <tr> <td colspan="3"> Wybierz towar z listy. } SetInfo().MainForm.// tworzenie nowej opcji NewOpt = new Option( aName.Product_List. Funkcja SetupProductsList() deserializuje dane towarów. Funkcja korzysta z obiektu WddxDeserializer dostępnego w SDK dla WDDX. Wydruk 13. Przygotowanie pakietu danych WDDX <?php Rozdział 13 – Fajny PHP 170 .options[nIndex] = NewOpt.selectedIndex.

include( "db_mysql. Dane pochodzące z wyniku są przechowywane pod indeksami numerycznymi. foreach( $aRecord as $aName => $aValue ) { if ( !is_numeric( $aName ) ) { $aRecords[$nIndex][$aName] = $aValue.5. Sprawdzenie to usuwa dane indeksowane liczbami. 171 PHP – Kompendium wiedzy . Na rysunku 13. gdzie pierwszy wymiar jest numeryczną reprezentacją numeru wiersza.include( "class.tpl" ) ). while( $aDB->next_record() ) { $aRecord = $aDB->Record. Funkcja mysql_fetch_array() zwraca wiersz z wyniku w postaci tablicy. $aDB = new products_db. "base" ). } } $nIndex++. var $User = "root". Linia z funkcją is_numeric() jest używana do usuwania nadmiarowych informacji zwracanej przez niejawnie wykonywaną funkcję mysql_fetch_array(). } $aTemplate = new FastTemplate( ". $nIndex = 0. var $Password = "root". pozostawiając jedynie dane asocjacyjne. $aWDDXPacket = wddx_packet_end( $aPacketID ). $aPacketID = wddx_packet_start( "products" ). $aTemplate->assign( array( "TITLE" => "Products Page" ) ). dodając dane do nowej tablicy. Drugi wymiar to tablica asocjacyjna z nazwami kolumn i ich wartościami. Jest to tablica dwuwymiarowa. "aRecords" ). $aRecords. $aTemplate->FastPrint( "BASE" ). Zawsze po wybraniu nowego towaru automatycznie jest uaktualniana cena i waga. } wddx_add_vars( $aPacketID.php" ). Jest to realizowane w pętli przebiegającej przez rekordy wyniku. Głównym działaniem skryptu jest odczytanie zawartości tabeli Products i utworzenie pakietu WDDX zawierającego odpowiednie dane. jak również pod indeksami asocjacyjnymi gdzie jako klucze są wykorzystywane nazwy pól.inc" ). $aRecords = array(). $aDB->query( "select * from Products" ). pokazana jest wynikowa strona w przeglądarce. class products_db extends DB_Sql { var $Host = "localhost". ?> Główny skrypt PHP wykorzystuje klasę FastTemplate w celu utworzenia kompletnej strony HTML. $aTemplate->parse( "BASE". $aTemplate->define( array( "base" => "products_wddx. var $Database = "mydb". $aTemplate->assign( array( "PRODUCTS_WDDX" => addslashes( $aWDDXPacket ) ) ). Jeszcze jeden fragment tego kodu wymaga skomentowania." ).FastTemplate. error_reporting( E_ALL & ~E_NOTICE ).

Na wydruku 13. Ostatnia wykorzystuje gniazda do wysłania żądania HTTP HEAD do strony w celu sprawdzenia dostępności serwera i samej strony. może być używany na wiele sposobów.0. Poniższy przykład wykorzystuje potoki i gniazda do zrealizowania prostych funkcji monitorujących sieć. } } pclose( $aFile ). WDDX zawiera narzędzia do szybkiego dostarczania treści w postaci neutralnej dla platformy i języka. tworzenie narzędzi monitorujących sieć jest łatwe. Można rozszerzyć ten przykład o sprawdzanie stanu serwera nazw. który można rozszerzać o nowe funkcje.5. $aTotalTime += $aTime. "r" ) ) { // odczytanie danych z potoku while ( !feof( $aFile ) ) { $aLine = fgets ( $aFile. // *nix // *nix // zwraca średni czas wykonania komendy ping function phpPing( $aAddress ) { global $aPingCmd. Monitorowanie sieci Ponieważ PHP wewnętrznie obsługuje gniazda i protokoły sieciowe. } Rozdział 13 – Fajny PHP 172 . oraz łatwego współdzielenia danych pomiędzy różnymi platformami i językami. if ( $aPos > 0 ) { // wykorzystanie zmienności typów zmiennych PHP // do konwersji czasu na liczbę $aTime = substr( $aLine. serwera pocztowego itd. $aTotalTime = 0. // odszukanie danych o czasie $aPos = strpos( $aLine. Jeżeli planujesz współdzielenie danych. $aTraceCmd = '/usr/sbin/traceroute -n'. phpTrace() i phpPageCheck(). $aPingCount = 0. $aPingCount++. Przykład ten może być szkieletem. if ( $aFile = popen( "$aPingCmd $aAddress".19. Funkcje sieciowe <?php $aPingCmd = '/bin/ping -c 4'. Może być używany do przesyłania firmowych danych pomiędzy serwerami. 1024 ). Pierwsze dwie wykorzystują komendy systemowe do wykonania operacji ping i traceroute. $aPos + 5 ) * 1. zamieszczone są trzy funkcje. Przykład wykorzystania danych WDDX na kliencie Choć przykład ten pokazuje w wykorzystanie WDDX do dostarczenia danych dla klienta.19. } return $aTotalTime / $aPingCount. "time=" ). phpPing().0. Wydruk 13.Rysunek 13.

} ?> Funkcje te mogą być wykorzystane w skrypcie automatyzującym do okresowego zapisywania wyników do bazy danych lub do pliku. } } } } } return $aResult. 0.php" ). "r" ) ) { // odczytanie wszystkich danych z potoku while ( !feof( $aFile ) ) { $aLine = fgets ( $aFile. 173 PHP – Kompendium wiedzy . $aTraceResults . "<br>". "</ul><br>" ). Przykład ten pokazuje jak łatwo można wykorzystać PHP do wykonania podstawowego monitorowania sieci.20.net' ) . "phpPageCheck: " ). PHP obsługuje również inne protokoły sieciowe. Wykorzystanie funkcji sieciowych <?php include( "./net_funcs. } return $aTraceResults. phpPageCheck( 'http://www.net' ) . SNMP. 1024 ).net/' ) ? "OK" : "NOT OK" ). } function phpPageCheck( $aWebPage ) { $aURL = parse_url( $aWebPage ). if ( $aSocket ) { fputs( $aSocket. "<br><br>" ). if ( $aFile = popen( "$aTraceCmd $aAddress".= $aLine . takie jak IMAP. co pozwala rozszerzać przytoczony przykład o sprawdzenie dostępności wszystkich rodzajów serwerów i komponentów sieciowych.php. phpPing ( 'www. Wydruk 13. if ( ( $aArray[1] >= 200 ) && ( $aArray[1] < 300 ) ) { $aResult = True. albo mogą być użyte bezpośrednio ze strony WWW.php.function phpTrace( $aAddress ) { global $aTraceCmd.php. NNTP i POP3. $aTraceResults = "". phptrace( 'www.0\r\n\r\n". 80 ).20. 4 ) == "HTTP" ) { $aArray = explode( " ". $aSocket = fsockopen( $aURL["host"]. ?> <html> <head> <title>Test funkcji sieciowych</title> </head> <body> <?php print( print( print( print( print( ?> </body> </html> "phpPing: " . "phpTrace: <ul>" . "<br>" ). Skrypt z wydruku 13. } pclose( $aFile ). $aLine ). $aRequest ). 1024 ). $aResult = False. if ( substr( $aLine. pokazuje w jaki sposób używa się tych funkcji. if ( $aURL["scheme"] == "http" ) { $aRequest = "HEAD {$aURL['path']} HTTP/1. while( !feof( $aSocket ) ) { $aLine = fgets( $aSocket.

analizy XML. Istnieją również rozszerzenia do tworzenia rysunków. Ponieważ PHP jest tak rozszerzalny i rozwijany przez ogromną grupę programistów. Rozdział 13 – Fajny PHP 174 . tworzenia plików PDF i wielu innych zadań.Podsumowanie Rozdział ten opisywał różne zagadnienia pokazujące siłę i elastyczność PHP. należy spodziewać się dalszego zwiększania elastyczności i funkcjonalności.

Aby stworzyć system szablonów dla takiej witryny zdefiniowano następujące szablony: 1. Na rysunku 14.tpl: Podstawowy plik zawierający ogólny układ HTML. pokazana jest typowa strona WWW. 6.tpl: Treść każdej strony. takie jak cena. Każda strona musi zawierać wspólne elementy nawigacyjne oraz logo całej witryny. merch_navi. waga. 5. Katalog ten jest podzielony na kategorie produktów. Wydruki od 1.tpl.Rozdział 14. ponieważ są one właściwie takie same. contacts. merch_body.Informacje. zabawki itd.1..stopka kilku plików HTML base page . należy ocenić potrzeby witryny i zinwentaryzować elementy znajdujące się na stronach. Przeglądając wybraną kategorię produktów. Aby pokazać jak zostały stworzone te pliki. Przykłady przytoczone w tym rozdziale wykorzystują klasę FastTemplate dostępną z witryny http://www.tpl <html> <head> .thewebmasters. merch_base. Aby zaprojektować witrynę korzystającą z szablonów. Page header . Na wydruku 14. Użycie szablonów do projektowania aplikacji umożliwia o wiele więcej.3 pokazany został plik merch_catubrania_header. takie jak: ubrania. Wydruk 14. łącza. Każda strona produktu powinna zawierać dane o towarze. „Oddzielanie HTML od PHP” zostało opisane użycie systemu szablonów. W innych. Witryny oparte o szablony W rozdziale 12. do 6 zawierają kolejne pliki wymienione powyżej. niż jedynie oddzielanie logiki aplikacji od projektu graficznego. właściwy dla kategorii produktów ubrania. 4. Podstawy wykorzystania szablonów Tworzenie witryn WWW korzystających z systemu szablonów wymaga nieco dokładniejszego projektowania interfejsu użytkownika. która może być podzielona na kilka osobnych plików szablonów. nowości Na rysunku 14.1. każda strona może być tworzona na podstawie kilku szablonów.tpl: Panel nawigacyjny katalogu. personalizacji. Na niektórych witrynach WWW może być wykorzystany tylko jeden szablon dla wszystkich stron witryny.panel nawigacji składająca się z footer . 2.tpl: Nagłówek wspólny dla wszystkich stron witryny.1. niż tworzenie tej samej aplikacji bez szablonów. kontakty. links. Szablony umożliwiają zastosowanie zapożyczania fragmentów witryn. które składają się na stronę HTML z różnymi logicznymi sekcjami strony. merch_footer. news . merch_base. Rysunek 14. niezależności od przeglądarki oraz obsługi wielu języków. elastyczna i łatwa do nauki. Przykładem będzie witryna pełniąca funkcję sieciowego katalogu towarów.tpl: Nagłówek określonej kategorii (XXX zastąpione przez nazwę kategorii).nagłówek strony Strona WWW navigation . pokazana jest strona składająca się z jednego lub więcej szablonów. prezenty. Istnieją również inne systemy szablonów. przedstawiona zostaną teraz zawartość każdego z nich. merch_catXXX_header. Pliki dla pozostałych kategorii nie zostały pokazane.tpl: Stopka każdej strony. dostępne kolory itd. merch_header.net/. Jednak korzyści wykorzystania dobrze zaprojektowanego zaczną się ujawniać bardzo szybko. 3.Podstawowa strona HTML szablonów Main body . ale ta implementacja jest wydajna. W tym rozdziale zostanie szczegółowo opisane wykorzystanie szablonów do tworzenia witryn.Główny obszar strony information.1. powinien być wyświetlany element graficzny oznaczający tą kategorię.

$aTPL->define( array( 'base' 'header' 'navi' 'footer' 'cat_header' 'body' => => => => => => 'merch_base2.tpl'.56. // zakładamy. Należy zwrócić uwagę. na przykład nagłówek zawiera jedynie rysunek.tpl'. 'merch_footer.180. jak i mapę obrazu. merch_navi.FastTemplate.221" href="{HREF_COMPANY_INFO}" > <area shape="rect" coords="7. Wydruk 14.90.73. pokazuje w jaki sposób można połączyć pliki szablonów w jedną całość.tpl'.gif" width="630" height="61" border="0"> Wydruk 14.2.7.7.tpl <img name="merch_layout_r2_c1" src="merch_layout_r2_c1.166" href="{HREF_CONTACT}" > <area shape="rect" coords="12. Skrypt PHP pokazany na wydruku 14.gif" width="630" height="37" border="0"><br> <div align="center"><p>{CATEGORY_SPECIALS}</p></div> Wydruk 14. $aTPL = new FastTemplate( ". 'merch_navi. a jedynie zmienne szablonu Pozwala to na stworzenie właściwych adresów łączy. merch_footer. merch_body.5.132" href="{HREF_CART}" > <area shape="rect" coords="18. jak na przykład szablon panelu nawigacyjnego zawiera zarówno rysunek.tpl <img src="merch_layout_r3_c1.3. że wybraną kategorią są ubrania $aCategoryHeader = 'merch_catubrania_header.gif" width="104" height="382" border="0" usemap="#merch_layout_r3_c1"> <map name="merch_layout_r3_c1"> <area shape="rect" coords="5.tpl' Rozdział 14 – Witryny oparte o szablony 176 .tpl'. Niektóre z tych plików.143." ).84.4. $aCategoryHeader. merch_catubrania_header.97.80" href="{HREF_HOME}" > </map> Wydruk 14.tpl <img src="merch_layout_r1_c1. 'merch_body. </p> Pliki te pokazują jak niewiele potrzeba do stworzenia dosyć skomplikowanej witryny korzystającej z szablonów. 'merch_header.php" ).<title>{TITLE}</title> </head> <body bgcolor="White"> <table width="630" border="0" cellspacing="0" cellpadding="0" align="center"> <tr> <td colspan="2">{PAGE_HEADER}</td> </tr> <tr> <td colspan="2" align="center">{CAT_HEADER}</td> </tr> <tr> <td valign="top">{LEFT_NAVI}</td> <td valign="top"> {BODY} </td> </tr> <tr> <td colspan="2"> {PAGE_FOOTER} </td> </tr> </table> </body> </html> Wydruk 14.tpl <p> &nbsp.86. Łączenie szablonów <?php include( "class. Wszystkie prawa zastrzeżone. że szablon nawigacyjny nie zawiera aktualnych adresów URL. Inne. merch_header.6.tpl <hr> <p> &copy {COPYRIGHT_YEARS} Intechra LLC. </p> <h3> {PRODUCT_NAME} </h3> <p> {PRODUCT_DESCRIPTION} </p> <p> {PRODUCT_PRICE} </p> Wydruk 14.tpl'. na przykład zawierających identyfikator sesji.

$aTPL->parse( 'PAGE_FOOTER'. 'company.phtml'. że niektóre zmienne FastTemplate są ustawiane przy użyciu metody assign(). Dla przykładu. Dla przykładu zmienna PAGE_HEADER jest ustawiana poprzez analizę strony o nazwie header. Dodatkowo należy analizować szablony we właściwej kolejności. że wartość PAGE_HEADER jest już dostępna w czasie analizy pliku merch_base.phtml'. 'body' ).tpl jest inicjowana wartością 2000 przy użyciu metody assign(). który w naszym przykładzie został nazwany base. 'Świetna koszulka z logo Intechra LLC!'. $aTPL->parse( 'CAT_HEADER'. z zamieszczonego na wydruku 14. Na rysunku 14. Aby zrozumieć w jaki sposób FastTemplate analizuje stronę należy wiedzieć. Efekt zmiany szablonu base pokazany jest na rysunku 14.6. Zmieniając szablon o nazwie base. Powoduje to. $aTPL->FastPrint( 'BASE' ). 'Koszulka Intechra'.) ).phtml'. $aTPL->parse( 'LEFT_NAVI'. na ten z wydruku 14.1. $aTPL->parse( 'BASE'. Skrypt ten po prostu przypisuje wartości do wszystkich zmiennych potrzebnych we wszystkich plikach szablonów. '14.2. ?> => => => => => => => => => => 'Katalog towarów: Ubrania'. W przykładzie tym wszystkie wartości zostały na stałe zaszyte w skrypcie w celu uproszczenia opisu. 'cart. $aTPL->parse( 'PAGE_HEADER'. Dodatkowo niektóre zmienne FastTemplate są ustawiane za pomocą metody parse(). 'contact. większość wymaganych zmiennych (takich jak PAGE_HEADER i BODY) nie było by dostępnych.8. Należy pamiętać.phtml' 'header' ). wygląd strony ulega całkowitej zmianie. $aTPL->parse( 'BODY'. 'cat_header' ). że w przypadku zagłębiania szablonów należy zainicjować wszystkie wymagane zmienne szablonu przed jego analizą. W prawdziwej aplikacji dane na temat kategorii produktu oraz wyświetlanego produktu powinny być dostarczone poprzez formularz lub inną metodę dynamicznego dostarczania danych. Siłą zastosowania szablonów jest możliwość łatwego wprowadzania zmian w projekcie graficznym witryny. jeżeli w powyższym przykładzie strona base była by analizowana na początku. Skrypt ten wykorzystuje klasę FastTemplate do analizy i połączenia wszystkich plików szablonów tworzących katalog produktów. 'footer' ). pokazany został wygląd strony wygenerowanej przez skrypt z wydruku 14. 177 PHP – Kompendium wiedzy . Na przykład zmienna COPYRIGHT_YEARS wykorzystywana w szablonie merch_footer. 'Sprzedajemy koszulki Intechra!'. 'index. $aTPL->assign( array( 'TITLE' 'CATEGORY_SPECIALS' 'PRODUCT_NAME' 'PRODUCT_DESCRIPTION' 'PRODUCT_PRICE' 'COPYRIGHT_YEARS' 'HREF_HOME' 'HREF_CART' 'HREF_CONTACT' 'HREF_COMPANY_INFO' ) ).3. 'navi' ). '2001'.95 zł'.tpl. 'base' ).

Wydruk 14.css"> </head> <body bgcolor="White"> <table width="630" border="0" cellspacing="0" cellpadding="0" align="center"> <tr> <td colspan="2">{PAGE_HEADER}</td> </tr> <tr> <td colspan="2" align="center">{CAT_HEADER}</td> </tr> <tr> <td width="526" valign="top"> {BODY} </td> <td valign="top">{LEFT_NAVI}</td> </tr> <tr> <td colspan="2"> {PAGE_FOOTER} </td> </tr> </table> </body> </html> Rozdział 14 – Witryny oparte o szablony 178 . Strona wygenerowana przez skrypt z wydruku 14.8. Nowy plik szablonu „base” <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="new_base.7.Rysunek 14.2.

Rysunek 14. Tak jak to zostało pokazane. Dodatkowo. wykorzystanie szablonów pozwala programistom na wykorzystywanie zestawu prototypowych plików interfejsu. można zmienić atrybuty wszystkich elementów HTML. zmieniając zawartość szablonu base. natomiast nie zostały wprowadzone żadne zmiany po stronie PHP. Strona wygenerowana przy użyciu nowego szablonu „base” Siła systemu szablonów nie może być przeceniana. CSS jest wartościowym dodatkiem do większości zastosowań WWW. ale po zdefiniowaniu zestawu plików szablonów i zmiennych szablonów praca obu grup może pracować równolegle. aby w kontekście tej witryny wyglądał w określony sposób. Oczywiści zachodzi niezbędna interakcja pomiędzy programistami i projektantami interfejsu.3.com/).5. 179 PHP – Kompendium wiedzy . Elastyczność ta pozwala projektantom na tworzenie i konserwację bogatego interfejsu użytkownika.bradsoft.4. ponieważ stanowi on system szablonów dla HTML. pokazany jest wygląd komercyjnego edytora CSS o nazwie TopStyle z firmy Bradbury Software LLC (http://www. Na przykład można tak zdefiniować znacznik <h3>. znacznie zmieniony został wygląd strony. i 14. Edytor ten upraszcza proces tworzenia plików CSS oraz pozwala na podgląd zmienionych stylów. do czasu aż projektanci dostarczą im ostateczne wersje. Na wydrukach 14. natomiast programiści aplikacji równolegle tworzą i konserwują część logiczną. Wykorzystując CSS. W poprzednim przykładzie jedyną znacząca zmianą wprowadzoną w szablonie base było dołączenie pliku CSS.

Arkusz stylu pokazujący możliwość modyfikacji znaczników <body>. pozwala zrealizować kolejny poziom konfiguracji wyglądu tworzonej aplikacji.5. Inny arkusz stylu pokazujący możliwość modyfikacji znaczników <body>. Pliki CSS mogą być nawet dołączane dynamicznie. Rozdział 14 – Witryny oparte o szablony 180 . w postaci zmiennej szablonu.4. że nie jest to optymalne rozwiązanie dla wszystkich typów witryn.Rysunek 14. <td> i <h3> Użycie CSS wraz z systemem szablonów zwiększa możliwość wprowadzania zmian do wyglądu witryny minimalizując konieczność wprowadzania zmian do kodu aplikacji. <td> i <h3> Rysunek 14. Mimo.

Efekt końcowy pokazany jest na rysunku 14. foreach( $aCategories as $aID => $aName ) { $aTPL->assign( array( 'CAT_ID' => $aID. 'items' ). "książki" ). "prezenty". ?> Rysunek 14. "zabawki".11.Poprzedni przykład stanowi podstawowy szkielet dla tworzenia aplikacji WWW opartej o szablony.tpl'.6.12. Wynik działania skryptu przedstawiony jest na rysunku 14. '. $aTPL->parse( 'BASE'. $aTPL->FastPrint( 'BASE' ).10. $aTPL->define( array( 'base' => 'cat_base. // analiza elementu i jego dołączenie do zmiennej szablonu // ITEM_LIST $aTPL->parse( 'ITEM_LIST'. i 14.FastTemplate.php" ).phtml?cat_id={CAT_ID}">{CAT_NAME}</a></li> Wydruk 14. lub listę kategorii zapisanych w bazie danych. Skrypt generujący stronę z listą kategorii <?php include( "class. $aTPL->parse( 'ITEMS'.9. Szablon dla pojedynczej kategorii <li><a href="show_category. Szablon kategorii ‘items’ Do wyboru są następujące kategorie produktów: <ul> {ITEM_LIST} </ul> Wydruk 14. 'item' => 'cat_item. to zawartość szablonu items. Wydruk 14. Zmiany są ograniczone jedynie do plików items i item. 'items' => 'cat_items.6.item' ). $aCategories = array( "ubrania".tpl'." ). Kolejny przykład pokazuje.12 znajduje się skrypt łączący te szablony w całość. Na wydruku 14.9.7. 'base' ). } $aTPL->assign( array( 'TITLE' => 'Lista kategorii' ) ).10.tpl' ) ). że dział projektowy zdecydował się na zmianę formatu listy kategorii z listy wypunktowanej na tabelę. Wykorzystując poprzedni przykład zmienione szablony przedstawione są na wydrukach 13. Wydruk 14. natomiast wydruk 14. Lista kategorii Przedstawiony przykład zawiera wbudowaną listę kategorii w celu wygenerowania strony z listą kategorii. PHP – Kompendium wiedzy 181 . zawiera główny plik szablonu. Jednak nie zostały tu pokazane przykłady tworzenia powtarzających się elementów.11. Często zachodzi potrzeba stworzenia tabeli zawierającej wszystkie towary. korzystając z klasy FastTemplate. $aTPL = new FastTemplate( ". w jaki sposób można dołączyć powtarzające się elementy. Wydruk 14. 'CAT_NAME' => $aName ) ). Główny szablon kategorii <html> <head> <title>{TITLE}</title> </head> <body> {ITEMS} </body> </html> Wydruk 14. szablon pojedynczego elementu. Po raz kolejny załóżmy.

15. Aby użyć tego mechanizmu zmienimy szablon items.phtml?cat_id={CAT_ID}">{CAT_NAME}</a> </td> </tr> <!-.Wydruk 14.13. $aTPL = new FastTemplate( ". oraz główny skrypt PHP.FastTemplate. Użycie szablonów wymaga również kilku zmian w skrypcie używającym klasy FastTemplate.phtml?cat_id={CAT_ID}">{CAT_NAME}</a> </td> </tr> Rysunek 14. co stworzenie osobnego pliku zawierającego szablon item. Nowy skrypt PHP <?php include( "class.7. Jest to dokładnie to samo.7. {CAT_ID} </td> <td> <a href="show_category.BEGIN DYNAMIC BLOCK: item --> <tr> <td> Kategoria nr. Na wydrukach 15. i 16. Rozdział 14 – Witryny oparte o szablony 182 .16. Wydruk 14.tpl') ). Wydruk 14. {CAT_ID} </td> <td> <a href="show_category. Lista kategorii w postaci tabeli Przedstawiony przykład pokazuje podstawowe kroki potrzebne do generowania listy powtarzających się elementów przy użyciu FastTemplate.16.php" ).END DYNAMIC BLOCK: item --> </table> W szablonie tym został zdefiniowany podszablon — blok dynamiczny o nazwie item. Zaletą takiego rozwiązania jest utrzymanie oryginalnej struktury pliku HTML oraz ograniczenie ilości niezbędnych plików szablonów. jak pokazany na rysunku 14.14. zamieszczone są zmienione pliki. Wynik działania tego skryptu jest taki." ). Zostały one zamieszczone na wydruku 14. $aTPL->define( array( 'base' => 'cat_base. Nowy szablon „item” <tr> <td> Kategoria nr. 'items' => 'cat_items_dyn. Nowy szablon „items” Do wyboru są następujące kategorie produktów: <br><br> <table border="1"> {ITEM_LIST} </table> Wydruk 14. Nowy szablon „items” korzystający z dynamicznych bloków Do wyboru są następujące kategorie produktów: <br><br> <table border="1"> <!-.tpl'. Istnieje również w FastTemplate inny mechanizm pozwalający na wyeliminowanie dodatkowych plików zawierających szablon pojedynczego elementu.

W prostych przypadkach możesz dodać jedynie kilka znaków firmowych. 'CAT_NAME' => $aName ) ). // analiza elementu i jego dołączenie do zmiennej szablonu // ITEM_LIST $aTPL->parse( 'ITEM_LIST'. 'base' ). $aTPL->parse( 'BASE'. wykorzystana jest metoda FastTemplate define_dynamic(). Od tej chwili FastTemplate traktuje blok dynamiczny identycznie. Po drugie. żądać zmian w terminologii itd. poniższe pliki szablonów są wykorzystywane w aplikacji przedstawionej w poprzedniej części. aby blok dynamiczny był poprawny składniowo. Ponieważ aplikacja opiera się na interfejsie z innej firmy. należy zdecydować na ile konfigurowalna powinna być taka witryna. 'items' ).12. </p> Wydruk 14. w nowym skrypcie brakuje jednego wywołania metody define(). } $aTPL->assign( array( 'TITLE' => 'Lista kategorii' ) ). Składnia linii BEGIN i END musi być poprawna i wymagane jest zachowanie odpowiedniej wielkości liter. "książki" ). W linii zawierającej wyrażenia BEGIN i END nie powinno być żadnego innego tekstu. Zapożyczanie witryny to wykorzystanie projektu witryny partnerskiej jako podstawy własnej aplikacji. W tym scenariuszu zmienione zostały jedynie dane o prawach autorskich oraz szablon bazowy. 'items' ). można jedynie umieszczać tam dowolną ilość znaków odstępu.18. Zapożyczanie Zapożyczanie jest bardzo łatwo realizowalne za pomocą witryny opartej o szablony. &copy 2000 &copy {COPYRIGHT_YEARS} Intechra LLC. Dyrektywa musi być napisana dokładnie w takiej postaci. jak poniższa linia kodu. foreach( $aCategories as $aID => $aName ) { $aTPL->assign( array( 'CAT_ID' => $aID. $aCategories = array( "ubrania". Bazowy szablon partnera <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="new_base.$aTPL->define_dynamic( 'item'. i 18. To samo obowiązuje dla dyrektywy END.css"> 183 PHP – Kompendium wiedzy . że w szablonie items istnieje blok dynamiczny o nazwie item.17. "prezenty". Linia ta musi być dokładnie taka. Tworząc aplikację. niezmiernie ważne jest. ?> W skrypcie tym widoczne są dwie wyraźne zmiany w stosunku do wydruku 14.item' ). Dla przedstawianego wcześniej przykładu katalogu produktów. Korzystając z tego mechanizmu. aby upewnić się. Szablon partnera z opisem prawa autorskich <hr> <p> Niektóre fragmenty witryny pochodzą z firmy Keen Partner Company. że wszystkie funkcje działają tak. która wskazuje systemowi FastTemplate. Istnieje kilka sposobów zrealizowania takiego scenariusza w PHP. jest możliwe aby kilka witryn dystrybutorów korzystających z własnego projektu graficznego używało katalogu jako jednej z dostępnych usług. Tworzenie zapożyczonej witryn jest w zasadzie identyczne. jak byłby to osobny plik. jak przedstawiona. ale wykorzystując szablony można zrobić to bardzo szybko. zawierają stopkę z prawami autorskimi oraz plik bazowy. jak to zostało zaplanowane. <!-. Po pierwsze. Blok kodu zaczyna się od nowej linii tekstu przeznaczonej jedynie dla tej dyrektywy. Aby zilustrować to zagadnienie. Wydruki 17. z dokładnością do odstępów pomiędzy znakami. Linie BEGIN i END nie mogą rozciągać się na większa ilość linii. jak tworzenie innych witryn opartych o szablony. Wydruk 14. Następna część tego rozdziału zawiera kilka przykładów scenariuszy stosowanych w prawdziwych aplikacjach. '. $aTPL->parse( 'ITEMS'. W niektórych przypadkach partnerzy mogą umieścić dodatkowe informacje o prawach autorskich. $aTPL->FastPrint( 'BASE' ).BEGIN DYNAMIC BLOCK: nazwa_bloku --> Wszystkie te przykłady tworzą szkielet aplikacji WWW korzystających z szablonów. "zabawki". Wszystkie prawa zastrzeżone. która może być zapożyczana. integracja i testowanie musi być przeprowadzone przez obie strony.

19. 'Koszulka Intechra'. 'PAGE_FOOTER'. 'CAT_HEADER'. 'base' ).19.katalog. 'cat_header' ). 'body' ). '2000'.com/. 'BASE'. Wydruk 14.95 zł'.tpl'. $aTPL->parse( $aTPL->parse( $aTPL->parse( $aTPL->parse( $aTPL->parse( $aTPL->parse( 'PAGE_HEADER'. '14.tpl'. Główny skrypt realizujący zapożyczanie <?php include( "class.phtml'.tpl'. break.com/. switch ( $aPartner ) { case "cobrand" : $aPartnerBase = "partner_base. 'merch_navi. natomiast witryna partnera poprzez http://cobrand. => => => => => => $aPartnerBase. 'index. Nazwy te są oczywiście używane jedynie do testowania i nie muszą być to docelowe nazwy witryny. default : $aPartnerBase = "merch_base2.". 'BODY'.tpl". Rozdział 14 – Witryny oparte o szablony 184 .tpl".</head> <body bgcolor="White"> <table width="630" border="0" cellspacing="0" cellpadding="0" align="center"> <tr> Firma Keen Partner Company wykorzystuje katalog produktów firmy Intechra LLC. 'navi' ). 'merch_header. 'contact. 'LEFT_NAVI'.phtml'." ). } // Zakładamy.phtml'. $aCategoryHeader. 'Sprzedanemy koszulki Intechra!'. $aPartnerFooter = "partner_footer. aby rozpoznał właściwy wygląd witryny na podstawie nazwy partnera. 'cart.tpl". pokazany jest taki skrypt. 'merch_body. $HTTP_HOST ). 'footer' ).tpl". 'Świetna koszulka z logo Intechra LLC!'. $aPartnerFooter. break.php" ).tpl' => 'Katalog produktów: Ubrania'. $aTPL->assign( array( 'TITLE' 'CATEGORY_SPECIALS' 'PRODUCT_NAME' 'PRODUCT_DESCRIPTION' 'PRODUCT_PRICE' 'COPYRIGHT_YEARS' 'HREF_HOME' 'HREF_CART' 'HREF_CONTACT' 'HREF_COMPANY_INFO' ) ). że wybraną kategorią są ubrania $aCategoryHeader = 'merch_catubrania_header.FastTemplate. $aPartner = $aHostArray[0]. Na wydruku 14. <td colspan="2">{PAGE_HEADER}</td> </tr> <tr> <td colspan="2" align="center">{CAT_HEADER}</td> </tr> <tr> <td width="526" valign="top"> {BODY} </td> <td valign="top">{LEFT_NAVI}</td> </tr> <tr> <td colspan="2"> {PAGE_FOOTER} </td> </tr> </table> </body> </html> Zmodyfikowany został również główny skrypt łączący szablony a skrypt tworzący stronę wynikową jest również tak zmieniony. $aHostArray = explode( ".phtml' => => => => => => => => => 'header' ). $aTPL = new FastTemplate( ". Na przykład główna witryna jest dostępna poprzez adres http://www. $aTPL->define( array( 'base' 'header' 'navi' 'footer' 'cat_header' 'body' ) ). Po uruchomieniu głównego skryptu sprawdzana jest nazwa witryny i wyświetlana jest odpowiednia strona.katalog. 'company. $aPartnerFooter = "merch_footer.

10. Jeżeli nazwa zawiera cobrand. Rysunek 14. chciałbym odwołać się do witryny.com. We wielu przypadkach personalizacja jest ograniczona do typu wyświetlanych informacji i niektórych podstawowych kolorów. Najlepszą cechą witryny jest możliwość wybrania własnego tematu używanego w stronach informacyjnych. wynik jest identyczny jak na rysunku 14. ale jedynie pokazać jak bardzo można modyfikować wygląd witryny korzystając z dobrego systemu szablonów.jpg.com/ i jest to sieciowy serwis dla rodzin adoptujących dzieci. Ostatni plik jest zbiorem zmiennych specyficznych dla szablonu. Witryna pozwala na tworzenie własnych profili poprzez odpowiedź na kilka prostych pytań oraz wybranie odpowiednich opcji. Gdy strona ta zostanie wywołana poprzez adres http://www. Trzeci jest mapą obrazu dla panelu nawigacyjnego. używane są szablony partnera.pokazany jest wygląd witryny po wybraniu tematu kolejowego. Każdy portal i wiele dużych witryn pozwalają na personalizowanie witryny tak. Na rysunku 14. Zamiast tworzyć przykłady dla tej części książki. Gdy Użytkownik kliknie ikonę tematu.jpg. aby spełniała potrzeby użytkownika.katalog. którą wykonałem. przedstawia wygląd strony po wywołaniu strony poprzez adres zapożyczonej witryny. która witryna została wywołana. Tą witryną jest http://www. {temat}_header. w bazie danych zapisywany jest wybrany identyfikator tematu i jest on używany później przy wyświetlaniu. PHP – Kompendium wiedzy 185 . Do stworzenia tematu potrzebne są cztery pliki: {temat}_navi.tpl oraz {temat}_vars.8. Wykorzystując szablony możliwa jest o wiele bardziej zaawansowana modyfikacja wyglądu witryny. które są dołączane do pliku skryptu PHP korzystającego z danych tematu. Każdy z dostępnych tematów jest przedstawiony w postaci ikony na stronie.3. Rysunek 14. Zapożyczenie katalogu produktów Personalizacja witryny Personalizacja wydaje się ostatnio najpopularniejszym elementem przy projektowaniu witryn. aby sprawdzić.$aTPL->FastPrint( 'BASE' ). Pierwsze dwie są rysunkami używanymi w nagłówku oraz panelu nawigacyjnym. ?> Po uruchamianiu tego skryptu analizowana jest zmienna $HTTP_HOST.8. Nie jest moim celem reklamować ten serwis.php.HopeToAdopt. {temat}_map. Przykład takiego pliku jest pokazany na wydruku 14.20. natomiast w pozostałych przypadkach używane są standardowe szablony.

FILLWIDTH => 584. Plik dołączany specyficzny dla tematu <?php function AddTemplateVars( &$tpl. Witryna HopeToAdopt. LEFTIMGHEIGHT => 312.20. ale poprzednie przykłady zawierają wystarczająco dużo informacji. Rozdział 14 – Witryny oparte o szablony 186 . } function GetTemplteValue( $aValName ) { switch ( $aValName ) { case "NavSide": return "left". Dodatkowo dostępna jest funkcja zwracająca do głównego skryptu dane na temat tematu. TABLECOLOR => "#ffadad")).Wydruk 14.10. Przykład ten jest specyficzny dla aplikacji HopeToAdopt.com jest używana jako działający przykład pokazujący siłę systemu szablonów — zamiast tworzenia kolejnego trywialnego przykładu. ale może służyć jako ilustracja elastyczności systemu szablonów. $aCurTemplate ) { $tpl->assign( array( BODYBGCOLOR => "#FFFFFF". MAINWIDTH => 584. aby stworzyć tego typu witrynę. oraz wysokość i szerokość różnych rysunków używanych w temacie. } } ?> Rysunek 14.com. case "HasOvr" : return False. Pełny kod tej witryny nie może być tutaj zamieszczony. TOPIMGWIDTH => 584. LEFTIMGWIDTH => 137. Profil użytkownika z tematem kolejowym Plik ten zawiera dane na temat kolorów wykorzystywanych w temacie. TOPIMGHEIGHT => 128.

'navimap' ). oraz główny plik.php" ).21. Nie będziemy tu zamieszczać wszystkich plików. $PHP_SELF . "?Lang=deu" ) ). polskim i niemieckim.14 pokazana jest strona główna w języku odpowiednio: angielskim. $PHP_SELF . $aHeaderImg. 14.21.phtml?Lang=$Lang".phtml?Lang=$Lang". ?> => => => => => => => => => "intl.13 i 14." ). pokażemy jedynie główny skrypt i wynik działania. ale efekt jest wart tej pracy. $aTPL = new FastTemplate( ". "links. elastyczność i siła tego rozwiązania jest ogromna.gif".tpl'. Niezależnie od prostoty przedstawionego przykładu. "body_{$Lang}. zamieszczony jest główny skrypt. 'navimap' => $aNaviMap ) ). $aTPL->FastPrint( 'BASE' ).phtml?Lang=$Lang". 'body' ). Drugą jest umieszczenie identyfikatorów języka w nazwach i plikach szablonów. mapa rysunku. który generuje jedną stronę międzynarodowej witryny opartej o szablony. $aTPL->parse( 'BASE'.gif". if ( empty( $Lang ) ) { $Lang = 'enu'. "about. W przykładzie tym. W dużych aplikacjach przedstawiona metoda definiowania wszystkich możliwych łączy staje się nieporęczna. Na rysunkach 14. } $aHeaderImg $aNaviImg $aNaviMap $aBodyTpl = = = = "intl_head_{$Lang}. "?Lang=pol". $aTPL->define( array( 'base' => 'intl_base.12.tpl". w porównaniu z innymi przedstawionymi w tym rozdziale jest część na początku ustalająca bieżący język i korzystająca z tej informacji w celu dołączenia właściwego pliku. Na wydruku 14. Jedyną widoczną różnicą w tym skrypcie.FastTemplate. $aTPL->assign( array( 'HREF_HOME' 'HREF_LINKS' 'HREF_ABOUT' 'HREF_CONTACT' 'HEADER_IMG' 'NAV_IMG' 'HREF_ENU' 'HREF_POL' 'HREF_DEU' $aTPL->parse( 'NAV_MAP'. $aNaviImg. Jedną z pierwszych decyzji jest zadecydowanie. I tym razem tworzenie tak skomplikowanej aplikacji wymaga uważnego projektowania przed rozpoczęciem prac programowych. Wydruk 14. rysunek panelu nawigacyjnego.Obsługa wielu języków Coraz częstsze jest tworzenie witryn działających w kilku językach. "?Lang=enu". a następnie w łatwy sposób dodać później kolejne języki. 187 PHP – Kompendium wiedzy . Metoda ta zostanie zastosowana w przykładzie. więc każde łącze w witrynie musi przesyłać tą daną do kolejnej strony. $aTPL->parse( 'BODY'. Główny skrypt międzynarodowej witryny <?php include( "class. "intl_map_{$Lang}. 'body' => $aBodyTpl.tpl". W praktyce kod generujący łącza prawdopodobnie będzie umieszczony w oddzielnym pliku dołączanym. Wykorzystując system szablonów do obsługi tej funkcji pozwala na tworzenie aplikacji w jednym języku. Jedną z metod jest stworzenie oddzielnych katalogów dla poszczególnych języków. W przykładzie tym identyfikator języka jest przesyłany poprzez adres URL. "contact. dla każdego języka wymagane są cztery pliki: rysunek nagłówka. $PHP_SELF . w jaki sposób będą dzielone i identyfikowane elementy właściwe dla języka. "intl_nav_{$Lang}.phtml?Lang=$Lang". 'base' ).

12. Witryna międzynarodowa w języku polskim Rozdział 14 – Witryny oparte o szablony 188 .13.Rysunek 14. Witryna międzynarodowa w języku angielskim Rysunek 14.

Dostarczone przykłady pokazują. personalizacji i obsługi języków.net/. Witryna międzynarodowa w języku niemieckim Podsumowanie W rozdziale tym pokazano jak zastosowanie systemu szablonów polepsza elastyczność i łatwość utrzymania aplikacji WWW. 189 PHP – Kompendium wiedzy . Niezależnie od rodzaju używanego systemu szablonów jest zalecane zapoznanie się z tym sposobem tworzenia aplikacji WWW.14.Rysunek 14. Używanym systemem szablonów jest FastTemplate. który można uzyskać pod adresem http://www. w jaki sposób można użyć szablonów do obsługi zapożyczania.thewebmasters.

a nie obsługa języka. Nieprawidłowy projekt bazy danych zwykle prowadzi do problemów z integracją. aby go tutaj przedstawić. funkcjonalność. Ponieważ PHP obsługuje wiele popularnych systemów baz danych. więc opisane zostaną niektóre podstawowe informacje. Dostępne są również inne bazy danych. która będzie wykorzystywana w dwóch kolejnych rozdziałach. Jeżeli przypuszczasz. Rozdziały te stanowią podstawę dla tego rozdziału. powinieneś rozważyć zastosowanie Oracle lub Microsoft SQL Server. że po stworzeniu aplikacji system bazy danych może być zmieniony na inny. Projekt bazy danych W każdym aspekcie tworzenia oprogramowania wynikiem dobrego projektu jest dobry produkt. Dodatkowo należy pamiętać o różnicach w obsłudze standardu SQL w różnych systemach baz danych. dostępnością obsługi technicznej. Wybór niewłaściwego systemu bazy danych może spowodować. Wybór właściwej bazy danych dla aplikacji wymaga wyboru pomiędzy ceną. skalowalnością i dostępnymi funkcjami. oraz w skorowidzu funkcji na końcu tej książki. „Współpraca z bazami danych” opisane zostały narzędzia PHP pozwalające na dostęp do baz danych. utrzymaniem i tworzeniem aplikacji. które także mają swoje silne strony. przy podejmowaniu tej decyzji powinniśmy wziąć pod uwagę koszty. która obsługiwać będzie dużą liczbę użytkowników lub potrzebujesz obsługi transakcji. Po wybraniu systemu bazy danych kolejnym krokiem jest stworzenie i dokładne przetestowanie modelu danych. Posiada on obsługę dużego podzbioru SQL oraz bogate API. oraz korzystać ze standardowego języka SQL. należy skorzystać z pośredniego API stanowiącego bufor pomiędzy aplikacją a funkcjami specyficznymi dla określonej bazy danych. ponieważ PHP posiada domyślnie wbudowaną obsługę MySQL. obsługującego w . więc zmiana systemu bazy danych na inny może być niepraktyczna nawet dla małych aplikacji. Dla przykładu w Oracle można korzystać z następujących podzapytań: SELECT * FROM tabela1 WHERE id IN (SELECT id FROM tabela2) W czasie pisania tej książki MySQL nie potrafił obsługiwać takiej konstrukcji. przeznaczonego dla wielu sprzedawców lub sklepów. Pierwszą decyzją jaką należy podjąć jest wybór systemu zarządzania bazą danych (SZRBD). skalowalność oraz inne kluczowe aspekty bazy danych. Prawidłowe projektowanie baz danych jest tematem wielu wspaniałych książek i jest to temat zbyt obszerny i skomplikowany. Więcej na ten temat można przeczytać w rozdziale 6. W ostatnim rozdziale dokładnie opisane jest wykorzystanie systemu szablonów do oddzielenia interfejsu aplikacji od kodu aplikacji. Witryny oparte o bazę danych Wstęp W rozdziale 6. Tworzenie kodu SQL niezależnego od systemu bazy danych jest wyzwaniem samym w sobie.Rozdział 15. Informacje na temat instalacji i korzystania z MySQL znajdują się w rozdziale 6. W tym rozdziale opisany zostanie proces projektowania i implementacji bazy danych. Przykłady w tym rozdziale są napisane w oparciu o bazę danych MySQL. Dla wielu aplikacji PHP świetnym systemem bazy danych jest MySQL. Celem jest stworzenie sieciowego katalogu. Jako przykładu użyjemy sieciowego katalogu towarów. W rozdziale tym opisane są szczegóły projektu i implementacji na wysokim poziomie. więc nie będą opisane niskopoziomowe funkcje obsługi baz danych. MySQL jest dostępny na zasadach licencji GNU General Public License (GPL). Jeżeli masz zamiar stworzyć aplikację. że w przypadku dużego obciążenia aplikacja będzie miała niską wydajność lub odmówi posłuszeństwa.

2. null. 191 PHP – Kompendium wiedzy . Jego implementacja w SQL zamieszczona jest na wydruku 15. Podstawowy model danych katalogu towarów Rozwijając model z rysunku 15. każdy sprzedawca może mieć jedną lub więcej kategorii produktów. not null. a każdy z tych sprzedawców może mieć wiele kategorii produktów. index( name ). null.jednej bazie danych fragmenty danych przypisane do różnych sprzedawców.1.1. null. Rysunek 15. Rysunek 15. Na tym poziomie szczegółowości można stworzyć kompletny model danych. Pełny model danych katalogu towarów Wydruk 15. not null. Ogólny schemat tej bazy danych jest pokazany na rysunku 15. Na rysunku 15. Implementacja modelu danych katalogu produktów CREATE TABLE mcMerchants ( merchant_id int name varchar(50) created_date datetime internal_status int addtl_handling float mgr_email varchar(25) mgr_username varchar(30) mgr_password varchar(30) mgr_name varchar(50) primary key ( merchant_id ). null. CREATE TABLE mcCategories ( merchant_id int category_id int name varchar(50) not not not not default 0.1. null.0 not not not not not null. null. null.2 pokazany jest kompletny model danych katalogu produktów.1. null. not null. index( mgr_username ) ).1. a każda z kategorii może zawierać jeden lub więcej produktów.

primary key ( merchant_id. celem jest dostarczenie metody na dodawanie. zmianę i wyświetlanie dowolnej danej zawartej w katalogu produktów. not null. value_id ). null. not null. • Umożliwienie sprzedawcom zarządzanie kategoriami produktów i przypisywanie produktów do kategorii w dowolnym momencie z dowolnego komputera przyłączonego do sieci Internet. primary key ( merchant_id. Podstawowymi założeniami aplikacji katalogu produktów są: • Wyświetlanie danych o produktach w logicznym i łatwym do użycia formacie. index( name ) ). null. product_id. primary key ( merchant_id. null. category_id. null. product_id ) not not not not not null. category_id ). product_id. CREATE TABLE mcProductsOptions ( merchant_id int product_id int option_id int name varchar(100) sort_type tinyint default 0 not not not not not not not not not not not null. null. Zarządzanie danymi aplikacji Po zaprojektowaniu i stworzeniu bazy danych można rozpocząć tworzenie aplikacji zarządzającej rekordami w bazie danych. option_id. wykorzystując do tego celu Internet. index( name ) ). • Umożliwienie sprzedawcom uaktualniania danych o produktach w dowolnym momencie z dowolnego komputera przyłączonego do sieci Internet. null. Mówiąc prościej. null. Podstawowymi operacjami jakie można przeprowadzać na dowolnych danych jest Rozdział 15 – Witryny oparte o bazę danych 192 . CREATE TABLE mcProducts ( merchant_id int product_id int category_id int name varchar(200) descr text has_image_file tinyint default 0 external_id varchar(100) ship_weight float price float created_date datetime deleted tinyint default 0 primary key ( merchant_id. null.created_date deleted datetime tinyint default 0 not null. product_id ). primary key ( merchant_id. null. null. null. CREATE TABLE mcProductsOptionsValues ( merchant_id int product_id int option_id int value_id int name varchar(100) not not not not not null. null. option_id ). index( name ) ). Po zaprojektowaniu i sprawdzeniu modelu danych można rozpocząć prace nad aplikacją. null. not null. null. null. null. null. index( name ) ). not null. W następnej sekcji opisane zostanie zarządzanie tymi danymi. null. CREATE TABLE mcProductsToCategories ( merchant_id int category_id int product_id int ).

tpl) <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="mgmt.&nbsp. Szablony używane do stworzenia strony zarządzania konkretną kategorią umieszczone są na wydrukach od 5. Wydruk 15.6. </p> {EXISTING_CATEGORIES} Wydruk 15. W aplikacji będziemy korzystać z omówionego wcześniej systemu szablonów FastTemplate.Identyfikator kategorii&nbsp. </p> Szablony przedstawione na wydrukach od 2.tpl) <table width="630" align="center"> <tr> <td align="center" class="title"> {MERCHANT_NAME} </td> </tr> <tr> <td> {PAGE_BODY} </td> </tr> <tr> <td> &nbsp. do 4. W tej aplikacji niezbędne będzie również zarządzanie hierarchią danych.3. ze sprzedawca może się zalogować do fragmentu witryny w celu zarządzania danymi. Wszystkie prawa zastrzeżone. do 7.8.&nbsp.tpl) <h1> Zarządzanie kategoriami produktów </h1> <p> Proszę użyć poniższych narzędzi do dodaniam edycji i usunięcia kategorii produktów.tpl) <h2> Istniejące kategorie produktów: </h2> <table cellspacing="0" cellpadding="0"> <tr> <th> &nbsp. Podstawowy szablon zarządzania danymi aplikacji (mgmt_app_base. Mając na uwadze tą zasadę. 2000 Intechra LLC. Szablon zarządzania danymi aplikacji — tabela kategorii (mgmt_cats_table. musi istnieć co najmniej jedna kategoria produktów dla sprzedawcy. </td> </tr> <tr> <td> {FOOTER} </td> </tr> </table> Wydruk 15.&nbsp.2. Aby spełnić to wymaganie. Szablon zarządzania danymi aplikacji — stopka (mgmt_footer.Nazwa kategorii&nbsp.phtml">Kliknij tutaj</a> aby dodać kategorię. Szablon zarządzania danymi aplikacji (mgmt_body. </th> <th> &nbsp. Na wydruku 15. Do podstawowego zarządzania danymi aplikacji użyte zostaną szablony przedstawione na wydrukach od 2. W aplikacji tej zakładamy. znajduje się skrypt łączący te szablony i wyświetlający dane z bazy danych. spełniona musi być zasada.&nbsp. do 4.tpl) <hr> <p class="footer"> &copy. </th> 193 PHP – Kompendium wiedzy . Wydruk 15.5. </p> <p> <a href="mgmt_cat_add.css"> </head> <body bgcolor="White"> {BODY} </body> </html> Wydruk 15. stanowią podstawowy szablon aplikacji zarządzania danymi. Szablon zarządzania danymi aplikacji — główny szablon kategorii (mgmt_cats_ovr. zmiana i usuwanie. logicznym punktem startowym jest strona z możliwością zarządzania kategoriami produktów.dodawanie.4. że przed dodaniem jakiegokolwiek produktów.

phtml?cat_id={CAT_ID}">USUŃ</a> </td> </tr> Wydruk 15. } else { $aTPL->assign( array( } $aTPL->assign( array( "EXISTING_CATEGORIES" => "" ) ). Szablon zarządzania danymi aplikacji — bieżąca kategoria (mgmt_cats_item." ). session_start().&nbsp. $aDB = new mgmt_db(). $aTPL->assign( array( "CAT_ID" => $aCatID.tpl". } include( "class. "mgmt_cats_item. "body" ).phtml?cat_id={CAT_ID}">ZMIEŃ</a> <a href="mgmt_cat_del. $aSQL = "select category_id. Jeżeli nie jest on ustawiony. "base" ). ?> Pierwszą operacją jaką wykonuje skrypt jest rozpoczęcie sesji i sprawdzenie identyfikatora sprzedawcy. $aTPL->parse( "CATEGORY_LIST".cat_item" ). // niejawne ustawienie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { header( "Location: login. "page_body" ).php" ). Aplikacja zarządzająca danymi — zarządzanie kategoriami (mgmt_cats. "\n" ).php" ). include( ".<th> &nbsp.tpl". include( ". "TITLE" => "MERCHANT_NAME" => ) ). $aTPL->parse( "FOOTER". "mgmt_cats_ovr. "cat_table" ). $aTPL = new FastTemplate( ".Operacje&nbsp. } $aTPL->parse( "EXISTING_CATEGORIES". $aMerchantID ) $aTPL->parse( "PAGE_BODY".phtml) <?php error_reporting( E_ALL & ~E_NOTICE ). GetMerchantName( $aDB. "mgmt_footer. $aTPL->define( array( "base" "body" "footer" "page_body" "cat_table" "cat_item" => => => => => => "mgmt_app_base. "footer" ). Na stronie logowania sprawdzane są dane użytkownika i jeżeli zostanie on rozpoznany.phtml?retpage=" . "mgmt_body.tpl".tpl"./mgmt_db.tpl) <tr> <td> {CAT_ID} </td> <td> {CAT_NAME} </td> <td class="small"> <a href="mgmt_cat_edit.&nbsp. name from mcCategories where ( merchant_id = $aMerchantID )".FastTemplate.7. $aTPL->parse( "PAGE". exit. ta zmienna sesji jest inicjowana identyfikatorem Rozdział 15 – Witryny oparte o bazę danych 194 .8. "mgmt_cats_table. urlencode( $REQUEST_URI ) . $aCatName = $aDB->f( "name" ). $aDB->query( $aSQL ). ".tpl" ) ). $aTPL->parse( "BODY". "Zarządzanie katalogiem towarów". $aMerchantID. </th> </tr> {CATEGORY_LIST} </table> Wydruk 15. $aTPL->FastPrint( "PAGE" ).tpl"./mgmt_funcs. użytkownik jest kierowany na stronę logowania.php" ). "CAT_NAME" => $aCatName ) ). if ( $aDB->num_rows() > 0 ) { while ( $aDB->next_record() ) { $aCatID = $aDB->f( "category_id" ).

10.3.9. Wydruk 15. Strona zarządza nia kategoria mi katalogu produktó w Dodawanie kategorii jest zrealizowane za pomocą kliknięcia w łącze.phtml) <?php session_start(). szablony dodawania kategorii oraz skrypt umieszczone są na wydrukach 9. urlencode( $REQUEST_URI ) . na rysunku 15. skrypt ten pobiera kategorie z bazy danych. Jeżeli istnieje co najmniej jedna kategoria.3.sprzedawcy. exit.3. // niejawne ustawienie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { header( "Location: login.FastTemplate. 195 PHP – Kompendium wiedzy . pokazana jest strona z dwiema kategoriami testowego sprzedawcy.php" ).phtml?retpage=" . i 10.tpl) <h1> Dodawanie kategorii produktu </h1> <form action="{FORM_ACTION}" method="post"> <table> <tr> <td colspan="2"> {ERRORS} </td> </tr> <tr> <td> Nazwa kategorii: </td> <td> <input type="text" name="CategoryName"> </td> </tr> <tr> <td colspan="2"> <input type="submit" name="Submit" value="Wyślij"> </td> </tr> </table> </form> Wydruk 15. } include( "class. Aplikacja zarządzająca danymi — dodawanie kategorii (mgmt_cat_add. Szablon zarządzania danymi aplikacji — dodawanie kategorii (mgmt_cat_add. Następnie używając identyfikatora jako filtru. Rysunek 15. Na rysunku 15. skrypt pobiera te dane i generuje tabelę istniejących kategorii. Jeżeli istnieją kategorie. każda z nich posiada własne łącza ZMIEŃ i USUŃ. "\n" ).

$aMerchantID. $aDB = new mgmt_db(). "mgmt_body. jest podobny do wielu innych skryptów zbierających i kontrolujących dane. ponieważ jest on bardzo podobny do kodu z wydruków 9. "base" ). jakie mogą wystąpić. $aTPL->parse( "PAGE_BODY"./mgmt_db. "page_body" ). Te funkcje pomocnicze zostaną zamieszczone w dalszej części rozdziału na wydruku pliku mgmt_funcs. można zauważyć. Tworząc aplikacje WWW działające w oparciu o bazę danych. } } $aTPL->define( array( "base" "body" "footer" "page_body" => => => => "mgmt_app_base. exit. Podczas tworzenia kategorii należy pamiętać. $aTPL->parse( "FOOTER".phtml?cat_id=1. Dla przykładu pełny adres URL do usuwania kategorii Ubrania to http://server.= "Proszę wybrać inną nazwę kategorii. i 10. Jest on używany do wyświetlenia formularza oraz kontroli poprawności wprowadzonych danych./mgmt_funcs. Funkcje edycji i usuwania kategorii są bardzo podobne do innych skryptów zamieszczonych już w tej książce. ?> Skrypt przedstawiony na wydruku 15. $aMerchantID. ten sam mechanizm umożliwia wczytanie nazwy kategorii do pola tekstowego. więc można na jego podstawie skonstruować proste wyrażenie SQL DELETE. czy nie istnieje produkt należący do tej kategorii.phtml\n" ). Inne zasady mogą być realizowane w bazie danych za pomocą wyzwalaczy lub procedur przechowywanych.". $aTPL->parse( "PAGE".php" ). GetMerchantName( $aDB.tpl" ) ). Funkcja sprawdzająca poprawność szuka jedynie kategorii o takiej samej nazwie. Tworząc kod obsługi zasad biznesowych dobrą praktyką jest tworzenie funkcji obsługi wszystkich zasad.php" ). $aErrors $aTPL->assign( array( "TITLE" "MERCHANT_NAME" "FORM_ACTION" "ERRORS" ) ). $CategoryName ).).include( ". } else { $aErrors = "Nazwa kategorii została już użyta. "mgmt_footer. if ( $REQUEST_METHOD == 'POST' ) // Tutaj wchodzimy po wysłaniu danych z formularza { if ( IsValidCategory( $aDB. Do skryptu jest przekazany identyfikator kategorii. $aErrors . Niektóre z zasad mogą być realizowane przez funkcje bazy danych. spełnienie wszystkich zasad biznesowych w kodzie jest krytyczne do dobrego działania aplikacji. W tym przypadku cała logika kontroli poprawności oraz zapamiętywania nowych kategorii jest umieszczona w funkcjach IsValidCategory() i SaveCategory()." ). Dla przykładu należy użyć funkcji DeleteEntity() zamiast wplatać w kod wyrażenia DELETE. $aTPL = new FastTemplate( ".php (wydruk 15. na przykład wymuszanie więzów integralności lub kaskadowe operacje na danych. Pozostałe zasady biznesowe muszą być realizowane w kodzie aplikacji. W przypadku edycji. $aTPL->FastPrint( "PAGE" ). "footer" ).tpl". że nazwa nowej kategorii nie może znajdować się w bazie danych. => => => => "Zarządzanie katalogiem produktów". W Rozdział 15 – Witryny oparte o bazę danych 196 . $aTPL->parse( "BODY". header( "Location: mgmt_cats.tpl". że łącza do usuwania i zmiany kategorii zawierają identyfikator kategorii.php. $aErrors = "". "mgmt_cat_add. $CategoryName ) == True ) { SaveCategory( $aDB.tpl".com/ch15/mgmt_cat_del. Funkcje usuwające i zmieniające kategorie pokazane są na wydruku pliku mgmt_funcs.10. "body" ). Przyglądając się wydrukowi 8. W przypadku usuwania kategorii należy sprawdzić. Jeżeli do kategorii należą jakieś produkty usunięcie kategorii spowodowałoby powstanie osieroconych rekordów produktów i potencjalnie błędów aplikacji. $aMerchantID ). które były opisane w tej książce. Funkcja DeleteEntity() może zawierać w sobie całą logikę wymaganą do kontroli więzów integralności oraz zasad biznesowych i zwracać różne wartości kodu powrotu w zależności od różnych błędów. ". Kod źródłowy tych stron nie został tu zamieszczony. include( ". $PHP_SELF.12.

tpl". $aProdID = $aDB->f( "product_id" )."\n" ).tpl". $aTPL = new FastTemplate( ". $aSQL . "mgmt_prods_item. Ekran zarządza nia produkta mi Wydruk 15.". natomiast na wydruku 15. "mgmt_prods_ovr.category_id)". Wracając do katalogu produktów. "mgmt_footer. $aDB = new mgmt_db().price.name as cat_name from mcProducts a. include( ". $aProdName = $aDB->f( "name" ). kolejnym krokiem jest utworzenie stron obsługi aktualnego zestawu produktów.4 pokazana jest strona zarządzania produktami. session_start().category_id = b.php" ).external_id.name. $aSQL .tpl". znajduje się skrypt generujący tą stronę.= "b.php" ).11. $aDB->query( $aSQL ).tpl"./mgmt_db. // niejawne ustawianie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { header( "Location: login.tpl" ) ). "mgmt_body. $aTPL->define( array( "base" "body" "footer" "page_body" "prod_table" "prod_item" => => => => => => "mgmt_app_base.product_id.= "= $aMerchantID) and (a. mcCategories b where (a. Na rysunku 15.11. Rysunek 15. } include( "class. $aProdPrice = $aDB->f( "price" )." ). Aplikacja zarządzania danymi — zarządzanie produktami (mgmt_prods.php" ). Strony te są logicznie identyczne ze stronami obsługi kategorii. urlencode( $REQUEST_URI ). "mgmt_prods_table. $aSQL = "select a.FastTemplate. include( ". a. $aTPL->assign( array( "PROD_ID" => $aProdID. $aProdEID = $aDB->f( "external_id" ).tpl".category_id.merchant_id". a. 197 PHP – Kompendium wiedzy .phtml) <?php error_reporting( E_ALL & ~E_NOTICE ).phtml?retpage=" . $aCatName = $aDB->f( "cat_name" ).4. a.ten sposób poprawia się możliwość późniejszego użycia kodu oraz ułatwia wprowadzanie do aplikacji zmian w logice./mgmt_funcs. exit. if ( $aDB->num_rows() > 0 ) { while ( $aDB->next_record() ) { $aCatID = $aDB->f( "category_id" ). a.

$aTPL->parse( "PAGE". ". "PROD_CAT" => $aCatName. "PROD_PRICE" => '$' . "Zarządzanie katalogiem produktów". $aTPL->parse( "FOOTER". Zasady biznesowe obowiązujące przy dodawaniu nowych produktów są następujące: • Produkt musi zostać przypisany do jednej kategorii. Rozdział 15 – Witryny oparte o bazę danych 198 . GetMerchantName( $aDB.php) <?php function GetMerchantName( $aDB. "page_body" ). • Nazwy produktów w kategorii muszą być unikalne. } else { $aTPL->assign( array( } $aTPL->assign( array( "TITLE" => "MERCHANT_NAME" => ) ). $aTPL->parse( "PAGE_BODY". if ( $aDB->next_record() == True ) { $aResult = $aDB->f( "name" ). $aSQL . $aDB->query( $aSQL ). number_format( $aProdPrice. "body" ). } return $aResult. $aSQL = "select name from mcMerchants where ".= "( merchant_id = $aMerchantID )". $aTPL->parse( "PRODUCT_LIST".= "( upper( name ) = upper( '$aCategoryName' ) )". $aSQL .12 zamieszczony został fragment pliku mgmt_funcs.php zawierający niektóre funkcje dostępu do bazy danych oraz funkcje zasad biznesowych używanych w aplikacji. $aDB->query( $aSQL ).= "( merchant_id = $aMerchantID ) and ". $aMerchantID ) "EXISTING_PRODUCTS" => "" ) ). $aMerchantID ) { $aSQL = "select ( max( category_id ) + 1 ) as new_id ". • Cena produktu musi wynosić co najmniej zero. "base" ). ?> Strony umożliwiające dodawanie.12. "prod_table" ). $aTPL->FastPrint( "PAGE" ). // Jeżeli istnieje rekord z tą samą nazwą kategorii. • Waga towaru również musi wynosić co najmniej zero. } function IsValidCategory( $aDB. } $aTPL->parse( "EXISTING_PRODUCTS". "footer" ). Po zmianie danych produktu muszą być spełnione te same zasady biznesowe co przy dodawaniu nowego produktu. } function NewCategoryID( $aDB. ale są dostępne na stronie WWW wymienionej w zasobach sieci na końcu książki.prod_item" ). } return $aResult. $aCategoryName ) { $aSQL = "select category_id from mcCategories where ". } if ( empty( $aResult ) == True ) { $aResult = 1. $aSQL . $aDB->query( $aSQL ). if ( $aDB->next_record() ) { $aResult = $aDB->f( "new_id" ). Aplikacja zarządzająca danymi — funkcje użytkowe (mgmt_funcs.= "from mcCategories where ( merchant_id = $aMerchantID )"."PROD_EID" => $aProdEID. W chwili obecnej nie ma ograniczeń na kasowanie produktów. $aMerchantID. Na wydruku 15. usuwanie i zmianę produktów nie zostały tutaj szczegółowo przedstawione. "PROD_NAME" => $aProdName. Wydruk 15. 2 ) ) ). $aTPL->parse( "BODY". $aMerchantID ) { $aResult = "". $aSQL .

$aDB->query( $aSQL ). 199 PHP – Kompendium wiedzy .= " NOW() )". } function SaveCategory( $aDB.= "$aMerchantID ) and ( category_id = $aCategoryID )".= "category_id. Na wydruku 15.13. Na rysunku 15. pozwalający na znalezienie określonego produktu.= "where ( merchant_id = $aMerchantID ) and ".= "( category_id = $aCategoryID )". wyświetlanie alfabetycznej listy produktów oraz zapewnia mechanizm przeszukiwania. Aby odszukać produkty i kategorie bieżącego sprzedawcy wykorzystywany jest identyfikator sprzedawcy. Strona ta pozwala na natychmiastowy dostęp do danych podzielonych na kategorie oraz na przeszukiwanie katalogu. } function DeleteCategory( $aDB. $aCategoryName ) { $aNewID = NewCategoryID( $aDB.= "( $aMerchantID. $aCategoryName ) { $aSQL = "update mcCategories set name='$aCategoryName' ". return ( $aDB->Errno == 0 ). $aNewID. $aDB->query( $aSQL ). $aDB->query( $aSQL ). $aSQL . zamieszczony jest skrypt generujący tą stronę. $aSQL . $aSQL .5. ". created_date ) values ". $aMerchantID. Jeżeli nie ma zarejestrowanych żadnych kategorii (co oznacza brak towarów). Zmienna ta jest ustawiana jeszcze zanim użytkownik wejdzie na stronę. } function UpdateCategory( $aDB. $aSQL . $aCategoryID ) { $aSQL = "delete from mcCategories where ( merchant_id = ". } // i inne funkcje ?> Aplikacja zarządzająca danymi jest jedynie małym fragmentem całego katalogu produktów. '$aCategoryName'. $aMerchantID. przekazywany w postaci zmiennej sesji. Następna część tego rozdziału traktuje właśnie o tych zagadnieniach. return ( $aDB->Errno == 0 ). szukania produktów oraz odczytywania szczegółowych danych o produktach w katalogu. name. return ( $aDB->Errno == 0 ). wyświetlana jest informacja. na której wyświetlane są informacje o produktach. Wyświetlanie danych Aplikacja wyświetlająca dane produktów z bazy pozwala na wyświetlanie produktów określonej kategorii. Zapewnia ona interfejs WWW do zarządzania elementami katalogu. że dla ten sprzedawca nie ma zarejestrowanych produktów. znajduje się główna strona katalogu produktów. $aMerchantID ). $aSQL . $aSQL . ". $aSQL = "insert into mcCategories ( merchant_id. $aMerchantID.// zwróć false return ( $aDB->num_rows() == 0 ). $aCategoryID. Inną ważną funkcją katalogu jest możliwość wyświetlania produktów.

phtml) <?php error_reporting( E_ALL & ~E_NOTICE ). Rozdział 15 – Witryny oparte o bazę danych 200 . "mgmt_main." ). $aDB->query( $aSQL ). } include( "class. $aTPL->define( array( "base" "body" "footer" "page_body" "cat_body" "cat_item" => => => => => => "mgmt_app_base.php" ). Aplikacja zarządzająca danymi — wyświetlanie produktów (mgmt_main.tpl". "mgmt_main_body. $aCatName = $aDB->f( "name" ). $aTPL->assign( array( "CAT_HREF" => GetCategoryHREF( $aCatID )./mgmt_db.php" ). Główna strona katalogu produktó w Wydruk 15.5. "CAT_NAME" => $aCatName ) ). $aDB = new mgmt_db(). "mgmt_body.tpl". "mgmt_footer.php" ).tpl".13.cat_item" ). // niejawne ustawianie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { print( "Błąd wewnętrzny aplikacji. "mgmt_main_cat_item. include( ".tpl" ) ). include( ".tpl"." ). $aSQL = "select category_id. if ( $aDB->num_rows() > 0 ) { while ( $aDB->next_record() ) { $aCatID = $aDB->f( "category_id" ). ". } else { $aTPL->assign( array("CATALOG_MAIN_BODY" => "Brak dostępnych produktów. exit./mgmt_funcs. session_start(). } $aTPL->parse( "CATALOG_MAIN_BODY".tpl".Rysunek 15.FastTemplate." ) ). name from mcCategories where ( merchant_id = $aMerchantID )". $aTPL->parse( "CATEGORY_LIST". $aTPL = new FastTemplate( ". Brak identyfikatora sprzedawcy. "cat_body" ).

= "a.14. W skrypcie pokazanym na poprzednim wydruku.descr.category_id = b. } else { if ( empty( $cat_id ) == False ) // lista według kategorii { $aSQL = "select a.category_id = b. a. a.ship_weight.= "and ( a.= "upper( '%{$SearchTerms}%' ) ) ) order by a.has_image_file. b. a.= "mcProducts a.name.= "mcProducts a. } include_once( "class. $aMerchantID ) Pliki szablonów użyte do wygenerowania tej strony są bardzo podobne do tych. mcCategories b where ". $aSQL . if ( $REQUEST_METHOD == 'POST' ) // Tutaj wchodzimy po wysłaniu danych z formularza { $aSQL = "select a.15.phtml?cat_id=$aCatID". $aTPL->parse( "PAGE_BODY". session_start().html".name".= "and (a. Funkcja ta wchodzi w skład pliku mgmt_funcs. $aTPL->FastPrint( "PAGE" ).ship_weight. a.category_id ) and ( ( upper( a. $aSQL . a.category_id = b.merchant_id = $aMerchantID) ".name".category_id = $cat_id ) order by a. zamieszczony został skrypt wyświetlający produkty. a.} $aTPL->assign( array("TITLE" => "MERCHANT_NAME" => ) ).name". include_once( "mgmt_funcs. ".name as ".php i jest przedstawiona na wydruku 15. a. została wykorzystana funkcja GetCategoryHREF(). Metoda ta zostanie opisane szczegółowo w następnym rozdziale. a. a. exit. $aDynamic = True ) { if ( $aDynamic == True ) { return "mgmt_prod_list.category_id.php" ).category_id) ".php" ). Brak identyfikatora sprzedawcy.has_image_file.price. Przykład skryptu wyświetlającego produkty <?php error_reporting( E_ALL & ~E_NOTICE ).product_id. zamieszczonym na poprzednim wydruku.external_id.external_id.FastTemplate.15.php" ). a.descr.name ) like ".external_id. $aSQL .= "and ( a. a. } else { return "mgmt_cat_{$aCatID}. $aSQL . include_once( "mgmt_db. "page_body" ). $aSQL .= "upper( '%{$SearchTerms}%' ) ) or ( upper( a. b. $aSQL . $aSQL . a. listy alfabetycznej oraz wyników wyszukiwania. Funkcja ta pozwala na wygenerowanie przez ten skrypt serii statycznych stron na podstawie dynamicznych danych. ".category_id) order by a. $aTPL->parse( "PAGE".product_id. Wydruk 15. a. a. } } 201 PHP – Kompendium wiedzy . b. $aTPL->parse( "BODY".= "cat_name from mcProducts a. "body" ).merchant_id = $aMerchantID) and (a.name.ship_weight. a. $aSQL . "base" ). a." ). $aTPL->parse( "FOOTER". $aSQL . a.descr. $aSQL . } else // lista alfabetyczna { $aSQL = "select a.descr ) like ". GetMerchantName( $aDB. } } Na wydruku 15. Funkcja GetCategoryHREF() function GetCategoryHREF( $aCatID. mcCategories b where (a. $aSQL . ". ?> "Zarządzanie katalogiem produktów". do generowania adresów URL dla poszczególnych nazw kategorii.name as cat_name from ". które były używane w skrypcie zarządzającym kategoriami.has_image_file.14.category_id.merchant_id = $aMerchantID) ". a.product_id. Jest on używany do wyświetlania listy podzielonej na kategorie.price.name as cat_name from ". "footer" ). mcCategories b where ( a.= "(a. Wydruk 15.category_id.= "a. $aSQL .price.name. // niejawne ustawianie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { print( "Błąd wewnętrzny aplikacji.= "a. $aMerchantID = 1.

Rozdział 15 – Witryny oparte o bazę danych 202 ." ). } $aTPL->assign( array( "PROD_NAME" "CAT_NAME" "PROD_EID" "PROD_PRICE" "PROD_DESCR" "IMAGE_FILE" ) ). $aTPL->define( array( "base" "body" "footer" "page_body" "prod_item" => => => => => "mgmt_app_base. W oparciu o te informacje. GetMerchantName( $aDB. $aProdWeight = $aDB->f( "ship_weight" ). "mgmt_prod_item. oznacza to. pokazane są odpowiednio: lista dla pojedynczej kategorii. 15. $aCatID = $aDB->f( "category_id" ). $aTPL->parse( "FOOTER". generowane jest odpowiednie zapytanie SQL. "mgmt_body. "footer" ). $aProdEID.6.8. $aProdEID = $aDB->f( "external_id" ). "Zarządzanie katalogiem produktów". Jeżeli ustawiona została zmienna $cat_id. $aTPL->parse( "PAGE". potrzebna jest lista dla określonej kategorii. i 15. $aDB = new mgmt_db(). jaki zbiór danych powinien zostać wybrany. $aCatName. $aTPL->FastPrint( "PAGE" ). if ( $aDB->num_rows() > 0 ) { while ( $aDB->next_record() ) { $aProdName = $aDB->f( "name" ). 2 ). "base" ). Szukaną frazą było „pol”. number_format( $aProdPrice. ?> Pierwszą operacją podejmowaną przez skrypt jest sprawdzenie. $aMerchantID ) => => => => => => ).. Na rysunkach 15. "mgmt_footer. $aImageFile $aTPL->parse( "PAGE_BODY".prod_item" } } else { $aTPL->assign( array("ITEM_LIST" => "Nie ma produktów dla wybranego kryterium.'zł'. $aDB->query( $aSQL ).tpl". Jeżeli jest on uruchomiony poprzez wywołanie POST.. lista alfabetyczna oraz lista wyników wyszukiwania. "mgmt_prod_main. Jeżeli jest on ustawiony.")).tpl". generowana i wykorzystywana jest standardowa nazwa pliku.7. if ( $aHasImage == True ) { $aImageFile = "images/{$aMerchID}_{$aCatID}_{$aProdID}. $aProdDescr = $aDB->f( "descr" ). W zależności od wyniku zapytania wynikowa strona zawiera listę produktów albo komunikat.tpl".tpl". $aCatName = $aDB->f( "cat_name" ). lub tylko dla jednej kategorii. Dla każdego rekordu sprawdzany jest znacznik has_image_file. $aProdPrice = $aDB->f( "price" ).$aTPL = new FastTemplate( ". "page_body" ). "body" ).jpg". który informuje użytkownika o braku produktów dla wybranej przez niego kryteriów. $aProdName. natomiast w przeciwnym wypadku wyświetlany jest domyślny rysunek.tpl" ) ). $aHasImage = $aDB->f( "has_image_file" ). W przeciwnym przypadku należy wygenerować listę alfabetyczną.jpg". że użytkownik chciał wyszukiwać dane. $aProdID = $aDB->f( "product_id" ). $aTPL->parse( "ITEM_LIST". $aImageFile = "images/default. $aTPL->parse( "BODY". ". } $aTPL->assign( array( "TITLE" => "MERCHANT_NAME" => ) ). $aProdDescr.

Rysunek 15.6. Alfabetycz na lista produktów 203 PHP – Kompendium wiedzy . Lista dla kategori i (katego ria ubrania ) Rysunek 15.7.

która jest bardzo łatwa do zarządzania. Następne dwa rozdziały są zbudowane w oparciu o dane i przykłady tu zaprezentowane.Rysunek 15. Zwykle wyświetlanie danych z bazy danych jest dużo łatwiejsze od manipulowania danymi. Po stworzeniu systemu administracyjnego aplikacja może być w uaktualniania dowolnym momencie i z dowolnego miejsca świata. oraz zlokalizowanie wszystkich reguł biznesowych. Podsumowanie Tworzenie aplikacji WWW korzystających z bazy danych wymaga dokładnego projektowania i programowania. ale wynik jest wart zachodu. Rozdział 15 – Witryny oparte o bazę danych 204 . ponieważ występuje tu mniej problemów i mniej możliwości wystąpienia błędu. Jeżeli te elementy zostaną odpowiednio zaprojektowane i zaprojektowane. co skutkuje powstaniem dynamicznej witryny WWW.8. konserwacja i utrzymanie aplikacji zostanie niezwykle uproszczone. Najważniejszym krokiem jest dokładne zaprojektowanie bazy danych. Lista wyników wyszukiwa nia (szukanie „pol”) W sekcji tej skupiliśmy się na wyświetlaniu danych w witrynie WWW.

wymagająca wprowadzenia jedynie minimalnych zmian. Jest logicznie identyczny ze skryptem z wydruku7 z rozdziału 6. class MySQLDBTest extends DB_Sql . katalog produktów z poprzedniego rozdziału jest dynamiczny jedynie w tym sensie. Zawartością tą może być najprostszy licznik odwiedzin. można zastosować funkcje PHP pozwalające kontrolować mechanizm buforowania do przechwycenia wynikowego kodu HTML i zapisania go do pliku. gdy po zmianie wartości w bazie danych trzeba powtórnie wygenerować stronę. Koncepcja Jednym z pomysłów na stworzenie statycznych stron jest wysyłanie kodu HTML do pliku zamiast do przeglądarki. Listy te są pobierane z bazy danych. ale każdy użytkownik powinien zobaczyć te same produkty i kategorie. Skrypt ten generuje kod strony na której można wybrać stan USA oraz kraj. Dla przykładu. Można to łatwo zrealizować korzystając ze standardowych funkcji obsługi plików w PHP. że można zmieniać produkty. Wykorzystanie buforowania do tworzenia statycznych stron HTML z PHP <?php ob_start(). Na szczęście. przy minimalnej ilości zmian. Generowanie stron statycznych Ponieważ PHP jest niezwykle elastyczny. że skrypt nie uruchamia się przy każdym wywołaniu. przy pomocy PHP można z łatwością wygenerować takie strony. Ten sposób opisany jest w części pod tytułem „Techniki buforowania”. Pierwszym sposobem jest wykorzystanie funkcji buforujących. można zrezygnować z pobierania tych elementów z bazy danych za każdym razem.Rozdział 16.php" ). Dla większości witryn jest to niepraktyczne. drugim jest wykorzystanie klasy FastTemplate opisanej w poprzednich rozdziałach. Działanie takie ma jednak sens jedynie wtedy. Innym sposobem na poprawianie wydajności serwera jest buforowanie stron. Generowanie statycznych stron HTML w oparciu o dynamiczne dane Wstęp Podstawowym zastosowaniem PHP jest tworzenie stron WWW z dynamicznie zmieniającą się zawartością. aż do personalizowanych stron korzystających z bazy danych. istnieją co najmniej dwa sposoby generowania statycznych stron z istniejących skryptów PHP. Wydruk 16. ponieważ lista stanów USA oraz krajów nie zmienia się często. Użycie buforowania Jeżeli rozmiar witryny nie jest zbyt duży. Istnieje lepsza metoda. aby cały kod HTML był włączony w kod PHP. W takich sytuacjach bardziej efektywne jest jednokrotne generowanie statycznych stron HTML (po zmianie danych źródłowych) i ich wyświetlanie w odpowiedzi na żądania użytkowników. Jeżeli trzeba poprawić wydajność aplikacji. include ( "db_mysql. Jest to dobry kandydat do stworzenia strony statycznej. gdy użytkownik zażąda tej strony.1. W niektórych jednak przypadkach w pełni dynamiczna zawartość strony nie jest konieczna lub zbytnio obniża wydajność witryny. We wielu przypadkach zawartość witryn nie jest w pełni dynamiczna.1. działająca z wszystkimi istniejącymi skryptami i stronami. „Współpraca z bazami danych”. Skrypt z wydruku 16. Pomysł ten został opisany w części „Generowanie stron statycznych”. Metoda ta wymaga jednak przepisania każdej ze stron tak. co powoduje. więc nie będą potrzebne żadne dodatkowe narzędzia do zamiany dynamicznej witryny na częściowo dynamiczną.

?> </select> </td> </tr> <tr> <td> Wybierz kraj: </td> <td> <select name="world_country" size="1"> <?php print( GetGenOpts( "world_countries". "root". "root". ?> </select> </td> </tr> </form> </body> </html> <?php $aFileName = ereg_replace( 'phtml'. a do przeglądarki wysyłany jest komunikat informacyjny. $PATH_TRANSLATED ). print( "Plik <i>$aFileName</i> utworzony<br>" ).{ var var var var $Host $Database $User $Password = = = = "localhost". ?> Pierwszą czynnością wykonywaną przez skrypt jest uaktywnienie buforowania przy pomocy wywołania funkcji ob_start(). "ZA" ) ). } ?> <html> <head> <title>Formularz wyboru krajów i stanów USA</title> </head> <body> <form action="some_place. Po uaktywnieniu buforowania. Name from $aTableName order by Name". $aDB = new MySQLDBTest. $aCurSel = "" ) { $aResult = "".phtml" method="post"> <table> <tr> <td> Wybierz stan USA: </td> <td> <select name="us_state" size="1"> <?php print( GetGenOpts( "us_states". ob_get_contents() ). } function GetGenOpts( $aTableName. fclose( $aFile ). Po utworzeniu pliku bufor jest czyszczony. ob_end_clean(). if ( $aID == $aCurSel ) { $aResult . } } return $aResult. "mydb".= "<option value=\"$aID\" selected>$aName</option>". Do nowego pliku można sięgnąć za pomocą przeglądarki zmieniając rozszerzenie żądanego pliku z phtml na html.= "<option value=\"$aID\">$aName</option>". "ID" ) ). } else { $aResult . "w" ). fwrite( $aFile. $aSQL = "select ID. Na końcu skryptu generowana jest nowa nazwa pliku i zamieniane jest rozszerzenie pliku z phtml na html. Generowanie statycznych stron HTML w oparciu o dynamiczne dane 206 . $aDB->query( $aSQL ). $aID = $aDB->f( "ID" ). 'html'. dane nie są przesyłane do przeglądarki a tylko są zbierane w wewnętrznym buforze. while( $aDB->next_record() ) { $aName = $aDB->f( "Name" ). $aFile = fopen( $aFileName. Rozdział 16.

aby była możliwość tworzenia stron statycznych./mgmt_funcs. z rozdziału 15. a. $aCatName.2 znajduje się skrypt.php" ).tpl".jpg".tpl". number_format( $aProdPrice. // Niejawnie ustawia zmienną sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { print( "Błąd wewnętrzny.Metoda ta działa świetnie dla wielu typów stron. if ( $aDB->num_rows() > 0 ) { while ( $aDB->next_record() ) { $aProdName = $aDB->f( "name" ).tpl". W praktyce skrypty generujące strony powinny być umieszczone w obszarze serwera WWW chronionym hasłem i jedynie niektórzy użytkownicy powinni mieć do nich dostęp.category_id)". $aProdPrice = $aDB->f( "price" ).= "cat_name from mcProducts a. $aSQL = "select a.product_id.= "and ( a.FastTemplate. $aSQL . "page_body" => "mgmt_prod_main. Brak identyfikatora sprzedawcy. musi zostać zdefiniowana struktura katalogu. $aSQL ." ). Możliwe jest również stworzenie stron za pomocą których można zarządzać danymi dynamicznymi i za pomocą takiego interfejsu WWW generować statyczne strony.2. $aCatDB->query( $aSQL ).= "a.has_image_file. a. „Witryny oparte o bazę danych”. $aCatName = $aDB->f( "cat_name" ). if ( $aHasImage == True ) { $aImageFile = "images/{$aMerchID}_{$aCatID}_{$aProdID}.tpl" ) ). Wykorzystanie klasy FastTemplate do tworzenia statycznych stron HTML z PHP <?php error_reporting( E_ALL & ~E_NOTICE ). $aProdEID = $aDB->f( "external_id" ). $aTPL = new $aDB = new $aCatDB = new $aTPL->define( FastTemplate( ". } include( "class. $aProdWeight = $aDB->f( "ship_weight" ). Jest to kolejny przykład witryny.jpg". a. Kategorie i produkty oferowane przez firmę mogą zmieniać się raz w miesiącu lub raz w tygodniu. $aProdDescr. Użycie FastTemplate W ostatnim rozdziale tematem przykładów był katalog produktów.tpl". while( $aCatDB->next_record() ) { $cat_id = $aCatDB->f( "category_id" ). mcCategories b where ". $aProdDescr = $aDB->f( "descr" )./mgmt_db. } $aTPL->assign( array( "PROD_NAME" "CAT_NAME" "PROD_EID" "PROD_PRICE" "PROD_DESCR" "IMAGE_FILE" => => => => => => $aProdName.html. exit.php" ).name. gdzie aktualne dane strony nie zmieniają się zbyt często. include( ".external_id. $aHasImage = $aDB->f( "has_image_file" ). a. Na wydruku 16. array( "base" => "mgmt_app_base. $aImageFile = "images/default. "prod_item" => "mgmt_prod_item. $aCatID = $aDB->f( "category_id" ). Klasa FastTemplate była używana w poprzednim rozdziale do stworzenia witryny katalogu. //print( "$cat_id<br>" ).descr.ship_weight. mgmt_db()." ). session_start(). $aDB->query( $aSQL ). $aProdID = $aDB->f( "product_id" ). $aSQL = "select category_id from mcCategories". "body" => "mgmt_body.category_id. $aImageFile 207 PHP – Kompendium wiedzy .merchant_id = $aMerchantID) and (a.price.name". 2 ). Po pierwsze.category_id = b. który tworzy listę kategorii produktów dla wszystkich kategorii. b. Wydruk 16. a. '$' .= "(a. ". Jest on podobny do skryptu z wydruku 16. Dla stron kategorii każda ze stron jest nazywana korzystając z szablonu mgmt_cat_{$aCatID}. $aSQL . według wspomnianego szablonu nazw. $aProdEID.category_id = $cat_id ) order by a. Katalog jednak może być przeglądany codziennie i zawsze musi zawierać aktualne dane. W tym przypadku tworzy on listę wszystkich kategorii i zapisuje kolejne strony do osobnych plików. jakie należy wprowadzić do skryptów tak.15. a.php" ). "footer" => "mgmt_footer. include( ". W tym rozdziale zostaną omówione zmiany.name as ". mgmt_db(). $aSQL .

jest ona generowana. Techniki buforowania Generowanie stron statycznych jest efektywne w przypadku wielu rodzajów witryn. umieszczana w buforze do wykorzystania przez kolejne wywołanie.prod_item" ).3. Gdy użytkownik wysyła żądanie pobrania skryptu. na przykład cron. Podczas wykonywania swoich zadań klasa FastTemplate zapisuje całą zawartość strony w wewnętrznych buforach. Rozdział 16. $aTPL->fetch( "PAGE" ) ). fwrite( $aFile. GetCategoryHREF(). Na przykład w witrynie może istnieć strona powitalna z bieżącą datą. zawartość tej strony jest wysyłana do przeglądarki. co umożliwia wykonanie następnego przebiegu pętli. $aTPL->assign( array( "TITLE" => "Zarządzanie katalogiem towarów: Kategoria $aCatName". Generowanie statycznych stron HTML w oparciu o dynamiczne dane 208 . która była używana w aplikacji zarządzającej katalogiem. Jeżeli tak. W przypadku wielu aplikacji wystarczająca powinna być pośrednia technika buforowania stron. $aDynamic = True ) { if ( $aDynamic == True ) { return "mgmt_prod_list. $aTPL->parse( "BODY". Jeżeli dane wykorzystywane w aplikacji nie zmieniają się zbyt często. "base" ). ale gdy znacznik $aDynamic zostanie ustawiony na False. $aTPL->parse( "PAGE". Jeżeli nie ma tej strony. ". że w zmiennej sesji przekazany został identyfikator sprzedawcy. $aTPL->parse( "ITEM_LIST". print("Kategoria. zwróci adres strony statycznej. ale aby było efektywne. na początku sprawdzane jest czy istnieje aktualna strona w buforze. Wydruk 16. w trakcie edycji danych można przeglądać strony dynamiczne a później generować zbiór stron statycznych. Do generowania stron w regularnych odstępach czasu można wykorzystać odpowiednie oprogramowanie systemowe.3. Wartość ta jest zapisywana do pliku wyjściowego. powinno się rozważyć generowanie statycznych stron. W poprzednim rozdziale przytoczona została specyficzna funkcja." ) ). <i>$aCatName</i>. "MERCHANT_NAME" => GetMerchantName( $aDB. $aMerchantID ) ) ). wymaga dokładnego projektowania i programowania. } } else { $aTPL->assign( array( } "ITEM_LIST" => "Brak produktów dla kategorii <i>$aCatName</i>. Funkcja GetCategoryHREF() function GetCategoryHREF( $aCatID. zapisana do pliku: <b>$aFileName</b><br>"). fclose( $aFile ). Koncepcyjnie buforowanie jest bardzo podobne do generowania stron statycznych i nadal wymaga ingerencji w tekst każdego ze skryptów. która reprezentuje całą stronę HTML. Metoda Clear() powoduje skasowanie wszystkich buforów i zmiennych FastTemplate. Dla wielu typów witryn generowanie statycznych stron z danych dynamicznych jest stosunkowo praktyczne i powoduje wzrost wydajności serwera.html". W trybie domyślnym zwraca ona adres strony dynamicznej. $aTPL->Clear(). Aby zapisać te dane w dowolnej zmiennej można skorzystać z metody fetch(). W poprzednim przykładzie metoda fetch() jest wykorzystywana do pobrania wartości zmiennej FastTemplate PAGE. zależy od typu strony.phtml?cat_id=$aCatID". } else { return "mgmt_cat_{$aCatID}. musi być ona generowana raz w ciągu dnia i jest aktualna przez 24 godziny. $aTPL->parse( "FOOTER". "body" ).html". a do przeglądarki wysyłany jest komunikat potwierdzający prawidłowe wykonanie operacji. $aFileName = "mgmt_cat_{$aCatID}.) ). } ?> W skrypcie tym zakładamy. W tym przypadku strona jest aktualna przez godzinę. $aFile = fopen( $aFileName. $aTPL->parse( "PAGE_BODY". Jest ona używana do tworzenia łącza do strony zadanej kategorii. Jeżeli na tej stronie nie ma więcej elementów dynamicznych. To czy strona jest aktualna. "w" ). Inną stroną może być strona z wiadomościami uaktualnianymi co godzinę. "footer" ). "page_body" ). Jest ona zamieszczona ponownie na wydruku 16. W przypadku mocno obciążonych witryn wzrost wydajności może z łatwością przeważyć dodatkowe komplikacje związane z tworzeniem skryptów generujących strony. } } Stosując tą metodę.

ob_get_contents() ). Funkcja DumpCacheFile() realizuje kilka ważnych operacji./cache. ini_set( 'include_path'. return True./mweather" ).php) <?php function GetCacheFileName( $aFileName ) { return $aFileName . $aOldIncludePath . która zapisuje zawartość strony. } ?> Wydruk 16. } ob_start(). fwrite( $aFile.php" ). if ( ( $aCurTime . 60 * 60 ) ) { // aktualny plik w buforze. } } } function SaveCacheFile( $aFileName. 209 PHP – Kompendium wiedzy . sprawdzana jest data ostatniej modyfikacji pliku w buforze i jest ona porównywana z bieżącą datą. if ( $aResult = DumpCacheFile( $PATH_TRANSLATED. główny skrypt się kończy. ponieważ plik z bufora jest aktualny i został on już wysłany do przeglądarki. SaveCacheFile( $PATH_TRANSLATED. } function DumpCacheFile( $aFileName. W przykładzie tym strona jest generowana przez dołączany skrypt mweather. Jeżeli wartość ta wynosi False. znajdują się funkcje realizujące buforowanie. zawiera główną stronę. Wydruk 16. Jedynym zadaniem głównego skryptu jest modyfikacja zmiennej PHP include_path.net/prjects/mweather/.5. Funkcje buforujące (cache. więc mogą zostać łatwo dołączone do każdej strony. Na wydrukach 4. Po pierwsze. Jeżeli tak nie jest.4.$aModTime ) > $aExpire ) { return False. Na końcu skryptu wywoływana jest funkcja SaveCacheFile(). wyświetla go i zwraca wartość True. if ( is_file( $aCacheFile ) == True ) { $aModTime = filemtime( $aCacheFile ). fclose( $aFile ). koniec skryptu exit. funkcja odczytuje plik z bufora. Skrypt ten jest dostępny na stronie http://sourceforge.php" ). Można do tego celu wykorzystać buforowanie wyjścia lub szablony.php. i 5. ". $aContents ) { $aCacheFile = GetCacheFileName( $aFileName ). w celu zrealizowania cogodzinnego buforowania strony z prognozą pogody. zamieszczony jest przykład z zastosowaniem buforowania wyjścia. $aFile = fopen( $aCacheFile. } else { readfile( $aCacheFile ). Jeżeli jest ona True. ":. korzysta z funkcji buforujących umieszczonych na wydruku 16. ini_restore( 'include_path' ). "w" ). Wydruk 16. Na wydruku 16. Jest to wymagane przez skrypt MWeather i nie ma nic wspólnego z buforowaniem.4. ?> Skrypt z wydruku 16. która wyświetla bieżące dane o pogodzie wykorzystując skrypt o nazwie MWeather. $aExpire = 3600 ) { $aCacheFile = GetCacheFileName( $aFileName ).4. // dane strony $aOldIncludePath = ini_get( 'include_path' ).5. $aContents ). include( "mweather. include( ".Implementacja stron buforowanych jest bardzo prosta. Wykorzystanie funkcji buforujących <?php error_reporting( E_ALL & ~E_NOTICE ).5. funkcja zwraca False. skrypt jest wykonywany i za pomocą funkcji buforowania wydruku jego wynik jest zapamiętywany.cache". $aCurTime = time(). Po powrocie do skryptu sprawdzana jest zwracana wartość. Jeżeli różnica pomiędzy tymi datami jest większa od wartości expire.

Rozdział 16. Jeżeli skrypt wyświetlałby pogodę w miejscu określonym przez użytkownika. można wyraźnie poprawić wydajność witryny. że strona została by umieszczona w buforze przez użytkownika z Londynu. buforowanie jest niepraktyczne w przypadku stron zależnych od wartości wprowadzonych przez użytkownika. Poprzedni przykład pokazuje pogodę w Rexburg w stanie Idaho. W przedstawionym przykładzie do pobrania danych o aktualnej pogodzie potrzebny jest czas około dwóch sekund. Projektanci witryny powinni w ten sposób zrównoważyć szybkość ładowania się statycznych stron z elastycznością stron dynamicznych. Generując statyczne strony lub buforując je. ten typ buforowania jest bardzo użyteczny i wyraźnie poprawia wydajność witryny. Inaczej mówiąc. buforowanie nie może być już zastosowane. aby aplikacja miała dostateczną szybkość i była użyteczna dla użytkowników. Podsumowanie Mimo. jakie skrypty mogą działać z tym typem buforowania. Otrzymana strona była by oczywiście nieprawidłowa dla użytkownika z Cape Town. Generowanie statycznych stron HTML w oparciu o dynamiczne dane 210 . aby zdawać sobie sprawę. strona pojawia się natychmiast.Plik cache.php może być używany z dowolnym skryptem PHP. Przedstawiony typ buforowania jest użyteczny. Bardzo ważne jest jednak. Jeżeli aplikacja zawiera strony z informacjami zmieniającymi się co określony odcinek czasu i niezależne od danych użytkownika. w którym należy zrealizować funkcje buforowania na żądanie. a kolejne wywołanie pochodziło by z Cape Town. że PHP jest najczęściej używany do dynamicznego tworzenia stron WWW. Wyobraźmy sobie. aby odnaleźć sytuacje. niezależnie kto ogląda stronę. ważne jest. Metoda ta sprawdza się jedynie dla stron. które nie są wynikiem żądań HTTP GET lub POST. gdy nie są potrzebne w pełni dynamiczne strony. Po zbuforowaniu. ale nie może być używany dla wszystkich przypadków.

W części tej zawierają się zwykle strony zawierające dane o firmie. Witryna firmy Thawte . Certyfikaty Kolejnym krokiem wymaganym do stworzenia bezpiecznej aplikacji jest zainstalowanie certyfikatu bezpieczeństwa. W części tej zbierane są prywatne dane. Samo programowanie i korzystanie z istniejących narzędzi przeznaczonych dla e-handlu jest trywialne.redhat. Użycie PHP z SSL nie różni się niczym do używania PHP na serwerze nie obsługującym SSL.com/) istnieje również serwer zawierający OpenSSL. Duża część tego rozdziału jest poświęcona koncepcjom i założeniom projektowania tego typu aplikacji. W dystrybucji RedHat (http://www. który jest przesyłany do przeglądarki razem ze stronami WWW. jakie ma spełniać firmowa witryna WWW. można użyć jednej z metod opisanych w rozdziale 1. Z tego powodu niezmiernie ważne jest poznanie sposobu zrealizowania za pomocą PHP wszystkich aspektów tworzenia aplikacji handlu elektronicznego. Większość aplikacji posiada dwa obszary działania. Certyfikaty są wystawiane przez kilka firm. które wymagają zastosowania bezpiecznego połączenia za pomocą mechanizmu secure socket layer (SSL). są to zazwyczaj wymagania większości centrów rozliczających karty kredytowe. Jednym z nich jest Stronghold (http://www. Zastosowanie SSL Pierwszym krokiem powinno być wyodrębnienie fragmentów witryny. Nie należy tego traktować jako propozycji. takie jak dane niezbędne do identyfikacji klienta lub numery kart kredytowych. Należy wykonać kilka kroków w celu zapewnienia możliwie najwyższego poziomu bezpieczeństwa. Witryny handlu elektronicznego Wstęp Handel elektroniczny jest dla większości firm najważniejszym zadaniem. Po zainstalowaniu bezpiecznego serwera WWW opartego o Apache. „Kompilacja i instalowanie PHP” w celu dodania PHP w postaci współdzielonego modułu.thawte. Większość tego rozdziału jest poświęcona temu właśnie fragmentowi witryny. Bezpieczeństwo Pierwszorzędną kwestią przy tworzeniu aplikacji przeznaczonych do handlu elektronicznego jest zagadnienie bezpieczeństwa. stabilnej i skalowalnej aplikacji handlu elektronicznego. Jedną z takich firm jest Thawte Consulting (http://www.net/products/sh3/). Można również przekompilować bezpieczny serwer Apache ze statycznie dołączonym modułem PHP. Drugi fragment zawiera aplikację handlową. Można go użyć do skompilowania bezpiecznego serwera Apache. Prawdziwym wyzwaniem jest stworzenie bezpiecznej. które są rozpoznawane przez większość nowoczesnych przeglądarek jako bezpieczne. Pierwszy jest obszarem zawierającym opisy dostępnych produktów i usług oferowanych na witrynie. Już w czasie projektowania aplikacji należy mieć na uwadze ochronę danych o klientach.com/). Certyfikat to plik na serwerze.Rozdział 17. Istnieje kilka dostępnych bezpiecznych serwerów WWW. regulaminy i inne dane nie związane bezpośrednio z handlem.c2.

Z witryny firmy Thawte można pobrać i zainstalować certyfikat testowy. przechowują dane prywatne w mało bezpieczny sposób. które spowodują ujawnienie krytycznych danych.1.zawiera wszystkie dane niezbędne do wypróbowania i wykupienia certyfikatu bezpieczeństwa. Użycie tych lub podobnych funkcji poprawia jednak poziom ochrony przechowywanych danych. VeriSign i CCVS. na przykład akt założycielski spółki. to informacje te są bardzo jasno napisane i łatwe do odszukania.1. Dokument potwierdzający istnienie firmy. Plik httpd. że we wielu przypadkach witryny przechowują dane w niezaszyfrowanej bazie danych dostępnej bezpośrednio z Internetu. Zaczyna być to powszechnie stosowaną praktyką. Jeżeli nazwa widniejąca na dokumentach przedstawionych w punkcie 1. Funkcje te nie są jednak wystarczająco dobre do szyfrowania krytycznych danych.phtml index. bezpiecznym serwerem WWW i narzędziami obsługi płatności.: CyberCash. Na wydruku 17.crt/server.1. przedstawiony został obieg informacji pomiędzy użytkownikiem. Przetwarzanie płatności Po skompilowaniu i przetestowaniu bezpiecznego serwera WWW należy wybrać metodę obsługi płatności. Dokument potwierdzający prawo do nazwy domeny.html </VirtualHost> Na witrynie firmy Thawte dostępne są wszystkie informacje potrzebne do wygenerowania i zainstalowania certyfikatu. Ostatecznie to ty i twoja firma jesteście odpowiedzialni za dziury w systemie bezpieczeństwa.1:443> SSLEnable ServerAdmin webmaster@server. Jeżeli wykorzystujemy taki certyfikat przeglądarka generuje ostrzeżenia.1. albo o zastosowaniu obu tych rozwiązań. Wiele nowoczesnych systemów baz danych zawiera funkcje szyfrujące dane.129. Witryny handlu elektronicznego 212 . aby zaczął on korzystać z certyfikatu należy zainstalować certyfikat i zmodyfikować plik httpd. umieszczeniu bazy danych za firewallem.server.129. Nawet witryny używające kodowania SSL do zbierania danych. Jeżeli używanym serwerem jest Apache.conf. Bezpieczeństwo bazy danych Jednym z odkryć jakie zawdzięczamy ostatnio internetowym złodziejom numerów kart kredytowych jest to. np. Rozdział 17. Wydruk 17. ale można przetestować aplikację bez konieczności kupienia certyfikatu. Jeżeli korzystasz z dystrybucji RedHat. 2.crt SSLCertificateKeyFile /apache/conf/ssl.key/server. Aplikacja powinna kodować zarówno transmisję jak również przechowywane dane prywatne.1.1:443 <VirtualHost 129. nie trzeba dostarczać dokumentów wymienionych w punkcie 2. pokazana jest przykładowa konfiguracja wirtualnego systemu hostingowego. Na przykład SZBD MySQL zawiera funkcje ENCODE() oraz DECODE() jako integralną część języka. należy ich szukać w dokumentacji serwera. PHP zawiera własne interfejsy do kilku systemów przetwarzania płatności.conf z dyrektywami dotyczącymi certyfikatów SSLCertificateFile /apache/conf/ssl.key NameVirtualHost 19.com DirectoryIndex index. Aby otrzymać certyfikat należy dostarczyć kilka dokumentów: 1. zgadza się z danymi uzyskanymi przez zapytanie whois do domeny dla której instalowany jest certyfikat. niektóre umowy pomiędzy sprzedawcami a centrami rozliczeniowymi zawierają klauzulę o przechowywaniu danych w postaci zaszyfrowanej. Jeżeli potrzebne jest więcej informacji na temat instalowania certyfikatu w konkretnym serwerze WWW.com DocumentRoot /home/server/secure ServerName secure. Ostatnio jednak. Na rysunku 17.

Inaczej mówiąc. Na witrynie WWW firmy CyberCash znajduje się dokładny opis instalacji MCK.com/ jako sprzedawca CyberCash. serwer. 3. CyberCash (http://www. że protokół komunikacyjny używany do przesyłania informacji pomiędzy serwerem a systemem obsługi transakcji. Jeżeli korzystamy z systemu CCVS możliwe jest ominięcie systemu przetwarzania i bezpośrednia komunikacja z finansowym centrum rozliczeniowym. zostały pokazane cztery podstawowe jednostki biorące udział w obsłudze płatności: użytkownik. 5. jeżeli skrypt otworzy port. 213 PHP – Kompendium wiedzy .1. Jednym z powodów wyboru systemu obsługi płatności CyberCash jest to. Serwer komunikuje się z systemem obsługi płatności za pomocą protokołu narzuconego przez system.cybercash.com/) jest firmą oferującą interfejsy programistyczne (API) dla C i C++ oraz Javy. należy je zarejestrować u jednego z partnerów firmy CyberCash. Wersja API dla C i C++ może zostać wbudowana w PHP za pomocą opcji konfiguracji --withcybercash.Rysunek 17. Klient i serwer komunikują się ze sobą za pomocą protokołu SSL. Kompilacja PHP z obsługą CyberCash (--with-cybercash). 2. wykorzystanie niektórych możliwości systemów transakcyjnych nie będzie możliwe. 4. Dekompresja instalatora: uncompress install-mck-3. Jeżeli nie masz jeszcze konta sprzedawcy.Z. że mimo użycia bezpiecznego serwera wykorzystującego protokół SSL. Pakiet ten może być zainstalowany na systemach Unix lub pod Windows. Główne kroki wymagane do zainstalowania MCK są następujące: 1. sam PHP nie posiada implementacji SSL. własnego algorytmu Triple DES (potrójny DES). Ściągnięcie MCK. Najpierw należy ściągnąć z witryny CyberCash pakiet Merchant Connection Kit (MCK). to nie zostanie automatycznie użyty protokół SSL. Należy pamiętać. Sam system przetwarzania komunikuje się z instytucją finansową w celu sprawdzenia czy może przyjąć płatność za pomocą karty kredytowej (lub innej metody płatności).cybercash. Inne systemy transakcji wymagają użycia przez aplikację bezpiecznych gniazd. Zależności w aplikacji handlu elektronicznego Na rysunku 17. Dekompresja i zainstalowanie MCK. Proces ten wymaga podania wielu szczegółowych informacji finansowych. w celu zrealizowania komunikacji z nimi. Procedura instalacji dla systemów Unix jest bardzo prosta. ale może być przeprowadzony w ciągu 24 godzin. który zapewnia dwukierunkową szyfrowaną transmisję.1.6-<system_operacyjny>. system przetwarzania i instytucja finansowa. Nawiązanie współpracy z przedstawicielem finansowym firmy CyberCash (konto sprzedawcy). Oprócz tego należy upewnić się. Podstawowe kroki są następujące: 1. Dopóki PHP nie będzie posiadał bezpośredniej obsługi gniazd SSL. CyberCash używa do zapewnienia bezpiecznej transmisji pomiędzy serwerem WWW a centrum przetwarzania. jest wbudowany w interfejs programistyczny do CyberCash. W pozostałej części rozdziału będziemy wykorzystywać CyberCash jako system przetwarzania płatności. że twoje konto sprzedawcy może być używane w systemie CyberCash. pomimo że serwer WWW używa SSL.0. Zarejestrowanie się na witrynie http://amps.2.

50". "Card-City" => "Washington". Po wykonaniu tych kroków można przekompilować PHP podając opcję konfiguracji --withcybercash=/ścieżka/do/MCK.2./configure.$val. Uruchomienie programu konfiguracyjnego: . */ $payment_url="http://cr. Użycie PHP do komunikacji z CyberCash jest bardzo proste i wymaga jedynie dołączenia jednego skryptu. Na wydruku 17. Zawartość tej tablicy jest określana przez wartość zmiennej $auth_type. Nie potrzeba nawet wywoływać żadnej z funkcji cybercash_xxx() dostępnych w PHP. Tabela 17. Dane niezbędne do działania z Cyberash są przekazywane za pomocą tablicy asocjacyjnej będącej ostatnim parametrem funkcji SendCC2_1Server().php. Jedną z miłych cech użycie MCK wraz z PHP jest możliwość opuszczenia większości opcji konfiguracji (jak sugeruje to podręcznik). jak również obsługuje komunikację za pomocą gniazd z serwerem CyberCash. "Card-Zip" => "20500".$val)=each($response)) { echo $key./install-mck-3.cybercash.0.php (skrypt testowy CyberCash) <?php require "cyberlib. $auth_type. W punktach 3. batch-query Pytanie o grupę. Po utworzeniu PHP z obsługą CyberCash można przeprowadzić testowe transakcje. "Amount" => "usd 11. Zmienna ta określa rodzaj wykonywanej operacji lub typ komunikatu przesyłanego do CyberCash."=".2. Test. $response=SendCC2_1Server($merchant. card-query Odczytuje dane karty kredytowej dla podanego zamówienia. Komunikaty dostępne w CyberCash oraz zadania przez nie realizowane Komunikat Realizowane zadanie batch-commit Potwierdza transakcje zebrane w grupę. "Card-Address" => "1600 Pennsylvania Avenue".2. */ $merchant_key="". "Card-Country" => "USA".6-<system_operacyjny>. "Card-Exp" => "12/99". $merchant="". while(list($key.array("Order-ID" => "2342322". Należy podać pełną ścieżkę do katalogu gdzie został zainstalowany MCK.0. Uruchomienie programu instalacyjnego: . sklepu sieciowego i innych informacji tego typu. 3.com/cgi-bin/". } ?> Jak widać przetwarzanie płatności przy pomocy PHP i CyberCash jest bardzo proste. "Card-State" => "DC". Następnie po ustawieniu w tablicy asocjacyjnej danych wymaganych przez CyberCash płatność jest przekazywana do obsługi przy pomocy wywołania funkcji SendCC2_1Server() zdefiniowanej w dołączonym pliku cyberlib.6-<system_operacyjny>. zamieszczony jest ten właśnie skrypt testowy. Funkcja SendCC2_1Server() hermetyzuje w sobie wszystkie niezbędne funkcje. 4. $auth_type="mauthonly". batch-unroll Zapytanie o transakcję wysłaną w postaci grupy. Witryny handlu elektronicznego 214 . Komunikaty obsługiwane przez CyberCash zawarte są w tablicy 17. i 4. /* Tutaj należy umieścić idnetyfikator sprzedawcy."<br>".$payment_url.1.1. Zmiana uprawnień do pliku instalatora w taki sposób. checkauth Sprawdza i autoryzuje płatność czekiem Rozdział 17.2. "Card-Name" => "Bill Clinton")). /* Tutaj należy umieścić klucz sprzedawcy.$merchant_key. Zmienne $merchant oraz $merchant_key muszą zawierać identyfikator sprzedawcy oraz jego klucz nadany przez CyberCash.2. batch-retry Ponawia próbę przetworzenia oczekującej grupy. Skrypt pokazujacy sposób użycia CyberCash znajduje się w dystrybucji PHP zawierającej pełny kod źródłowy w katalogu <php>/ext/cybercash. zostaną zadane pytania na temat firmy. "Card-Number" => "4111111111111111". Wydruk 17. batch-prep Powoduje wysłanie transakcji oznaczonych jako gotowe do przetworzenia w postaci grupy. aby można było go uruchomić: chmod +x installmck-3.php".

Jest używany dla końcowych procesorów przechwytujących. UWAGA: pole jest wymagane w przypadku kart AVS i Discover. Przechwytuje płatność kartą kredytową autoryzowaną za pomocą mauthonly lub checkauth. Dokumentacja CyberCash zawiera dokładny opis każdego z komunikatów oraz jego przeznaczenia. Jest używany jedynie dla głównych procesorów przechwytujących. Tabela 17. zebrane są wszystkie pola używane do obsługi komunikatu mauthonly. UWAGA: pole jest wymagane w przypadku kart AVS i Discover. Unieważnia transakcję. które należy obowiązkowo umieścić w komunikacie. Jest on używany do autoryzacji płatności dokonywanej kartą kredytową. Należy używać notacji waluta złote. Odszukuje w bazie danych PayNow danych na temat określonych rachunków. Autoryzuje rozpoczętą przez sprzedawcę sprzedaż za pomocą karty kredytowej. Data ważności karty kredytowej obciążanej tą transakcją.50). Miejscowość w której mieszka właściciel karty. Komunikat ten jest obsługiwany jedynie przez procesor Paymentech (wykorzystując opcję Electronic Check Payment — ECP). Pola komunikatu mauthonly i ich opis Pole Opis Wy magane orderUnikalny identyfikator transakcji. Numer karty kredytowej obciążanej tą transakcją. Odpytuje bazę transakcji. Zwraca pieniądze na konto czekowe klienta. Należy użyć formatu mm/rr (na przykład: 02/01 dla lutego 2001). można tak skonfigurować CyberCash. Nazwa właściciela karty kredytowej. W zależności od rodzaju sprzedawanego produktu lub usługi. Zwraca pieniądze na kartę kredytową klienta. Ponawia oczekującą transakcję dla podanego zamówienia.2. Autoryzuje i przechwytuje rozpoczętą przez sprzedawcę transakcję za pomocą karty kredytowej. aby automatycznie zaznaczał i realizował wszystkie poprawnie autoryzowane transakcje.2. Sprawdza i autoryzuje zainicjowaną przez sprzedawcę płatność w systemie PayNow. W większości przypadków pierwszym obsługiwanym komunikatem (i często jedynym) jest komunikat mauthonly. Sprawdza bieżący status zamówień. Adres zamieszkania właściciela karty kredytowej. Uaktualnia serwer rachunków za pomocą zmian przeprowadzonych w bramce. id amount cardnumber cardexp cardname cardaddress cardcity Kwota do autoryzacji (to znaczy kwota płatności) w tej transakcji.checkreturn mauthcapture mauthonly postauth query retry return void merchant-checkpayment check-query check-update-status check-query-orderstatus zainicjowaną przez sprzedawcę. W tabeli zaznaczone są wszystkie pola.grosze (na przykład: usd 12. PHP – Kompendium wiedzy 215 . W tabeli 17.

• failure-swversion — transakcja nieudana z powodu użycia starego lub nieistniejącego (nieistniejący numer wersji) oprogramowania. Rozdział 17. „NW3 5RJ” i „113 192”. znajduje się przykład użycia CyberCash. UWAGA: Jeżeli response-data brak jest takich danych pole to jest puste. Witryny handlu elektronicznego 216 . merchNumer używany przez bramkę do identyfikacji przeprowadzanej txn transakcji. Pole to występuje jedynie w przypadku nieudanej transakcji. Pole to nie zawsze występuje. • failure-hard — nieudana transakcja. Zwracane są następujące wartości: • smps — wystąpił błąd w CashRegister. MErrLoc Miejsce wystąpienia błędu w transakcji.cardzip cardstate cardcountry Kod pocztowy miejscowości. pochodzący z działającej witryny.3. UWAGA: pole jest wymagane w przypadku kart AVS i Discover. Funkcja SendCC2_1Server() zwraca wartości również w postaci tablicy asocjacyjnej. Pole to pojawia się jedynie w przypadku nieudanej transakcji (czyli MStatus jest różny od success). „201911448. • partial success — grupa zawiera nieudane transakcje. MSWErrM Komunikat błędu przy użyciu nieaktualnej wersji portfela lub serwera sg płatności. znajdują się pola znajdujące się w odpowiedzi na komunikat mauthonly. UWAGA: pole jest wymagane w przypadku kart AVS i Discover. id Pole to występuje zawsze. która zawiera dane na temat transakcji przesłane przez CyberCash. w której mieszka właściciel karty. • failure-q-or-cancel. W tabeli 17. failure-q-or-discard — nieudane transakcje z powodu problemów z transmisją. • success-duplicate — wynik poprzedniej udanej transakcji. custNumer transakcji używany przez portfel CyberCash do identyfikacji txn transakcji. Dla transakcji nie posiadających portfela jest on taki sam jak merch-txn. Na wydruku 17. Stan w którym mieszka właściciel karty. MErrCod Numer błędu odpowiadający komunikat błędu przekazanego w e MErrMsg.2. Może przyjmować jedną z następujących wartości: • success — transakcja udana. • failure-bad-money — transakcja nieudana z powodu problemu z obciążeniem przez instytucję finansową. Elementy te nie były zawarte w przykładowym skrypcie z wydruku 17. • ccsp — wystąpił błąd w bramce.”. orderIdentyfikator zamówienia do którego należy przetwarzana transakcja.3. Pola odpowiedzi na komunikat mauthonly i ich opis Pole Opis MStatus Zwracany kod statusu wykonanej operacji Pole to zawsze istnieje. aux-msg Komunikat bramki sprzedawcy zawierający dodatkowy opis z bramki lub serwera płatności. Tabela 17. addnlDodatkowe dane transakcji zwracane przez bramkę. Prawidłowymi zapisami są „22091”. jej powtórzenie nie uda się. Przykład ten zawiera obsługę błędów oraz wysyła informacje zwrotne do klienta. • financial institution — błąd wystąpił w instytucji finansowej • CCMckDirectLib3_2 — błąd wystąpił w MCK MErrMsg Tekst komunikatu błędu zwracanego przez transakcję. mogą być powtórzone. Kraj w którym mieszka właściciel karty.3. Pole to występuje zawsze.

} // Jeżeli klient już zapłacił. "From: support@intechra. $tpl->assign( array( TITLE URL THEDATE ORDERID HIDDENID ) ). } else { $aIsPaid = 0. $merchant $merchant_key $payment_url $auth_type = = = = "". } // pobierz nowy MCK_ID dla tego klienta $aSQL = "select MAX( MCK_ID ) as MAX_ID from customers_to_mcks where ( ID = $aCustomerID )".3.= "$aKey=$aValue.cybercash.php".com/cgi-bin/". "footer" ). $aIsPaid = $aRow["ISPAID"]. Użycie CyberCash <?php include "cyberlib." ). => "c_footer. $aDB = new dbAccess. exit. "Czy chcesz jeszcze raz zapłacić??". "mauthonly". // FastTemplate // funkcja zamieniająca tablicę asocjacyjną // w jeden ciąg rozdzielany średnikami function ArrayCrunch( $aArray ) { $aResult = "". $tpl->parse( FOOTER. */ "http://cr.". pokaż informację i zakończ skrypt if ( $aIsPaid == 1 ) { mail( "blake@intechra. /* tutaj identyfikator sprzedawcy. $aDB->Init(). } return $aResult. // pobranie identyfikatora pliku z zaszyfrowanego pola formularza $aCustomerID = UnhideID( $ID ). $tpl->parse( PAGE. $aInternalURL. */ "". } $tpl = new FastTemplate( ".FastTemplate. if ( $aDB->RecordCount() == 1 ) { $aRow = $aDB->GetData( 0 ). foreach( $aArray as $aKey => $aValue ) { $aResult . "Ponowna próba płatności ($aCustomerID)".php". $aDB->SetSQL( $aSQL ). if ( $aDB->RecordCount() == 1 ) { $aRow = $aDB->GetData( 1 ).tpl".tpl" => => => => => "Płatność Intechra. $tpl->parse( BODY.Net". AddSiteVars( $tpl.Wydruk 17.php". "base" ).net\r\n" ). $aOrderID. => "a_base. j F Y" ). $tpl->define( array( base footer body ) ). // Klasa bazy danych dla tej aplikacji include "class. => "s_paid_already. $aHiddenID ). /* tutaj klucz sprzedawcy. // kontrola czy klient ten nie zapłacił wcześniej $aSQL = "select ISPAID from orders where ( ID = $aCustomerID )". $aDB->SetSQL( $aSQL ). $ID 217 PHP – Kompendium wiedzy . // Funkcje obsługi CyberCash include "dbclass. date( "l.tpl". $tpl->FastPrint( PAGE ).net". "body" ).

tpl". = "INT-" . $merchant_key. "From: support@intechra. "usd 39. => "a_base. $tpl->define( array( base footer body ) ). $CCState. $aRawResponse = ArrayCrunch( $response ). $CCAddr. $ID AddSiteVars( $tpl. => "s_paid_fail.tpl". 0. Witryny handlu elektronicznego 218 . \"good_password\" ). "footer" ). => "a_base. "base" ). "-" . $aOrderDetails ).net".net zrealizowana ($aCustomerID)". TITLE HIDDENID ) ). "footer" ). = 0. $aOrderID. $tpl->parse( PAGE. date( "l. $CCNum. "From: support@intechra.$aMaxID } else { $aMaxID } $aCurID $aOrderID = $aRow["MAX_ID"]. => "c_footer.tpl" $tpl->assign( array( => => => => => "Płatności Intechra.net nieudana ($ ($aCustomerID)". $aSQL = "update orders set ISPAID = 1 where ( ID = $aCustomerID )". } else { mail( "blake@intechra. Rozdział 17. $tpl->parse( PAGE. $aDB->SetSQL( $aSQL ). => => => => => => => => => $aOrderID. $aSQL = "insert into customers_to_mcks values ( $aCustomerID. $aRawRequest = ArrayCrunch( $aOrderDetails ).net". $tpl->parse( BODY.tpl". date( "Ymd" ) . => "c_footer. TITLE URL THEDATE ORDERID HIDDENID ) ).net". $tpl->define( array( base footer body ) ). $tpl->FastPrint( PAGE ). $aOrderDetails = array( "Order-ID" "Amount" "Card-Number" "Card-Address" "Card-City" "Card-State" "Card-Zip" "Card-Exp" "Card-Name" $response = SendCC2_1Server( $merchant. ENCODE( \"$aRawRequest\". $auth_type. j F Y" ). $aDB->SetSQL( $aSQL ). $payment_url. $tpl->parse( FOOTER. \"good_password\" ) )".net\r\n" ). $aInternalURL. sprintf( "%04d".net\r\n" ). $tpl->FastPrint( PAGE ).tpl".00". "-" . "Płatność dla Intechra. $CCName ). $aHiddenID ). $CCCity. $aFamilyID ) . $CCZip. "Płatność nieudana". $aCurID. "Płatność zakończona sukcesem". "base" ). => $ID $tpl->assign( array( $tpl->parse( FOOTER.tpl" => "Płatności Intechra. $tpl->parse( BODY. sprintf( "%06d". ENCODE( \"$aRawResponse\".net". $aCurID ). = $aMaxID + 1. $CCExpDate. => "s_paid_ok. "Płatność dla Intechra. "body" ). NOW(). if ( $response["MStatus"] == "success" ) { mail( "blake@intechra. "body" ).

Dokumentacja CyberCash nakazuje. w tym ustawiając typ komunikatu na mauthonly. aplikacja przetwarzania płatności staje się o wiele bardziej skomplikowana od pokazanej w tym rozdziale. Następnie inicjuje zmienne CyberCash. 219 PHP – Kompendium wiedzy . że wielu wystawców kart kredytowych żąda. daszków i podkreśleń. oraz wyświetla stronę informującą użytkownika. że użycie API CyberCash w PHP jest proste. Jeżeli operacja się nie powiedzie. Na tym skrypt się kończy. że wykorzystując narzędzia sieciowe UPS można skorzystać z mechanizmów obliczających dokładne koszta przesyłek da dowolnych miejsc na ziemi przy użyciu dowolnego poziomu usługi.} ?> Skrypt z wydruku 17. gdzie YYYYMMDD jest bieżącą datą. Na początku skrypt pobiera identyfikator klienta z pola formularza. w którym użytkownik podaje dane karty kredytowej. Dane są pobierane z witryny UPS — aplikacja odpytuje ich serwery pobierając dane prawidłowe w momencie sprzedaży. Następnie w bazie danych sprawdzane jest. Powodem jest to.1.com/) dostarczają narzędzia do integracji modułu przesyłek we własnej aplikacji WWW. W tablicy $aOrderDetails umieszczane są dane płatności i wywoływana jest funkcja SendCC2_3Server(). Dostępne jest kilka możliwości śledzenia na bieżąco przesyłek i kosztów. Jeżeli użytkownik już zapłacił skrypt wysyła do administratora pocztę zawierającą komunikat informujący o tym fakcie. Dostarczanie produktów Innym aspektem aplikacji handlu elektronicznego. Jeżeli wysyłasz towary. że dokonał już wcześniej płatności. CCCCCC to identyfikator klienta a OOOO jest identyfikatorem pobieranym z bazy danych. Następnie sprawdzany jest status odpowiedzi. pokazuje w jaki sposób na podstawie skryptu z wydruku 17. W tej aplikacji każdy użytkownik dokonuje jednej płatności za usługę.ups. Należy poświęcić nieco czasu na przestudiowanie dokumentacji procesora transakcji. Można używać w nim liter. wyświetlany jest komunikat o prawidłowym przetworzeniu transakcji i uaktualniane są dane klienta na temat płatności. ale stworzenie bezpiecznej i stabilnej aplikacji handlu elektronicznego wymaga sporej ilości przemyśleń i planowania. aby karta była obciążana dopiero po dostarczeniu towaru do klienta. kropek. można stworzyć prawdziwy system obsługi płatności. ale obciążenie nie będzie zrealizowane do czasu dostarczenia towaru. Po systemie obsługującym prawdziwe pieniądze klienci oczekują najlepszej jakości usług.com/) jak i Federal Express (http://www. Można jedynie powiedzieć. Zarówno UPS (http://www. który wymaga planowania jest kwestia dostarczania towarów do klientów. umieszczę odpowiednie informacje na witrynie WWW wymienionej w zasobach sieci w dodatkach. z bazy danych pobierany jest nowy niepowtarzalny identyfikator.fedex.2. klienci nie będą zadowoleni. Narzędzia UPS są bardzo elastyczne i wydajne i łatwo mogą być umieszczone w aplikacji PHP korzystając z niewielkiej ilości kodu. Ważne jest również podawanie rzeczywistego kosztu przesyłki. aby identyfikator ten był co najwyżej 25 znakowy i musi być unikalny. Jeżeli transakcja zakończyła się powodzeniem. Jeżeli aplikacja pozwoli na przypadkowe wielokrotne płatności lub nie dostarczy odpowiednich informacji. czy użytkownik nie zapłacił już wcześniej. klient jest o tym informowany. Niestety nie otrzymałem pozwolenia na dokumentację żadnego z tych systemów przed zakończeniem tego rozdziału. Jeżeli płatność nie była jeszcze dokonana. Można żądać autoryzacji przed dostarczeniem towaru. Jeżeli otrzymam pozwolenie. Jednak wiele wymaganych czynności może być zrealizowane za pomocą PHP. Żądanie i odpowiedź są zapisywane do bazy danych w postaci zaszyfrowanej. Skrypt ten jest używany do przetwarzania danych formularza. Skrypt ten generuje identyfikatory w postaci RRRRMMDD-CCCCCC-OOOO. Dostępne jest mnóstwo informacji i ty jesteś odpowiedzialny za ich zrozumienie i właściwą implementację. Zalecanym scenariuszem jest stworzenie osobnej aplikacji zapisującej stan przesyłek i po dostarczeniu przesyłki kończona jest płatność kartą i do klienta wysyłany jest komunikat. Przeglądając ten przykład można stwierdzić. Jeżeli twój towar musi być wysłany do klienta. liczb. W każdym z przypadków do administratora wysyłany jest informujący e-mail. wymagane jest kilku dodatkowych kroków oprócz wymienionych poprzednio.

Wyzwaniem staje się stworzenie aplikacji. która jest jednocześnie bezpieczna i prosta w użyciu.Podsumowanie Tworzenie aplikacji handlu elektronicznego nie jest zbytnim wyzwaniem patrząc jedynie od strony kodu. Tworząc aplikacje handlowe należy poświęcić nieco czasu na poznanie wszystkich komponentów oraz na gruntowne testowanie systemu. Rozdział 17. Należy również szyfrować przechowywane dane oraz całą transmisję pomiędzy klientem i serwerem realizować za pomocą SSL. Witryny handlu elektronicznego 220 . oraz integruje w sobie wszystkie niezbędne technologie.

} foo (1. "<br>\n". array func_get_args( void ) <?php function foo() { $numargs = func_num_args(). } foo (1. w której każdy element zawiera odpowiedni argument z listy argumentów funkcji. generowane jest ostrzeżenie a funkcja func_get_arg() zwraca False. if ($numargs >= 2) echo "Drugi argument: " . Jeżeli wartość $arg_num jest większa niż ilość przekazanych argumentów. Funkcje function_exists Szuka w liście zdefiniowanych funkcji nazwy przekazanej w znaleziono podaną nazwę funkcji. Func_get_arg() generuje ostrzeżenie jeżeli jest wywołana poza funkcją. Argumenty są numerowane od 0. $i < $numargs. Funkcja ostrzeżenie w przypadku wywołania jej z poza funkcji. func_get_args() do zrealizowania func_get_args func_get_args() Zwraca tablicę. "<br>\n". if ($numargs >= 2) echo "Drugi argument: " . func_get_arg() do zrealizowania func_num_args Zwraca liczbę argumentów przekazanych do bieżącej funkcji. 2. $arg_list[$i] . 3). w przeciwnym wypadku zwraca False. "<br>\n". $i++) echo "Argument $i = " . func_get_arg(1) . Funkcja została dodana w PHP 4. func_get_arg(1) . for ($i = 0. echo "Ilość argumentów: $numargs<br>\n".Dodatek A. ?> Funkcja func_get_arg() może być używana wraz z func_num_args() i funkcji ze zmienna liczbą argumentów. Zwraca True. Funkcja została dodana w PHP 4. $arg_list = func_get_args(). echo "Ilość argumentów: $numargs<br>\n". 2. int function_exists( string nazwa_funkcji ) $function_name. Funkcja generuje ostrzeżenie w wypadku wywołania jej spoza definicji funkcji. 3). jeżeli func_get_arg Zwraca argument numer $arg_num z listy argumentów funkcji. ?> Funkcja func_get_args() może być używana wraz z func_num_args() i funkcji ze zmienna liczbą argumentów. mixed func_get_arg( int arg_num ) <?php function foo() { $numargs = func_num_args(). int func_num_args( void ) func_num_args() generuje .

echo "Ilość argumentów: $numargs<br>\n". $value) = each($headers)) { echo "$header: $value<br>\n". Jeżeli podany został argument $length. array geallheaders( void ) Przykład: getallheaders() $headers = getallheaders(). na przykład 299 • weekday — dzień tygodnia jako tekst. } Przykład ten wyświetla wszystkie nagłówki bieżącego żądania HTTP. fopen(). Tablica zawiera następujące elementy: • seconds — sekundy • minutes — minuty • hours — godziny • mday — dzień miesiąca • wday — dzień tygodnia jako numer • mon — miesiąc jako numer • year — rok jako numer • yday — dzień w roku jako numer. Funkcja została dodana w PHP 4.Funkcje 222 . int length]) getallheaders Zwraca tablicę asocjacyjną z wszystkimi nagłówkami HTTP wysłanymi wraz z bieżącym żądaniem. Jeżeli podany został argument $length. getallheaders() działa getcwd Zwraca bieżący katalog. func_get_arg() do zrealizowania fwrite Zapisuje zawartość $string do pliku wskazywanym przez $fp. Aby odczytać wszystkie zmienne środowiska zdefiniowane w ten sposób należy użyć funkcji phpinfo(). gdy PHP pracuje jako moduł Apache. while (list ($header. Można to zrealizować gdy PHP pracuje jako moduł Apache lub jako CGI. na przykład Friday • month — miesiąc jako tekst. Wskazówka Można również odczytać wartości zmiennych współdzielonych CGI ze środowiska. zapisywanie jest przerywane po zapisaniu $length bajtów lub całej zawartości $string. ignorowana jest opcja konfiguracji magic_quotes_runtime i z $string nie będą usuwane ukośniki. ?> Funkcja func_num_args() może być używana wraz z func_get_args() i funkcji ze zmienna liczbą argumentów. int fwrite( int fp. 3).<?php function foo() { $numargs = func_num_args(). Funkcja jedynie. 2. Patrz również fread(). popen() i fputs(). string getcwd( void ) getdate Zwraca tablicę asocjacyjną zawierającą informacje o dacie odczytane na podstawie parametru $timestamp. } foo (1. fsockopen(). string [. na przykład January Dodatek A .

2 = JPG. 4 = SWF. string gethostbyaddr( string ip_address ) $ip_address. Patrz również: gethostbyname(). W przypadku wystąpienia gethostbyname Zwraca adres IP komputera o nazwie przekazanej w $hostname. string gethostbyname( string hostname ) gethostbynamel gethostbyaddr(). gethostbyaddr Zwraca nazwę komputera o adresie przekazanym w argumencie błędu funkcja zwraca $ip_address.edu/cgi/) na stronie poświęconej zmiennym środowiska (http://hoohoo. JPG. getmxrr() Zwraca listę adresów IP skojarzonych z nazwą oraz man named(8). Indeks 2 zawiera znacznik określający typ rysunku. Funkcja zwraca tablicę z 4 elementami. lub w przypadku wystąpienia błędu False.ncsa. PNG lub SWF i zwraca wymiary. checkdnserr().jpg" <?php echo $size[3].array getdate( int timetamp ) getenv Zwraca wartość zmiennej środowiska o nazwie $varname. Patrz również: gethostbyaddr(). Znaczenie wielu z nich opisane jest w specyfikacji CGI (http://hoohoo. &$info). Przykład: GetImageSize() zwracający IPTC <?php $size = GetImageSize ("testimg. Częstym zastosowaniem jest umieszczanie danych IPTC http://www.jpg". Patrz również: gethostbyname(). Uwaga Funkcja ta nie działa w trybie ISAPI. Pod indeksem 0 znajduje się szerokość rysunku w pikselach.uiuc. który może być użyty bezpośrednio w znaczniku IMG. } ?> Uwaga 223 PHP – Kompendium wiedzy . 3 = PNG. ?> <IMG SRC="img/flag. pod indeksem 1 znajduje się wysokość rysunku. string getenv( string varname ) $ip = getenv( "REMOTE_ADDR" ). $hostname.jpg"). array GetImageSize( string filename [. Niektóre programy wykorzystują znaczniki APP do umieszczenia w rysunku informacji tekstowej.uiuc. Pod indeksem 3 znajduje się ciąg zawierający tekst height=xxx width=xxx.xe.edu/cgi/env. if (isset(($info["APP13"])) { $iptc = iptcparse( $info["APP13"]). W chwili obecnej zwracane są różne znaczniki APP pliku JPG w postaci tablicy asocjacyjnej. ?> Opcjonalny parametr $imageinfo pozwala na odczytanie dodatkowych danych z pliku rysunku.html). // odczytuje numer IP użytkownika Listę zmiennych środowiska można uzyskać za pomocą funkcji phpinfo().net/iptc/ w znaczniku APP13. array imgeinfo]) Przykład: GetImageSize() <?php $size = GetImageSize ("img/flag. string gethostbynamel( string hostname ) GetImageSize Odczytuje wielkość rysunku GIF. Do zamiany binarnego znacznika APP13 na postać czytelną dla człowieka można użyć funkcji iptcparse().ncsa. typ pliku oraz ciąg tekstu z szerokością i wysokością w postaci fragmentu znacznika IMG. var_dump( $iptc). 1 = GIF.

jeżeli znalezione zostały jakieś rekordy. int getxrr( string hostname. date ("F d Y H:i:s. get_current_user(). gethostbyaddr() oraz man named(8). getlastmod()). getmypid() i getlastmod(). lub False w przypadku wystąpienia błędu. getmyinode() oraz getlastmod().Funkcja ta nie wymaga biblioteki GD getlastmod Zwraca czas ostatniej zmiany bieżącej strony.". Jeżeli zostanie podana tablica $weight. Uwaga Funkcja ta nie działa w Windows int getmyinode( void ) getmypid Zwraca identyfikator procesu PHP lub False w przypadku wystąpienia błędu. get_current_user(). Zwraca True. getmxrr Szuka w DNS rekordu MX skojarzonego z $hostname. int getmypid( void ) getmyuid Zwraca identyfikator użytkownika uruchamiającego bieżący skrypt. Uwaga Jeżeli PHP działa jako moduł serwera. W przypadku błędu zwraca False. array mxhosts [. getmyinode() oraz getmypid(). Patrz również: getmypid(). zostanie wypełniona wagami odnalezionych rekordów. get_current_user(). że identyfikatory procesów będą różne. int getlastmod( void ) Przykład: getlastmod() <?php // zwraca ciąg w postaci 'Ostatnia modyfikacja: March 04 1998 20:43:59. Zwracana wartość jest znacznikiem czasu Uniksa. getmyuid(). array weight]) getmyinode Zwraca bieżący inode pliku ze skryptem lub False w przypadku wystąpienia błędu. Patrz również: getmyuid(). w przypadku wystąpienia błędu lub braku rekordów zwracana jest wartość False. get_current_user(). Patrz również: Dodatek A . gethostbyname(). w kolejnych wywołaniach skryptu nie jest gwarantowane. int getmyuid( void ) getprotobyname Zwraca numer protokołu skojarzonego z protokołem getprotobynumber().Funkcje 224 .' echo "Ostatnia modyfikacja: ". Patrz również: getmyuid(). Patrz również: checkdnsrr(). ?> Patrz również: date(). Lista znalezionych rekordów MX jest umieszczana w tablicy $mxhosts. int getprotobyname( string name ) $name według pliku /etc/protocols. gethostbynamel(). getmyinode() oraz getlastmod().

Jako Znaków zastępczych można używać podkreślenia. // wybierz domenę textdomain( "myPHPApp").tv_sec"]. mt_srand() int getrandmax( void ) Zwraca maksymalną wartość. getrusage Jest to interfejs do getrusage(2). $dat["ru_majflt"].tv_usec"]. Patrz również: getrandmax srand()./locale"). getrusage można znaleźć w podręczniku systemowym pod hasłem getservbyname Zwraca numer portu używanego przez usługę $service dla protokołu $protocol. jaka może być zwrócona przez funkcję oraz mt_getrandmax(). int getservbyname( string service. $dat["ru_utime. $dat["ru_nswap"]. # # # # ilość ilość użyty użyty stronicowań błędów strony czas użytkownika (sekundy) czas użytkownika (mikrosekundy) Więcej szczegółów na temat getrusage(2). Jeżeli $who jest równe 1. Zwraca przetłumaczony ciąg lub oryginalny ciąg. według definicji w /etc/services. array getrusage( [int who] ) Przykład: getrusage() $dat echo echo echo echo = getrusage(). string protocol) gettext Funkcja szuka tłumaczenia ciągu w jednej z tablic tłumaczeń. rand(). // Określ połozenie tablic tłumaczeń bindtextdomain( "myPHPApp". int getprotobynumber( string name ) $number według pliku /etc/protocols. • sec — sekundy • usec — mikrosekundy • minuteswest — przesunięcie w minutach na zachód od Greenwich • dsttime — typ poprawki dst array gettimeofday( void ) 225 PHP – Kompendium wiedzy . jeżeli tłumaczenie nie zostanie znalezione. Zwraca tablicę asocjacyjną zawierającą dane zwracane przez wywołanie systemowe. Patrz również: rand(). $protocol może być TCP lub UDP.getprotobynumber Zwraca nazwę protokołu skojarzonego z protokołem getprotobyname(). string gettext( string message ) Przykład: gettext() <?php // Ustaw język na niemiecki putenv( "LANG=de"). Patrz również: getservbyport(). // wypisz komunikat testowy print (gettext( "Welcome to My PHP Application")). ?> gettimeofday Jest to interfejs do gettimeofday(2). mt_rand(). $dat["ru_utime. ". Zwraca tablicę asocjacyjną zawierającą dane zwrócone przez wywołanie systemowe. getrusage zostanie wywołane z RUSAGE_CHILDREN.

?> Wynik działania tego skryptu może wyglądać następująco Mozilla/4.ini. return $str. na przykład numer wersji.0 (compatible.0)<br> <b>parent:</b> IE 5. Więcej informacji (w tym adresy skąd można ściągnąć plik browscap. $value) = each($array)) $str . Windows NT 5\. lub False w przypadku wystąpienia błędu. Domyślnie używana jest wartość zmiennej $HTTP_USER_AGENT. identyfikator. JavaScript.Funkcje 226 . Możliwe zwracane wartości zamieszczone są poniżej: boolean array unknown type integer object double resource string user function string gettype( mixed var ) Patrz również: settype(). ale można przekazać dowolną dowolny parametr $user_agent (na przykład.php. Zwracany jest obiekt zawierający dane opisujące. wartości True lub False dla takich własności jak. aby wskazywała na katalog z plikiem browscap. object get_browser( [string user_agent]) Przykład: get_browser() <?php function list_array ($array) { while (list ($key. get_browser Odczytuje możliwości przeglądarki użytkownika. get_cfg_var Zwraca wartość zmiennej konfiguracji PHP określonej przez $varname.php. aby odczytać możliwości innej przeglądarki). Funkcja ta nie zwraca danych konfiguracji ustawionych przy kompilacji PHP lub poprzez pliki konfiguracyjne Apache (przy użyciu dyrektywy php3_configuration_option). Jest to realizowane przez odszukanie danych na temat przeglądarki w pliku browscap.net/FAQ. że plik browscap. Aby sprawdzić.ini zawiera dane o wielu przeglądarkach.0 (compatible. Poniższy przykład pokazuje przykładowe dane zwracane dla przeglądarki użytkownika. } echo "$HTTP_USER_AGENT<hr>\n".0<br> <b>version:</b> 5. Format pliku jest bardzo prosty. obsługa ramek. Mimo. echo list_array( (array) $browser).5. Windows NT 5. cookie itd. MSIE 5.5<br> <b>minorver:</b> 5<br> <b>platform:</b> Win2000<br> <b>beta:</b> <br> <b>browser:</b> IE<br> <b>majorver:</b> 5<br> <b>frames:</b> 1<br> <b>tables:</b> 1<br> <b>cookies:</b> 1<br> <b>backgroundsounds:</b> 1<br> <b>vbscript:</b> 1<br> <b>javascript:</b> 1<br> <b>javaapplets:</b> 1<br> <b>activexcontrols:</b> 1<br> <b>win16:</b> <br> <b>ak:</b> <br> <b>sk:</b> <br> <b>aol:</b> <br> <b>crawler:</b> <br> <b>msn:</b> <br> <b>cdf:</b> 1<br> <b>dhtml:</b> 1<br> <b>xml:</b> 1<br> Aby skrypt ten mógł działać należy tak ustawić zmienną konfiguracji browscap.= "<b>$key:</b> $value<br>\n".ini) można znaleźć w FAQ do PHP pod adresem http://www.gettype Zwraca typ zmiennej PHP $var. czy system Dodatek A .ini. $browser = get_browser(). MSIE 5\.5. to jednak użytkownik musi dbać o jego aktualność.0)<hr> <b>browser_name_pattern:</b> Mozilla/4\.

get_object_vars(). int quote_style]) Przykład: Tablica translacji $trans = get_html_translation_table( HTML_ENTITIES ). OverloadedTestClass (zdefiniowana w ext/standard/basic_functions. array get_class_vars( string class_name ) $class_name. array get_class_methods( string class_name ) $class_name. Wykonanie tych linii spowoduje wypisanie listy funkcji umieszczonych w modułach xml i gd. get_object_vars(). Domyślnym ustawieniem jest tryb ENT_COMPAT. należy spróbować odczytać wartość zmiennej konfiguracji jest to możliwe. Patrz również oraz getlastmod().c). print_r (get_extension_funcs( "gd")). $encoded = strtr( $str. string get_html_translation_table( int table [. Tak samo jak w przypadku funkcji htmlspecialchars() i htmlentities() można opcjonalnie określić rodzaj ukośników $quote_style. array get_extension_funcs( string module_name ) Przykład: get_extension_funcs() print_r (get_extension_funcs( "xml")). string get_current_user( void ) getmyuid(). Możliwe jest określenie potrzebnej w danym momencie tabeli (HTML_ENTITIES i HTML_SPECIALCHARS).1pl2 na początku tablicy zwracane były trzy dodatkowe klasy: stdClass (zdefiniowana w Zend/zend. W PHP 4. Patrz również: get_parent_class().c). Patrz również: get_class_vars Zwraca tablicę z nazwami właściwości zdefiniowanych w klasie określonej przez również: get_class_methods(). get_html_translation_table Zwraca tablicę translacji używaną wewnętrznie w funkcjach htmlspecialchars() i htmlentities(). 227 PHP – Kompendium wiedzy .korzysta z pliku konfiguracji. Patrz również: get_loaded_extensions(). że jest używany plik konfiguracji. Patrz get_current_user Zwraca nazwę właściciela bieżącego skryptu PHP.0. array get_declared_classes( void ) get_extension_funcs Zwraca nazwy wszystkich funkcji zdefiniowanych w module $module_name. $trans).h) oraz Directory (zdefiniowana w ext/standard/dir. is_subclass_of(). string get_cfg_var( string varname ) cfg_file_path. Jeżeli get_class Zwraca nazwę klasy przekazanego obiektu $obj. oznacza to. string get_class( object obj ) get_class_methods Zwraca tablicę z nazwami metod zdefiniowanych w klasie określonej przez get_class_vars(). getmypid(). Opis trybów znajduje się w opisie funkcji htmlspecialchars(). $str = "To firma & <PRO> & spółka". getmyinode() get_declared_classes Zwraca tablicę nazw klas zadeklarowanych w bieżącym skrypcie.

Uwaga Funkcja ta została dodana w PHP 4. W PHP 4.0. 1 — włączone). long get_magic_quotes_gpc( void ) get_magic_quotes_runtime Zwraca stan ustawienia magic_quotes_runtime (0 — wyłaczone. get_magic_quotes_gpc Zwraca stan ustawienia magic_quotes_gpc (0 — wyłaczone. Ciekawym zastosowaniem jest użycie funkcji array_flip() w celu zmiany kierunku translacji. get_included_files Funkcja zwraca tablicę asocjacyjną z nazwami wszystkich plików dołączonych do skryptu za pomocą funkcji include_once(). set_magic_quotes_runtime(). $trans = array_flip( $trans ). $trans). strtr() i array_flip(). include_once(). &amp. 1 — włączone). Spowoduje to wypisanie listy podobnej do następującej: Array ( [0] => standard [1] => bcmath [2] => Calendar [3] => com [4] => variant [5] => ftp [6] => mysql [7] => odbc [8] => pcre [9] => session [10] => xml [11] => wddx [12] => apache ) Patrz również: get_extension_funcs(). set_magic_quotes_runtime(). long get_magic_quotes_runtime( void ) get_meta_tags Otwiera plik $filename i analizuje go szukając znaczników meta. array get_meta_tags( string filename [.php. Patrz również: require_once(). Patrz również: get_magic_quotes_runtime(). array get_loaded_extensions( void ) Przykład get_loaded_extensions() print_r (get_loaded_extensions()). sp&oacute.PRO&gt. Indeksami tej tablicy są nazwy plików użytych w include_once() bez rozszerzenia .ka. int use_include_path]) Przykład: Znaczniki <META> Dodatek A . $original = strtr ($str. Teraz w zmiennej $original będzie znajdował się ciąg: To firma & <PRO> & spółka.php i inne rozszerzenia nie działają. htmlentities(). Patrz również: get_magic_quotes_gpc(). get_required_files(). &lt. array get_included_files( void ) get_loaded_extesions Zwraca nazwy wszystkich modułów wkompilowanych i załadowanych przez interpreter PHP.0 Patrz również htmlspecialchars().1pl2 funkcja zakładała.&sup3.Zmienna $encoded zawiera teraz ciąg To firma &amp. że pliki dołączane poprzez include_once() mają rozszerzenia .Funkcje 228 .

natomiast pozostały tekst jest konwertowany do małych liter. $y) { $this->x = $x. // Array // ( // [x] => 1. array get_object_vars( object obj) Przykład: użycie get_object_vars() <?php class Point2D { var $x. której instancją jest obiekt is_subclass_of(). "label" => $this->label). } } $p1 = new Point2D( 1. Dzięki temu można wykorzystać standardowe funkcje przeglądające tablice. var $label. $y. get_parent_class Zwraca nazwę klasy bazowej dla klasy.<meta name="author" content="name"> <meta name="tags" content="php3 documentation"> </head> <!-. ale nie zainicjowana // Array // ( // [x] => 1.445 // ) $p1->setLabel("point #1"). } function setLabel( $label) { $this->label = $label.233.445). natomiast zawartość umieszczana jest w tablicy jako wartość elementu. 229 PHP – Kompendium wiedzy . string get_parent_class( object obj ) $obj. Jeżeli zmienna zdefiniowana w klasie nie ma przypisanej wartości. więc pliki z MacIntosha mogą nie działać na Uniksie. get_object_vars Zwraca tablicę asocjacyjną właściwości zdefiniowanych w obiekcie określonym przez $obj. Znaki specjalne są zastępowane znakiem podkreślenia. nie znajdzie się ona w tablicy asocjacyjnej.233 // [y] => 3. Ustawienie use_include_path na 1 spowoduje.tutaj zatzymuje się analiza --> Uwaga Uwaga na końce linii — PHP wykorzystuje własną funkcję analizującą plik wejściowy.445 // [label] => point #1 // ) ?> Patrz również: get_class_methods(). function Point2D( $x. print_r(get_object_vars($p1)). Nazwa właściwości staje się kluczem. "y" => $this->y. } function getPoint() { return array( "x" => $this->x. Patrz również: get_class(). print_r(get_object_vars($p1)). // Właściwość $Label jest zdefiniowana. 3. że PHP będzie próbował otworzyć plik znajdujący się na standardowej ścieżce dołączania.233 // [y] => 3. get_class_vars(). $this->y = $y.

1998)). int minute. ?> Wykonanie tego skryptu spowoduje wygenerowanie następnego wyniku: Pliki dołączane przez require_once Array ( [0] => C:\helion\php4-devguide\site\doda\local.get_required_files Zwraca tablicę asocjacyjną z nazwami wszystkich plików załadowanych do skryptu poprzez funkcję require_once(). require_once( ". print_r (get_included_files()). gmdate Funkcja ta jest identyczna z date().Funkcje 230 . echo gmdate("M d Y H:i:s".1.0. natomiast drugie: Jan 01 1999 01:00:00. echo "Pliki dołączane przez include_once\n"..1998)). że przekazane parametry reprezentują czas GMT.php [5] => C:\helion\php4-devguide\site\doda\util4. echo "Pliki dołączane przez require_once\n". pierwsza linia przykładu zwróci Jan 01 1998 00:00:00. poza tym. include_once(). mktime( 0.php".php [5] => C:\helion\php4-devguide\site\doda\util4.php [3] => C:\helion\php4-devguide\site\doda\util2. int gmmktime( int hour. Jeżeli przykłąd zostanie uruchomiony w Polsce (GMT +0100).php [4] => C:\helion\php4-devguide\site\doda\util3. Dodatek A .0.1. $i<5. mktime() i gmmktime(). że pliki dołączane poprzez include_once() mają rozszerzenia . int second.1. pierwsze wywołanie z przykładu wypisze ciąg Dec 31 1998 20:00:00./inc/global.php [4] => C:\helion\php4-devguide\site\doda\util3.0. $i . poza tym. ale zwracany czas jest czasem GMT. Patrz również: require_once().php [1] => C:\helion\php4-devguide\site\inc\global.php ) Uwaga W PHP 4. int is_dst]) gmstrftime Zachowuje się tak samo jako jak funkcja strftime(). int year [. gmmktime Funkcja identyczna jak mktime().0. string gmdate( string format. get_included_files().php [2] => C:\helion\php4-devguide\site\doda\util1.php i inne rozszerzenia nie działają. array get_required_files( void ) Przykład: Wypisywanie plików dołączanych za pomocą require i include.php" ).php [1] => C:\helion\php4-devguide\site\inc\global.php [2] => C:\helion\php4-devguide\site\doda\util1. print_r (get_required_files()). <?php require_once( "local. int timestamp ) Przykład: gmdate() echo date("M d Y H:i:s". natomiast druga Dec 31 1997 23:00:00. int day. int month. mktime( 0. że zwracany czas jest czasem Greenwich (GMT). $i++) include "util".0.php ) Pliki dołączane przez include_once Array ( [0] => C:\helion\php4-devguide\site\doda\local. for ($i=1. jeżeli będzie użyta w strefie czasowej GMT -0500.php [3] => C:\helion\php4-devguide\site\doda\util2.1pl2 funkcja zakładała. ". Na przykład. Patrz również: date().1.php" ).

1970). string gzgetc( int zp ) 231 PHP – Kompendium wiedzy . ?> gzclose Funkcja zamyka plik gz wskazywany przez $zp. int day. $gregorian = JDToGregorian( $jd ). False.0. int use_include_path]) gzgetc Zwraca ciąg zawierający jeden znak (nieskompresowany) odczytany z pliku na który wskazuje $zp.e. 11. GregorianToJD Prawidłowy zakres dat kalendarza gregoriańskiego to 4714 p. int level]) gzeof Zwraca True. Chociaż można stosować tak szeroki zakres dat. echo "$jd\n".12.n. int year) Przykład: Funkcje kalendarza <?php $jd = GregorianToJD( 10. mktime( 20. Większość krajów europejskich przed kalendarzem gregoriańskim używała kalendarza juliańskiego.Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). W przypadku powodzenia zwraca True. Patrz również: gzuncompress(). int GregorianToJD( int month.0. a w przypadku błędu. Niektóre kraje jeszcze długo nie wprowadziły tego kaledarza. 'en_US'). array gzfile( string filename [. Opcjonalny parametr $level może przyjmować wartości od 0 dla braku kompresji. Na przykład Anglia przyjęła go w 1752 roku. echo gmstrftime("%b %d %Y %H:%M:$S". do 9 dla maksymalnej kompresji. Patrz również: strftime(). echo strftime("%b %d %Y %H:%M:$S". Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). lub False w przypadku wystąpienia błędu. int gzclose( int zp ) gzcompress Zwraca dane wejściowe przekazane w $data skompresowane gzipem. co spowoduje szukanie pliku również na ścieżce ustawionej w include_path. do 9999 n. nie ma to jednak sensu. Kalendarz gregoriański został ustanowiony 15 października 1582 roku (lub 5 października 1582 roku według kalendarza juliańskiego). W przeciwnym przypadku zwraca False. Zwraca False na końcu pliku (tak samo jak gzeof()). echo "$gregorian\n". jeżeli wskaźnik pliku gz znajduje się na końcu pliku lub wystąpił błąd. że gzfile() zwraca zawartość pliku w tablicy.98)). Patrz również: readgzfile(). Można ustawić parametr opcjonalny na 1.12. string gzcompress( string data [.31.98)).0. int timestamp ) Przykład: gmstrftime() setlocale( 'LC_TIME'. poza tym.31. mktime( 20.0. Patrz również: gzopen() i gzgets(). gzopen().string gmstrftime( string format. int gzeof( int zp ) gzfile Funkcja identyczna z readgzfile(). Rosja w 1918 a Grecja w 1923 roku.e.

int use_include_path]) Przykład gzopen() $fp = gzopen( "/tmp/file. int gzpassthru( int zp ) gzputs Identyczna jak funkcja gzwrite().13. Funkcja gzopen() zwraca wskaźnik do otwartego pliku. np.gz". int length [. string gzgets( int zp. Można użyć opcjonalnego trzeciego argumentu i ustawić go na 1 w celu włączenia poszukiwania pliku do otwarcia na ścieżce include_path. Zwraca False w przypadku wystąpienia błędu. Jeżeli wystąpi błąd zwraca False. a jego (nieskompresowaną) zawartość kieruje na wyjście. gzgetss(). Jeżeli otwarcie pliku nie uda się. PHP4B3. które mają pozostać w tekście.: "wb1h". int gzopen( string filename. Można również wykorzystać gzopen() do odczytania danych. string mode [. Po tej operacji wszystkie dane odczytywane z tego pliku są dekompresowane. ale dodatkowo gzgetss() usiłuje usunąć znaczniki HTML i PHP z odczytanego tekstu. które nie są w formacie gzip. Więcej informacji na temat filtrowania znajduje się w opisie deflateIni2 w pliku zlib. 10000 ).gzgets Zwraca ciąg znaków (nieskompresowany) o maksymalnej długości $length-1 odczytany z pliku na który wskazuje $zp. string allowable_tags]) gzopen Otwiera plik gzip (. ale może zawierać również poziom kompresji ("wb9") lub strategię: f dla filtrowania danych. Można użyć opcjonalnego trzeciego parametru w celu określenia znaczników. gzgetc() i fgets(). gdy zostanie odczytane $length znaków (nieskompresowanych). lub napotkany zostanie koniec pliku. Dodatek A . Parametr $mode jest taki jak w fopen() ("rb" lub "wb"). string str [. "r"). W takim przypadku gzread() odczytuje plik bez jego dekompresji. int length ) Przykład: gzread() // odzytanie zawartości pliku gz do ciągu $filename = "/usr/local/somth. Czytanie kończy się po odczytaniu $length-1 znaków.txt. Patrz również: gzwrite(). $zd = gzopen( $filename. gzgets(). string gzread( int zp. Po zakończeniu odczytu pliku jest on zamykany. gzfile(). int length]) gzread Odczytuje maksymalnie $length bajtów z pliku gz wskazywanego przez $zp. gzpassthru(). funkcja zwraca False. int gzputs( int zp. Patrz również: gzopen().Funkcje 232 . Patrz również: gzclose(). Parametr $allowable_tags został dodany w PHP 3. Patrz również: gzgets(). int length ) gzgetss Funkcja identyczna jak gzgets().h. gzopen() i strip_tags(). "r" ). Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). na przykład "wb6f".0. znaku nowej linii lub znaku EOF. gzpassthru Odczytuje plik wskazywany przez wskaźnik do pliku gz. string gzgetss( int zp. natomiast dane zapisywane do pliku są kompresowane. aż do znaku EOF. $contents = gzread( $dz. Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). h dla kompresji tylko metodą Huffmana. Odczyt zostaje przerwany. gzopen().gz) do odczytu lub zapisu.gz".

funkcja jest wykonywana. Patrz również gztell() i gzrewind(). Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). gzseek() kompresuje wtedy sekwencję zer aż do nowej pozycji. funkcja zwraca False. Uwaga Jeżeli podany został argument $length. header Funkcja używana na początku pliku HTML do wysłania surowych nagłówków HTTP.org/Protocols/rfc2616/rfc2616). SEEK_SET). Uwaga Przesunięcie poza znacznik EOF nie jest traktowane jako błąd. Jeżeli wystąpi błąd.w3. Jest to odpowiednik wywołania (w C) gzseek( zp. zapis jest przerywany po zapisaniu $length bajtów (nieskompresowanych). lub jest większy od opcjonalnego parametru $length.gzrewind Ustawia znacznik pozycji na początku pliku. int length]) gzwrite Zapisuje zawartość $string do pliku gz wskazywanego przez $zp. int gzseek( int zp. Patrz również gzcompress(). Uwaga 233 PHP – Kompendium wiedzy . obsługiwane jest jedynie przesunięcie w przód. Więcej informacji na temat surowych nagłówków można znaleźć w specyfikacji protokołu HTTP 1. gztell(). Patrz również: gzopen(). gzseek() i gzrewind(). Jeżeli plik jest otwarty do zapisu.1 (http://www. W przypadku błędu zwraca False. Jeżeli podano argument $length. ale może być to niezwykle powolne. lub po osiągnięciu końca danych wejściowych. int offset ) gztell Zwraca pozycje znacznika pozycji dla pliku wskazywanego przez $zp. int gztell( int zp ) gzuncompress Na podstawie danych $data. offset. Jeżeli wystąpi błąd. funkcja zwraca 0. W przypadku powodzenia operacji zwraca 0. string gzuncompress( string data [. ignorowany jest parametr konfiguracji magic_quotes_runtime i z ciągu $string nie będą usunięte ukośniki. gzopen() i gzputs(). Patrz również: gzread(). Wskaźnik pliku gz musi być prawidłowym wskaźnikiem wskazującym na plik otwarty przez funkcję gzopen(). Jeżeli plik jest otwarty do odczytu. Patrz również gzseek(). int gzrewind( int zp ) gzseek Ustawia znacznik pozycji pliku wskazywanego przez $zp na pozycję określoną przez $offset. to znaczy przesunięcie od początku pliku. skompresowanych za pomocą funkcji gzcompress() zwraca oryginalne nieskompresowane dane. Funkcja zakończy się niepowodzeniem. w przeciwnym wypadku zwraca -1. jeżeli rozmiar rozkompresowanych danych przekracza 256 krotność wielkości danych wejściowych $data.

Bardzo często spotykanym błędem jest umieszczanie wolnych linii przed wywołaniem funkcji header(). gmdate("D. tak aby wskazywała na skrypt PHP. jaka może być skonwertowana jest 7fffffff lub 2147483647 dziesiętnie. Patrz również: hebrevc(). */ Drugim nagłówkiem specjalnego przeznaczenia jest nagłówek rozpoczynający się ciągiem HTTP/ (wielkość znaków bez znaczenia). string hebrev(string hebrew_text [. Patrz również: hebrev(). /* przekierowuje rzeglądarkę do witryny PHP */ exit. Dla programistów skryptów może nie być to zbyt ważne. header("LastModified: " . boolean headers_sent( void ) False. Funkcja próbuje uniknąć łamania wyrazów.1 // HTTP/1. natomiast użycie funkcji Dodatek A .Funkcje 234 . int max_chars_per_line]) hexdec Zwraca dziesiętny odpowiednik liczby szesnastkowej przekazanej w parametrze $hex_string.php. //Data w przeszłości // Czas GMT // zawsze zmodyfikowane HTTP/1. Największą liczbą. Używane kolory są zdefiniowane w wewnętrznym module wyróżniania składni. hexdec() int hexdec( string hex_string ) highlight_file Wynikiem działania funkcji jest wersja pliku PHP. że konwertuje znaki nowej linii (\n) na <br>\n. niezależnie czy poprzez normalny kod HTML czy poprzez PHP. /* należy się upewnić.0 404 Not Found"). W tym celu należy wysłać nastepujący nagłówek: header("HTTP/1. Patrz również: dechex().net"). że skrypt PHP generuje błąd 404. że funkcja header() musi być wywołana przed wysłaniem danych HTML. header("Pragme: no-cache"). 26 ul 1997 05:00:00 GMT"). Oprócz odesłania tego nagłówka do przeglądarki zwraca on do Apache kod statusu REDIRECT. o nazwie $filename. Pierwszy to nagłówek Location. jeżeli wysłane zostały nagłówki HTTP. dobrze jest się upewnić. d M y H:i:s"). Funkcja próbuje uniknąć łamania wyrazów. z wyróżnioną składnią. skorzystamy z dyrektywy Apache ForceType. w przeciwnym przypadku zwraca również: header(). Skrypty PHP często generują dynamiczny kod HTML. ale ważne jest dla programistów zainteresowanych działaniem serwera Apache. header("Cache-Control: no-cache. must-revalidate"). Istnieją dwa nagłówki specjalnego przeznaczenia. Można zablokować wiele serwerów proxy za pomocą nagłówków: header("Expires: Mon.0 Patrz również: headers_sent().. headers_sent Zwraca True. który nie powinien być buforowany w przeglądarkach i serwerach proxy. Funkcja konwertuje ciąg szesnastkowy na liczbę dziesiętną. void highlight_file( string filename ) Przykład: Tworzenie łączy do plików z wyróżnioną składnią Aby utworzyć łącze umożliwiające wyróżnienie składni dowolnego pliku. int max_chars_per_line]) hebrevc Funkcja podobna do hebrev() z tą różnicą. Patrz hebrev Opcjonalny parametr $max_chas_per_line wskazuje na maksymalną ilość znaków w linii danych wyjściowych. int header( string string ) Przykład: header() header("Location: http://www.Należy pamiętać. że kod poniżej nie zostanie wykonany. string hebrevc( string hebrev_text [. Na przykład jeżeli skonfigurowana zostanie dyrektywa Apache ErrorDocument 404. Opcjonalny parametr $max_chars_per_line wskazuje maksymalną ilość znaków w wyniku. Pozwala to na stworzenie eleganckiego adresu URL.

Funkcja ta jest użyteczna do usuwania znaczników HTML z tekstu wprowadzonego przez użytkownika. należy użyć funkcji htmlentities(). $script)) { echo "<H1>Źródło skryptu: $PATH_INFO</H1>\n<hr>\n". pozostawiając bez zmian apostrofy. } echo "Przetworzony: " . highlight_string Wysyła na wyjście pokolorowaną wersję ciągu $str. if (!$script) { echo "<BR><B>BŁĄD: wymagana nazwa skryptu</B><BR>". Jeżeli wymagana jest kompletna konwersja. int quote_style]) htmlspecialchars Niektóre znaki mają specjalne znaczenie w HTML i powinny być reprezentowane przez symbole HTML. ENT_QUOTES 235 PHP – Kompendium wiedzy . Są to najczęściej używane konwersje przy programowaniu dla WWW. Patrz również: htmlspecialchars() i nl2br(). Argument opcjonalny. Domyślny tryb ENT_COMPAT jest dostępny dla zachowania zgodności z poprzednimi wersjami i konwertuje jedynie cudzysłowy.3. ENT_QUOTES powoduje konwersję zarówno cudzysłowów jak i apostrofów. pozostawiając bez zmian apostrofy. time()). void highlight_string( string str ) htmlentities Funkcja jest identyczna z htmlspecialchars(). że zarówno cudzysłowy jak i apostrofy pozostają niezmienione.conf należy dodać następujące linie: <Location /source> ForceType application/x-httpd-php </Location> Następnie należy utworzyć plik o nazwie source i umieścić go w głównym katalogu serwera WWW: <HTML> <HEAD> <TITLE>Wyświetlanie źródła</TITLE> </HEAD> <BODY COLOR BGCOLOR="white"> <?php $script = getenv( "PATH_TRANSLATED").0. Tak jak w przypadku funkcji htmlspecialchars() można użyć opcjonalnego argumentu wskazującego na sposób traktowania cudzysłowów i apostrofów. http://serwer. ENT_NOQUOTES powoduje.highlight_file() pozwala na pokazanie ładnie wyglądającego kodu. } else { if ereg("(\. string htmlentities( string string [. Używane kolory są zdefiniowane w wewnętrznym module PHP.com/source/sciezka/do/skryptu. W chwili obecnej używany jest zestaw znaków ISO-8859-1. Należy pamiętać. na przykład w księdze gości lub na tablicy ogłoszeniowej.17 i PHP 4. że argument opcjonalny został dodany w PHP 3. Wartość ENT_COMPAT (domyślna) konwertuje jedynie cudzysłowy. </BODY> </HTML> ?> Teraz można użyć adresów podobnych do przytoczonego poniżej.php Patrz również: highlight_string() i show_source(). } else echo "<H1>BŁĄD: Dopuszczalne sa jedynie rozszerzenia php i inc</H1>". aby wyświetlić kolorową wersję skryptu /sciezka/do/skryptu. highlight_file( $script ). date( "Y/M/d H:i:s".0.php.inc)$". $quote_style wskazuje sposób konwersji apostrofów i cudzysłowów. Patrz również: highlight_file() i show_source(). ale wszystkie znaki posiadające odpowiadające im symbole HTML są zamieniane na te symbole.php|\. W pliku httpd. Funkcja ta zwraca ciąg z zastosowanymi niektórymi z tych konwersji.

array hw_ChildrenObj( int connection. Należy pamiętać. False. Patrz również: hw_pConnect(). Każdy z argumentów powinien być ciągiem poza numerem portu. jeżeli operacja się uda.3. Patrz również: hw_mv(). Kopiuje obiekt o identyfikatorze podanym w drugim parametrze do kolekcji o identyfikatorze Zwracaną wartością jest ilość skopiowanych obiektów. Tablica zawiera wszystkie elementy potomne. Należy jedynie pamiętać. string password ) hw_Cp $destination_id. int port. jeżeli $connection nie jest prawidłowym indeksem połączenia. string hw_Array2Objrec( array object_array ) hw_Children Zwraca tablicę identyfikatorów obiektów. jak i apostrofy pozostają niezmienione. int destination_id Dodatek A . Każdy identyfikator należy do elementu kolekcji o identyfikatorze $objectID. Każdy z obiektów należy do elementu potomnego o identyfikatorze $objectID. Tablica zawiera wszystkie elementy potomne.0. jeżeli jest ustawiona wartość ENT_QUOTES < jest zmieniane na &lt. że argument opcjonalny został dodany w PHP 3. który jest potrzebny w innych funkcjach Hyperwave. int hw_Close( int connection ) hw_Connect Otwiera połączenie do serwera Hyperwave i zwraca indeks połączenia. int objectID ) hw_ChildrenObj Zwraca tablicę rekordów obiektów.powoduje konwersję zarówno cudzysłowów jak i apostrofów. " jest zamieniany na &quot.Funkcje 236 .. zarówno dokumenty jak i kolekcje. string username. > jest zmieniane na &gt. Wielokrotne atrybuty na przykład Title w różnych językach są obsługiwane prawidłowo. int hw_Cp( int conection. że przesyłane hasło nie jest zaszyfrowane. Można utrzymywać kilka połączeń do serwera. Jeżeli nie. int objectID ) hw_Close Zwraca False. Funkcja ta wykonuje jedynie przedstawione translacje. Jest to zbliżone do identyfikacji użytkownika anonimowego.0. Aby przeprowadzić pełną translację należy użyć funkcji htmlentities(). Funkcja zwraca indeks połączenia. o ile nie jest ustawiona wartość ENT_NOQUOTES ' jest zmieniany na &#039. zarówno dokumenty jak i kolekcje. W takim przypadku nie będzie przeprowadzana identyfikacja użytkownika. array object_id_array. int quote_style]) Wykonywane są następujące konwersje: & jest zamieniane na &amp. Zamyka połączenie o podanym indeksie do serwera Hyperwave. a w przeciwnym przypadku True. array hw_Children( int connection. że zarówno cudzysłowy string htmlspecialchars( string string [. hw_Array2Objrec Konwertuje $object_array na rekord obiektowy. Argumenty $username i $password są opcjonalne i mogą być opuszczone. • • • • • Uwaga ENT_NOQUOTES powoduje. zwraca int hw_Connect( string host.17 i PHP 4. Patrz również: hw_objrec2array().

do którego należy $anchorID. do którego należy $anchorID. ale jej stosowanie nie jest zalecane. string hw_Document_Content( int hw_document ) hw_Document_SetContent Zapisuje lub zmienia zawartość dokumentu. Patrz również: hw_Document_Attributes(). Parz również: hw_Document_Attributes(). int hw_Document_Size( int hw_document ) Zwraca wielkość 237 PHP – Kompendium wiedzy . Jeżeli funkcja się nie powiedzie. int anchorID ) hw_Document_Attributes Zwraca rekord obiektu dokumentu. Nie zaleca się jej stosowania. int anchorID ) hw_DocByAnchorObj Zwraca rekord obiektu dokumentu. znacznik BODY powinien być wydrukowany przez dokumentem. Usuwa wszystkie kopie obiektu. Jednak nie zaleca się stosowania tej nazwy. Jeżeli informacje te zostaną umieszczone w zawartości dokumentu. int object_to_delete ) hw_DocByAnchor Zwraca identyfikator obiektu. hw_Document_Size() i hw_Document_Content(). int hw_DocByAnchorObj( int connection. zawartość stanowi wszystko po znaczniku BODY. string hw_Document_BodyTag( int hw_document ) hw_Document_Content Dane Zwraca treść dokumentu. Jeżeli dokument jest w formacie HTML. Patrz również: hw_Document_Attributes(). Dla zachowania zgodności z poprzednimi wersjami akceptowane jest również hw_DocumentAttributes(). lub False gdy błędy wystąpiły. Zwraca True. Dla zapewnienia zgodności akceptowana jest również nazwa hw_DocumentBodyTag(). Patrz również: hw_Document_BodyTag() i W celu zachowania zgodności akceptowana jest również nazwa hw_DocumentSize. hw_Document_Attributes(). nie jest to najlepsze rozwiązanie. string hw_DocumentSetContent( int hw_document. po wstawieniu dokumentu serwer Hyperwave zmieni odpowiednio rekord obiektu. zawartością jest wszystko po znaczniku BODY. Jeżeli jest to dokument HTML. hw_Document_Size(). int hw_DocByAnchor( int connection. string content ) hw_Document_Size dokumentu w bajtach. dokument będzie zawierał poprzednią zawartość. ze znaczników BODY i HEAD są zapamiętywane w rekordzie obiektu. jeżeli nie wystąpiły żadne błędy. int hw_Deleteobject( int connection. Dane ze znaczników HEAD i BODY są przechowywane w rekordzie obiektu. Patrz również hw_mv(). hw_Document_Size() i hw_DocumentSetContent(). Patrz również: hw_Document_BodyTag() i hw_Document_Size().hw_Deleteobject Usuwa obiekt o identyfikatorze przekazanym w drugim argumencie funkcji. hw_Document_BodyTag Zwraca znacznik BODY dokumentu. Jeżeli jest to dokument HTML.

Patrz również: hw_Unlock() i hw_GetObject(). Funkcja nie zwraca dokumentów potomnych. hw_FreeDocument(). Rekord obiektu dokumentu nie może być modyfikowany do czasu zakończenia edycji. array hw_GetChildCollObj( int connection. array hw_GetChildColl( int connection.Funkcje 238 . string hw_GetAndLock( int connection. hw_Output_Document() i hw_GetText(). Każdy z rekordów obiektów należy do kolekcji potomnej w kolekcji o identyfikatorze $objectID. Funkcja ta działa jedynie dla dokumentów czysto tekstowych. int hw_Error( int connection ) hw_ErrorMsg False. string hw_ErrorMsg( int connection ) hw_Free_Document Zwalnia pamięć zajmowaną przez dokument Hyperwave. array hw_GetAnchors( int connection. Każdy z identyfikatorów należy do kolekcji potomnej w kolekcji o identyfikatorze $objectID.hw_EditText Przesyła test dokumentu na serwer. zwraca 0. int objectID ) Dodatek A . Funkcja nie zwraca dokumentów potomnych. Patrz również: hw_GetChildren() i hw_GetChildDocColl(). int objectID ) hw_GetChildCollObj Zwraca tablicę rekordów obiektów. int objectID ) hw_GetChildColl Zwraca tablicę identyfikatorów obiektów. Dodatkowo nakłada blokadę na obiekt. int hw_Free_Document( int hw_document ) hw_GetAnchors Zwraca tablicę identyfikatorów obiektów z łączami dokumentów z identyfikatorem obiektu $objectID. Jeżeli funkcja się nie udała. Zwraca ciąg zawierający ostatni komunikat błędu lub ciąg No Error. int objectID ) hw_GetAndLock Zwraca rekord obiektu dla obiektu o identyfikatorze $objectID. Patrz również: hw_ChildrenObj() i hw_GetChildDocCollObj(). Nie otwiera specjalnego połączenia i przez to na czas przesyłania blokuje połączenie sterujące. Jeżeli nie występowały żadne błędy. int hw_EditText( int connection. Patrz również: hw_PipeDocument(). dzięki czemu inni użytkownicy nie mają do niego dostępu do czasu zwolnienia blokady. hw_Document_BodyTag(). array hw_GetAnchorsObj( int connection. hw_Document_Size(). zwraca Komunikat błędu odnosi się do ostatnio wykonanej komendy. int objectID ) hw_GetAnchorsObj Zwraca tablicę rekordów obiektów z łączami dokumentów z identyfikatorem obiektu $objectID. int hw_document ) hw_Error Zwraca kod ostatniego błędu. Błąd odnosi się do ostatnio wykonanej komendy.

array} objectID. string query. array hw_GetChildDocCollObj( int connection.) */ <operator> ::= "=" | /* równy */ "<" | /* mniejszy od (porównanie ciągów) */ ">" | /* większy od (porównanie ciągów) */ "~" /* porównywanie wyrażeń regularnych */ Zapytanie pozwala na dalszy wybór odpowiednich obiektów z listy zwracanych obiektów. Patrz również: hw_GetAndLock() i hw_GetObjectByQuery(). string query ) Ciąg zapytania posiada następującą składnię: <expr> ::= "(" <expr> ")" | "!" <expr> | /* Negacja */ <expr> "||" <expr> | /* OR */ <expr> "&&" <expr> | /* AND */ <attribute> <operator> <value> <attribute> ::= /* dowolna nazwa atrybutu (Tytuł. maksymalna ilość zwracanych identyfikatorów nie jest ograniczona. Jeżeli drugi parametr jest tablicą liczb całkowitych. zwraca rekord obiektu dla obiektu o identyfikatorze $objectID.. int objectID. int objectID ) hw_GetObject Jeżeli drugi parametr jest liczą całkowitą. Maksymalna ilość obiektów jest ograniczona do $max_hits. W tym przypadku analizowany jest również trzeci parametr — ciąg zapytania. Patrz również: i hw_GetChildCollObj(). funkcja zwróci tablicę rekordów obiektów. Zapytanie działa jedynie na atrybutach posiadających indeksy. Jeżeli $max_hits ma wartość -1. Zapytanie działa jedynie na atrybutach posiadających indeksy. to zapytanie może działać na atrybutach bez indeksów. Patrz również: hw_GetObjectByQueryObj(). {int. czy możliwy jest dostęp do dokumentu. int max_hits ) hw_GetObjectByQueryColl Przeszukuje obiekty w kolekcji o identyfikatorze $objectID i zwraca tablicę identyfikatorów obiektów. int max_hits ) hw_GetObjectByQueryCollObj Przeszukuje obiekty w kolekcji o identyfikatorze $objectID i zwraca tablicę rekordów obiektów. array hw_GetObjectByQuery( int connection. maksymalna ilość zwracanych obiektów nie jest ograniczona. Zapytanie działa jedynie na atrybutach posiadających indeksy. Autor. Patrz również: hw_GetObjectByQueryColl(). maksymalna ilość zwracanych identyfikatorów nie jest ograniczona. W przeciwieństwie do pozostałych funkcji zapytań. array hw_GetObjectByQueryCollObj( int connection. TypDokumentu . array hw_GetChldDocColl( int connection. string query. string query. Jeżeli $max_hits ma wartość -1. Maksymalna ilość identyfikatorów jest ograniczona do $max_hits. Maksymalna ilość identyfikatorów jest ograniczona do $max_hits. int objectID. Patrz również: hw_GetObjectByQueryCollObj(). Ilość zwracanych rekordów obiektów zależy od zapytania i od tego. int max_hits ) 239 PHP – Kompendium wiedzy . hw_GetObjectByQuery Przeszukuje wszystkie obiekty na serwerze i zwraca tablicę identyfikatorów obiektów. array hw_GetObjectByQueryColl( int connection. int objectID ) hw_GetChildDocCollObj hw_ChildrenObj() Zwraca tablicę rekordów obiektów dla dokumentów potomnych w kolekcji. array hw_GetObject( int connection. Patrz również: hw_GetChildren() i hw_GetChildColl().hw_GetChildDocColl Zwraca tablicę identyfikatorów obiektów dokumentów potomnych w kolekcji.. Jeżeli $max_hits ma wartość -1.

niż wykonanie tego samego w PHP. Powinieneś również rozważyć użycie PHP zamiast Hyperwave do komunikacji z zdalnym źródłem danych. Powinieneś również rozważyć użycie PHP zamiast Hyperwave do komunikacji z zdalnym źródłem danych. int objectID ) hw_GetRemoteChilden Zwraca obiekty pochodne do zdalnego dokumentu. Patrz również: hw_GetAnchors(). powinieneś dobrze znać HGI. Dokumenty zdalne w sensie Hyperwave są dokumentami pobieranymi z zewnętrznych źródeł. Patrz również: hw_GetRemoteChildren(). funkcja zwraca tablice rekordów obiektów. int max_hits ) hw_GetParents Zwraca indeksowaną tablicę identyfikatorów obiektów. array hw_GetSrcByDestObj( int connection. maksymalna ilość zwracanych identyfikatorów nie jest ograniczona.hw_GetObjectByQueryObj Przeszukuje wszystkie obiekty na serwerze i zwraca tablicę rekordów obiektów. funkcja zwraca ten obiekt sformatowany przez HGI. Hyperwave wprowadza protokół Hyperwave Gateway Interface (HGI). Maksymalna ilość identyfikatorów jest ograniczona do $max_hits. jeżeli można ograniczyć zapytanie bazy danych. Jeżeli zamierzasz wykorzystać tą funkcję powinieneś dobrze znać HGI. Najczęściej dokumentami zdalnymi są strony WWW lub zapytania do baz danych. który jest podobny do CGI. array hw_GetParents( int connection. Dodatkowa tablica jest umieszczona w ostatnim elemencie zwracanej tablicy. Jeżeli istneije więcej niż jeden element pochodny. Funkcja ta może być wykorzystana. niż wykonanie tego samego w PHP. Patrz również: hw_GetObjectByQuery(). Jeżeli chcesz użyć tej funkcji. W chwili obecnej poprzez HGI można uzyskać dostęp do serwerów http. Jeżeli istnieje tylko jeden obiekt pochodny. hw_GetSrcByDestObj Zwraca rekordy obiektów wskazujących na obiekt o identyfikatorze dokumentem lub zakotwiczeniem. string query. Jest to opisane w podręczniku Hyperwave Programmer’s Guide. int objectID ) hw_GetRemote Zwraca zdalny dokument. array hw_GetObjectByQueryObj( int connection. ftp i niektórych baz danych.Funkcje 240 . Wywołanie hw_GetRemote() zwraca dokument pochodzący ze zdalnego źródła danych. Obiektami pochodnymi zdalnego dokumentu są również zdalne dokumenty. int hw_GetRemote( int connection. z których każdy być może może być wartością wejściową w kolejnym wywołaniu funkcji hw_GetRemoteChildren(). Obiekty te są obiektami wirtualnymi i nie istnieją w serwerze Hyperwave. Dodanie obsługi baz danych poprzez Hyperwave będzie bardziej skomplikowane. Każdy identyfikator obiektu jest obiektem podrzędnym do obiektu o identyfikatorze $objectID. Aby był możliwy dostęp do zewnętrznych źródeł dokumentów. Obiekt ten może być Dodatek A . int objectID ) $objectID. i dlatego nie posiadają własnych identyfikatorów. Patrz również: hw_GetRemote(). array hw_GetParentsObj( int connection. Każdy z rekordów obiektów jest obiektem podrzędnym do obiektu o identyfikatorze $objectID. Jeżeli $max_hits ma wartość -1. Dodanie obsługi baz danych poprzez Hyperwave będzie bardziej skomplikowane. Zapytanie działa jedynie na atrybutach posiadających indeksy. int objectID ) hw_GetParentsObj Zwraca indeksowaną tablicę rekordów obiektów oraz dodatkowo skorelowaną tablicę z danymi statystycznymi o rekordach obiektów.

int hw_GetText( int connection.. <Użytkownik>. na przykład /my_script. Jeżeli jest to liczba. na wyróżnienie części hierarchii dokumentów. określa w jaki sposób wstawiane są do dokumentu łącza. Jest to uzyteczne przy tworzeniu aplikacji WWW. wynikowe łącze HTML będzie miało postać <A HREF=". Wartością domyślną jest 0 i powoduje to utworzenie łączy z nazwy i obiektu docelowego łącza. Będziesz musiał tak ustawić swój serwer WWW. Zwracany ciąg posiada następującą postać: <Serwer>. Położenie źródła i celu łącza jest ignorowane. Autoryzacja jest ważna jedynie w bieżącej sesji. Jeżeli nie chcesz tego robić. Wszystkie łącza powinny zaczynać się od /my_script./c/internet_movie">. łącze HTML będzie miało postać <A HREF="/internet_movie">. zostaną one wstawione. int objectID [. Jednak gdy czwarty argument jest równy 1. Funkcja nie jest potrzebna zbyt często. gdzie znak . array object_id_array.jest separatorem hierarchii w serwerze Hyperwave.php3 musi sprawdzić zawartość $PATH_INFO i odczytać dokument. łącze jest tworzone z wszystkich nazw względem bieżącego obiektu. hw_Document_BodyTag(). W tym przypadku musi być to ciąg. aby zamieniał takie łącza na. czy zbiór obiektów (dokumentów lub kolekcji) przekazanych w $object_id_array jest częścią kolekcji przekazanych w $collection_id_array. zaczynając od $rootID/$prefix oddzielanych ukośnikami. Patrz również: hw_Connect(). array collection_id_array. Opcja ta pozwala na przykład. w której zawarte są wyniki przekazanego zapytania.php3/internet_movie. int return_collections) hw_Info Zwraca dane na temat bieżącego połączenia.php3/. jeżeli chcesz zapisać całą zawartość serwera na dysk i odwzorować hierarchię dokumentów w systemie plików. Opcjonalny parametr $rootID/$prefix może być ciągiem lub liczbą całkowitą. <Host>. zbiór kolekcji posiadających co najmniej jeden obiekt w znalezionym podzbiorze obiektów podrzędnych jest zwracany w postaci tablicy. <Zamiana bajtów>. Jeżeli na przykład poprzedni dokument internet_movie jest umieszczony w a-b-c-internet_movie. Jeżeli dokument posiada zakotwiczenia.hw_GetText Zwraca dokument z identyfikatorem $objectID. a dokument źródłowy znajduje się w a-b-d-source. array hw_InCollections( int connection. Jest to korzystne. string hw_Info( int connection ) 241 PHP – Kompendium wiedzy . Funkcja ta działa jedynie dla dokumentów tekstowych. $return_collections jest równy 0. <Port na kliencie>. mixed rootID/prefix]) Jeżeli $rootID/$prefix jest liczbą różną od 0. możesz ustawić odpowiednio parametr opcjonalny $rootID/$prefix na dowolny prefiks. Patrz również: hw_PipeDocument(). <Port>. które można do niego wstawić. string hw_getusername( int connection ) hw_Identify Autoryzuje użytkownika za pomocą ciągów $username i $password. hw_FreeDocument(). Jeżeli łącze wskazuje na nazwę internet_movie. hw_Document_Size() i hw_Open_Document(). Nie otwiera ona specjalnego połączenia. hw_getusername Zwraca nazwę użytkownika połączenia. więc blokuje na czas przesyłu połączenie sterujące. Skrypt my_script. Jeżeli czwarty parametr. lub więcej kolekcji) jest zwracany w postaci tablicy. podzbiór identyfikatorów będących częścią kolekcji (na przykład dokumenty lub kolekcje podrzędne do jednej. W większości przypadków łatwiejszą metodą autoryzacji jest otwarcie połączenia. hw_InCollections Sprawdza.

int parentID. do kolekcji o identyfikatorze int hw_InsColl( int connection. o ile został podany. array object_array ) hw_InsDoc Wstawia nowy dokument z atrybutami zawartymi w $object_record. Patrz również: hw_PipeDocument(). Title i Name. Nie jest to wykonywane domyślnie. należy usunąć stary atrybut i dodać nowy. int hw_mapid( int connection. Funkcja zwraca identyfikator obiektu nowego dokumentu. Pozycje niewidoczne są wymagane. $remove. hw_InsDoc() i hw_InsColl(). int hw_InsertDocument( int connection. string parameter ) hw_mapid Mapuje identyfikator globalnego obiektu na dowolnym serwerze Hyperwave. na przykład do pobrania rekordu obiektu za pomocą hw_getobject(). Patrz również: hw_PipeDocument(). należy użyć funkcji hw_insertdocument(). Dokument musi być wcześniej utworzony za pomocą funkcji hw_NewDocument(). int parent_id. string object_record. co obecnie można wykonać jedynie w czasie kompilacji pliku hg_comm. jak każdy inny identyfikator obiektu. jeżeli opis ni ma odpowiedniego łącza do tekstu opisu. jest listą atrybutów które należy dodać do obiektu. dodanie lub zmianę poszczególnych atrybutów rekordu obiektu. $object_array. nawet jeżeli nie wykonano podłączenia do niego za pomocą hw_connect(). int hw_document ) hw_InsertObject Umieszcza obiekt na serwerze. lub False. $add. int server_id. int object_id ) hw_Modifyobject Polecenie to pozwala na usunięcie. Ten obiekt wirtualny może być używany identycznie. string object_rec. czy Dodatek A . Przydatne jest ustawienie atrybutu MimeType. do kolekcji o identyfikatorze Funkcja wstawia rekord obiektu lub rekord obiektu oraz tekst przekazany w $text. int hw_InsDoc( int connection. string 3text ) hw_InsertDocument Przesyła dokument do kolekcji o identyfikatorze $parentID. Obiekt jest określony za pomocą identyfikatora $object_to_change.hw_InsColl Wstawia nową kolekcję z atrybutami zawartymi w tablicy $objectID.Funkcje 242 . Identyfikator serwera jest pierwszą częścią globalnego identyfikatora obiektu (GOid) i w chwili obecnej jest to numer IP w postaci liczby. Pierwsza tablica. jest listą atrybutów do usunięcia. że rekord obiektu posiada co najmniej następujące atrybuty: Type. W celu zmiany atrybutu. int hw_InsertObject( int connection. int objectID. końcową lub invisible.c. Należy zapoznać się z komentarzami na początku pliku hg_comm. Więcej danych na ten temat znajduje się w dokumentacji HG-CSP. że wartości atrybutów do usunięcia nie są tablicą ciągów. $parentID. Jeżeli chcesz wstawić dokument dowolnego typy.c. hw_InsertDocument(). Ostatni parametr wskazuje. Uwaga Aby użyć tej funkcji należy ustawić znacznik F_DISTRIBUTED. Uwaga Jeżeli chcesz wstawić zakotwiczenie atrybut position musi być zawsze ustawiony na wartość początkową. Funkcja hw_Modifyobject() zawsze najpierw usuwa stare atrybuty a potem dodaje nowe chyba. Obiekt musi być prawidłowym obiektem Hyperwave. Druga tablica. DocumentType. Patrz również: hw_InsertDocument() i hw_InsColl(). Należy się upewnić. do identyfikatora obiektu wirtualnego.

Uwaga Nie musisz otaczać wywołania tej funkcji wywołaniami hw_getandlock() i hw_unlock(). $addarr = array("Name" => "artykuły"). Przykład: zmiana atrybutu // $connect jest istniejącym połączeniem do serwera Hyperwave // $objid jest identyfikatorem obiektu do zmiany $remarr = array("Name" => "książki"). jeżeli chcesz usuwać atrybuty w sposób rekurencyjny. $hw_modifyobject($connect. powinieneś utworzyć dwie tablice i wywołać funkcję hw_modifyobject(). Atrybut Name ma specjalne znaczenie. $remarr. Description i Keyword prawidłowo obsługują prefiksy języków. Poprzedni przykład może być zapisany w następujący sposób: Przykład: zmiana atrybutu Title $remarr = array("Title" => "en:Books"). $objid. Jeżeli chcesz zmienić atrybut Name z bieżącą wartością książki na artykuły. Jest to niezbędne. $remarr. Jeżeli chcesz usunąć wszystkie atrybuty o zadanej nazwie. Funkcja hw_error() może nie wskazać żadnego błędu. $addarr = array("Name" => "artykuły"). usunięcie się nie uda. Funkcja hw_modifyobject() robi to samodzielnie. $objid. $addarr = array("Title" => array("en" => "Articles". Aby usunąć lub dodać parę nazwa–wartość. Wartością każdego z elementów tablicy może być tablica ciągów. Zwraca True w przypadku pomyślnego wykonania i False w przypadku błędu. $addarr). Jedynie atrybuty Title. Jeżeli atrybut nie posiada prefiksu języka. należy przekazać tablice zawierające dodawane i usuwane atrybuty przekazując w trzecim parametrze pustą tablicę. spowoduje. $hw_modifyobject($connect. lub przekazywanie tablicy z elementami dla każdego języka zapisanymi w identyczny sposób jak poprzednio. na przykład 0. array remove. $remarr. $objid. na przykład Title mogą być zmieniane na dwa sposoby. Wstawienie pustego ciągu spowoduje całkowite usunięcie atrybutu. jeżeli chcesz dodać całkowicie nowy atrybut a nie wartość istniejącego atrybutu. Jeżeli tablica z elementami do usunięcia będzie zawierała pusty ciąg dla atrybutu. ciąg. że nie będzie podjęta próba jego usunięcia. $remarr. wartość atrybutu jest tworzona z klucza. $addarr). $objid. $objid. int hw_Modifyobject( int connecion. Jeżeli atrybut jest pierwszym atrybutem o tej nazwie. W przykładzie tym zostanie usunięty angielski tytuł Books i dodany tytuł angielski Articles i niemiecki Artikel. Jeżeli będzie to tablica. ale na przykład liczbą. Jeżeli nie jest możliwa modyfikacja niektórych obiektów. Przykład: dodanie całkowicie nowego atrybutu // $connect jest istniejącym połączeniem do serwera Hyperwave // $objid jest identyfikatorem obiektu do zmiany $remarr = array("Name" => 0). $hw_modifyobject($connect. $addarr = array("Title" => "en:Articles"). $remarr. średnika i wartości. zostaną pominięte bez żadnej informacji o tym fakcie. $addarr = array("Title" => "en:Articles"). Przykład: usuwanie atrybutu $remarr = array("Title" => ""). Dlatego zawsze musisz dodawać nowy atrybut Name przed usunięciem starego. bądź cokolwiek innego. lub Przykład: zmiana atrybutu Title $remarr = array("Title" => array("en" => "Books")). int mode ) Kluczami w obu tablicach są nazwy atrybutów. Otrzymasz wtedy komunikat błędu Change of base attribute (nie jest jasna przyczyna tego błędu). $hw_modifyobject($connect. Uwaga Atrybuty w wielu językach. Jest to wygodne. należy ustawić wartości w tablicy atrybutów do usunięcia na liczby całkowite. 243 PHP – Kompendium wiedzy . Ustawienie wartości tego atrybutu na. w niektórych przypadkach nie jest możliwe jego całkowite usunięcie. $addarr). choć nie wszystkie obiekty będą zmienione. Pierwszym sposobem jest wpisywanie wartości atrybutów w postaci język:tytuł. użyty zostanie prefiks xx. Wartość 1 oznacza rekurencyjne wywołanie.operacja ma być wykonana w sposób rekurencyjny. Uwaga Wykonanie poprzedniego przykładu spowoduje usunięcie wszystkich atrybutów o nazwie Title i dodanie nowego atrybutu Title. $addarr). Jeżeli wartość nie jest ani ciągiem ani tablicą. musisz przekazać pusty ciąg jako wartość atrybutu. array add. natomiast dodanie atrybutu powiedzie się. nie będą podejmowane żadne operacje na atrybucie. $hw_modifyobject($connect. int object_to_change. "ge"=>"Artikel"). $addarr).

Jeżeli jest to ostatni egzemplarz obiektu. hw_Document_BodyTag(). Atrybuty wielowartościowe. int document_size) hw_Objrec2Array Konwertuje $object_record na tablicę obiektów. Patrz również: hw_array2objrec(). takie jak Title. Jeżeli nie podany został parametr opcjonalny. Część ta musi mieć dwa znaki. gdy połączenie nie może być wykonane. hw_Output_Document() i hw_InsertDocument(). Można mieć kilka jednocześnie otwartych trwałych połączeń. string password) hw_PipeDocument Zwraca dokument Hyperwave o identyfikatorze obiektu $objectID. Przekazując tablice zawierająca typy każdego z argumentów można zmienić to zachowanie. Patrz również: hw_Connect(). array hw_objrec2array (string object_record [. hw_Document_Size(). Dla zgodności z poprzednimi wersjami można użyć nazwy ale jest to postać przestarzała. Więcej informacji na temat wstawiania łączy znajduje się w opisie funkcji hw_FreeDocument(). Description i Keyword są traktowane jako atrybuty języka.. Jest to zbliżone do korzystania z konta gościa. Zawartość dokumentu jest przekazana w parametrze $document_data.Funkcje 244 . array object_id_array. array format]) hw_Output_Document hw_OutputDocument(). int destination_id ) hw_New_Document Zwraca nowy dokument Hyperwave. Patrz również: hw_FreeDocument(). hw_Document_BodyTag() i hw_Output_Document(). int hw_pconnect (string host. int hw_pipedocument (int connection. zostaną one wstawione. Funkcja zwraca numer połączenia. atrybuty Title. Każdy z argumentów oprócz numeru portu. który jest przekazywany do wszystkich funkcji Hyperwave. należy użyć funkcji hw_deleteobject(). string username.hw_Mv Przenosi obiekt o identyfikatorze podanym w drugim parametrze z kolekcji i identyfikatorze $source do kolekcji o identyfikatorze $destination. powinien być ciągiem znaków. Dokument zostanie przesłany poprzez połączenie specjalne. Inne wartości wielowartościowe nie posiadające prefiksów tworzą indeksowaną tablicę. lub False w przypadku. int hw_new_document (string object_record. hw_Document_Size(). natomiast atrybuty Group. int hw_Mv( int connection. int souce_id. które nie blokuje połączenia sterującego. Jeżeli dokument posiada możliwe do wstawienia zakotwiczenia. natomiast rekord obiektu w $object_record. Kluczami wynikowej tablicy są nazwy atrybutów. Jeżeli identyfikator kolekcji docelowej wynosi 0. Patrz również: hw_GetText(). Drukuje dokument bez znacznika BODY. Wielkość danych musi być przekazana w parametrze $document_size. int port. Funkcja ta nie wstawia dokumentu do serwera Hyperwave. Otwiera trwałe połączenie do serwera Hyperwave. Jeżeli chcesz usunąć wszystkie wystąpienia za pomocą jednego wywołania. int hw_output_document (int hw_document) hw_pConnect W przypadku powodzenia zwraca numer połączenia. w różnych językach tworzą własne tablice. Zwracana wartość jest ilością przeniesionych obiektów. W takim przypadku nie jest wykonywana autoryzacja na serwerze. Argumenty $username i $password są opcjonalne. obiekt jest usuwany ze źródłowej kolekcji. Kluczami w tych tablicach części stojące z lewej strony dwukropka. int objectID) Dodatek A . Parent i HtmlAttr są traktowane jako wartości wielowartościowe bez prefiksu. string document_data. Tablica jest tablicą asocjacyjną z nazwą atrybutu jako klucze i wartościami będącymi jedną z wartości HW_ATTR_LANG lub HW_ATTR_NONE. zostanie on usunięty. Patrz również: hw_cp() i hw_deleteobject().

pola onSinceDate. Zamiast tego zwracany jest identyfikator istniejącego połączenia. int ibase_close ([int connection_id]) ibase_connect Nawiązuje połączenie z serwerem InterBase. Jeżeli ibase_connect() jest wywoływany po raz drugi z tymi samymi parametrami. system. string username [. Jeżeli podane zostanie 0 lub parametr zostanie opuszczony. Połączenie z serwerem jest zamykane natychmiast po zakończeniu wykonywania skryptu. Argument $database musi być ścieżką do pliku bazy danych na serwerze. nie jest tworzone nowe połączenie. int objectID) hw_Who Zwraca tablicę z użytkownikami obecnie zalogowanymi na serwerze Hyperwave. Parametr $dialect wybiera domyślny dialekt SQL obowiązujący dla wszystkich wyrażeń wykonywanych poprzez bieżące połączenie. int hw_root () hw_Unlock Odblokowuje dokument. musi być poprzedzony albo ciągiem hostname: (TCP/IP). int buffers [. Patrz również: ibase_pconnect(). Parametr $charset jest domyślnym zestawem znaków dla bazy danych. Jeżeli identyfikator połączenia jest pominięty. serwer zakłada domyślną dla siebie ilość buforów. Każda pozycja jest kolejna tablica. nazwa. string password [.default_user i ibase. $stmt). oraz self. Patrz również: hw_GetAndLock(). Wartością domyślną jest najwyższy dialekt obsługiwany przez biblioteki klienta. $password). natomiast pozostałe transakcje są wycofywane. $username. int ibase_connect(string database [. Parametr $buffers określa ilość buforów bazy danych zakładanych na serwerze. Domyślna transakcja w tym połączeniu jest zatwierdzana. 245 PHP – Kompendium wiedzy . while ($row = ibase_fetch_object ($sth)) { print $row->email .default_password. Jeżeli serwer nie jest serwerem lokalnym. //hostname (NetBEUI) lub hostname@ (IPX/SPX) w zależności od protokołu używanego w tym połączeniu. ?> Uwaga Parametry $buffers i $dialect zostały dodane w PHP4-RC2. TotalTime. w chwili obecnej posiada ona wartość 0.hw_Root Zwraca identyfikator obiektu kolekcji korzenia. string charset [. $sth = ibase_query ($dbh. chyba. Parametr $role działa jedynie z InterBase 5 i wyższymi. $stmt = 'SELECT * FROM tblname'. "\n". onSinceTime. Wartością self jest 1 jeżeli pozycja należy do użytkownika inicjującego żądanie. int hw_who (int connection) ibase_close Zamyka połączenie z bazą danych InterBase identyfikowane przez identyfikator połączenia zwracany przez funkcję ibase_connect(). string role]]]]]]) Przykład: ibase_connect() <?php $dbh = ibase_connect ($host. Parametry $username i $password mogą być pobierane w dyrektywach konfiguracji ibase. int dialect [. Działają one jedynie z serwerem InterBase 6 i nowszymi od niego. int hw_unlock (int connection. Kolekcja potomna tej kolekcji jest główną kolekcją serwera. } ibase_close ($dbh). zawierającą atrybuty: identyfikator elementu. więc użytkownicy mają nów do niego dostęp. że wcześniej została wywołana funkcja ibase_close(). funkcja działa na ostatnio otwartym połączeniu.

int ibase_free_query (int query) ibase_free_result Zwalania wynik tworzony przez ibase_query(). "\n". $stmt = 'SELECT * FROM tblname'. array ibase_fetch_row (int result_identifier) ibase_free_query Zwalnia zapytanie przygotowane przez ibase_prepare(). $sth = ibase_query ($dbh. Przykład: ibase_num_fields() Dodatek A . gdy to samo zapytanie jest powtarzane dla różnych parametrów. } ?> ibase_fetch_object Pobiera wiersz w postaci pseudoobiektu korzystając z ibase_execute().ibase_execute Wykonuje zapytanie przygotowane za pomocą ibase_prepare(). int ibase_free_result (int result_identifier) ibase_num_fields Zwraca liczbę określającą ilość pól w wyniku zapytania. $stmt). ibase_fetch_row Zwraca kolejny wiersz korzystając z identyfikatora wyniku zwracanego przez funkcję ibase_query(). W przypadku. = array( 'Eric'. 'Larry' $query = ibase_prepare("UPDATE FOO SET BAR = ? WHERE BAZ = ?"). $username. jest to o wiele bardziej efektywne niż wykorzystanie ibase_query(). $bar) = each($updates)) { ibase_execute($query. Uwaga Funkcja ibase_num_fields() nie działa jeszcze w PHP 4. Patrz również ibase_field_info(). while ($row = ibase_fetch_object ($sth)) { print $row->email . object ibase_fetch_object (int result_id) $result_id zwróconego przez ibase_query() lub Przykład: ibase_fetch_object() <php $dbh = ibase_connect ($host. ?> Patrz również: ibase_fetch_row(). $bar. 'Filip'.Funkcje 246 . while (list($baz. $baz). } ibase_close ($dbh). int ibase_execute (int query [. $password). int bind_args]) Przykład: ibase_execute() <?php $updates 1 => 5 => 7 => ).

Jeżeli zostanie ion opuszczony. daty i czasu dla kolumn tych typów zwracanych zapytaniach. Parametr $columntype jest jedną ze stałych IBASE_TIMESTAMP. Parametr $columntype został dodany w PHP 4. string role]]]]]]) ibase_prepare Przygotowuje zapytanie dodając obsługę parametrów dołączanych później za pomocą funkcji ibase_execute(). int ibase_timefmt (string format [. są one identyczne.<?php $dbh = ibase_connect ($host. że funkcja ta obsługuje dołączanie zmiennych do parametrów. if (ibase_num_fields($sth) > 0) { while ($row = ibase_fetch_object ($sth)) { print $row->email . Przykład użycia funkcji jest umieszczony przy opisie funkcji ibase_prepare() i ibase_execute(). w czasie dołączania do serwera funkcja próbuje odszukać istniejące (trwałe) połączenie otwarte z tym samym zestawem argumentów. ?> ibase. ?> ibase_pconnect Działa bardzo podobnie do ibase_connect() z dwiema poważnymi różnicami. Po drugie. Połączenie pozostaje otwarte do wykorzystania w przyszłości (ibase_close() nie zamyka połączeń utworzonych przez ibase_pconnect()).0. $username. $password). i ibase.dateformat Można również ustawić domyślny format za pomocą dyrektyw konfiguracji PHP ibase. $sth = ibase_query ($dbh. Połączenie do serwera InterBase nie jest zamykane po zakończeniu wykonywania skryptu. string query]) ibase_query Wykonuje zapytanie na basie danych InterBase i zwraca identyfikator wyniku wykorzystywany w funkcjach ibase_fetch_row(). Wewnętrznie kolumny są formatowane przez funkcję C strftime(). } } else { die ("No Results were found for your query"). string charset [. przyjmowana jest wartość IBASE_TIMESTAMP w celu zapewnienia zgodności z poprzednimi wersjami. Jeżeli zostanie znalezione takie połączenie. string username [. string query [. $stmt = 'SELECT * FROM tblname'. IBASE_DATE i IBASE_TIME. ibase_timefmt("%H godzin %M minut". int dialect [. int buffers [. PHP – Kompendium wiedzy 247 . int ibase_pconnect(string database [. Po pierwsze. "\n". Opis parametrów przekazywanych do funkcji jest zamieszczony przy opisie funkcji ibase_connect(). Mimo. string password [. więc wszelkie szczegóły na temat ciągu formatującego znajdują się w jej dokumentacji. int ibase_query ([int link_identifier. ibase_fetch_object(). używanie tego udogodnienia w tej właśnie funkcji nie ma wielkiego sensu.timestampformat. int columntype]) Przykład: ibase_timefmt() <?php // kolumny InterBase 6 typu TIME będą zwracane w postaci // '05 godzin 37 minut'. int bind_args]]) ibase_timefmt Ustala format znacznika czasu. jego identyfikator jest zwracany i nie jest tworzone nowe połączenie. IBASE_TIME). ibase_free_result() i ibase_free_query(). int ibase_prepare ([int link_identifier. $stmt). } ibase_close ($dbh). Ma on znaczenie jedynie w wersjach InterBase 6 i wyższych.timeformat. Połączenie takie nazywane jest z tego powodu połączeniem trwałym.

Zwraca True.Uwaga W PHP 4. array time) • • • • • • Wszystkie pozycje z datą i czasem zawierają następujące atrybuty: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy Dodatek A . Wszystkie pozycje daty i czasu zawierają następujące atrybuty: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy icap_list_alarms icap_list_alarms() Zwraca tablicę z identyfikatorami zdarzeń które wyślą alarm o podanej godzinie. object start — Obiekt zawierający datę i czas. Zwracana jest tablica identyfikatorów zdarzeń z aktywnym alarmem o podanej godzinie. int event_id [. int icap_close (int icap_stream [. która powodowała niezgodność z poprzednimi wersjami. int uid) icap_fetch_event Pobiera zdarzenie określone przez $event_id ze strumienia kalendarza. int flags]) icap_delete_event Usuwa zdarzenie z kalendarza o identyfikatorze podanym w $uid. gdy jest prywatne. string description — Ciąg z opisem zdarzenia . int alarm — Ilość minut przed zdarzeniem gdy wysyłane jest powiadomienie lub alarm.0 wprowadzono zmianę. string title — Ciąg zawierający tytuł zdarzenia.Funkcje 248 .timeformat w celu ulepszenia działania funkcji. array date. int icap_list_alarms (int stream_id.dateformat i ibase. icap_close Zamyka podany strumień icap. string category — Ciąg zawierający kategorię zdarzenia. object end — Obiekt zawierający datę i czas. int icap_fetch_event (int stream_id. Funkcja wymaga podania daty i czasu oraz strumienia kalendarza. int options]) • • • • • • • • • • • • • • Zwraca obiekt zdarzenia zawierający następujące atrybuty: int id — Identyfikator zdarzenia. int public — True jeżeli zdarzenie jest publiczne lub False. string icap_delete_event (int sream_id.timeformat na ibase.timestampformat oraz dodane zostały dyrektywy ibase. zmieniając nazwę dyrektywy konfiguracji ibase.

int public — 1 jeżeli zdarzenie jest publiczne lub 0. True w przypadku powodzenia operacji. Funkcja icap_list_events() pobiera ze strumienia identyfikatory zdarzeń pomiędzy data początkową i końcową. int alarm — Ilość minut przed zdarzeniem gdy wysyłane jest powiadomienie lub alarm. jest on również przekazany do otwieranej skrzynki pocztowej. int begin_date [. False. natomiast w przypadku wystąpienia błędu. string options) icap_snooze Włącza alarm dla zdarzenia kalendarza określonego przez $uid. string icap_store_event (int stream_id. ifxus_close_slob Usuwa obiekt slob dla podanego w $bid identyfikatora obiektu slob. array icap_list_events (int stream_id. string category — Ciąg zawierający kategorię zdarzenia. Funkcja icap_open() otwiera połączenie ICAP do podanego w $calendar magazynu. string description — Ciąg z opisem zdarzenia . int ifxus_close_slob (int bid) False w przypadku 249 PHP – Kompendium wiedzy . Jeżeli podany jest parametr opcjonalny $options. Zwraca True. Wszystkie pozycje daty i czasu zawierają następujące atrybuty: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy Zwraca True w przypadku powodzenia operacji lub False w przypadku błędu. string username. gdy jest prywatne. string title — Ciąg zawierający tytuł zdarzenia. Zwraca wystąpienia błędu. int uid) icap_store_event Zapisuje zdarzenie w kalendarzu ICAP. object end — Obiekt zawierający datę i czas. object start — Obiekt zawierający datę i czas.icap_list_events Zwraca tablicę identyfikatorów zdarzeń pomiędzy dwiema datami. string password. string icap_snooze (int stream_id. int end_date]) • • • • • • Wszystkie pozycje z datą i czasem zawierają następujące atrybuty: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy icap_open W przypadku powodzenia zwraca strumień ICAP. stream icap_open (string calendar. Zwracana jest tablica identyfikatorów zdarzeń pomiędzy podanymi datami. object event) • • • • • • • • • • • • • • Obiekt zdarzenia zawiera następujące atrybuty: int id — Identyfikator zdarzenia.

ifxus_create_slob
Tworzy obiekt slob i otwiera go. Tryby: 1 = LO_RDONLY, 2 = LO_WRONLY, 4 = LO_APPEND, 8 = LO_RDWR, 16 = LO_BUFFER, 32 = LO_NOBUFFER. Można również użyć stałych o nazwach IFX_LO_RDONLY, IFX_LO_WRONLY itd. Zwraca False w przypadku wystąpienia błędu a w przypadku powodzenia, identyfikator obiektu slob.

ifxus_free_slob
Usuwa obiekt slob. Parametr $bid jest identyfikatorem obiektu slob. Zwraca wystąpienia błędu i True w przeciwnym wypadku.
int ifxus_free_slob (int bid)

False

w przypadku

ifxus_open_slob
LO_RDONLY, 2 = LO_WRONLY, 4 = LO_APPEND, 8 = LO_RDWR, 16 = LO_BUFFER, 32 = LO_NOBUFFER.
int ifxus_open_slob (long bid, int mode)

powinien być identyfikatorem istniejącego obiektu. Tryby: 1 = Zwraca False w przypadku wystąpienia błędu a w przeciwnym wypadku identyfikator nowego obiektu slob.
$bid

Otwiera obiekt slob. Parametr

ifxus_read_slob
Czyta n bajtów z obiektu slob. Parametr $bid jest identyfikatorem istniejącego obiektu slob, natomiast $nbytes jest ilością bajtów do przeczytania. Zwraca False w przypadku wystąpienia błędu a w przeciwnym wypadku zwraca ciąg.
int ifxus_read_slob (long bid, long nbytes)

ifxus_seek_slob
Ustawia bieżący plik lub wyszukuje pozycję w otwartym obiekcie slob. Parametr $bid powinien być identyfikatorem istniejącego obiektu slob. Tryby: 0 = LO_SEEK_SET, 1 = LO_SEEK_CUR, 2 = LO_SEEK_END natomiast $offset jest przesunięciem w bajtach. Zwraca False w przypadku wystąpienia błędu a w przeciwnym wypadku pozycję w pliku.
int ifxus_seek_slob (long bid, int mode, long offset)

ifxus_tell_slob
Zwraca bieżącą pozycję w pliku lub przesunięcie w otwartym obiekcie slob. Parametr $bid powinien być identyfikatorem istniejącego obiektu slob. Zwraca False w przypadku wystąpienia błędu a w przeciwnym wypadku pozycję w pliku.
int ifxus_tell_slob (long bid)

ifxus_write_slob
$content

Zapisuje zawartość ciągu do obiektu slob. Parametr $bid musi być identyfikatorem obiektu slob, natomiast zawiera dane do zapisania. Zwraca False w przypadku wystąpienia błędu, w przeciwnym przypadku ilość zapisanych bajtów.
int ifxus_write_slob (long bid, string content)

ifx_affected_rows
Parametr $result_id powinien być identyfikatorem wyniku zwracanym przez funkcję ifx_query() lub Zwraca ilość wierszy zmienionych przez zapytanie związane z $result_id. W przypadku operacji wstawienia, zamiany lub usunięcia, ilość ta jest prawdziwą liczbą operacji (sqlerrd[2]). W przypadku operacji SELECT nie jest dokładną liczbą zwracanych wierszy, a jedynie oszacowaniem (sqlerrd[0]). Serwer bazy danych może nigdy nie zwrócić ilości wierszy zwracanych przez operację SELECT w tej fazie operacji (zaraz po operacji
ifx_prepare().

Dodatek A - Funkcje

250

po ustaleniu planu wykonania przez optymalizator), ponieważ nie rozpoczął on odczytywania zwracanych wierszy. Jest to użyteczna funkcja do ograniczania zapytań do takich, które zwracają rozsądną ilość wierszy po przygotowaniu zapytania przez ifx_prepare(). Patrz również: ifx_num_rows().
int ifx_affected_rows (int result_id)

PREPARE,

Przykład: wykorzystanie funkcji serwera Informix ifx_affected_rows()
$rid = ifx_prepare ("select * from emp where name like " . $name, $connid); if (! $rid) { ... błąd ... } $rowcount = ifx_affected_rows ($rid); if ($rowcount > 1000) { printf ("Zapytanie zwraca zbyt dużo wierszy: (%d)\n<br>", $rowcount); die ("Proszę ograniczyć zapytanie<br>\n"); }

ifx_blobinfile_mode
Ustawia domyślny tryb przechowywania obiektów blob w zapytaniach przechowywanie blobów w pamięci, natomiast 1, przechowywanie ich w pliku.
void ifx_blobinfile_mode (int mode)

SELECT.

Tryb

0

oznacza

ifx_byteasvarchar
Ustawia domyślny tryb zapytaniach SELECT. Tryb zwracanie pola varchar z danymi tekstowymi.
void ifx_byteasvarchar (int mode)

0

powoduje zwracanie identyfikatora blob, natomiast 1,

ifx_close
Zawsze zwraca True. Funkcja ifx_close() powoduje zamknięcie połączenia z bazą danych Informix, skojarzoną z podanym identyfikatorem połączenia. Jeżeli nie został podany identyfikator połączenia, zamykane jest ostatnio otwarte połączenie.
Uwaga nie jest to operacja niezbędna, ponieważ nietrwałe połączenia są zamykane automatycznie po zakończeniu wykonywania skryptu. Funkcja ifx_close() nie zamyka połączeń trwałych generowanych przez ifx_pconnect().

Patrz również: ifx_connect() i ifx_pconnect().
int ifx_close ([int link_identifier])

Przykład: Zamykanie połączenia z bazą danych Informix
$conn_id = ifx_connect ("mydb@ol_srv", "itsme", "mypassword"); ... potrzebne zapytania ... ifx_close($conn_id);

ifx_connect
Zwraca identyfikator połączenia lub false w przypadku wystąpienia błędu. Funkcja ifx_connect() nawiązuje połączenie z serwerem Informix. Wszystkie argumenty są opcjonalne i w przypadku opuszczenia któregoś z nich, z pliku konfiguracyjnego pobierane są wartości domyślne, ifx.default_host zawiera nazwę serwera biblioteki Informixa korzystają ze zmiennej środowiskowej INFORMIXSERVER), ifx.default_user zawiera nazwę użytkownika a ifx.default_password zawiera domyślne hasło (jeżeli nie jest zdefiniowana to bez hasła). Jeżeli drugi raz wywołano funkcję ifx_connect() z tymi samymi argumentami, nie jest nawiązywane nowe połączenie. Zamiast tego zwracany jest identyfikator istniejącego połączenia. Połączenie nie jest zamykane po zakończeniu wykonywania skryptu lub po wywołaniu funkcji ifx_close(). Patrz również: ifx_pconnect() i ifx_close().
int ifx_connect (string [database], string [userid], string [password])

Przykład: Podłączenie do bazy Informix
$conn_id = ifx_connect ("mydb@ol_srv", "itsme", "mypassword");

251

PHP – Kompendium wiedzy

ifx_copy_blob
Tworzy kopię podanego obiektu blob. Parametr $bid jest identyfikatorem obiektu blob. Zwraca przypadku błędu, a w przeciwnym wypadku identyfikator nowego obiektu blob.
int ifx_copy_blob (int bid)

False

w

ifx_create_blob
Tworzy obiekt blob. Zwraca obiektu blob. • • •
False

w przypadku błędu, a w przeciwnym wypadku identyfikator nowego

int ifx_create_blob (int type, int mode, string param)

Parametr $type: 1 = TEXT, 0 = BYTE Parametr $mode: 0 = obiekt blob jest przechowywany w pamięci, 1 = obiekt blob jest przechowywany w pliku. Parametr $param: Jeżeli tryb=0 jest to wskaźnik na zawartość, jeżeli tryb=1, wskaźnik na strumień pliku.

ifx_create_char
Tworzy obiekt znakowy. Parametr $param powinien zawierać zawartość obiektu.
int ifx_create_char (string param)

ifx_do
Zwraca True gdy operacja się powiodła i False w przypadku błędu. Wykonuje uprzednio przygotowane zapytanie i otwiera dla niego kursor. W przypadku wystąpienia błędu nie zwalnia $result_id. Dla zapytań innych od SELECT ustawia również właściwą liczbę zmienionych wierszy, którą można odczytać za pomocą ifx_affected_rows(). Patrz również ifx_prepare().
int ifx_do (int result_id)

ifx_error
Kody błędów serwera Informix (SQLSTATE i SQLCODE) są formatowane następująco: x [SQLSTATE = aa bbb SQLCODE=cccc] Gdy x jest spacją, oznacza to brak błędu. E — błąd N — koniec danych W — ostrzeżenie ? — niezdefiniowany
string ifx_error (void)

Jeżeli znak x jest czymkolwiek poza spacją, SQLSTATE i SQLCODE dokładniej opisują błąd. Opis SQLSTATE i SQLCODE można znaleźć w podręczniku do serwera Informix. Zwraca jeden znak określający wynik wyrażenia oraz zarówno wartość SQLSTATE jak i SQLCODE związane z ostatnio wykonywanym wyrażeniem SQL. Format tego ciągu jest następujący: (znak) [SQLSTATE=(dwa znaki) (trzy znaki) SQLCODE=(jeden znak)]. Pierwszym znakiem może być spacja (sukces), W (wyrażenie wygenerowało ostrzeżenia), E (zdarzył się błąd w czasie wykonywania wyrażenia) lub N (wyrażenie nie zwróciło żadnych danych). Patrz również: ifx_errormsg().

ifx_erormsg
Zwraca komunikat serwera Informix opisujący ostatni błąd w serwerze lub gdy podano wartość opcjonalnego parametru $errorcode, komunikat związany z podanym numerem błędu. Patrz również: idx_error().
string ifx_errormsg ([int errorcode])

Przykład: ifx_errormsg()
printf("%s\n<br>", ifx_errormsg(-201));

Dodatek A - Funkcje

252

ifx_fetch_row
Zwraca tablicę asocjacyjną zawierająca odczytany wiersz, lub False jeżeli nie ma następnego wiersza. Kolumny blob są zwracane w postaci numerycznych identyfikatorów blob, które można użyć w funkcji ifx_get_blob(), lub jeżeli zostały wywołane funkcje ifx_textasvarchar(1) lub ifx_byteasvarchar(1), pola blob są zwracane w postaci ciągów znaków. W przypadku wystąpienia błędu zwraca False. Parametr $result_id musi być prawidłowym identyfikatorem wyniku zwracanym przez ifx_query() lub ifx_prepare() (tylko dla zapytań SELECT). Opcjonalny parametr $position wskazuje na rodzaj operacji na kursorze. Może być to NEXT, PREVIOUS, CURRENT, FIRST, LAST lub liczba. Jeżeli podana zostanie liczba, odczytywany jest wiersz o podanym numerze. Jest to parametr opcjonalny stosowany tylko dla kursorów typu SCROLL.
array ifx_fetch_row (int result_id [, mixed position])

Funkcja ifx_fetch_row() odczytuje jeden wiersz danych z wyniku związanego z podanym identyfikatorem wyniku. Wiersz jest zwracany w postaci tablicy. Każda kolumna wyniku jest przechowywana w osobnej komórce tablicy, której kluczem jest nazwa kolumny. Kolejne wywołania ifx_fetch_row() zwracają kolejne wiersze wyniku lub False, gdy nie ma już kolejnych wierszy. Przykład: Odczyt wierszy wyniku
$rid = ifx_prepare ("select * from emp where name like " . $name, $connid, IFX_SCROLL); if (! $rid) { ... error ... } $rowcount = ifx_affected_rows($rid); if ($rowcount > 1000) { printf ("Zapytanie zwraca zbyt dużo wierszy: (%d)\n<br>", $rowcount); die ("Proszę ograniczyć zapytanie<br>\n"); }} if (! ifx_do ($rid)) { ... error ... } $row = ifx_fetch_row ($rid, "NEXT"); while (is_array($row)) { for(reset($row); $fieldname=key($row); next($row)) { $fieldvalue = $row[$fieldname]; printf ("%s = %s,", $fieldname, $fieldvalue); } printf("\n<br>"); $row = ifx_fetch_row ($rid, "NEXT"); } ifx_free_result ($rid);

ifx_fieldproperties
Zwraca tablicę asocjacyjną z nazwami pól jako kluczami i właściwościami pól SQL dla wyniku zapytania określonego przez $result_id, jako danymi. W przypadku wystąpienia błędu zwraca False. Zwraca właściwości SQL serwera Informix w postaci tablicy asocjacyjnej, dla każdego pola zwracanego przez zapytanie. Właściwości te są zapisywane jako SQLTYPE:długość:dokładność:skala:ISNULLABLE, gdzie SQLTYPE jest typem Informixa, np.: SQLVCHAR, natomiast ISNULLABLE może mieć wartość Y lub N.
array ifx_fieldproperties (int result_id)

Przykład: właściwości pól SQL serwera Informix
$properties = ifx_fieldproperties ($resultid); if (! isset($properties)) { ... błąd ... } for ($i = 0; $i < count($properties); $i++) { $fname = key ($properties); printf ("%s:\t typ = %s\n", $fname, $properties[$fname]); next ($properties); }

ifx_fieldtypes
Dla wyniku zapytania o identyfikatorze $result_id zwraca tablicę asocjacyjną z nazwami pól jako kluczami i typami pól SQL jako danymi. W przypadku wystąpienia błędu zwraca False.
array ifx_fieldtypes (int result_id)

Przykład: Nazwy i typy pól SQL
types = ifx_fieldtypes ($resultid);

253

PHP – Kompendium wiedzy

if (! isset ($types)) { ... błąd ... } for ($i = 0; $i < count($types); $i++) { $fname = key($types); printf("%s :\t typ = %s\n", $fname, $types[$fname]); next($types); }

ifx_free_blob
Usuwa obiekt blob o podanym identyfikatorze przeciwnym wypadku True.
int ifx_free_blob (int bid)

$bid.

W przypadku wystąpienia błędu zwraca

False,

w

ifx_free_char
Usuwa obiekt znakowy o podanym identyfikatorze $bid. W przypadku wystąpienia błędu zwraca False, w przeciwnym wypadku True.
int ifx_free_char (int bid)

ifx_free_result
Dla identyfikatora wyniku $result_id zwalnia zasoby przydzielone dla zapytania. W

przypadku wystąpienia błędu zwraca False.
int ifx_free_result (int bid)

ifx_getsqlca
Zwraca pseudo-wiersz (tablicę asocjacyjną) z wartościami sqlca.sqlerrd[0] ... sqlca.sqlerrd[5] po skojarzeniu zapytania z $result_id. Parametr $result_id musi być prawidłowym identyfikatorem wyniku zwracanym przez ifx_query() lub ifx_prepare().
array ifx_getsqlca (int result_id)

Dla zapytań INSERT, UPDATE i DELETE zwracane wartości są ustawiane przez serwer po wykonaniu zapytania. Pozwala to odczytać ilość wierszy zmienionych przez zapytanie oraz numer kolejny wstawionego wiersza. W przypadku wyrażeń SELECT, wartości te są ustawiane po wykonaniu operacji PREPARE. Pozwala to na odczytanie przewidywanej ilości wierszy wyniku. Wykorzystanie tej funkcji pozwala na zmniejszenei narzutu czasowego na wykonanie zapytania select dbinfo('sqlca.sqlerrdx') i odczytanie wartości zapisanych w odpowiednim momencie przez sterownik bazy Informix. Przykład: Odczytywanie wartości sqlca.sqlerrd[x]
/* zakładamy, że pierwsza kolumna 'sometable' jest numerem seryjnym rekordu */ $qid = ifx_query("insert into sometable values (0, '2nd column', 'another column') ", $connid); if (! $qid) { ... błąd ... } $sqlca = ifx_getsqlca ($qid); $serial_value = $sqlca["sqlerrd1"]; echo "Numer seryjny wstawionego wiersza wynosi: " . $serial_value<br>\n";

ifx_get_blob
Zwraca zawartość obiektu blob o podanym identyfikatorze obiektu $bid.
int ifx_get_blob (int bid)

ifx_get_char
Zwraca zawartość obiektu znakowego o podanym identyfikatorze obiektu $bid.
int ifx_get_char (int bid)

Dodatek A - Funkcje

254

ifx_htmltbl_result
Zwraca ilość odczytanych wierszy, lub False w przypadku wystąpienia błędu. Formatuje wiersze wyniku o identyfikatorze $result_id do postaci tabeli HTML. Drugim opcjonalnym parametrem funkcji jest ciąg atrybutów znacznika <TABLE>.
int ifx_htmltbl_result (int result_id [, string html_table_options])

ifx_nullformat
Ustawia domyślną wartość wartości NULL po odczytaniu wiersza. Tryb 0 powoduje zwracanie "" a tryb 1 zwracanie "NULL".
void ifx_nullformat (int mode)

ifx_num_fields
Zwraca ilość kolumn zapytania o identyfikatorze $result_id lub False w przypadku wystąpienia błędu. Po przygotowaniu lub wykonaniu zapytania wywołanie to pozwala na odczytanie ilości kolumn w zapytaniu.
int ifx_num_fields (int result_id)

ifx_num_rows
Zwraca ilość wierszy odczytanych do tej pory z wyniku zapytania $result_id, po wykonaniu ifx_query() lub ifx_do().
int ifx_num_rows (int result_id)

ifx_pconnect
Zwraca dodatni identyfikator trwałego połączenia do serwera Informix lub False w przypadku wystąpienia błędu. Funkcja ifx_pconnect() działa bardzo podobnie do ifx_connect() z dwoma wyjątkami. Funkcja działa identycznie jak ifx_connect(), jeżeli PHP nie działa jako moduł Apache. Po pierwsze, w czasie połączenia funkcja próbuje znaleźć łącze (trwałe) otwarte do tego samego serwera z identycznym użytkownikiem i hasłem. Jeżeli zostanie znalezione takie połączenie, zamiast otwierania nowego połączenia, zwracany jest identyfikator istniejącego połączenia. Po drugie, połączenie z serwerem SQL nie jest zamykane po zakończeniu wykonywania skryptu. Zamiast tego łącze pozostanie otwarte do wykorzystania w przyszłości (ifx_close() nie zamyka łączy zestawionych za pomocą ifx_pconnect()). Z tego powodu ten typ łącza nazywany jest trwałym. Patrz również: ifx_connect().
int ifx_pconnect ([string database [, string userid [, string password]]])

ifx_query
Zwraca identyfikator wyniku lub w przypadku wystąpienia błędu wartość False. Identyfikator ten jest używany przez inne funkcje do pobrania wyników działania zapytania. Ustawia jest wartość określająca ilość wierszy zwracanych przez zapytanie, którą można odczytać przez wywołanie ifx_affected_rows(). Funkcja ifx_query() wysyła zapytanie do bazy danych określanej przez podany identyfikator połączenia. Jeżeli nie zostanie podany identyfikator połączenia, operacja jest wykonywana na ostatnio otwartym połączeniu. Jeżeli nie istnieje otwarte połączenie, funkcja próbuje je ustanowić, identycznie jak funkcja ifx_connect() i następnie wykorzystuje to połączenie. Wykonuje zapytanie $query na połączeniu $conn_id. W przypadku zapytań SELECT deklarowany i otwierany jest kursor. Opcjonalny parametr $cursor_type pozwala na utworzenie kursora typu SCROLL lub (oraz) HOLD. Jest to maska bitowa, która może przyjmować wartości IFX_SCROLL, IFX_HOLD lub jednocześnie obie wartości. Zapytania inne niż SELECT wykonywane są w trybie natychmiastowym. IFX_SCROLL i IFX_HOLD są stałymi symbolicznymi i nie należy ich zapisywać w apostrofach. Jeżeli nie podasz tego parametru, otwierany jest zwykły kursor sekwencyjny. Dla dowolnego typu zapytania zapamiętywana jest ilość wierszy będących wynikiem zapytania (rzeczywista lub szacowana), którą można odczytać za pomocą funkcji ifx_affected_rows().
int ifx_query (string query [, int link_identifier [, int cursor_type,

255

PHP – Kompendium wiedzy

mixed [blobidarray]]])

Jeżeli w zapytaniu UPDATE występuje kolumna BLOB (BYTE lub TEXT), można dodać parametr $blobidarray, zawierający odpowiednie identyfikatory blob, i powinieneś zamienić te kolumny znakiem ? w tekście zapytania. Jeżeli zawartość kolumny TEXT (lub BYTE) pozwala na to, można wywołać funkcje ifx_textasvarchar(1) i ifx_byteasvarchar(1). Pozwoli to na traktowanie kolumn TEXT (lub BYTE) w zapytaniach SELECT, tak, jakby była to zwykła (choć długa) kolumna VARCHAR, i nie przejmować się identyfikatorami obiektów blob. Wywołując ifx_textasvarchar(0) i ifx_byteasvarchar(0) (domyślna sytuacja) zapytania SELECT kolumny BLOB będą zwracane jako identyfikatory obiektów blob (wartości numeryczne). Mając taki identyfikator można pobrać zawartość kolumny BLOB za pomocą funkcji obsługujących bloby. Patrz również: ifx_connect(). Przykład: Wyświetlenie wszystkich wierszy tabeli orders jako tabeli html
ifx_textasvarchar(1); // użycie "trybu tekstowego" do blobów $res_id = ifx_query("select * from orders", $conn_id); if (! $res_id) { printf("Nie można wykonać zapytania : %s\n<br>%s<br>\n", ifx_error()); ifx_errormsg(); die; } ifx_htmltbl_result($res_id, "border=\"1\""); ifx_free_result($res_id);

Przykład: Wstawienie kilku wierszy do tabeli catalog
// utworzenie identyfikatorów blobów dla kolunm byte i text $textid = ifx_create_blob(0, 0, "Kolumna Text w pamięci!"); $byteid = ifx_create_blob(1, 0, "Kolumna Byte w pamięci"); // zapamiętanie identyfikatorów blob w tablicy blobid $blobidarray[] = $textid; $blobidarray[] = $byteid; // wykonanie zapytania $query = "insert into catalog (stock_num, manu_code, " . "cat_descr,cat_picture) values(1,'HRO',?,?)"; $res_id = ifx_query($query, $conn_id, $blobidarray); if (! $res_id) { ... błąd ... } // zwonienie identyfikatora wyniku ifx_free_result($res_id);

ifx_textasvarchar
Ustawia domyślny tryb tekstowy dla zapytań SELECT. Tryb natomiast tryb 1 powoduje zwracanie zawartości jako tekstu.
void ifx_textasvarchar (int mode)

0

powoduje zwracanie identyfikatorów blob,

ifx_update_blob
Uaktualnia zawartość obiektu blob dla podanego identyfikatora $bid. Parametr $content jest ciągiem zawierającym nowe dane. Zwraca False w przypadku błędu a w przeciwnym przypadku True.
ifx_update_blob (int bid, string content)

ifx_update_char
Uaktualnia zawartość obiektu znakowego dla podanego identyfikatora $bid. Parametr $content jest ciągiem zawierającym nowe dane. Zwraca False w przypadku błędu a w przeciwnym przypadku True.
ifx_update_char (int bid, string content)

ignore_user_abort
Funkcja ta ustawia znacznik, czy klient może spowodować przerwanie wykonywania skryptu. Zwraca wcześniejsze ustawienie i może być wywołana bez argumentów w celu sprawdzenia bieżącego ustawienia, bez jego zmiany.
int ignore_user_abort ([int setting])

Dodatek A - Funkcje

256

0). kolor to $col. int red. Odległość od żądanego koloru i kolorów istniejących w palecie jest obliczana tak. 3. int blue) 257 PHP – Kompendium wiedzy . 2. ImageColorDeAllocate($im. natomiast punkty początkowe i końcowe są określane w stopniach podawanych w argumentach $s i $e. int green. używane są wbudowane czcionki (największa liczba reprezentuje największą czcionkę). int red. int ImageChar (int im. Jeżeli $font jest 1. 3. Jeżeli $font jest 1. int w. int s. int col) ImageCharUp Rysuje pionowo pierwszy znak w $c na rysunku określonym przez $id. int h. int green. Lewy górny róg litery znajduje się na współrzędnych $x. $white). int col) ImageChar Rysuje pierwszy znak w $c na rysunku określonym przez $id. Patrz również: ImageColorsForIndex(). 255. w palecie kolorów rysunku. Patrz również: ImageColorExact(). int x. string c. int e. Patrz również imageloadfont(). 255. int cy. $y (lewy górny róg to 0.ImageArc Rysuje fragment elipsy o środku o współrzędnych $cx. który będzie używany na rysunku $im. int ImageCharUp (int im. int x.0). int imagecolorallocate (int im. kolor to $col. int imagecolorclosest (int im. 4 lub 5. 255). int font. 255). Parametry $w i $h określają szerokość i wysokość elipsy. $cy (lewy górny róg to 0. int imagecolordeallocate (int im. int green. używane są wbudowane czcionki (największa liczba reprezentuje największą czcionkę). int col) ImageColorAllocate Zwraca identyfikator koloru reprezentujący kolor stworzony z podanych składników RGB. 0. int y) ImageColorSet() i ImageColorClosest Zwraca indeks koloru. int y. string c. zwracana jest wartość -1. int cx. Patrz również imageloadfont(). Funkcja ImageColorAllocate() musi być wywołana do stworzenia każdego koloru. int imagecolorexact (int im. int blue) Przykład $white = ImageColorAllocate ($im. Jeżeli kolor nie występuje w palecie. int font. Argument $im jest wynikiem funkcji imagecreate(). 4 lub 5. 0. int x. 255. Lewy górny róg litery znajduje się na współrzędnych $x. Patrz również: ImageColorClosest(). $black = ImageColorAllocate ($im. int y. int ImageArc (int im. int blue) ImageColorDeAllocate Usuwa kolor poprzednio utworzony za pomocą funkcji ImageColorAllocate(). int red. int index) Przykład: $white = ImageColorAllocate($im.0). który jest najbliższy podanej wartości RGB. ImageColorAt Zwraca indeks koloru piksela o podanych współrzędnych. 2. int imagecolorat (int im. $y (lewy górny róg to 0.0) na rysunku reprezentowanym przez $im. 255. jakby wartości RGB reprezentowały punkty w przestrzeni trójwymiarowej. ImageColorExact Zwraca indeks podanego koloru w palecie kolorów rysunku.

int srcH) ImageCreate Zwraca identyfikator rysunku wskazujący na pusty rysunek o rozmiarze $x_size na $y_size. Patrz również: ImageColorAt(). $text_color). 91). int imagecreate (int x_size. int src_x. int green. int red.ImageColorResolve Funkcja gwarantuje zwrócenie indeksu dla podanego koloru. $background_color = ImageColorAllocate ($im. ?> Dodatek A . wyniki są nieprzewidywalne. int dstX. 14. 255. int src_w. "Prosty tekst przykładowy". stosowane jest odpowiednie przeskalowanie kopiowanego fragmentu. int blue) ImageColorSet Ustawia indeks w palecie kolorów na podany kolor. Zdefiniowany fragment jest kopiowany do docelowego rysunku na współrzędne $dst_x i $dst_y. int col]) ImageCopy Kopiuje fragment rysunku $src_im do $dst_im. $im = @ImageCreate (50. Patrz również: ImageColorClosest(). natomiast $src_im to identyfikator rysunku źródłowego. int srcY. bez potrzeby wykonywania wypełniania. int blue) ImageColorsForIndex Zwraca tablicę asocjacyjną z kluczami red. Ustawia kolor przezroczysty w rysunku $im na $col. int dstH. $text_color = ImageColorAllocate ($im. int dst_x. int ImageCopy (resource dst_im. 255. Funkcja może być używana do kopiowania obszarów tego samego rysunku (jeżeli $dst_im jest taki sam jak $src_im). 1. ale gdy obszary te nachodzą na siebie. int ImageCopyResized (resource dst_im. int y_size) Przykład: Tworzenie nowego strumienia rysunku GD i tworzenie rysunku. resource src_im. int imagecolorresolve (int im. ImageString ($im. 100) or die ("Nie można zainicjować nowego strumienia rysunku GD"). int imagecolortransparent (int im [.Funkcje 258 . $src_y o szerokości $src_w i wysokości $src_h. int index) ImageColorsTransparent ImageCreate(). ImagePng ($im). Jeżeli współrzędne źródła i celu oraz szerokość i wysokość różnią się. int dst_y. Jest to przydatne do tworzenia efektów wypełniania za pomocą palety. 5. green i blue. int dstW. Zwracany jest identyfikator nowego (lub bieżącego. resource src_im. które zawierają odpowiednie wartości dla podanego indeksu koloru. Parametr $im jest identyfikatorem zwracanym przez natomiast $col jest identyfikatorem koloru zwracanym przez ImageColorAllocate(). int srcX. int red. 233. Patrz również: ImageColorAt() i ImageColorExact(). int src_h) ImageCopyResized Kopiuje prostokątny fragment rysunku do innego rysunku. jeżeli nie podano nowego koloru) koloru przezroczystego. Współrzędne wskazują na lewy górny róg. <?php header ("Content-type: image/png"). Będzie to dokładnie identyczny kolor lub najbliższy mu podobny. int index. Parametr $dst_im jest docelowym rysunkiem. int srcW. array imagecolorsforindex (int im. rozpoczynając od współrzędnych $src_x. bool imagecolorset (int im. 5. int dstY. 255). int src_y. int green.

} return $im. /* Próba otwarcia */ if (!$im) { /* Jeżeli się nie udało */ $im = ImageCreate (150. 150.com) function LoadGif ($imgname) { $im = @ImageCreateFromGIF ($imgname). 30. 30). ale niestety jest on wyświetlany w przeglądarce jako nieprawidłowe łącze. 30.ImageCreateFromGif Zwraca identyfikator rysunku reprezentujący rysunek pobrany z pliku o podanej nazwie. } 259 PHP – Kompendium wiedzy . 255. 0. który tworzy rysunek PNG z komunikatem błędu. /* Próba otwarcia */ if (!$im) { /* Jeżeli się nie udało */ $im = ImageCreate (150. 5. } return $im. /* Wyświetlenie komunikatu błędu */ ImageString($im. "Błąd przy ładowaniu $imgname". ImageFilledRectangle ($im. /* Wyświetlenie komunikatu błędu */ ImageString($im. który tworzy rysunek JPEG z komunikatem błędu. /* Tworzenie pustego rysunku */ $bgc = ImageColorAllocate ($im. 150. 0). 255. /* Próba otwarcia */ if (!$im) { /* Jeżeli się nie udało */ $im = ImageCreate (150. 0. 1. ImageCreateFromJPEG() int ImageCreateFromJPEG (string filename) Przykład: Obsługa błędu w czasie tworzenia rysunku (podziękowania dla vic@zymsys. int ImageCreateFromGif (string filename) Przykład: Obsługa błędu w czasie tworzenia rysunku (podziękowania dla vic@zymsys. 255. ale niestety jest on wyświetlany w przeglądarce jako nieprawidłowe łącze. 150. 255). $tc). $tc = ImageColorAllocate ($im.6 funkcja ta nie jest już dostępna. ale niestety jest on wyświetlany w przeglądarce jako nieprawidłowe łącze. 0. 0. $tc = ImageColorAllocate ($im. 255. Wyświetla również komunikat błędu. 0. 0. 30). Wyświetla również komunikat błędu. $bgc). $tc). 5. 0. 255. 255). $bgc). /* Wyświetlenie komunikatu błędu */ ImageString($im. 1. ImageCreateFromJPEG Zwraca identyfikator rysunku reprezentujący rysunek pobrany z pliku o podanej nazwie. 5. 1. $tc). 5. 0.com) function LoadJPEG ($imgname) { $im = @ImageCreateFromJPEG ($imgname). Aby ułatwić uruchamianie można zastosować poniższy przykład. Funkcja w przypadku wystąpienia błędu zwraca pusty ciąg. który tworzy rysunek GIF z komunikatem błędu. 0. "Błąd przy ładowaniu $imgname". 0. 0). 30. Wyświetla również komunikat błędu. 0). 5. 0. $tc = ImageColorAllocate ($im. Funkcja w przypadku wystąpienia błędu zwraca pusty ciąg. /* Tworzenie pustego rysunku */ $bgc = ImageColorAllocate ($im. Funkcja ImageCreateFromGif() w przypadku wystąpienia błędu zwraca pusty ciąg. } return $im. 5.com) function LoadPNG ($imgname) { $im = @ImageCreateFromPNG ($imgname). /* Tworzenie pustego rysunku */ $bgc = ImageColorAllocate ($im. 30). ImageFilledRectangle ($im. 255. ImageFilledRectangle ($im. Przykład: Obsługa błędu w czasie tworzenia rysunku (podziękowania dla vic@zymsys. "Błąd przy ładowaniu $imgname". $bgc). Aby ułatwić uruchamianie można zastosować poniższy przykład. } Uwaga Ponieważ obsługa GIF została usunięta z biblioteki GD od wersji 1. 0. 255). } ImageCreateFromPNG ImageCreateFromPNG() Zwraca identyfikator rysunku reprezentujący rysunek pobrany z pliku o podanej nazwie. Aby ułatwić uruchamianie można zastosować poniższy przykład.

int imagefill (int im. int imagedestroy (int im) ImageFill Wykonuje wypełnianie metodą zalewania (flood fill) rysunku (lewy górny róg to 0. int y1. int imagedashedline (int im. Parametr $points jest tablicą PHP zawierającą wierzchołki wieloboku. int imagefontheight (int font) ImageFontWidth() i ImageFontWidth Zwraca szerokość znaku w pikselach dla określonej czcionki. int col) $im rozpoczynając od współrzędnych $x.ImageDashedLine Rysuje na rysunku $im linię przerywaną z Patrz również: ImageLine(). $points[2] = x1. int num_points. int y2. $points[1] = y0. $points[3] = y1 i tak dalej. $x1. $y1 do $x2. int imagefilledpolygon (int im.Funkcje 260 . int y. int x. Parametr $im jest identyfikatorem rysunku zwracanym przez funkcję ImageCreate(). $y1.0. kolor wypełnienia to $col. $y2. to znaczy $points[0] = x0. int x1. kończąc na prawym dolnym rogu o współrzędnych $x2. Lewy górny róg rysunku ma współrzędne 0. int col) ImageFilledRectangle Na rysunku $im tworzy wypełniony prostokąt o kolorze $col. Patrz również: ImageLoadFont(). float inputgamma. int col) $border. $y ImageFilledPolygon Tworzy wypełniony wielobok na rysunku $im. int y1. int border. $y (lewy górny róg to 0. int x2. int ImageFontWidth (int font) ImageFontHeiht() i ImageGammaCorrect Stosuje korekcję gamma na rysunku $im na podstawie wartości gamma wejściowej wyjściowej $outputgamma. int imagefilledrectangle (int im.0) o kolorze $col.0) kolorem $col. int col) ImageFillToBorder Wypełnia na rysunku obszar ograniczony kolorem zdefiniowanym w parametrze rozpoczęcia wypełniania to $x. Patrz również: ImageLoadFont(). $y2 (lewy górny róg to 0. float outputgamma) $inputgamma i Dodatek A . Parametr $num_points zawiera całkowitą ilość wierzchołków. Punkt ImageFontHeight Zwraca wysokość znaku w pikselach dla określonej czcionki. rozpoczynając od górnego lewego rogu o współrzędnych $x1. int x. int y. int imagegammacorrect (int im. array points. int x2.0). int y2. int imagefilltoborder (int im. int col) ImageDestroy Zwalnia pamięć zajętą przez rysunek $im. int x1.

można stworzyć skrypt PHP. jeżeli biblioteka GD jest w wersji 1. przeplot nie zostanie zastosowany. który bezpośrednio wysyła do przeglądarki rysunki GIF. string filename [. int y2. co komputer na którym jest uruchomione PHP. utworzony zostanie bezpośredni surowy strumień rysunku. Jeżeli jest 0. $y1 do $x2. Wysyłając za pomocą funkcji header() typ zawartości image/gif. int quality]]) ImageLine Na rysunku $im rysuje linię od $x1.0) o kolorze $col. int x2. $y2 (lewy górny róg to 0. ImageCreate().ImageGIF Tworzy plik GIF na podstawie rysunku $im. rysunek będzie z przeplotem. int imagegif (int im [. utworzony zostanie bezpośredni surowy strumień rysunku.6 funkcja ta nie jest już dostępna. int imageinterlace (int im [. int col) ImageLoadFont Ładuje czcionkę bitmapową zdefiniowaną przez użytkownika i zwraca identyfikator czcionki (zawsze większy od 5. W takim przypadku formatem pliku będzie GIF89a. Format pliku jest następujący: Pozycja Typ Opis w bajtach danych C 0 — 3 int Ilość znaków w pliku czcionek 4 —7 int Wartość pierwszego znaku czcionki (często 32 dla spacji) 8 — 11 int Szerokość każdego znaku w pikselach 12 — 15 int Wysokość każdego znaku w pikselach 16 — char Tablica danych znakowych. że rysunek będzie zawierał kolor przezroczysty stworzony za pomocą funkcji ImageColorTransparent(). że należy generować pliki czcionek na komputerze z takim samym procesorem. int imagejpeg (int im [. Funkcja zwraca bieżącą wartość bitu przeplotu dla rysunku. Parametr $im jest identyfikatorem zwracanym przez funkcję Nazwa pliku jest opcjonalna. jeżeli zostanie pominięta. Rysunek zostanie zapisany w formacie GIF87a chyba. int x1. razem (znaki*szerokość*wyskokość) bajtów Patrz również: ImageFontWidth() i ImageFontHeight(). int imageline (int im.8 lub nowszej. string filename]) ImageInterlace $interlace Ustawia i kasuje bit przeplotu. int y1. Parametr $im jest identyfikatorem zwracanym przez funkcję ImageCreate(). zależny od architektury. Jeżeli $interlace jest równy 1. Format pliku jest obecnie binarny. który bezpośrednio wysyła do przeglądarki rysunki JPEG. Patrz również: ImageCreate() i ImageColorAllocate(). Aby opuścić nazwę pliku i jednocześnie podać wartość parametru $quality należy użyć pustego ciągu (""). więc nie koliduje z wbudowanymi czcionkami). 261 PHP – Kompendium wiedzy . można stworzyć skrypt PHP. Uwaga Ponieważ obsługa GIF została usunięta z biblioteki GD od wersji 1. int interlace]) ImageJPEG Tworzy plik JPEG na podstawie rysunku $im. jeżeli zostanie pominięta. Wysyłając za pomocą funkcji header() typ zawartości image/jpeg. Uwaga Obsługa formatu JPEG jest dostępna jedynie. Oznacza to. Nazwa pliku jest opcjonalna. jeden bajt na piksel w każdym xxx znaku.

int tightness [. 1 — lewa dolna współrzędna y.default_encoding na odpowiedni plik kodowania. int imagepolygon (int im. int num_points. gdzie 1 jednostka odstępu jest 1/1000 pica do kwadratu. array points. Jeżeli kąt wynosi 0. int size [. IsoLatin1. string encodingfile) ImagePsExtendfont Powiększa lub zmniejsza czcionkę funkcja zmniejsza czcionkę. Ramka ograniczająca jest wyliczana z wykorzystaniem dostępnych danych z metryki czcionki i niestety nieco różni się od wyników otrzymywanych przez rasteryzację tekstu. Parametr $angle jest wyrażony w stopniach. $space pozwala zmienić domyślna wartość odstępu w czcionkach. Parametr $points jest tablicą PHP zawierającą wierzchołki wieloboku to znaczy $points[0] = x0. Parametr $tightness pozwala kontrolować ilość światła pomiędzy literami. że tekst będzie potrzebował o 1 piksel więcej w każdym kierunku. Wartość ta jest dodawana do standardowej wartości odstępu i może być ujemna. ImagePng($im). $points[2] = x1. Patrz również: ImagePSText(). prawie na pewno musisz zmienić wektor kodowania w przypadku wykorzystywania języków innych niż angielski. Wartość ta jest dodawana do normalnej szerokości znaku i może również być ujemna. float extend) ImagePSFreeFont Patrz również: ImagePSLoadFont(). int imagepng (int im [. Wszystkie załadowane przez użytkownika czcionki będą miały odpowiednio zdefiniowane kodowanie. void imagepsfreefont (int fontindex) Dodatek A . int space [.enc.enc i IsoLatin2. lepszym sposobem na zdefiniowanie kodowania jest ustawienie w pliku konfiguracyjnym zmiennej ps. Jeżeli wartość parametru $extend jest mniejsza od jeden. int col) ImagePSBBox Parametr $size jest wyrażony w pikselach. Dokładny format pliku jest opisany w dokumentacji T1lib.int imageloadfont (string file) ImagePNG Otwiera strumień GD ($im) w formacie PNG i przesyła dane do standardowego wyjścia (zwykle jest to przeglądarka). Funkcja zwraca tablicę zawierającą następujące elementy: 0 — lewa dolna współrzędna x. Jeżeli chcesz cały czas wykorzystywać tą funkcję. Parametry $space. Patrz również: ImageCreate(). $font_index. int imagepsencodefont (int font_index. 2 — prawa górna współrzędna x i 3 — prawa górna współrzędna y. T1lib zawiera dwa gotowe do użycia pliki. Ponieważ w czcionkach PostScript wektor kodowania nie zawiera wielu znaków na pozycjach powyżej 127. ?> ImagePolygon Tworzy wielobok na rysunku $im. array ImagePSBBox (string text. należy się spodziewać. $tightness i $angle są opcjonalne. $points[1] = y0. int font. lub jeżeli podana jest nazwa pliku $filename. float angle]]]) ImagePSEncodeFont Ładuje z pliku wektor kodowania znaków i zmienia na niego istniejący wektor kodowania czcionki.png"). string filename]) Przykład: <?php $im = ImageCreateFromPng("test. Parametry $space i $tightness są podawane w jednostkach odstępu znaku. Parametr $num_points zawiera całkowitą ilość wierzchołków. $points[3] = y1 i tak dalej. zapisuje rysunek do pliku. bool imagepsextendfont (int font_index.Funkcje 262 .

1 — lewa dolna współrzędna y. int x2. znajdują się w dokumentacji PostScript. Jeżeli coś się nie powiedzie. 2 — prawa górna współrzędna x i 3 — prawa górna współrzędna y.ImagePSLoadFont Jeżeli wszystko odbędzie się bez błędów. float slant) ImagePSText Parametr $size jest wyrażony w pikselach. Jeżeli potrzebujesz bliższych informacji na temat czcionek i systemu miar. Jeżeli $font wynosi 1. $tightness. Patrz również: ImagePSBBox(). używane są wbudowane czcionki. Parametr $antialiasing_steps pozwala na określanie ilości kolorów użytych do wygładzania tekstu. int antialias_steps]]]]) Parametr $space pozwala na zmianę domyślnego odstępu w czcionce. Wartość ta jest dodawana do normalnej wartości. float angle [. Patrz również: ImageLoadFont(). $angle i $antialias są opcjonalne. Parametry $space i $tightness są wyrażane w jednostkach odstępu znaku. Funkcja zwraca tablicę zawierającą następujące elementy: 0 — lewa dolna współrzędna x.0. gdzie $x. bool imagepsslantfont (int font_index. $y1 i ImageSetPixel Rysuje na rysunku $im piksel w kolorze również: ImageCreate() i ImageColorAllocate(). int font. int y [. ponieważ potrzeba wtedy mniej obliczeń. int col) ImageString Na rysunku $im rysuje ciąg $s rozpoczynając od współrzędnych $x. więc może być ujemna. int font. gdzie wygładzanie mocno wpływa na jakość tekstu. int x. $y definiują początek (punkt odniesienia) pierwszego znaku (mniej więcej lewy dolny róg znaku). int ImageString (int im. int y. Lewy górny róg rysunku ma współrzędne 0. int space [. Wartość $angle podawana jest w stopniach. ImageRectangle Na rysunku $im tworzy prostokąt w kolorze $col o współrzędnych lewego górnego rogu prawego dolnego $x2. 2. natomiast $background to kolor na który tekst będzie się zmieniał przy zastosowaniu wygładzania (antialiasing). $y (lewy górny róg to 0. więc tło nie będzie zamalowane. Dopuszczalnymi wartościami są 4 i 16. array imagepstext (int image. string text. Wartość ta jest dodawana do normalnej szerokości znaki i również może być ujemna. int background. Patrz również: ImagePSFreeFont(). int x.0) w kolorze $col. gdzie 1 jednostka odstępu jest 1/1000 pica do kwadratu. W przypadku większych czcionek można użyć wartości 4. int ImagePSLoadFont (string filename) ImagePsSlantFont Pochyla czcionkę wskazywaną przez parametr $font_index o wartość przekazaną w parametrze $slant. int foreground. int y. int tightness [. funkcja zwraca False i drukuje komunikat opisujący błąd. int x1. Parametr $foreground jest kolorem jakim zostanie namalowany tekst. int y2. int y1. $col na współrzędnych $x. Wyższa wartość jest polecana dla tekstów o rozmiarze mniejszych od 20.0). int size. funkcja zwraca prawidłowy indeks czcionki. string s. 3. int col) $x1. int x. $y (lewy górny róg to 0. Parametry $space. Parametr $tightness powala na kontrolowanie ilości światła pomiędzy literami. Funkcja różni się tym od ImageString(). Patrz int ImageSetPixel (int im. który może być użyty do innych celów. 4 lub 5. $y określają lewy górny róg pierwszego znaku. Współrzędne przekazane w $x. int ImageRectangle (int im. Nie są rysowane żadne punkty w kolorze $background. $y2. int col) 263 PHP – Kompendium wiedzy .

3. $white. 20. int font. 2 — współrzędna X prawego dolnego rogu. $y (lewy górny róg to 0. 20. int x. string text) ImageTTFText Na rysunku $im rysuje ciąg $text. $black = ImageColorAllocate ($im. int y. $im = imagecreate (400. więc „lewy górny” oznacza górny wierzchołek po lewej stronie. Parametr $text jest ciągiem do zmierzenia. 0). więc „lewy górny” oznacza górny wierzchołek po lewej stronie. $y (lewy górny róg to 0. 0. 7 — współrzędna Y lewego górnego rogu. (wartość 90 powoduje narysowanie tekstu od góry do dołu). natomiast wyższe wartości reprezentują pochylenie w kierunku przeciwnym do ruchu wskazówek zegara. Dodatek A . int col. Parametr $fontflile jest ścieżką do pliku TrueType z używaną czcionką. Funkcja ImageTTFBBox() zwraca tablicę składająca się z ośmiu elementów reprezentujących cztery punkty tworzące ramkę otaczającą tekst: 0 — współrzędna X lewego dolnego rogu. int angle.0). Patrz również: ImageTTFText(). int col) ImageSX Zwraca szerokość rysunku identyfikowanego przez $im. int ImageSX (int im) ImageSY Zwraca wysokość rysunku identyfikowanego przez $im. "Testowanie. 0."). $white = ImageColorAllocate ($im. prawy górny. 6 — współrzędna X lewego górnego rogu. $fontfile jest nazwą pliku z czcionką TrueType (może być w postaci URL). 1 — współrzędna Y lewego dolnego rogu. int angle. rozpoczynając od współrzędnych $x. string text) Przykład: ImageTTFText <?php Header ("Content-type: image/gif"). patrząc na tekst poziomo. Patrz również: ImageLoadFont(). ImageTTFText ($im. Parametr $text jest ciągiem tekstowym. y określają prawy górny róg pierwszego znaku.ttf". 255). $col jest indeksem koloru. 5 — współrzędna Y prawego górnego rogu.0) w kolorze $col. int ImageStringUp (int im. int size. 10. Punkty te są niezależne od pochylenia tekstu. za pomocą czcionki TrueType umieszczonej w pliku $fontfile. Parametr $size jest wielkością czcionki. "/path/arial. 255. gdzie x. gdzie 0 stopni określa tekst czytany z lewej do prawej (kierunek na godzinę trzecią). 30). string fontfile. 4 — współrzędna X prawego górnego rogu.ImageStringUp Na rysunku $im rysuje pionowo ciąg $s rozpoczynając od współrzędnych $x. Omega: &#937. int y. array imagettfbbox (int size. Funkcja wymaga bibliotek GD i FreeType. 255. używane są wbudowane czcionki. pod kątem $angle w kolorze $col. Patrz również: ImageCreate() i ImageSY().Funkcje 264 . string s. Patrz również: ImageCreate() i ImageSX(). Parametr $angle jest wyrażony w stopniach. prawy dolny i lewy dolny. patrząc na tekst poziomo. 2. Współrzędne podane w $x. $angle jest kątem pochylenia tekstu $text w stopniach. ImageGif ($im). Jeżeli $font wynosi 1. który może zawierać sekwencje znaków UTF-8 (w postaci :{) używane do stosowania znaków o kodach powyżej 255. Różni się to od funkcji ImageString(). Punkty te są niezależne od pochylenia tekstu. array imagettftext (int im. Użycie ujemnego indeksu koloru powoduje wyłączenie wygładzania tekstu. 4 lub 5. ImageDestroy ($im). Funkcja ImageTTFText() zwraca tablicę ośmioelementową reprezentującą cztery punkty stanowiące ramkę ograniczającą tekst. 0. int ImageSY (int im) ImageTTFBBox Funkcja oblicza i zwraca ramkę otaczającą tekst TrueType (w pikselach). $y określają punkt bazowy pierwszego znaku (mniej więcej lewy dolny róg znaku). int x. Punkty te są umieszczone w tablicy w kolejności lewy górny. string fontfile... 3 — współrzędna Y prawego dolnego rogu.

"\r\n" . aby komunikaty te były pokazywane użytkownikowi.8). print "Ilość komunikatów przed dołączeniem: ". Zwraca ciąg quotedprintable."\n".Drafts".Drafts" . imap_append($stream.7). proszę zignorować\r\n" ). Zdekodowany komunikat jest zwracany w postaci ciągu. $check = imap_check($stream). "password")."przesyłka testowa.host\r\n" . $check->Nmsgs. imap_base64 Dekoduje tekst zakodowany metodą BASE-64 (patrz RFC2045. string mbox. Jeżeli podane zostały opcjonalne znaczniki $flags. Działając na serwerze Cyrus IMAP. sekcja 6. Gdy zostanie wywołana funkcja imap_alerts().host}INBOX. ImageTypes Funkcja zwraca maskę bitową związaną z formatami rysunków obsługiwanych przez bibliotekę GD dołączoną do PHP. imap_alerts(). array imap_alerts (void) imap_append Zwraca True w przypadku powodzenia i False w przypadku błędu. } ?> imap_8bit Konwertuje ciąg 8-bitowy na ciąg quoted-printable (zgodnie z RFC2045.host}INBOX."To: you@your. string imap_8bit (string string) imap_alerts Zwraca tablicę wszystkich komunikatów ostrzeżeń IMAP wygenerowanych od ostatniego wywołania lub od początku strony. print "Ilość komunikatów po dołączeniu : ". string imap_base64 (string text) 265 PHP – Kompendium wiedzy ."Subject: test\r\n" . Zwracane są następujące bity: IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP. string flags]) Przykład: imap_append() $stream = imap_open("{your. stos ostrzeżeń jest czyszczony.?> Funkcja wymaga bibliotek GD i FreeType. sekcja 6. Patrz również: imap_binary(). lub operacja się nie powiedzie. string message [. Specyfikacja IMAP wymaga. $check->Nmsgs. trzeba użyć terminatorów linii „\r\n” zamiast „\n”. imap_close($stream). Patrz również imap_qprint()."\n"."From: me@my. $check = imap_check($stream).imap.imap. int imagetypes (void) Przykład: ImageTypes <?php if (ImageTypes() & IMG_PNG) { echo "Obsługa PNG jest aktywna". Funkcja dołącza ciąg komunikatu do skrzynki pocztowej $mbox."{your."username".host\r\n" . int imap_append (int imap_stream. Patrz również: ImageTTFBox(). funkcja dołącza również do skrzynki te znaczniki.

IMAP. string imap_binary (string string) imap_body Zwraca treść przesyłki o numerze $msg_number z bieżącej skrzynki pocztowej.host}"."password". \\Deleted. string flag. int msg_number [. Zwraca ciąg base64. NNTP • Mailbox — nazwa skrzynki pocztowej • Nmsgs — ilość przesyłek w skrzynce • Recent — ilość nowych przesyłek w skrzynce object imap_check (int imap_stream) imap_clearflag_full Funkcja powoduje usunięcie określonego znacznika ze zbioru znaczników przesyłki w określonej sekwencji. Funkcja imap_check() sprawdza status bieżącej skrzynki na serwerze i zwraca dane w postaci obiektu o następujących właściwościach: • Date — ostatnia zmiana zawartości skrzynki • Driver — protokół używany do komunikacji ze skrzynką: POP3. int imap_close (int imap_stream [. Aby odczytać jeden fragment wieloczęściowej przesyłki kodowanej za pomocą MIME należy użyć funkcji imap_fetch_structure() do zanalizowania struktury i imap_fetch_body() do skopiowania pojedynczego komponentu przesyłki. string sequence. Parametr $options jest maską bitową składającą się z następujących znaczników: ST_UID. \\Flagged. $name1 = "phpnewbox". Znacznikami do usuwania są: \\Seen. string imap_clearflag_full (int stream. imap_deletemailbox() i imap_open() gdzie znajduje się opis formatów nazw $mbox.OP_HALFOPEN) or die("nie można połączyć: ". Patrz również: imap_renamemailbox(). Nazwy zawierające znaki narodowe powinny być zakodowane przy pomocy funkcji imap_utf7_encode(). Zwraca True w przypadku powodzenia lub False w przypadku wystąpienia błędu. string options) imap_close Zamyka strumień imap. sekwencja argumentów zawierająca UID zamiast numerów sekwencji. \\Draft i \\Recent (według RFC2060). string mbox) Przykład: imap_createmailbox() $mbox = imap_open("{your. jeżeli jest już ustawiony • FT_INTERNAL — Zwracany ciąg jest w formacie wewnętrznym Funkcja imap_body() zwraca dosłowną kopię treści przesyłki. int flags]) imap_createmailbox Tworzy nową skrzynkę pocztową o nazwie $mbox. \\Answered."username". sekcja 6. który powoduje wyczyszczenie skrzynki przed zamknięciem poprzez usunięcie przesyłek zaznaczonych jako usunięte. Opcjonalny parametr jest maską bitową zawierającą jedną lub więcej wartości: • FT_UID — Wartość $msgno jest idnetyfikatorem UID • FT_PEEK — Nie ustawia znacznika \Seen. Posiada opcjonalny parametr $flag CL_EXPUNGE. $flags string imap_body (int imap_stream.imap_last_error()). Patrz również: imap_base64().8). W przypadku błędu zwraca False. int imap_createmailbox (int imap_stream.Funkcje 266 .imap_binary Konwertuje 8-bitowy ciąg na ciąg zakodowany metodą BASE-64 (zgodnie z RFC2045. int flags]) imap_check Zwraca dane na temat bieżącej skrzynki pocztowej.imap. Dodatek A .

SA_ALL)."<br>\n". "username".imap."<br>\n"."<br>\n". Zwraca True w przypadku powodzenia i False w przypadku błędu. $check = imap_mailboxmsginfo ($mbox)."<br>\n". Patrz również: imap_createmailbox(). że argumenty $msg_number należy traktować jako identyfikatory UID."{your.host}INBOX. przywracając stan początkowy<br>\n". print("Nieprzeczytanych:". # tworzymy nową skrzynkę o nazwie "phptestbox" w skrzynce poczty przychozącej # sprawdzamy status po utworzeniu i na koniec usuwamy. print("Następny UID: "."<br>\n". if(imap_renamemailbox($mbox. "<br>\n" . } if(@imap_deletemailbox($mbox.$name2")) { echo "zmieniono nazwę srzyni z '$name1' na '$name2'<br>\n". print("Poprawność UID: ". } } else { print "nie można utworzyć nowej skrzyki: ". imap_last_error()). przywracając skrzynkę # do stanu początkowego if(@imap_createmailbox($mbox. int flags]) Przykład: imap_delete() $mbox = imap_open ("{your. Opcjonalny parametr $flags posiada tylko jedną opcję.host}INBOX. FT_UID. $check->Nmsgs . } imap_close($mbox).host}INBOX. Funkcja imap_delete() oznacza do usunięcia przesyłkę wskazywaną przez $msg_number. $status->uidvalidity). if($status) { print("nowa skrzynka '$name1' ma następujący status:<br>\n").imap_errors()).host}INBOX.imap.imap.$newname"))) { $status = @imap_status($mbox. Przesyłki zaznaczone do usunięcia pozostają w skrzynce do czasu wywołania funkcji imap_expunge() lub imap_close() z ustawionym parametrem opcjonalnym CL_EXPUNGE. 1). 267 PHP – Kompendium wiedzy . $status->uidnext ). $status->recent ).imap.host}INBOX. $check->Nmsgs ."<br>\n".$newname". } else { print "Nieudane wywołanie imap_renamemailbox na nowej skrzynce: " . $check->Nmsgs . print "Przesyłki po wyczyszczeni: " ."<br>\n". imap_expunge ($mbox). $status->unseen ).$newname". echo "Nową nazwą będzie '$name1'<br>\n". imap_delete ($mbox. int imap_delete (int imap_stream. "password") or die ("nie można połączyć: " ."{your. imap_deletemailbox suwa podaną skrzynkę pocztową (format nazw $mbox można znaleźć przy opisie imap_open()). $check = imap_mailboxmsginfo ($mbox). imap_renamemailbox() i imap_open(). print "Przesyłki przed usunięciem: " .$newname")) { print "nowa skrzynka usunięta."{your. imap_close ($mbox).imap_errors()) . print("Ostatnich: ". "<br>\n" . print "Przesyłki po usunięciu: " .imap_utf7_encode("{your. $newname = $name1. } else { print "Nieudane wywołanie imap_deletemailbox na nowej skrzynce: " . $status->messages ).imap_last_error(). imap_delete Zwraca True.implode("<br>\n". która wskazuje funkcji.imap. $check = imap_mailboxmsginfo ($mbox).imap. int msg_number [. print("Komunikatów: "."<br>\n". $newname=$name2. } } else { print "Nieudane wywołanie imap_status na nowej skrzynce: " ."<br>\n". "<br>\n" .implode("<br>\n".host}INBOX".$name2 = imap_utf7_encode("phpnewböx"). "{your.imap_last_error().

jeżeli wymagany jest pełny tekst przesyłki (na przykład.int imap_deletemailbox (int imap_stream. FT_UID. Części z treścią nie są dekodowane przez tą funkcję. Po wywołaniu imap_errors() stos błędów jest czyszczony. string mbox) imap_errors imap_errors() Zwraca tablicę wszystkich komunikatów błędów IMAP wygenerowanych od ostatniego wywołania lub od początku skryptu. array imap_errors (void) imap_expunge Usuwa imap_setflag_full(). które są indeksami w liście części. string part_number [. rozmiar. przesyłki zaznaczone Zwraca True. int flags) imap_fetchstructure Funkcja pobiera wszystkie informacje o strukturze podanej przesyłki.Funkcje 268 . Pozwala to uniknąć dodatkowego RTT na połączeniu IMAP. Specyfikacja sekcji jest ciągiem liczb rozdzielonych kropkami. int msg_number. int msgno. oraz podobne obiekty dla każdego załącznika MIME. operacja „zapis do pliku”) string imap_fetchheader (int imap_stream. że argumenty $msg_number należy traktować jako identyfikatory UID. Opcje są następujące: • FT_UID — Parametr $msg_number jest UID • FT_INTERNAL — Zwracany ciąg jest w postaci wewnętrznej bez konwersji końców linii. datę wewnętrzną. object imap_fetchstructure (int imap_stream. jeżeli nie był wcześniej ustawiony • FT_INTERNAL — Zwracany ciąg jest w postaci wewnętrznej bez konwersji końców linii. int msg_number [. string imap_fetchbody (int imap_stream. Zwracany obiekt zawiera kopertę. Opcjonalny parametr $flags posiada tylko jedną opcję. int flags]) Tabela 1.RFC822 powinien być w tym samym czasie wstępnie pobrany. imap_mail_move() lub int imap_expunge (int imap_stream) imap_fetchbody Funkcja powoduje pobranie sekcji z treści podanego komunikatu w postaci tekstu i zwrócenie tego tekstu. flags flags]) imap_fetchheader Powoduje odczytanie całego. Zwracany obiekt z imap_fetchstructure() Typ Typ treści encoding Kodowanie do przesłania treści ifsubtype TRUE jeżeli występuje ciąg podtypu subtype Podtyp MIME ifdescription TRUE jeżeli jest to ciąg opisu description Ciąg opisu treści ifid TRUE jeżeli jest to ciąg identyfikacyjny id Ciąg identyfikacyjny lines Ilość linii Dodatek A . jako usunięte przez imap_delete(). nieprzefiltrowanego RFC822 nagłówka formatu podanego komunikatu i zwrócenie go ciągu znaków. Parametrem imap_fetchbody() jest maska bitowa z jedną lub więcej stałych: • FT_UID — Parametr $msg_number jest UID • FT_PEEK — Nie ustawia znacznika \Seen. w sposób określony przez specyfikację IMAP4. która wskazuje funkcji. • FT_PREFETCH — TEXT. znaczniki i strukturę treści.

że nie mogą posiadać następnych obiektów parts. string sequence [. " .host:143}".4:6". Podstawowe typy treści 0:text. int flags]) Przykład: imap_fetch_overview() $mbox = imap_open("{your.0). $val->subject . 4:QUOTED-PRINTABLE. Parametr $sequence może zawierać sekwencję indeksów wiadomości lub identyfikatorów UID. while( list($key."username".imap.imap_last_error()). 4:audio." . "\n".bytes ifdisposition disposition ifdparameters dparameters ifparameters parameters parts Uwaga Ilość bajtów TRUE jeżeli jest to ciąg rozmieszczenia Ciąg rozmieszczenia TRUE jeżeli istnieje tablica dparameters Tablica parametrów rozmieszczenia TRUE jeżeli istnieje tablica parametrów Tablica parametrów MIME Tablica obiektów opisujących każdą część przesyłki Dparameters jest tablica obiektów posiadających atrybuty $attribute i $value. } } imap_close($mbox). 2:BINARY. 7-other Rodzaje kodowania 0:7BIT. 1:8BIT. 3:BASE64. 269 PHP – Kompendium wiedzy . Funkcja zwraca tablicę obiektów opisujących następujące nagłówki kolejnych wiadomości: • subject — temat wiadomości • from — nadawca wiadomości • date — data wysłania • message_id — identyfikator wiadomości • references — odwołania do tego identyfikatora wiadomości • size — rozmiar w bajtach • uid — identyfikator UID wiadomości w skrzynce • msgno — numer kolejny komunikatu w skrzynce • recent — wiadomość oznaczona jako niedawna • flagged — wiadomość zaznaczona • answered — wiadomość na którą została udzielona odpowiedź • deleted — wiadomość zaznaczona do usunięcia • seen — wiadomość przeczytana • draft — wiadomość oznaczona jako szkic array imap_fetch_overview (int imap_stream. gdy parametr $flag zawiera FT_UID. " . Parameters jest tablicą obiektów posiadających atrybuty $attribute i $value." . 1: multipart. 3:application. z ograniczeniem. if(is_array($overview)) { reset($overview)."password") or die("błąd połaczenia: ". $overview = imap_fetch_overview($mbox. 5:OTHER imap_fetch_overview Pobiera nagłówki dla podanej sekwencji $sequence i zwraca skrót ich zawartości.$val) = each($overview)) { print $val->msgno . 2:message. $val->date . 6-video."2. 5:image. Parts jest tablicą obietów o identycznej strukturze jak nadrzędny obiekt.

subject.Funkcje 270 . print $val->attributes. $delimiter — znak podziału w tej części hierarchii. Mogą być tu używane dwa znaki specjalne: * i %."\n". działa dokładnie tak samo. otrzymamy skrzynki z głównego poziomu hierarchii. followup_to. Jeżeli chcesz uzyskać wszystkie skrzynki. imap_header( void ) imap_headerinfo Zwraca obiekt do różnych fragmentów nagłówka: message_id."username". imap_header( void ) remail. Znak % powoduje otrzymanie jedynie skrzynek z bieżącego poziomu hierarchii. która może być testowana za pomocą następujących stałych: • LATT_NOINFERIORS — skrzynka nie posiada „dzieci” (skrzynek w niej założonych) • LATT_NOSELECT — jest to kontener a nie skrzynka i nie może być otwierany • LATT_MARKED — skrzynka jest zaznaczona i używana jedynie przez UW-IMAPD • LATT_UNMARKED — skrzynka nie jest zaznaczona i używana jedynie przez UW-IMAPD array imap_getmailboxes (int imap_stream. while (list($key.imap. } } else print "nieudane wywołanie funkcji imap_getmailboxes: ". $list = imap_getmailboxes($mbox. do których użytkownik posiada array imap_getsubscribed (int imap_stream. in_reply_to. print imap_utf7_decode($val->name).host}". ' ' jeżeli nie usunięta Dodatek A . "~/mail/%" na UW-IMAPD zwróci wszystkie skrzynki z katalogu ~/mail."'. Dostępne są następujące znaczniki wiadomości: • Recent — 'R' jeżeli wiadomość jest przeczytana i niedawna.". date. $val) = each($list)) { print "($key) "."{your. imap_getsubscribed Identyczna z subskrypcję.host}". Date. string ref."<br>\n". 'N' jeżeli jest niedawna i nieprzeczytana. string pattern) Nazwy skrzynek zawierające znaki narodowe z poza drukowalnego zakresu kodów ASCII są zakodowane i mogą być rozkodowane za pomocą funkcji imap_utf7_decode(). Przykład: imap_getmailboxes() $mbox = imap_open("{your.$val->delimiter. w której znajduje się skrzynka. $attributes — maska bitowa. Jeżeli podamy jedynie "%". if(is_array($list)) { reset($list). ale bez podkatalogów.OP_HALFOPEN) or die("błąd połączenia: ".". string pattern) imap_header Alias funkcji imap_headerinfo(). print "'". należy przekazać do parametru $pattern ciąg "*"."password". natomiast $pattern określa początek przeszukiwania w hierarchii skrzynek pocztowych. imap_getmailboxes().imap. newsgroups. Każdy obiekt posiada następujące atrybuty: $name — zawiera pełną nazwę skrzynki. Jeżeli użyjemy znaku * w wyniku otrzymamy wszystkie skrzynki w hierarchii.imap_last_error()). tak jak jest to opisane przy funkcji imap_open()."*").".imap_getmailboxes Zwraca tablicę obiektów zawierających dane na temat skrzynek pocztowych. Subject. ' ' jeżeli nie jest niedawna Unseen — 'U' jeżeli nie jest przeczytana i nie jest niedawna. imap_close($mbox). ale zwraca jedynie skrzynki. ' ' jeżeli nie udzielono odpowiedzi Deleted — 'D' gdy usunięta.imap_last_error(). Normalnie $ref powinien być określany przez specyfikację serwera. ' ' jeżeli przeczytana lub niedawna Answered — 'A' jeżeli udzielono odpowiedzi. string ref. references.

host) reply_toaddress (kompletna linia reply_to:. string ref. adl. Jeżeli chcesz sprawdzić. aby zmieściła się w $fromlength znakach) toaddress imap_headers Zwraca tablicę ciągów sformatowanych z danymi nagłówków.host}"."username". Pozwala na jeden element na przesyłkę."\n". if(is_array($list)) { reset($list). $val) = each($list)) print imap_utf7_decode($val).imap_last_error()). array imap_listmailbox (int imap_stream. imap_listmailbox Zwraca tablicę zawierającą nazwy skrzynek pocztowych. mailbox. jeżeli nie wystąpią w międzyczasie inne błędy. adl. do 1024 znaków) bcc[] (zwraca tablicę obiektów z linii bcc: zawierająca: personal. host) udate (mail. aby zmieściła się w $fromlength znakach) fetchsubject (linia subject: sformatowana tak.imap_last_error().— 'X' jeżeli jest szkicem. mailbox. czy wiadomość nie jest przeczytana. while (list($key. • • • • • • • • • • • • • • • • • (kompletna linia to:.host}". mailbox. array imap_headers (int imap_stream) imap_last_error Zwraca pełny tekst ostatniego komunikatu błędu IMAP."<br>\n". adl. mailbox. host) senderaddress (kompletna linia sender:.imap. in. adl. adl."*"). mailbox. host) fromaddress (kompletna linia from:. Stos błędów pozostaje niezmieniony. do 1024 znaków) to[] (zwraca tablicę obiektów z linii to: zawierająca: personal. do 1024 znaków) cc[] (zwraca tablicę obiektów z linii cc: zawierająca: personal. do 1024 znaków) reply_to[] (zwraca tablicę obiektów z linii reply_to: zawierająca: personal."password". time) fetchfrom (linia from: sformatowana tak. do 1024 znaków) sender[] (zwraca tablicę obiektów z linii sender: zawierająca: personal.OP_HALFOPEN) or die("błąd połaczenia: ". Opis parametrów przy opisie imap_getmailboxes(). ' ' Flagged — 'F' jeżeli jest zaznaczona. mailbox. sprawdź Unseen == 'U' || Recent == 'N'. host) bccaddress (kompletna linia bcc:.imap. message. Kolejne wywołania imap_last_error() zwrócą ten sam błąd. } else print "Nieudane wywołanie funkcji imap_listmailbox: ". mailbox. unix. $list = imap_listmailbox($mbox. ' ' jeżeli jest oznaczona Draft Uwaga gdy nim nie jest Działanie znaczników Recent i Unseen jest nieco dziwne. date. imap_close($mbox). string pattern) $ref i $pattern znajduje się Przykład: imap_listmailbox() $mbox = imap_open("{your. host) return_path (kompletna linia return_path:."{your. adl. host) ccaddress (kompletna linia cc:. który wystąpił na bieżącej stronie. adl. do 1024 znaków) return_path[] (zwraca tablicę obiektów z linii return_path: zawierająca: personal. do 1024 znaków) from[] (zwraca tablicę obiektów z linii from: zawierająca: personal. 271 PHP – Kompendium wiedzy .

Dodatek A . string subject."<br>\n" . do których posiadasz subskrypcję. "password") or die("błąd połączenia: ". . print "Unread: " ."<br>\n" . print "Deleted: " . string imap_mail (string to. print "Recent: " . ale zwraca jedynie te skrzynki."<br>\n" . $part1["type"]=TYPEMULTIPART. ?> $check->Date $check->Driver $check->Mailbox $check->Nmsgs $check->Recent $check->Unread $check->Deleted $check->Size . string bcc [.imap_last_error(). object imap_mailboxmsginfo (int imap_stream) • • • • • • • • Właściwości skrzynki pocztowej Date — data ostatniej zmiany Driver — sterownik Mailbox — nazwa skrzynki Nmsgs — ilość wiadomości Recent — ilość ostatnich wiadomości Unread — ilość wiadomości nie przeczytanych Deleted — ilość usuniętych wiadomości Size — rozmiar skrzynki Przykład: imap_mailboxmsginfo() <?php $mbox = imap_open("{your. . ale dodatkowo sumuje rozmiary wszystkich wiadomości w skrzynce. } else { print "imap_check() } imap_close($mbox)."<br>\n" . ."<br>\n" . "<br>\n". string rpath]]]]) imap_mailboxmsginfo Zwraca informacje na temat bieżącej skrzynki pocztowej. co jednak powoduje wydłużenie czasu wykonywania funkcji."<br>\n" ."<br>\n" . Zwraca dane w postaci obiektu z następującymi właściwościami. print "Size: " . array imap_listsubscribed (int imap_stream.imap_last_error()). string message [. failed: "."username". . string additional_headers [.host}INBOX". .imap. string ref.imap_listsubscribed Zwraca tablicę z wszystkimi skrzynkami pocztowymi. $check = imap_mailboxmsginfo($mbox).com". if($check) { print "Date: " ."<br>\n" . Jest podobna do imap_status().Funkcje 272 . $envelope["to"]="musone@darkstar". Zwraca False w przypadku wystąpienia błędu. imap_mail_compose string imap_mail_compose (array envelope. . array body) Przykład: imap_mail_compose() <?php $envelope["from"]="musone@afterfive. . Jest ona niemal identyczna jak imap_listmailbox(). print "Mailbox: " . $envelope["cc"]="musone@edgeglobal. string pattern) imap_mail Funkcja ta jest obecnie dostępna tylko w PHP 3.com". print "Driver: " . string cc [. print "Messages: ". do których zalogowany użytkownik posiada subskrypcję. Funkcja imap_mailboxmsginfo() sprawdza status skrzynki na serwerze.

faqs. Zdekodowane elementy są zwracane w postaci tablicy obiektów.$i<count($elements).html).data"]=$contents. int imap_mail_move (int imap_stream. int flags]) imap_mime_header_decode Dekoduje rozszerzenia nagłówków komunikatów MIME.$part1["subtype"]="mixed".faqs. które zawierają tekst z poza ASCII (RFC2047 http://www.org/rfcs/rfc2060. Parametr $msglist może zawierać zakres a nie tylko numery komunikatów. string mbox [. echo "Text: {$elements[$i]->text}\n\n". $part3["description"]="description3". array imap_mime_header_decode (string text) Przykład: imap_mime_header_decode() $text="=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug. Parametr $flags jest maską bitową zawierającą CP_UID — sekwencja liczb zawiera UID i CP_MOVE — usuwa komunikaty ze skrzynki po ich skopiowaniu. $part2["type"]=TYPEAPPLICATION. jak to zostało opisane w RFC2060 (http://www. Kopiuje wiadomość określoną przez $msglist do określonej skrzynki pocztowej.gz". $part3["subtype"]="plain".html). $part2["subtype"]="octet-stream". $part3["contents. gdzie pierwszy element jest zakodowany za pomocą ISO-8859-1 a drugi będzie US-ASCII. $part2["description"]=basename($filename). $body[2]=$part2."r"). int uid) 273 PHP – Kompendium wiedzy . $part2["encoding"]=ENCBINARY. $fp=fopen($filename. string mbox [. $body[1]=$part1. $contents=fread($fp.data3\n\n\n\t". fclose($fp). $filename="/tmp/imap. string msglist. z który posiada dwie właściwości: charset i text.html). echo nl2br(imap_mail_compose($envelope.$body)).faqs. $elements=imap_mime_header_decode($text). } W przedstawionym przykładzie otrzymamy dwa elementy. właściwość charset jest ustawiona na wartość domyślną. $part2["contents. ?> imap_mail_copy Zwraca True w przypadku sukcesu lub False w przypadku wystąpienia błędu.dk>".org/rfcs/rfc2047. Parametr $msglist może zawierać zakres a nie tylko numery komunikatów.c. int imap_mail_copy (int imap_stream. Parametr $flags jest maską bitową i może zawierać jedną wartość CP_UID. Jeżeli element nie może być zdekodowany a inne słowa są w USASCII. for($i=0. $body[3]=$part3. jak to zostało opisane w RFC2060 (http://www. int flags]) imap_mail_move Przenosi przesyłkę pocztową określoną przez $msglist to podanej skrzynki pocztowej. Jest to odwrotność imap_uid(). int imap_msgno (int imap_stream. Zwraca True w przypadku sukcesu lub False w przypadku wystąpienia błędu.filesize($filename)).$i++) { echo "Charset: {$elements[$i]->charset}\n".org/rfcs/rfc2060. string msglist. $part3["type"]=TYPETEXT. imap_msgno Zwraca numer sekwencji wiadomości dla podanego UID.data"]="contents.

imap. Przykład: imap_open() $mbox = imap_open ("{your. a w przypadku błędu False. Aby podłączyć się z serwerem NNTP działającym na porcie 119 na komputerze lokalnym. • CL_EXPUNGE — automatycznie czyści skrzynkę po jej zamknięciu. int flags]) Opcje stanowią maskę bitową zawierającą jedną. } } imap_close($mbox). Nazwa specjalna INBOX określa bieżącą skrzynkę pocztową użytkownika. określenie protokołu komunikacji (rozpoczynające się od /). "password"). int imap_open (string mailbox.host:143}". Aby podłączyć się z serwerem POP3 działającym na porcie 110 na komputerze lokalnym. int imap_num_msg (int imap_stream) imap_num_recent Zwraca ilość ostatnich przesyłek w bieżącej skrzynki pocztowej. Aby podłączyć się z serwerem IMAP działającym na porcie 143 na komputerze lokalnym. "user_id".Funkcje 274 . Funkcja może być używana do otwarcia strumienia do serwerów POP3 i NNTP i nie wszystkie funkcje i własności są dostępne na serwerach IMAP. echo "<p><h1>Skrzynki pocztowe</h1>\n". if ($folders == false) { echo "wywołanie nieudane<br>\n". } else { while (list ($key.newsrc (tylko NNTP). "{your. "*"). "user_id". Nazwa skrzynki składa się z dwóch części: nazwy serwera i ścieżki do skrzynki na tym serwerze. $folders = imap_listmailbox ($mbox.$val) = each ($headers)) { echo $val. $val) = each ($folders)) { echo $val. "password"). Nazwy skrzynek zawierające znaki narodowe spoza drukowalnego podzbioru kodów ASCII są zakodowane za pomocą funkcji imap_utf7_encode(). "password"). • OP_ANONYMOUS — nie używa ani nie zmienia pliku . string username. "password"). • OP_HALFOPEN — dla połączeń IMAP i NNTP. otwiera połączenie. "username". oraz opcjonalnie numer portu rozpoczynający się od znaku :. int imap_num_recent (int imap_stream) imap_open W przypadku powodzenia zwraca strumień IMAP. Podawanie nazwy serwera jest obowiązkowe we wszystkich parametrach skrzynki pocztowej.imap_num_msg Zwraca ilość przesyłek w bieżącej skrzynce pocztowej. $headers = imap_headers ($mbox).host:143}". należy wywołać funkcję w następujący sposób: $mbox = imap_open ("{localhost:993/imap/ssl}INBOX"."<br>\n". Dodatek A . } else { while (list ($key."<br>\n". "user_id". ale nie otwiera skrzynki. z którym ma być nawiązane połączenie. } } echo "<p><h1>nagłówki w INBOX</h1>\n". należy wywołać funkcję w następujący sposób: $mbox = imap_open ("{localhost:110/pop3}INBOX". Fragment nazwy określający serwer jest otoczony nawiasami klamrowymi {} i zawiera nazwę serwera. należy wywołać funkcję w następujący sposób: $mbox = imap_open ("{localhost:143}INBOX". lub jego numer IP. Aby połączyć się ze zdalnym serwerem należy zastąpić localhost nazwą lub numerem IP serwera.imap. lub więcej z poniższych wartości: • OP_READONLY — otwiera skrzynkę tylko do odczytu. string password [. if ($headers == false) { echo "wywołanie nieudane<br>\n".

ale nie otwiera skrzynki. Może sprawdzać nową pocztę. string new_mbox) imap_reopen Ponownie otwiera strumień do nowej skrzynki na serwerze IMAP lub NNTP. } 275 PHP – Kompendium wiedzy . Patrz również: imap_createmailbox(). jeżeli strumień jest aktywny.php. root". int imap_renamemailbox (int imap_stream. if(! is_array($address_array)) die("coś poszło źle\n"). • personal — nazwa opisowa użytkownika. Zwraca ciąg 8-bitowy (binarny). Zwraca True gdy operacja się powiodła i False w przypadku błędu."<p>\n". sekcja 6. Opcje są maską bitową zawierającą jedną lub więcej następujących wartości: • OP_READONLY — otwiera skrzynkę tylko do odczytu. Funkcja imap_ping() sprawdza za pomocą operacji ping. string mailbox [. • adl — ścieżka do domeny źródłowej."<br>\n". string old_mbox.net. string imap_qprint (string string) imap_renamemailbox Zmienia nazwę skrzynki pocztowej na nową (format nazw skrzynek opisany jest przy funkcji imap_open()). print "personal: ". Jest to zalecana metoda okresowego sprawdzania nowej poczty oraz podtrzymywania połączenia do serwerów rozłączających nieaktywne połączenia (ponieważ skrypty PHP nie działają zbyt długo.$val)=each($address_array)){ print "mailbox : ".imap_ping Zwraca True. array imap_rfc822_parse_adrlist (string address.$val->mailbox.net>."<br>\n". postmaster@somedomain."<br>\n". False w przypadku nieaktywnego strumienia.$val->personal. Właściwościami obiektów są: • mailbox — nazwa skrzynki (nazwa użytkownika). $address_array = imap_rfc822_parse_adrlist($address_string.$val->host.org/rfcs/rfc2045.net"). Dla każdego adresu zwraca tablicę obiektów.newsrc (tylko NNTP). funkcja ta prawdopodobnie nie będzie zbyt użyteczna). reset($address_array). print "adl : ". string default_host) Przykład: imap_rfc822_parse_adrlist() $address_string = "Hartmut Holzgraefe <hartmut@cvs. print "host : ". imap_deletemailbox() i imap_open(). Zwraca True w przypadku powodzenia i False w przypadku błędu. czy strumień jest nadal aktywny. • OP_HALFOPEN — dla połączeń IMAP i NNTP. string flags]) imap_rfc822_parse_adrlist Analizuje adresy w sposób zdefiniowany w RFC822 (http://www/faqs. Patrz również: imap_8bit(). int imap_reopen (int imap_stream.7). • CL_EXPUNGE — automatycznie czyści skrzynkę po jej zamknięciu. • OP_ANONYMOUS — nie używa ani nie zmienia pliku . while(list($key.html). • host — nazwa hosta.$val->adl. int imap_ping (int imap_stream) imap_qprint Konwertuje ciąg zakodowany w postaci quoted-printable na ciąg 8-bitowy zgodnie z RFC2045 (http://www/faqs. otwiera połączenie."somedomain.html.org/rfcs/rfc2045.

array imap_scanmailbox (int imap_stream. a które nie była udzielona odpowiedź UNDELETED — szuka wiadomości."Hartmut Holzgraefe"). Parametr $criteria zawiera ciąg. na podstawie skrzynki pocztowej.net". string personal) RFC822 Przykład: imap_rfc822_write_address() print imap_rfc822_write_address("hartmut". int flags) — zwraca wszystkie wiadomości spełniające pozostałe warunki — szuka wiadomości z ustawionym znacznikiem \\ANSWERED BCC "string" — szuka wiadomości z ciągiem "string" w polu Bcc: BEFORE "date" — szuka wiadomości sprzed podanej daty BODY "string" — szuka wiadomości z ciągiem "string" w temacie wiadomości CC "string" — szuka wiadomości z ciągiem "string" w polu Cc: DELETED — szuka usuniętych wiadomości FLAGGED — szuka wiadomości z ustawionym znacznikiem \\FLAGGED (czasami nazywanymi wiadomościami ważnymi) FROM "string" — szuka wiadomości z ciągiem "string" w polu From: KEYWORD "string" — szuka wiadomości ze słowem kluczowym "string" NEW — szuka nowych wiadomości OLD — szuka starych wiadomości ON "date" — szuka wiadomości z polem Date: ustawionym na "date" RECENT — szuka wiadomości z ustawionym znacznikiem \\RECENT SEEN — szuka przeczytanych wiadomości (z ustawionym znacznikiem \\SEEN) SINCE "date" — szuka wiadomości z polem Date: ustawionym na datę wcześniejszą od "date" SUBJECT "string" — szuka wiadomości z ciągiem "string" w polu Subject: TEXT "string" — szuka wiadomości z ciągiem "string" w tekście TO "string" — szuka wiadomości z ciągiem "string" w polu To: UNANSWERED — szuka wiadomości. podobnie do imap_header(). Funkcja ta jest podobna do imap_listmailbox(). na przykład FROM "jan kowalski". string pattern."\n". string criteria. które nie są oznaczone UNKEYWORD "string" — szuka wiadomości nie posiadających słowa kluczowego "string" UNSEEN — szuka wiadomości nie przeczytanych ALL ANSWERED Dodatek A . string defaulthost]) imap_rfc822_write_address Zwraca prawidłowo sformatowany adres e-mail według definicji w (http://www/faqs. w którym dozwolone są zamieszczone poniżej słowa kluczowe rozdzielone spacjami. imap_scanmailbox Zwraca tablicę zawierającą nazwy skrzynek.imap_rfc822_parse_headers Zwraca obiekt z różnymi elementami nagłówka. które nie są usunięte UNFLAGGED — szuka wiadomości. które zawierają tekst przekazany w $string. string imap_rfc822_write_address (string mailbox.php. ale dodatkowo sprawdza czy w danych skrzynki zawarty tekst $content.Funkcje 276 . string content) imap_search Przeszukuje skrzynkę pocztową otwartą za pocą podanego strumienia IMAP.org/rfcs/rfc2045. ale bez znaczników i innych elementów pochodzących z serwera IMAP. • • • • • • • • • • • • • • • • • • • • • • • • array imap_search (int imap_stream. hosta i danych osobistych. Wszystkie elementy wielowyrazowe muszą być otoczone apostrofami. string host. string ref. Opis parametrów $ref i $pattern można znaleźć przy funkcji imap_getmailboxes().html)."cvs. object imap_rfc822_parse_headers (string headers [.

gdy UID skrzynki przestaje być prawidłowy • SA_ALL — ustawia wszystkie powyższe właściwości Dodatkowo ustawiany jest status->flags zawierający maskę bitową."password". aby odnaleźć wszystkie wiadomości wysłanych przez Mama. array imap_sort (int stream. int options) Dozwolonymi znacznikami są: SA_MESSAGES — ustawia status->messages na ilość wiadomości w skrzynce SA_RECENT — ustawia status->recent na ilość niedawnych wiadomości w skrzynce SA_UNSEEN — ustawia status->unseen na ilość nierzeczytanych (nowych) wiadomości w skrzynce SA_UIDNEXT — ustawia status->uidnext na następny UID jaki zostanie użyty w skrzynce SA_UIDVALIDITY — ustawia status->uidvalidity na stałą. int reverse. $status = imap_setflag_full($mbox. \\Answered. 277 PHP – Kompendium wiedzy . string imap_setflag_full (int stream.imap_last_error()). string options) Przykład: imap_setflag_full() $mbox = imap_open("{your."password") or die("błąd połączenia: ". Znaczniki jakie można ustawić to: \\Seen.imap.Na przykład. Podana lista warunków jest odczytana ze źródeł UW c-client i może być niekompletna lub nieprecyzyjna (patrz RFC2060 sekcja 6. który powoduje zwracanie tablicy zawierającej identyfikatory UID zamiast numerów kolejnych wiadomości. print $status. string sequence. imap_close($mbox).5". string flag. imap_sort Zwraca tablicę numerów wiadomości posortowaną według podanego parametru. Przy przeszukiwaniu duże i małe litery nie są rozróżniane. print gettype($status).OP_HALFOPEN) or die("błąd połaczenia: ". \\Draft i \\Recent (według RFC2060)."2.4. int options) $reverse jest 1."\\Seen \\Flagged"). Jeżeli sortowanie jest odwrotne. na które nie była udzielona odpowiedź. która zmienia się. \\Flagged."username". która może być porównywana z przedstawionymi powyżej stałymi."\n". • • • • • • • • • Sortowanie może się odbywać według jednego (tylko jednego) z poniższych warunków: SORTDATE — data wiadomości SORTARRIVAL — data otrzymania wiadomości SORTFROM — adresu nadawcy (From:) SORTSUBJECT — tematu wiadomości SORTTO — adresu z pola To: SORTCC — adresu z pola Cc: SORTSIZE — wielkości przesyłki liczonej w oktetach Opcje są maską bitową z następującymi wartościami: SE_UID — Funkcja zwraca identyfikatory UID zamiast numerów kolejnych SE_NOPREFETCH — nie odczytuje wstępnie szukanych wiadomości imap_status Zwraca obiekt zawierający dane statusu.imap_last_error()). należy użyć ciągu "UNANSWERED FROM Mama". int criteria. Prawidłową wartością parametru $flags jest SE_UID. string mailbox.host:143}". object imap_status (int imap_stream.imap."\n".4).host}". Przykład: imap_status() • • • • • $mbox = imap_open("{your. Prawidłową wartością parametru $flags jest ST_UID. imap_setflag_full Powoduje dodanie określonych znaczników do wiadomości z podanej sekwencji. \\Deleted. który powoduje zwracanie tablicy zawierającej identyfikatory UID zamiast numerów kolejnych wiadomości."username".

html sekcja 5. string imap_utf8 (string text) Dodatek A . string imap_utf7_encode (string data) imap_utf8 Konwertuje podany ciąg na postać UTF8 w sposób zdefiniowany w RFC2044. print("Nieprzeczytanych:".1. które mogą się zmienić po zmianie zawartości skrzynki. $status->unseen ). natomiast oryginalne kodowanie UTF-7 jest zdefiniowane w RFC1642 (http://www/faqs.html sekcja 5. $status->uidvalidity). imap_delete() lub int imap_undelete (int imap_stream. Funkcja ta jest niezbędna do dekodowania nazw skrzynek zwierających znaki narodowe spoza drukowalnego zakresu kodów ASCII.imap. lub False. int imap_subscribe (int imap_stream. Funkcja jest odwrotna do imap_msgno(). string mbox) True w przypadku powodzenia i False w przypadku imap_utf7_decode Dekoduje $text w postaci UTF-7 do danych 8-bitowych.1. Zwraca błędu. print("Następny UID: ".org/rfcs/rfc2060. if($status) { print("Wiadomości: "."\n". UID to jednoznaczny identyfikator nie zmieniający się w czasie w przeciwieństwie do numerów kolejnych. int imap_uid (int imap_stream. int msg_number) imap_unsubscribe Usuwa subskrypcję do podanej skrzynki.3). print("Poprawność UID: "."<br>\n".SA_ALL).host}INBOX". imap_subscribe Subskrybuje nową skrzynkę.Funkcje 278 . Zwraca ciąg zakodowany zmodyfikowaną metodą UTF-7. string mbox) True po poprawnym wykonaniu operacji lub False w przypadku imap_uid Zwraca identyfikator UID wiadomości na podstawie jej numeru kolejnego.html). Usuwa znacznik usunięcia dla podanej wiadomości ustawiony przez funkcję Zwraca True w przypadku powodzenia i False w przypadku błędu. Jest to niezbędne do zakodowania nazw skrzynek zawierających znaki narodowe spoza drukowalnego zakresu kodów ASCII. Zwraca zdekodowane dane 8-bitowe."{your."<br>\n".org/rfcs/rfc2060. $status->messages ). int imap_unsubscribe (int imap_stream. print("Niedawnych: ". Zwraca błędu. $status->uidnext ). Zmodyfikowane kodowanie UTF-7 jest zdefiniowane w RFC2060 (http://www/faqs. gdy ciąg wejściowy nie jest prawidłowym ciągiem UTF-7. } else print "nieudane wywołanie imap_status: "."<br>\n". int msgno) imap_undelete imap_move()."<br>\n".org/rfcs/rfc1642. imap_close($mbox). $status->recent ).$status = imap_status($mbox."<br>\n".html). Zmodyfikowane kodowanie UTF-7 jest zdefiniowane w RFC2060 (http://www/faqs.3). natomiast oryginalne kodowanie UTF-7 jest zdefiniowane w RFC1642 (http://www/faqs.imap_last_error(). string imap_utf7_decode (string text) imap_utf7_encode Konwertuje 8-bitowe dane do tekstu UTF-7.org/rfcs/rfc1642.

string newvalue) ini_get ini_restore() Zwraca wartość opcji konfiguracji lub False w przypadku wystąpienia błędu.implode Zwraca ciąg zawierający wszystkie elementy tablicy w tej samej kolejności z ciągiem sklejającym pomiędzy elementami. join() i split(). ini_restore() i ini_set(). int intval (mixed var [. Patrz również: explode(). int base]) in_array Szuka $needle w zostanie znaleziony. Uwaga Funkcja implode() może. ini_get() i ini_restore(). Nie można używać funkcji intval() na tablicach i obiektach. ini_get() i ini_set Ustawia wartość podanej opcji konfiguracji. string ini_alter (string varname. poprzednią wartość opcji. array pieces) Przykład: implode() $colon_separated = implode(":". jeżeli ciąg zostanie znaleziony w tablicy i False. i ini_set(). poprzednią wartość opcji. strval() i settype(). natomiast w Patrz również: ini_get(). string ini_restore (string varname) ini_alter(). False w przypadku niepowodzenia. jeżeli nie bool in_array (mixed needle. Jednak z powodu spójności z explode() powinno się korzystać z kolejności przedstawionej w dokumentacji. Zwraca przypadku sukcesu. ini_alter Zmienia wartość podanej opcji konfiguracji. string ini_set (string varname. Uwaga Jest to alias do ini_set(). Parametr $var może być dowolnym typem skalarnym. array haystack) PHP – Kompendium wiedzy . Zwraca False w przypadku niepowodzenia. Patrz również doubleval(). string newvalue) intval Zwraca wartość całkowitą zmiennej $var przy użyciu konwersji o podanej podstawie (wartością domyślną jest 10). Zwraca True. string ini_get (string varname) ini_restore Przywraca oryginalną wartość podanej opcji konfiguracji. $array). Patrz również: ini_alter(). z powodów historycznych. Patrz również ini_set(). 279 $haystack. pobierać swoje argumenty w dowolnym porządku. Patrz również: ini_alter(). natomiast w przypadku sukcesu. string implode (string glue.

bool is_array (mixed var) is_bool Zwraca True. echo isset ($a). a unset(). print isset ($foo). "NT". $out = "Następujące adresy są swoimi odpowiednikami:<br>\n". is_int(). is_string() Zwraca True. "Irix". echo isset ($a). Jeżeli zmienna została usunięta za pomocą Przykład: isset() $a = "test".= "http://www. W przypadku błędu lub braku danych IPTC zwraca False. bool is_dir (string filename) Dodatek A . is_int(). Patrz również: GetImageSize(). // TRUE unset ($a). is_integer(). is_array is_integer(). False. wartości znaczników. iptcparse Dzieli pojedynczy blok IPTC na pojedyncze znaczniki. $os)) { print "Znaleziono Irix". ?> Patrz również: long2ip(). // FALSE Patrz również: empty() i unset(). http://". array iptcparse (string iptcblock) isset Jeżeli istnieje $var zwraca True. is_string() i is_object()."/ i http://". } ip2long Generuje adres IPv4 na podstawie standardowego formatu (ciąg z kropkami). $out . Parz również: is_array(). gdy nią nie jest.Funkcje 280 .$ip. // FALSE $foo = NULL. bool is_bool (mixed var) is_dir Zwraca True. int ip2long (string ip_address) Przykład: ip2long() <?php $ip = gethostbyname("www. funkcja isset() zwraca False.Przykład: in_array() $os = array ("Mac".net/."/<br>\n". jeżeli istnieje katalog o podanej nazwie. if (in_array ("Irix". is_float(). Zwraca tablicę używając jako indeksów oznaczeń znaczników a jako wartości. echo $out. jeżeli parametr $var jest wartością boolean. Patrz również: is_file() i is_link(). boolean isset (mixed var) False gdy nie istnieje. Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache().php.ip2long($ip). "Linux").php. jeżeli $var jest tablicą i i is_object(). Wynik funkcji jest przechowywany w pamięci podręcznej.net"). Patrz również: is_float().

jeżeli parametr $var jest liczbą double. is_string(). Patrz również: is_bool(). Patrz is_numeric Zwraca True. is_array() i is_integer(). bool is_numeric (mixed var) 281 PHP – Kompendium wiedzy . w przeciwnym wypadku zwraca False. Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache(). Patrz również: is_bool(). is_float(). is_float(). is_string(). is_int(). bool is_executable (string filename) is_file Zwraca True. bool is_file (string filename) is_float Alias do funkcji is_double(). Patrz is_executable Zwraca True. is_string(). w przeciwnym wypadku zwraca również: is_bool(). is_float(). Patrz również: is_file() i is_link(). jeżeli $var jest liczbą lub ciągiem zawierającym liczbę. Funkcja ta nie działa w systemie Windows. is_array() i bool is_integer (mixed var) is_link Zwraca True. bool is_link (string filename) is_long Zwraca True. is_array() i bool is_int (mixed var) is_integer Alias do is_object(). Patrz również: is_bool(). is_array() i is_object(). bool is_float (mixed var) is_int Alias do is_object(). w przeciwnym wypadku zwraca również: is_bool().is_double Zwraca True. is_string(). is_integer(). is_array() i is_object(). jeżeli istnieje plik o podanej nazwie pliku i jest on łączem symbolicznym. Wyniki działania funkcji są przechowywane w pamięci podręcznej. Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache(). Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache(). is_object(). is_integer(). is_string(). jeżeli istnieje plik o podanej nazwie pliku i jest on plikiem wykonywalnym. is_integer(). is_long(). is_array() i is_object(). is_string(). is_int(). jeżeli $var jest liczbą całkowitą (long). Patrz również: is_dir() i is_link(). int is_double( mixed var) False. is_long(). Wyniki działania funkcji są przechowywane w pamięci podręcznej. Patrz również: is_bool(). is_float(). Wyniki działania funkcji są przechowywane w pamięci podręcznej. jeżeli istnieje plik o podanej nazwie pliku i jest on zwykłym plikiem. is_integer(). Patrz również: is_dir() i is_file(). is_integer(). is_int(). is_long( mixed var) False.

is_integer(). Należy pamiętać. is_int(). jeżeli plik o podanej nazwie został przesłany poprzez HTTP POST. Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache(). jeżeli $var jest ciągiem. która jest klasą pochodną po wypadku zwraca False. Patrz również: is_writable(). Nie są brane pod uwagę ograniczenia trybu bezpiecznego. int is_real( mixed var ) is_resource Zwraca True. na którym nie powinien. Zasobami są identyfikatory plików lub wyników zapytań do bazy danych. Zwraca True. Należy pamiętać. is_object() i is_array().0. Jest to użyteczne. is_real(). Patrz również: is_bool(). bool is_subclass_of (object obj. is_readable Zwraca True. is_int(). Jeżeli nie są one używane można zastosować ich porządkowanie. że PHP może czytać ten plik jako użytkownik na rzecz którego jest uruchomiony serwer WWW (często jest to nobody). string superclass) $superclass. w przeciwnym is_uploaded_file Funkcja ta jest dostępna w PHP3 począwszy od wersji PHP 3. is_float(). bool is_uploaded_file (string filename) is_writeable Zwraca True.Funkcje 282 .2. w przeciwnym przypadku zwraca False. że zawartość przesyłanego pliku może być pokazana użytkownikowi.16 i w PHP od wersji 4. ale nie powinny być one zwalniane przez kod użytkownika. jeżeli plik o podanej nazwie istnieje i można go odczytać. na przykład /etc/passwd. Parametr może być również nazwą katalogu. is_array() i is_object(). aby pracował on na pliku. w przeciwnym wypadku zwraca is_bool(). bool is_object (mixed var) is_bool(). Patrz również: is_int(). gdy istnieje jakakolwiek szansa. Patrz również: get_class().0. Nie są Dodatek A . w przeciwnym wypadku zwraca False. jeżeli zmienna przekazana przez parametr $var jest zasobem. is_integer(). get_parent_class(). co pozwala sprawdzić. Jest ona użyteczna do sprawdzenia. is_integer(). is_float(). jeżeli plik o podanej nazwie istnieje i można do niego pisać. czy można zapisywać do tego katalogu. Patrz również: move_uploaded_file(). jeżeli $var jest obiektem. że PHP może czytać ten plik jako użytkownik na rzecz którego jest uruchomiony serwer WWW (często jest to nobody). lub innym użytkownikom na tym samym systemie. bool is_resource (mixed var) is_string Zwraca True. które są tworzone i usuwane poprzez wewnętrzne funkcje PHP. Patrz również: is_subclass_of Zwraca True. czy złośliwy użytkownik nie próbuje oszukać skryptu tak. is_string() i is_array(). jeżeli $obj jest obiektem klasy.is_object Zwraca True. bool is_readable (string filename) is_real Alias do funkcji is_double(). bool is_string (mixed var) False. is_string().

bool is_writeable (string filename) JDDayOfWeek Zwraca dzień tygodnia. int mode) Tabela 3. Parametr $mode wskazuje funkcji do którego kalendarza skonwertować liczbę dni juliańskich i jaki typ nazwy miesiąca należy zwrócić. mixed jddayofweek (int julianday. string jdmonthname (int julianday. string jdtogregorian (int julianday) JDToJewish Konwertuje liczbę dni juliańskich na kalendarz żydowski. W zależności od trybu może zwracać ciąg lub liczbę. string jdtojulian (int julian3day) 283 PHP – Kompendium wiedzy .brane pod uwagę ograniczenia trybu bezpiecznego. itd. string jdtojewish (int julianday) JDToJulian Konwertuje liczbę dni juliańskich na ciąg zawierający datę w kalendarzu juliańskim w formacie miesiąc/dzień/rok. Tryby tygodni w kalendarzu Tryb Znaczenie 0 Zwraca numer dnia jako liczbę (0=niedziela.) 1 Zwraca ciąg zawierający dzień tygodnia (angielskigregoriański) 2 Zwraca ciąg zawierający skrót dnia tygodnia (angielski-gregoriański) JDMonthName Zwraca ciąg zawierający nazwę miesiące. Tryby kalendarza Tryb Znaczenie 0 Gregoriański — skrócony 1 Gregoriański 2 Juliański — skrócony 3 Juliański 4 Żydowski 5 Republiki francuskiej JDToFrench Konwertuje liczbę dni juliańskich do kalendarza Rewolucji Francuskiej. Więcej szczegółów na ten temat znajduje się w opisie funkcji clearstatchache(). 1=poniedziałek. Patrz również: is_readable(). string jdtofrench (int juliandaycount) JDToGregorian Konwertuje liczbę dni juliańskich na ciąg zawierający datę gregoriańską w formacie miesiąc/dzień/rok. int mode) Tabela 2.

"b"=>"banan". Uwaga Funkcja ta jest dostępna od wersji PHP4RC1.n. sort(). Jest to przydatne w przypadku tablic asocjacyjnych. int day.e.n. } ?> Wykonanie przykładu spowoduje wyświetlenie: d c b a = = = = cytryna jabłko banan pomarańcza Można zmienić działanie funkcji używając opcjonalnego parametru $sort_flags. Patrz również: asort(). jednak może być to mylące. int year) key Zwraca klucz bieżącej pozycji tablicy.. mixed key (array array) krsort Sortuje tablicę w odwrotnej kolejności utrzymując korelację między kluczami i danymi. Również początek roku różnił się w różnych kulturach — nie wszyscy zaakceptowali styczeń jako pierwszy miesiąc. int jdtounix (int jday) JewishToJD Mimo. Dodatek A . implode() i split(). while (list ($key. reset ($fruits). int jewishtojd (int month. że oprogramowanie może obsługiwać daty aż do roku 1 (3761 p.. "a"=>"pomarańcza". jednak może być to mylące. Mimo. Patrz również: current() i next().). do 9999 n. Patrz również: jdtounix(). int krsort (array array [. ale jego szczegóły nie ustabilizowały się do roku 8 n. ale w początkowym okresie nie było wzoru na wyliczenie początku miesiąca. Kalendarz żydowski jest w użyciu od kilku tysięcy lat. że oprogramowanie może obsługiwać daty od 413 p. array pieces) JulianToJD Zakres dat kalendarza juliańskiego to 4713 p.e. $val) = each ($fruits)) { echo "$key = $val\n". a nawet prawdopodobnie do 4 wieku. Patrz również: explode(). int year) join Jest to alias do funkcji implode() i działa identycznie.Funkcje 284 . krsort ($fruits).e. Kalendarz został utworzony w roku 46 p. ksort().jdtounix Zwraca znacznik czasu Uniksa odpowiadający dacie juliańskiej przekazanej w $jday.e. natsort() i rsort().e. "c"=>"jabłko"). string join (string glue. int day. lub False jeżeli $jday wykracza poza erę Uniksa (lata gregoriańskie pomiędzy 1970 i 2037 lub 2440588 <= $jday <= 2465342). Szczegółowy opis znajduje się przy funkcji sort(). int sort_flags]) Przykład: krsort() <? $fruits = array ("d"=>"cytryna". arsort(). int juliantojd (int month. Miesiąc był rozpoczynany po zaobserwowaniu nowiu księżyca.n.n.e.

"cn=John Jones. o=My Company. Funkcja łączy dwie wartości CG z okresem 2^31 . "b"=>"banan". $info["mail"]="jonj@here. // dodanie danych do katalogu $r=ldap_add($ds. "c"=>"jabłko"). ksort ($fruits). double lcg_value( void ) ldap_add Zwraca True w przypadku powodzenia operacji i False w przypadku błędu."cn=root. Patrz również: asort(). o=My Company. reset ($fruits). "a"=>"pomarańcza". int ksort (array array [. } ?> Wykonanie przykładu spowoduje wyświetlenie: a b c d = = = = pomarańcza banan jabłko cytryna Można zmienić działanie funkcji używając opcjonalnego parametru $sort_flags. } else { echo "Błąd wiązania z serwerem LDAP". c=US". DN dodawanego wpisu jest określane w parametrze $dn. W przypadku wielu wartości atrybutu są one indeksowane liczbami rozpoczynając od 0: entry["atrybut1"] = wartość entry["atrybut2"][0] = wartość1 entry["atrybut2"][1] = wartość 2 int ldap_add (int link_identifier. Tablica $entry zawiera informacje na temat wpisów. } ?> 285 PHP – Kompendium wiedzy . c=US". array entry) Przykład: Kompletny przykład autoryzowanego wiązania <?php $ds=ldap_connect("localhost"). ldap_close($ds). Jest to przydatne w przypadku tablic asocjacyjnych. krsort(). // zakładając. 1). while (list ($key. aby uzyskać możliwość wprowadzania zmian $r=ldap_bind($ds. Wartości wpisów są indeksowane kolejnymi atrybutami. Funkcja ldap_add() jest używana do dodawania wpisów do katalogu LDAP. $val) = each ($fruits)) { echo "$key = $val\n".now".and. sort(). int sort_flags]) Przykład: ksort() <? $fruits = array ("d"=>"cytryna". "secret").że serwer LDAP // działa na tym komputerze if ($ds) { // wiązanie z odpowiednim dn. $info).85 i 2^31 . string dn. lcg_value Zwraca liczbę pseudolosową z zakresu (0. // przygotowanie danych $info["cn"]="John Jones".249. natsort() i rsort(). $info["objectclass"]="person". arsort(). Okres tej funkcji jest równy iloczynowi obu liczb pierwszych. $info["sn"]="Jones". Szczegółowy opis znajduje się przy funkcji sort().ksort Sortuje tablicę utrzymując korelację między kluczami i danymi.

$attr. } ?> Uwaga Funkcja ldap_compare() nie może porównywać wartości binarnych! Funkcja została dodana w PHP 4. int ldap_bind (int link_identifier [. Funkcja ldap_compare() jest używana do porównywania wartości $value atrybutu $attribute z wartością tego samego atrybutu w pozycji katalogu LDAP określonej przez $dn. $value). w przypadku błędu zwraca Funkcja ldap_connect() zestawia połączenie z serwerem LDAP na komputerze $hostname i porcie $port. ou=My Unit. Zwraca True w przypadku powodzenia i False w przypadku błędu. string bind_password]]) ldap_close Zwraca True w przypadku powodzenia i False w przypadku błędu. Jeżeli nie zostaną podane. if ($r === -1) { echo "Błąd: ".że serwer LDAP // działa na tym komputerze if ($ds) { // wiązanie if(ldap_bind($ds)) { // przygotowanie danych $dn = "cn=Matti Meikku. o=My Company. wykonane zostanie wiązanie anonimowe. Jeżeli zostanie podana jedynie nazwa komputera. Funkcja ldap_close() zamyka połączenie z serwerem LDAP. False. string bind_rdn [. c=FI". jeżeli zostanie dopasowana wartość $value. zwracany jest identyfikator istniejącego połączenia. Zwraca -1 w przypadku błędu. // zakładając. Wywołanie to jest wewnętrznie identyczne z ldap_unbind(). $value = "secretpassword". Parametry $bind_rdn i $bind_password są opcjonalne. w jaki sposób można sprawdzić czy podane hasło odpowiada zdefiniowanemu w pozycji DN. } ldap_close($ds). } elseif ($r === TRUE) { echo "Hasło prawdłowe. string value) Przykład: Przykład kontroli hasła <?php $ds=ldap_connect("localhost"). string attribute.ldap_bind Wiąże z katalogiem LDAP z odpowiednim RDN i hasłem. Oba argumenty są opcjonalne.2. int port]]) Dodatek A . API LDAP korzysta z funkcji ldap_unbind(). int ldap_close (int link_identifier) ldap_compare Zwraca True.". ldap_connect W przypadku powodzenia operacji zwraca dodatni identyfikator łącza LDAP. string dn. } } else { echo "Błąd przy łączeniu z serwerem LDAP.0. int ldap_connect ([string hostname [.ldap_error($ds).". // porównanie wartości $r=ldap_compare($ds. Jeżeli nie podane zostaną argumenty.Funkcje 286 . domyślnym portem jest 389. Funkcja ldap_bind() wykonuje operację wiązania. w przeciwnym przypadku zwraca False. $attr = "password". } elseif ($r === FALSE) { echo "Hasło nieprawidłowe!". } else { echo "Nie można przyłączyć do serwera LDAP. int ldap_compare (int link_identifier. Zamieszczony przykład pokazuje. skojarzone z podanym identyfikatorem $link_identifier.". $dn. więc prawdopodobnie należy używać tej funkcji zamiast ldap_close().

tekstowe opisy błędów. } ?> ldap_errno Zwraca numer błędu LDAP dla ostatniego polecenia LDAP na podanym połączeniu.ldap_count_entries Zwraca ilość pozycji w wyniku lub False w przypadku wystąpienia błędu. string ldap_dn2ufn (string dn) ldap_err2str Zwraca ciąg z komunikatem błędu. int result_identifier) ldap_delete Zwraca True w przypadku powodzenia operacji lub usuwa pozycję z katalogu LDAP określoną przez $dn. Funkcja ldap_count_entries() zwraca ilość pozycji zapamiętanych w wyniku ostatniej operacji szukania. Choć numery błędów LDAP są zestandaryzowane. } $info = ldap_get_entries($ld. $res). int ldap_errno (int link_id) Przykład: Generowanie i przechwytywanie błędów <?php // przykład ten zawiera błąd. Nigdy nie należy porównywać tekstu komunikatów błędów. die("Aaaaaa!<br>\n"). Patrz również: ldap_errno() i ldap_error(). "objectclass"). string ldap_err2str (int errno) Przykład: Wyliczanie wszystkich komunikatów błędów LDAP <?php for($i=0. $info["count"]). Numer ten może zostać zamieniony na komunikat tekstowy za pomocą funkcji ldap_err2str(). Funkcja zwraca komunikat błędu objaśniający błąd wygenerowany przez ostatnie polecenie LDAP wykonane na podanym połączeniu. nawet przetłumaczone. printf("%d pasujących wpisów. ldap_error($ld)). Funkcja ta zwraca standardowy numer błędu zwracany przez ostatnie polecenie LDAP. $i<100. printf("LDAP-Error: %s<br>\n". zamiast tego zawsze należy używać do porównania numerów błędów. int ldap_count_entries (int link_identifier. int ldap_delete (int link_identifier. Funkcja ta zwraca komunikat błędu opisujący błąd numer $errno. $i++) { printf("Błąd $i: %s<br>\n". $bind = ldap_bind($ld). string dn) False w przypadku błędu. // aby działało musi być "objectclass=*" $res = @ldap_search($ld. ?> Patrz również: ldap_err2str() i ldap_error(). ldap_errno($ld)). ldap_err2str($i)). // błąd składni w wyrażeniu filtrującym (nr: 87). generowane błędy będą pokazywały się również w wynikowym HTML. różne biblioteki zwracają różne.<br>\n". "o=Myorg.ini lub nie będziesz poprzedzał funkcji LDAP znakiem @. c=DE". Parametr $result_identifier określa wewnętrzny wynik LDAP. który zostanie przechwycony $ld = ldap_connect("localhost"). Jeżeli nie zmniejszysz wystarczająco poziomu ostrzeżeń w pliku php. if (!$res) { printf("LDAP-Errno: %s<br>\n". Choć numery błędów LDAP są PHP – Kompendium wiedzy 287 . ldap_error Zwraca ciąg z komunikatem błędu. Funkcja ldap_delete() ldap_dn2ufn Używana do przekształcania DN na postać bardziej czytelna dla człowieka poprzez usunięcie nazw typów.

Patrz również: ldap_err2str() i ldap_errno(). czy RDN są zwracane ze swoimi wartościami. array ldap_explode_dn (string dn. która modyfikuje wskaźnik. Aby otrzymać tylko wartości. int ber_identifier) ldap_first_entry Zwraca identyfikator pierwszej pozycji wyniku lub False w przypadku błędu. Funkcja ldap_first_entry() zwraca identyfikator pierwszej pozycji wyniku. gdy skrypt wykonuje kolejne wyszukiwania. generowane błędy będą pokazywały się również w wynikowym HTML. We wielu aplikacjach szuka się określonego atrybutu. Funkcja ldap_first_attribute() zwraca pierwszy atrybut pozycji wskazywanej przez identyfikator pozycji. na który wskazuje $result_identifier. na przykład adresu e-mail lub nazwiska i nie ma potrzeby przejmować się zawartością innych pozycji. Funkcja ldap_free_result() zwalnia pamięć zajmowaną przez wynik. Jeżeli nie zmniejszysz wystarczająco poziomu ostrzeżeń w pliku php. True int ldap_free_result (int result_identifier) Zwraca ldap_get_attributes Zwraca wszystkie dane pozycji w postaci wielowymiarowej tablicy lub w przypadku wystąpienia błędu. atrybuty również mogą być czytane po kolei z określonej pozycji. Nigdy nie należy porównywać tekstu komunikatów błędów. Funkcja ldap_get_attribues() używana jest w celu uproszczenia odczytywania atrybutów i wartości z pozycji znajdującej się w wyniku. nawet przetłumaczone. czy bez. Pozycje w wyniku LDAP mogą być czytane sekwencyjnie przy użyciu funkcji ldap_first_entry() i ldap_next_entry(). Zwracaną wartością jest wielowymiarowa tablica atrybutów i wartości. Pozostałe atrybuty mogą być odczytane za pomocą kolejnych wywołań ldap_next_attribute(). różne biblioteki zwracają różne. gdy nie znamy struktury określonych atrybutów. int ldap_first_entry (int link_identifier. Aby otrzymać RDN z wartością (to znaczy w postaci atrybut=wartość) należy ustawić $with_attrib na 0.zestandaryzowane. aby zmniejszyć ilość pamięci zużywaną przez skrypt. Cała pamięć zajmowana przez wynik jest automatycznie zwalniana po zakończeniu skryptu. które powodują powstanie dużych wyników można wywołać funkcję ldap_free_result(). Struktura tabeli jest następująca: Dodatek A . zamiast tego zawsze należy używać do porównania numerów błędów. Patrz również: ldap_get_entries(). Każda z części nazywana jest Relative Distinguished Name (RDN). int with_attrib) ldap_first_attribute Zwraca pierwszy atrybut pozycji lub False w przypadku błędu. Podobnie do odnośnych pozycji. Identyfikator ten przekazywany jest do funkcji ldap_next_entry() w celu odczytania kolejnych pozycji wyniku. int result_identifier) ldap_free_result w przypadku powodzenia operacji lub False w przypadku błędu. Parametr $ber_identifier jest identyfikatorem wewnętrznego wskaźnika pamięci.Funkcje 288 . int result_entry_identifier. Funkcja ldap_explode_dn() zwraca tablicę zawierającą wszystkie te części. Można wykorzystać tą funkcje do napisania aplikacji za pomocą której można przeglądać pozycje katalogu nawet. string ldap_first_attribute (int link_identifier. Po odszukaniu odpowiedniej pozycji w katalogu możesz za pomocą takiego wywołania odczytać wszystkie informacje przechowywane w tej pozycji.ini lub nie będziesz poprzedzał funkcji LDAP znakiem @. na pojedyncze komponenty. Ten sam $ber_identifier jest przekazywany do ldap_next_attribute(). Patrz również: ldap_get_attributes(). należy ustawić go na 1. False. tekstowe opisy błędów. string ldap_error (int link_id) ldap_explode_dn Funkcja używana do podziału ciągu DN zwracanego przez funkcję ldap_get_dn(). Jest on przekazywany przez referencję. Za pomocą parametru $with_attrib można zdecydować. W przypadku.

return_value["count"] = ilość wartości atrybutu return_value[0] = pierwsza wartość atrybutu return_value[i] = i-ta wartość atrybutu array ldap_get_values (int link_identifier." atrybutów w tej pozycji:<p>". W aplikacji można na stałe zapisać nazwy interesujących nas atrybutów (na przykład surname lub mail). Pierwszy indeks ma wartość 0. Funkcja wymaga identyfikatora pozycji wyniku. Patrz również: ldap_first_attribute() i ldap_next_attribute(). string attribute) Przykład: Lista wszystkich wartości atrybutu ‘mail’ dla pozycji katalogu // $ds jest identyfikatorem połączenia z katalogiem // $sr jest prawidłowym wynikiem pochodzącym z 289 PHP – Kompendium wiedzy . więc musi być poprzedzona przez jedną z funkcji wyszukujących i jedno z wywołań pobierających poszczególne pozycje. False w przypadku błędu. return_value["count"] = ilość pozycji w wyniku return_value[0] : szczegóły pierwszej pozycji return_value[i]["dn"] = DN i-tej pozycji w wyniku return_value[i]["count"] = ilość atrybutów w i-tej pozycji return_value[i][j] = j-ty atrybut i-tej pozycji w wyniku return_value[i]["atrybut"]["count"] = ilość wartości dla atrybutów i-tej pozycji return_value[i]["atrybut"][j] = j-ta wartość atrybutu na i-tej pozycji array ldap_get_entries (int link_identifier. więc można na przykład zapamiętywać kilka adresów e-mail w pozycji katalogu zawierającej określoną osobę. Funkcja ldap_get_entries() używana jest w celu uproszczenia odczytywania wielu pozycji z wyniku i następnie odczytywanie atrybutów i wielokrotnych wartości. Struktura tablicy jest następująca. Indeksy atrybutów są konwertowane do małych liter (wielkość liter w atrybutach ma znaczenie dla serwerów katalogów. ale nie gdy są używane jako indeksy tablicy). Pozycja jest określona przez $result_entry_identifier. ldap_get_dn Zwraca DN pozycji wyniku lub sprawdzenia DN pozycji wyniku. for ($i=0. int result_entry_identifier) ldap_get_entries Zwraca wszystkie dane pozycji w postaci wielowymiarowej tablicy lub w przypadku wystąpienia błędu."<br>". $i<$attrs["count"]. $attrs = ldap_get_attributes($ds. Poszczególne wartości mogą być odczytane poprzez numeryczne indeksy tablicy. $sr). spod indeksu count. $entry). Funkcja ldap_get_values() jest używana do odczytania wszystkich wartości atrybutów z pozycji wyniku. LDAP pozwala na przechowywanie więcej niż jednej pozycji dla atrybuty. $i++) echo $attrs[$i]. Ilość wartości można odczytać z wynikowej tablicy. Wszystkie dane są zwracane za pomocą jednego wywołania funkcji we wielowymiarowej tablicy. można również użyć funkcji ldap_get_attributes() do sprawdzenia jakie atrybuty istnieją dla danej pozycji. int result_entry_identifier) Przykład: Wyświetlenie listy atrybutów przechowywanych w pozycji katalogu // $ds jest identyfikatorem połączenia z katalogiem // $sr jest prawidłowym wynikiem pochodzącym z // wywołania jednej z funkcji przeszukujących $entry = ldap_first_entry($ds. int result_entry_identifier. echo $attrs["count"].return_value["count"] = ilość atrybutów w pozycji return_value[0] = pierwszy atrybut return_value[n] = n-ty atrybut return_value["atrybut"]["count"] = ilość wartości atrybutu return_value["atrybut"][0] = pierwsza wartość atrybutu return_value["atrybut"][i] = i-ta wartość atrybutu array ldap_get_attributes (int link_identifier. Funkcja ldap_get_dn() jest używana do string ldap_get_dn (int link_identifier. int result_identifier) ldap_get_values Zwraca tablicę wartości atrybutu lub False w przypadku wystąpienia błędu. False.

Struktura pozycji jest identyczna jak ldap_add(). $i<$info["count"]. for ($i=0."mail"). for ($i=0. int sizelimit [. string dn. Funkcja dodaje atrybut do podanego $dn. $timelimit i $deref zostały dodane w PHP 4. Indeksy zaczynają się od 0. ldap_modify Zwraca True w przypadku powodzenia operacji lub False w przypadku błędu. int deref]]]]]) Przykład: Utworzenie listy wszystkich jednostek organizacyjnych w organizacji // $ds jest identyfikatorem połączenia do serwera katalogu $basedn = "o=My Company. że przeszukiwany zostanie tylko poziom bezpośrednio po podanym bazowym DN podanym w wywołaniu funkcji (ekwiwalent wpisania ls i pobrania naw plików i folderów w bieżącym katalogu). Wykonuje zmianę na poziomie atrybutu a nie na poziomie obiektu. echo $values["count"].// wywołania jednej z funkcji przeszukujących // $entry jest idnetyfikatorem pozycji pochodzącym z // jednego z wywołań zwracających pozycje katalogu $values = ldap_get_values($ds. int timelimit [. $sr). lub False w przypadku wystąpienia błędu. Ilość wartości można odczytać z indeksu count wynikowej tablicy. $i++) echo $values[$i]. Dodawanie na poziomie obiektu wykonywane jest za pomocą funkcji ldap_add(). int attrsonly [. string attribute) Zwraca tablicę ldap_list Zwraca identyfikator wyniku poszukiwania. $sizelimit.<p>". string base_dn.0. string dn. $i++) echo $info[$i]["ou"][0] . "ou=*". int ldap_list (int link_identifier. Opis znajduje się przy omawianiu funkcji ldap_search().0. int result_entry_identifier. array ldap_get_values_len (int link_identifier. array attributes [. Poszczególne wartości są dostępne w tablicy pod indeksami całkowitymi. ldap_get_values_len() Uwaga Funkcja została dodana w PHP 4. ldap_get_values_len wartości atrybutu lub False w przypadku wystąpienia błędu. Zasięg LDAP_SCOPE_ONELEVEL oznacza. array entry) ldap_mod_add Zwraca True w przypadku powodzenia operacji lub False w przypadku błędu. Funkcji tej używa się identycznie jak ldap_get_values(). string filter [.Funkcje 290 . $basedn. $entry. Funkcja posiada 5 parametrów opcjonalnych. c=US". $info = ldap_get_entries($ds.2. int ldap_mod_add (int link_identifier. $i < $values["count"]. Funkcja ldap_modify() używana jest do zmiany istniejących pozycji w katalogu LDAP."<br>". $sr=ldap_list($ds. int ldap_modify (int link_identifier. Uwaga Parametry opcjonalne $attrsonly. Pozycja jest określona przez $result_entry_identifier. array entry) Dodatek A . $justthese). $justthese = array("ou"). ale obsługuje dane binarne a nie ciągi." adresów email dla tej pozycji. Funkcja używana jest do odczytania wszystkich wartości atrybutu dla pozycji wyniku. Funkcja ldap_list() przeszukuje katalog w poszukiwaniu wartości pasujących do podanego filtra z zastosowaniem zasięgu LDAP_SCOPE_ONELEVEL.

$timelimit i $deref zostały dodane w PHP 4. Funkcja usuwa atrybut do podanego $dn. Funkcja jest wywoływana w celu odczytania atrybutów pozycji. string dn. można wykorzystać odpowiedni filtr. Wykonuje zmianę na poziomie atrybutu a nie na poziomie obiektu. Patrz również: ldap_get_entries(). Pierwsze wywołanie ldap_next_entry() jest wykonywane z identyfikatorem wyniku zwróconym przez ldap_first_entry(). Dostępny jest czwarty parametr opcjonalny. Funkcja ldap_search() szuka podanego filtra w katalogu. int ldap_mod_replace (int link_identifier. Patrz również: ldap_get_atributes(). Jeżeli wiesz. int ldap_mod_del (int link_identifier. Jeżeli nie ma już kolejnych pozycji w wyniku. int sizelimit [. który pozwala ograniczyć ilość zwracanych atrybutów i wartości. Jeżeli chcesz odczytać wszystkie dane z tej pozycji należy użyć filtra objectClass=*. string dn. Jest to ekwiwalent przeszukania zawartości katalogu. na przykład objectClass=inetOrgPerson. Użycie tego parametru powinno 291 PHP – Kompendium wiedzy . Jest on przekazywany do funkcji przez referencję. int ber_identifier) Zwraca ldap_next_entry Zwraca identyfikator pozycji dla następnej pozycji w wyniku. Funkcja ldap_next_entry() używana jest do odczytania pozycji znajdujących się w wyniku. array entry) ldap_next_attribute kolejny atrybut w pozycji lub False w przypadku wystąpienia błędu. Wykonuje zmianę na poziomie atrybutu a nie na poziomie obiektu. Nie jest dozwolone używanie pustego filtra. którego pierwsza pozycja została odczytana za pomocą ldap_first_entry(). więc jest odpowiednikiem odczytania pozycji z katalogu. Funkcja szuka filtra w katalogu z zakresie LDAP_SCOPE_BASE. int deref]]]]]) ldap_search Zwraca identyfikator wyniku przeszukiwania lub False w przypadku błędu. funkcja zwraca False. Funkcja zamienia atrybut(y) z podanego $dn. int timelimit [. array entry) ldap_mod_replace Zwraca True w przypadku powodzenia operacji lub False w przypadku błędu. z zastosowaniem zasięgu LDAP_SCOPE_SUBTREE. ldap_read() Uwaga Parametry opcjonalne $attrsonly. int ldap_read (int link_identifier. int result_entry_identifier) ldap_read Zwraca identyfikator wyniku przeszukiwania lub False w przypadku wystąpienia błędu. Pierwsze wywołanie ldap_next_identifier() jest wykonywane z $result_entry_identifier zwracanym przez ldap_first_identifier(). Kolejne wywołania ldap_next_entry() powoduje zwracanie kolejnych pozycji aż do ich wyczerpania.2. int result_entry_identifier. array attributes [. $sizelimit. Parametr $base_dn określa bazowy DN w katalogu. int attrsonly [. string base_dn. Modyfikacje na poziomie obiektu wykonywane jest za pomocą funkcji ldap_modify(). Usuwanie na poziomie obiektu wykonywane jest za pomocą funkcji ldap_del(). Opis znajduje się przy omawianiu funkcji ldap_search().ldap_mod_del Zwraca True w przypadku powodzenia operacji lub False w przypadku błędu. jaki typ pozycji jest użyty w serwerze katalogu. ldap_next_attribute() string ldap_next_attribute (int link_identifier. Funkcja posiada pięć parametrów opcjonalnych.0. int ldap_next_entry (int link_identifier. Stan wewnętrznego wskaźnika jest utrzymywany przez $ber_identifier. string filter [.

wskazuje na sposób obsługi aliasów w czasie szukania. $justthese = array( "ou". Jeżeli wystąpi taka sytuacja. gdy ustawiony zostanie szósty parametr $sizelimit ograniczający ilość pobieranych pozycji.być traktowane jako dobrą praktykę programistyczną. string base_dn. Należy pamiętać.htm). $timelimit i $deref zostały dodane w PHP 4. "givenname".2.com/docs/manuals/directory/41/ag/find. ale może go zmniejszyć. c=US". $dn. ale może go zmniejszyć. Ustawienie tego parametru na 0 powoduje zniesienie limitu. Czwarty parametr jest zwykłą tablicą ciągów zawierających wymagane atrybuty. int ldap_unbind (int link_identifier) False w przypadku błędu. Przykład: Przeszukiwanie LDAP // $ds jest identyfikatorem połączenia z katalogiem // $person jest kompletną nazwą lub jej częścią np: "Jo" $dn = "o=Firma. że niektóre serwery katalogów są tak skonfigurowane. array attributes [. int deref]]]]]) Piąty parametr $attrsonly powinien być ustawiony na 1. nazwisko. Uwaga DN jest zawsze zwracany niezależnie od typów żądanych typów atrybutów.: Netscape Directory SDK pod adresem http://developer." pozycji w wyniku<p>". int ldap_search (int link_identifier. Ósmy parametr. imię i e-mail wszystkich osób w firmie „Firma”. $sizelimit. Za pomocą szóstego parametru. Funkcja ldap_unbind() Dodatek A . Jest to ustawienie domyślne. int sizelimit [. $deref. int attrsonly [. $sr=ldap_search($ds. Może przyjmować następujące wartości: • LDAP_DEREF_NEVER — (domyślny) aliasy nie są rozwijane • LDAP_DEREF_SEARCHING — aliasy są rozwijane w czasie szukania. $timelimit. "cn"). Jeżeli ustawiony jest na 0. Przykład ten wykorzystuje filtry logiczne nakazujące serwerowi poszukiwanie danych we większej ilości atrybutów. ale nie w czasie określania podstawowych obiektów przeszukiwania • LDAP_DEREF_FINDING — aliasy są rozwijane w czasie określania podstawowych obiektów przeszukiwania. Uwaga Parametr ten nie może zwiększyć limitu ustawionego na serwerze. których nazwiska zawierają ciąg określony przez zmienną $person. $sr). pobierane są zarówno atrybuty jak i ich wartości. "sn". Uwaga Parametr ten nie może zwiększyć limitu ustawionego na serwerze. Występuje to również. serwer wskazuje. aby zwracać nie więcej. można ograniczyć ilość pobieranych pozycji. na przykład: array( "mail".netscape. ldap_unbind Zwraca True w przypadku powodzenia operacji lub odłącza od katalogu LDAP. print $info["count"]. string filter [. int timelimit [. Siódmy parametr. Filtry przeszukiwania mogą być proste lub zaawansowane z wykorzystaniem operatorów logicznych w formacie opisanym w dokumentacji LDAP (np. "mail"). $info = ldap_get_entries($ds. jeżeli potrzebujemy jedynie atrybutu. $justthese). niż skonfigurowaną ilość pozycji. ale nie w czasie szukania • LDAP_DEREF_ALWAYS — aliasy są zawsze rozwijane Parametry opcjonalne $atrsonly. ogranicza czas przeszukiwania katalogu do podanej liczby sekund. że zwraca jedynie częściowy wynik. $filter. $sizelimit. Poniższy przykład odczytuje jednostkę organizacyjną.Funkcje 292 . $filter="(|(sn=$person*)(givenname=$person*))".0.

Użycie funkcji użytkownika pozwala na możliwość wzięcia pod uwagę różnicy pomiędzy znakami lub nawet kontekstu. int cost_rep. która ma złożoność O(max(n.leak Powoduje „wyciek” określonej ilości pamięci. Jednak wywoływanie tej funkcji do obliczenia kosztu każdej operacji. string str2. Będzie wywoływał funkcję napisaną przez użtkownika. Funkcja ta używana jest do sprawdzania. zamiany i usunięcia. Patrz również: soundex(). link Tworzy trwałe łącze. będzie najbardziej ogólny. Funkcja użytkownika posiadać musi następujące parametry: • operacja do wykonania: I. similar_text() i metaphone(). string str2. powoduje utratę wszystkich optymalizacji użycia rejestrów procesora i pamięci podręcznej. czy łącze (wskazywane przez $path) istnieje (wykorzystując metodę 293 PHP – Kompendium wiedzy . który jeszcze nie został zaimplementowany. Algorytm ten ma złożoność O(m*n). gdzie m i n są długością ciągów $str1 i $str2 (całkiem nieźle w porównaniu do similar_text(). R lub D • bieżący znak w ciągu 1 • bieżący znak w ciągu 2 • pozycja w ciągu 1 • pozycja w ciągu 2 • pozostałe znaki w ciągu 1 • pozostałe znaki w ciągu 2 Funkcja napisana przez użytkownika musi zwracać liczbę dodatnią oznaczającą koszt bieżącej operacji. ale również najwolniejszy. void leak (int bytes) levenshtein Zwraca odległość Levenshtein pomiędzy dwoma ciągami przekazanymi jako argumenty lub -1 gdy jeden z ciągów jest dłuższy niż 255 znaków (255 powinno wystarczyć do porównywania nazwisk lub katalogów a nikt rozsądny nie będzie wykonywał analizy genetycznej za pomocą PHP). Patrz również: linkinfo(). po zakończeniu każdego żądania. Jest to przydatne przy testowaniu zarządcy pamięci. int cost_del) int levenshtein (string str1. function cost) W swojej najprostszej postaci funkcja wymaga jedynie dwóch ciągów jako parametry i oblicza ilość operacji wstawienia. w jakim występują w ciągu. Uwaga Funkcja ta nie działa w systemie Windows int link (string target. ale do tego celu może używać tylko niektórych z przekazanych argumentów. zamiany lub usunięcia potrzebnych do zamiany $str1 na $str2. aby zamienić $str1 na $str2. string link) symlink() do tworzenia łącz symbolicznych oraz readlink() i linkinfo Zwraca pole st_dev ze struktury stat zwracanej przez funkcję systemową lstat w systemie UNIX. Jest to bardziej ogólny i adaptowalny wariant funkcji. Drugi wariant potrzebuje trzech dodatkowych paramterów definiujących koszt operacji wstawienia. ale nie jest on tak wydajny. string str2) int levenshtein (string str1.m)**3). ale i tak jest to kosztowny algorytm) int levenshtein (string str1. Odległość Levenshtein jest definiowana jako minimalna ilość znaków jakie trzeba zamienić. wstawić lub usunąć. który automatycznie odzyskuje pamięć utraconą po „wycieku”. która będzie zwracała koszt każdej operacji. Trzeci wariant. int cost_ins. które są zastosowane w poprzednich dwóch wariantach.

h). " </tr>\n"). array localtime ([int timestamp [. Zwraca 0 w przypadku powodzenia lub ujemny kod błędu w przypadku niepowodzenia. salary FROM employees"). bool is_associative]]) Nazwy kluczy w tablicy asocjacyjnej są: • tm_sec — sekundy • tm_min — minuty • tm_hour — godziny • tm_mday — dzień miesiąca • tm_mon — miesiąc w roku • tm_year — rok. void list (. nie jest zgodny z rokiem 2000 • tm_wday — dzień tygodnia • tm_yday — dzień kolejny w roku • tm_isdst — czy zastosowano czas zimowy Dodatek A . int listen (resource socket. Kolejkowane i przetwarzane będzie $backlog połączeń. ale konstrukcją języka. Jeżeli nie zostanie podany.. użyty zostanie bieżący czas. Patrz również: symlink(). Jeżeli argument ten zostanie ustawiony na 1. zwracana tablica jest zwykłą tablicą z indeksami numerycznymi.. int backlog) localtime Zwraca tablicę identyczną ze strukturą zwracaną przez tą samą funkcję w C. socket().Funkcje 294 . Kod ten może być przekazany do strerror() w celu otrzymania tekstu opisującego błąd.php3?id=$id\">$name</a></td>\n". Patrz również: socket_connect().zdefiniowaną w makro S_ISLNK z pliku stat. Uwaga Funkcja ta nie działa w systemie Windows int linkinfo (string path) list Podobnie jak array() nie jest prawdziwą funkcją. "SELECT id. socket_get_status() i strerror(). localtime() zwróci tablicę asocjacyjną zawierającą wszystkie elementy struktury zwracanej przez wywołanie funkcji localtime() w C. Jeżeli jest ustawiony na 0 lub nie zostanie podany. można za pomocą funkcji listen() nakazać nasłuchiwanie przychodzących połączeń. connect(). name. przypisywania wartości do listy zmiennych przy pomocy jednej operacji. Zwraca 0 lub False w przypadku błędu. Drugi argument to $is_associative. link() i readlink(). } ?> </table> Patrz również: each() i array(). while (list ($id. " <td><a href=\"info. bind(). $name.) list() jest używane do Przykład: list() <table> <tr> <th>Nazwisko pracownika</th> <th>Pensja</th> </tr> <?php $result = mysql_query ($conn. Funkcja listen() działa jedynie na gniazdach o typie SOCK_STREAM lub SOCK_SEQPACKET. listen Po utworzeniu gniazda $socket za pomocą funkcji socket() i przyłączeniu go za pomocą bind(). $salary) = mysql_fetch_row ($result)) { print (" <tr>\n". " <td>$salary</td>\n". Pierwszym argumentem localtime() jest znacznik czasu.

\v. że gdy parametr $filename jest łączem symbolicznym. Szczegóły zostały opisane przy funkcji clearstatcache().bbb. float log (float arg) log10 Zwraca logarytm o podstawie 10 z $arg.log Zwraca logarytm naturalny z $arg. jeżeli rozmiar w bajtach jest to urządzenie z i-node * czas ostatniej czas ostatniej zmiany modyfikacji identyfikator grupy czas ostatniego dostępu rozmiar bloku dla operacji wejścia-wyjścia systemu plików * tryb zabezpieczenia i- ilość przydzielonych bloków * dostępne tylko na systemach obsługujących typ st_blksize — inne systemy (na przykład Windows) zwracają -1.ddd) na podstawie właściwej reprezentacji adresu. string additional_headers [. Jest on zwykle używany do wstawiania do wiadomości dodatkowych nagłówków. Wyniki tej funkcji są przechowywane w buforze. \0 oraz spacja. zwracany jest stan łącza a nie status pliku. Można podać wielu Przykład: wysyłanie poczty mail("rasmus@lerdorf. bool mail (string to. string additional_parameters]]) $to. string long2ip (int proper_address) lstat Zbiera statystyki pliku lub łącza symbolicznego o podanej nazwie. "Temat". na który wskazuje łącze. string message [. ltrim Usuwa znaki odstępu z początku ciągu i zwraca obcięty ciąg. Jeżeli zostanie przekazany czwarty argument ciąg ten jest wstawiany na końcu nagłówka.on. \t. PHP – Kompendium wiedzy 295 . Obsługiwanymi znakami odstępu są: \n. Patrz również: chop() i trim(). array lstat (string filename) Zwraca tablicę ze statystykami następujących parametrów pliku: urządzenie liczba dowiązań i-node node identyfikator właściciela typ urządzenia. Kolejne wiersze nagłówka muszą być rozdzielone znakiem nowego wiersza. string subject. string charlist]) mail Wysyła wiadomość pocztową o treści przekazanej w $message do odbiorcy w odbiorców umieszczając średnik pomiędzy adresami przekazanymi w parametrze $to. \r.ccc. "Linia 1\nLinia 2\nLinia 3"). string ltrim (string str [.ca". Funkcja jest podobna do stat() poza tym. float log10 (float arg) long2ip Generuje adres internetowy w postaci z kropkami (aaa.

// CC $headers .= "Przypominacz urodzin oddany do publicznego używania". usuń komentarz z poniższej linii */ // $headers . funkcja wymaga co najmniej dwóch parametrów i zwraca największy z nich. wszystkie wartości są traktowane jako double i zwracana jest liczba typu double. string calendar) mcal_date_compare Porównuje dwie podane daty. Można porównywać nieograniczoną ilość wartości. ciągiem lub liczbą double.= "3 \t\tSierpień \t\t1970\n". $message .Funkcje 296 .com". //Separator sygnaturki $message . int a_day.= "Dzień \t\tMiesiąc \t\tRok\n". */ $headers . $message.net\n". Zwraca <0. Zwraca identyfikator wstawionego zdarzenia. ". // wiadomość ważna! $headers . /* dodatkowe fragmenty nagłówka. // Typ mime $headers . //zwróć uwagę na przecinek $recipient . ".= "Return-Path: <birthday@php.= "Content-Type: text/html. Jeżeli pierwszy parametr jest tablicą. int a_month. Jeżeli żadna z wartości nie jest liczbą double. " . max Zwraca parametr o największej wartości numerycznej.= "--\r\n". >0 gdy a<b. $headers).net>\n". int b_year. mixed arg2.college.= "Kelly <kelly@u. Jeżeli pierwszy parametr jest liczbą całkowitą. $message. int b_day) Dodatek A . $recipient . 0. Przykład: Wysyłanie skomplikowanych przesyłek e-mail /* odbiorcy */ $recipient . $headers . phpversion()). int mcal_append_event (int mcal_stream) mcal_close Zamyka podany strumień MCAL. "Temat". /* można dodać sygnaturkę */ $message .= "bcc: birthdaycheck@php. $subject.= "X-Sender: <birthday@php. From cc.Przykład: Wysyłanie wiadomości z dodatkowymi nagłówkami mail("nobody@aol. int flags) mcal_create_calendar Tworzy nowy kalendarz o nazwie $calendar.net". // klient poczty $headers .= "From: Pzrypominacz urodzin <birthday@php. bcc. mixed argn) mcal_append_event Zapamiętuje globalne zdarzenie w kalendarzu MCAL.= "X-Mailer: PHP\n".net". dla podanego strumienia. $message . Można również stosować proste techniki budowania ciągów do tworzenia całkiem skomplikowanych wiadomości e-mail.= "Mary <mary@u. "From: webmaster@$SERVER_NAME\nReply-To: webmaster@$SERVER_NAME\nX-Mailer: PHP/" . itp.college.net>\n". // BCC /* wyślij wiadomość */ mail($recipient. int b_month. birthdaygifts@php. $message . /* wiadomość */ $message . int mcal_date_compare (int a_year. $headers .net>\n".= "17\t\tSierpień \t\t1973\n". int mcal_close (int mcal_stream.= "Wiadomość zawiera tabelę sformatowaną za pomocą znaków ASCII\n".edu>" .edu>" . charset=iso-8859-1\n".= "ronabop@php. string mcal_create_calendar (int stream. Jeżeli jedna lub więcej wartości jest liczbą double. a>b. wszystkie są traktowane jako liczby całkowite i również zwracana jest liczba całkowita.net. max() zwraca największą wartość w tablicy. /* temat */ $subject = "Przypomnienie o urodzinach w sierpniu". // ścieżka zwrotna dla błedów /* jeżeli chcez wysłać pocztę HTML. ".= "cc: birthdayarchive@php.= "X-Priority: 1\n". mixed max (mixed arg1. a==b.

gdy nie jest to data int mcal_date_valid (int year. czy rok jest przestępny czy nie. Zwraca True. int mcal_delete_event (int mcal_stream [. int day) mcal_delete_calendar Usuwa kalendarz o nazwie $calendar. string attribute. miesiąc i dzień jest prawidłową datą lub False. int mcal_ (int year. Zwraca True. int mcal_event_set_category (int stream. string category) mcal_event_set_class Ustawia klasę globalnej struktury zdarzenia na podaną wartość. int event_id]) mcal_event_add_attribute Dodaje do globalnej struktury zdarzeń strumienia atrybut o wartości przekazanej w parametrze $value. Zwraca True. string calendar) mcal_delete_event Usuwa zdarzenie kalendarza wskazywane przez $event_id. Zwraca True. int month. jeżeli podany rok. Zwraca True. Klasa może mieć wartość lub 0 — prywatna. int day) mcal_day_of_year Zwraca dzień w roku dla podanej daty. int mcal_day_of_week (int year. 297 1 — publiczna PHP – Kompendium wiedzy . int day) mcal_days_in_month Zwraca ilość dni w podanym miesiącu biorąc pod uwagę. int mcal_event_init (int stream) mcal_event_set_alarm Ustawia alarm w globalnej strukturze strumienia na podaną liczbę minut przed zdarzeniem. int mcal_days_in_month (int month. int leap year) mcal_day_of_week Zwraca dzień tygodnia dla podanej daty.mcal_date_valid Zwraca prawidłowa. string mcal_delete_calendar (int stream. int mcal_event_set_alarm (int stream. int month. int month. True. void mcal_event_add_attribute (int stream. Powoduje to ustawienie wszystkich elementów struktury na 0 lub na wartość domyślną. int alarm) mcal_event_set_category Ustawia kategorię globalnej struktury zdarzenia na podany ciąg. string value) mcal_event_init Inicjuje globalną strukturę strumienia.

int mcal_event_set_end (int stream. int class) mcal_event_set_description Ustawia opis globalnej struktury zdarzenia na podaną wartość. int mcal_event_set_recur_yearly (int stream.int mcal_event_set_class (int stream. int day [. int mcal_event_set_recur_monthly_mday (int stream. int hour Dodatek A . kończące się na podanej dacie. kończące się na podanej dacie. int interval) mcal_event_set_recur_none Wyłącza powtarzanie w globalnej strukturze zdarzenia (event->recur_type jest ustawiane na MCAL_RECUR_NONE). int year. Zwraca True. int mcal_event_set_description (int stream. int weekdays) mcal_event_set_recur_yearly Ustawia wartość powtarzania w globalnej strukturze zdarzenia na podaną coroczne powtarzanie. int hour [. int mcal_event_set_recur_none (int stream) mcal_event_set_recur_weekly Ustawia wartość powtarzania w globalnej strukturze zdarzenia na podaną cotygodniowe powtarzanie. kończące się na podanej dacie. int day. int min [. int year. string description) mcal_event_set_end Ustawia datę i czas zakończenia w globalnej strukturze zdarzenia na podaną wartość. int day. int mcal_event_set_recur_monthly_wday (int stream. int day [. int month. int year. int month. int sec]]]]) mcal_event_set_recur_daily Ustawia wartość powtarzania w globalnej strukturze zdarzenia na podaną codzienne powtarzanie kończące się na podanej dacie. int interval) mcal_event_set_recur_monthly_wday Ustawia wartość powtarzania w globalnej strukturze zdarzenia na podaną comiesięczne powtarzanie opierając się na tygodniu. int year. int interval) mcal_event_set_recur_monthly_mday Ustawia wartość powtarzania w globalnej strukturze zdarzenia na podaną comiesięczne powtarzanie opierając się na dniu miesiąca. int day. int month [. int month. Zwraca True. int month. int month. int year. int mcal_event_set_recur_weekly (int stream.Funkcje 298 . int interval) mcal_event_set_start Ustawia datę i czas rozpoczęcia w globalnej strukturze zdarzenia na podaną wartość. int year. int year. int day. kończące się na podanej dacie. int interval. int day. Zwraca True. int mcal_event_set_recur_daily (int stream. int month [. int mcal_event_set_start (int stream.

string description — Ciąg z opisem zdarzenia. int mcal_expunge (int stream) mcal_fetch_current_stream_event object mcal_fetch_current_stream_event (int stream) • • • • • • • • • • • • • • • • • • • Zwraca bieżącą strukturę zdarzenia ze strumienia w postaci obiektu zawierający następujące atrybuty: int id — Identyfikator zdarzenia. int recur_data — Dane powtarzania. string category — Ciąg z kategorią zdarzenia. object mcal_fetch_event (int mcal_stream. object start — Obiekt zawierający początkową datę i czas. Wszystkie pozycje zawierające datę i czas są obiektem zawierającym: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy int alarm — ilość minut przed zdarzeniem kiedy należy wysłać przypomnienie mcal_fetch_event Pobiera zdarzenie ze strumienia kalendarza określonego przez $id. FALSE jeżeli jest prywatne. int recur_interval — Okres powtarzania. int alarm — Ilość minut przed zdarzeniem do wysłania alarmu lub przypomnienia. object end — Obiekt zawierający końcową datę i czas. string title — Ciąg z tytułem zdarzenia. string title) mcal_expunge Usuwa wszystkie zdarzenia oznaczone jako usunięte. string title — Ciąg z tytułem zdarzenia. string description — Ciąg z opisem zdarzenia. int recur_interval — Okres powtarzania. int public — TRUE jeżeli zdarzenie jest publiczne. int recur_type — Typ powtarzania. FALSE jeżeli jest prywatne. int public — TRUE jeżeli zdarzenie jest publiczne. int options]) • • • • • • • • • • 299 Zwraca obiekt zdarzenia zawierający następujące atrybuty: int id — Identyfikator zdarzenia. int alarm — Ilość minut przed zdarzeniem do wysłania alarmu lub przypomnienia. int sec]]]]) mcal_event_set_title Ustawia tytuł w globalnej strukturze zdarzenia na podany ciąg. string category — Ciąg z kategorią zdarzenia. int event_id [. int mcal_event_set_title (int stream. object start — Obiekt zawierający początkową datę i czas.[. datetime recur_enddate — Data zakończenia powtarzania. PHP – Kompendium wiedzy . Zwraca True. int recur_type — Typ powtarzania. object end — Obiekt zawierający końcową datę i czas. int min [.

int weekstart. int mcal_open (string calendar. Zwracana jest tablica identyfikatorów zdarzeń. string username. string password [. Jeżeli podany zostanie opcjonalny parametr $options. int begin_day [. int mcal_popen (string calendar. array mcal_list_events (int mcal_stream. funkcja przekazuje również ten parametr do skrzynki. funkcja przekazuje również ten parametr do skrzynki. Funkcja mcal_list_events() posiada opcjonalne parametry: datę początkowa końcową dla strumienia kalendarza. Po zestawieniu połączenia inicjowana jest również wewnętrzna struktura strumienia. int options]) mcal_popen Zwraca strumień MCAL lub False w przypadku błędu. int begin_month [. lub jeżeli podano tylko strumień. jeżeli zdarzenie nie wystąpi lub wystąpił błąd.• • • • • • • • • — Data zakończenia powtarzania. int options]) Dodatek A . int mcal_is_leap_year (int year) mcal_list_alarms Zwraca tablicę identyfikatorów zdarzeń. które są pomiędzy podanymi datami lub datami z wewnętrznej struktury zdarzeń.Funkcje 300 . 0 gdy nie jest. int end_year [. array mcal_list_alarms (int mcal_stream [. Funkcja mcal_open() otwiera połączenie MCAL do określonego kalendarza. string password [. int begin_year [. które posiadają ustawiony alarm pomiędzy datą początkową i końcową. int mcal_next_recurrence (int stream. lub jeżeli podano tylko strumień. objectbegin_date [. Funkcja mcal_list_alarms() posiada opcjonalne parametry: datę początkowa końcową dla strumienia kalendarza. object end_date]) mcal_next_recurrence Zwraca obiekt z kolejną datą wystąpienia zdarzenia po podanej dacie. int end_month [. Jeżeli podany zostanie opcjonalny parametr $options. array next) mcal_open Zwraca strumień MCAL lub False w przypadku błędu. Wszystkie pozycje zawierające datę i czas są obiektem zawierającym: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy int alarm — ilość minut przed zdarzeniem kiedy należy wysłać przypomnienie datetime recur_enddate mcal_is_leap_year Zwraca 1 gdy podany rok jest przestępny. używane są daty z globalnej struktury zdarzeń. Po zestawieniu połączenia inicjowana jest również wewnętrzna struktura strumienia. string username. int recur_data — Dane powtarzania. Używa parametru $weekstart do określenia dnia rozpoczynającego tydzień. używane są daty z globalnej struktury zdarzeń. int end_day]]]]]]) mcal_list_events Zwraca tablicę identyfikatorów zdarzeń występujących pomiędzy datą początkową i końcową. Zwraca puste pole daty. Funkcja mcal_open() otwiera połączenie MCAL do określonego kalendarza. Zwracana jest tablica identyfikatorów zdarzeń. które mają alarm pomiędzy podanymi datami lub datami z wewnętrznej struktury zdarzeń.

mcal_rename_calendar Zmienia nazwę kalendarza z $old_name na $new_name. int mcal_store_event (int mcal_stream) True w mcal_time_valid Zwraca True. funkcja przekazuje również ten parametr do skrzynki. $Data to dane do zaszyfrowania lub odszyfrowania. Patrz również: mcrypt_cbc().x. $Key jest kluczem przekazywanym do algorytmu. mcrypt_ecb() i mcrypt_ofb(). $IV jest opcjonalnym wektorem inicjalizacji. string key. $IV jest opcjonalnym wektorem inicjalizacji. $Cipher 301 PHP – Kompendium wiedzy . int mode [. $Mode to MCRYPT_ENCRYPT lub MCRYPT_DECRYPT. $Cipher mcrypt_cfb Pierwszy prototyp jest dla przypadku. string key. string iv]) jest jedną ze stałych MCRYPT_ciphername. string mcal_rename_calendar (int stream. string iv]) jest jedną ze stałych MCRYPT_ciphername.4. int mode. Patrz również: mcrypt_cfb(). string iv]) string mcrypt_cbc (string cipher. Jeżeli podany zostanie opcjonalny parametr $options. Funkcja mcrypt_cfb() szyfruje i deszyfruje (w zależności od trybu) dane $data za pomocą $cipher i $key w trybie szyfrowania CFB i zwraca wynikowy ciąg. Funkcja mcrypt_cbc() szyfruje i deszyfruje (w zależności od trybu) dane $data za pomocą $cipher i $key w trybie szyfrowania CBC i zwraca wynikowy ciąg. minuta i sekunda tworzą prawidłowy czas. drugi gdy libmcrypt 2. string key.4. Musi być tajny. string data. gdy dołączona jest biblioteka libmcrypt 2.2. string key. int mode [. $Key jest kluczem przekazywanym do algorytmu. string iv) string mcrypt_cfb (string cipher. drugi gdy libmcrypt 2. nieprawidłowy. int minutes. string data. Musi być tajny. string old_name. $Data to dane do zaszyfrowania lub odszyfrowania.x. int mcal_reopen (string calendar [.x. • • • • • string mcrypt_cfb (int cipher. int options]) mcal_snooze Wyłącza alarm dla kalendarza o podanym identyfikatorze. int mcal_snooze (int id) mcal_store_event Zapamiętuje zmiany w bieżącym globalnym zdarzeniu dla podanego strumienia. string data. $Mode to MCRYPT_ENCRYPT lub MCRYPT_DECRYPT. int mcal_time_valid (int hour. mcrypt_ecb() i mcrypt_ofb(). string data. jeżeli podana godzina. Zwraca True. gdy dołączona jest biblioteka libmcrypt 2. int mode [.2. Zwraca przypadku powodzenia a False w przypadku błędu.x. int seconds) False gdy jest to czas mcrypt_cbc Pierwszy prototyp jest dla przypadku. string new_name) mcal_reopen Funkcja mcal_reopen() ponownie otwiera połączenie MCAL do określonego kalendarza. • • • • • string mcrypt_cbc (int cipher.

OFB oraz w niektórych algorytmach dla trybu STREAM. $block_size = mcrypt_get_block_size ($cipher). $iv = mcrypt_create_iv ($block_size. string data. string key. $Cipher Dodatek A . Jeżeli jest mniejszy od wymaganej wielkości klucza. nofb lub stream. string iv]) jest jedną ze stałych MCRYPT_ciphername. dane będą dopełnione znakami \0. drugi gdy libmcrypt 2.2. że wywołałeś srand() przed inicjalizacją generatora liczb losowych. mcrypt_ecb() i mcrypt_ofb(). mcrypt_cfb() i mcrypt_ofb(). string mode [. string data.x. $Mode to jedna ze stałych MCRYPT_MODE_modename która może być: ecb. Jeżeli używasz MCRYPT_RAND. • • • • • string mcrypt_decrypt (string cipher. MCRYPT_DEV_RANDOM (odczytanie danych z /dev/random) lub MCRYPT_DEV_URANDOM (odczytanie danych z /dev/urandom). gdy jest on wymagany przez algorytm. string mcrypt_create_iv (int size. funkcja wypisze ostrzeżenie i użyje IV z wszystkimi bajtami ustawionymi na \0. Patrz również mcrypt_cbc(). $Mode to jedna ze stałych MCRYPT_MODE_modename która może być: ecb. int source) Przykład: mcrypt_create_iv() <?php $cipher = MCRYPT_TripleDES. cbc. $size określa rozmiar IV. Funkcja mcrypt_ecb() szyfruje i deszyfruje (w zależności od trybu) dane $data za pomocą $cipher i $key w trybie szyfrowania CFB i zwraca wynikowy ciąg. cfb.mcrypt_create_iv Funkcja używana do tworzenia wektora IV. string key. nofb lub stream. $Data to dane do zaszyfrowania lub odszyfrowania. Jeżeli jest mniejszy od wymaganej wielkości klucza. Jeżeli nie podasz IV. Musi być tajny. ofb. $IV jest parametrem używanym do inicjalizacji dla trybów: CBC.4. ?> mcrypt_decrypt Pobiera dane zaszyfrowane i zwraca je w postaci odszyfrowanej.x. Jeżeli rozmiar danych nie jest n * blocksize. natomiast $source określa źródło IV. cfb. $Key jest kluczem przekazywanym do algorytmu. • • • • string mcrypt_encrypt (string cipher. • • • • • string mcrypt_ecb (int cipher. ofb. int mode [. $Data to dane do odszyfrowania za pomocą podanego szyfru i trybu. jest kluczem przekazywanym do algorytmu. string key. Zwracany zaszyfrowany ciąg może być dłuższy od danych przekazanych w parametrze $data. $Data to dane do zaszyfrowania za pomocą podanego szyfru i trybu. upewnij się. int mode) string mcrypt_ecb (string cipher. string mode [. MCRYPT_DEV_RANDOM). $IV jest opcjonalnym wektorem inicjalizacji. $Cipher $Key mcrypt_encrypt Szyfruje dane i zwraca ich zaszyfrowaną postać. string iv]) jest jedną ze stałych MCRYPT_ciphername. cbc. CFB. $Key jest kluczem przekazywanym do algorytmu. Źródłem może być MCRYPT_RAND (systemowy generator liczb losowych). string iv]) jest jedną ze stałych MCRYPT_ciphername. jest dopełniany znakami \0.Funkcje 302 . $Cipher mcrypt_ecb Pierwszy prototyp jest dla przypadku. $Mode to MCRYPT_ENCRYPT lub MCRYPT_DECRYPT. gdy dołączona jest biblioteka libmcrypt 2. string data. jest dopełniany znakami \0. string key. Patrz również: mcrypt_cbc(). Posiada dwa argumenty. string data.

oraz niektóre algorytmy w trybie stream. int mcrypt_enc_get_iv_size (resource td) mcrypt_enc_get_key_size Zwraca maksymalną wielkość klucza obsługiwaną przez algorytm określony przez deskryptor bajtach. MCRYPT_MODE_ECB. int mcrypt_enc_is_block_algorithm (resource td) 303 PHP – Kompendium wiedzy . echo strlen ($text). funkcja wypisze ostrzeżenie i użyje IV z wszystkimi bajtami ustawionymi na \0."\n". Przykład: mcrypt_encrypt() $IV <?php $iv = mcrypt_create_iv ( mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256.". gdy jest on wymagany przez algorytm. $key. ?> Przykład ten powinien wypisać: 35 64 mcrypt_enc_get_algorithms_name Zwraca nazwę algorytmu. cfb o ofb. w mcrypt_enc_get_modes_name Zwraca nazwę trybu. $crypttext = mcrypt_encrypt (MCRYPT_RIJNDAEL_256. echo strlen ($crypttext). $iv). 0 jeżeli jest to algorytm strumieniowy. CFB. że wszystkie wielkości kluczy pomiędzy 1 i mcrypt_enc_get_key_size() są obsługiwane przez algorytm. $text = "Spotkajmy się o 11:00 za pomnikiem. int mcrypt_enc_get_key_size (resource td) $td. IV jest ignorowany przez algorytm."\n". Jeżeli nie podasz IV. Parametru IV używają tryby cbc. string mcrypt_enc_get_modes_name (resource td) mcrypt_enc_get_supported_key_sizes Zwraca tablicę z wielkościami kluczy obsługiwanymi przez algorytm określony przez deskryptor szyfrowania. string mcrypt_enc_get_algorithms_name (resource td) mcrypt_enc_get_block_size Zwraca wielkość bloku dla algorytmu określonego przez deskryptor $td w bajtach. $key = "To jest sekretny klucz". $text. jeżeli algorytm jest blokowy. array mcrypt_enc_get_supported_key_sizes (resource td) mcrypt_enc_is_block_algorithm Zwraca 1. Jeżeli zwróci pustą tablicę to oznacza. int mcrypt_enc_get_block_size (resource td) mcrypt_enc_get_iv_size Zwraca wielkość iv dla algorytmu określonego przez deskryptor szyfrowania w bajtach.• jest parametrem używanym do inicjalizacji dla trybów: CBC. Jeżeli zwraca 0. MCRYPT_RAND). MCRYPT_MODE_ECB). OFB oraz w niektórych algorytmach dla trybu STREAM.

nOFB i OFB. Parametr $iv powinien mieć normalnie wielkość bloku używanego przez algorytm. int mcrypt_enc_is_block_algorithm_mode (resource td) 0 (na mcrypt_enc_is_block_mode Zwraca 1. Jeżeli test się uda. ofb). ale nie jest to zalecane. string module) Dodatek A . gdy tryb jest używany przez algorytm blokowy. W trybie ECB IV jest ignorowany. string iv) mcrypt_get_block_size Pierwszy prototyp jest dla przypadku. gdy dołączona jest biblioteka libmcrypt 2. bool mcrypt_generic_end (resource td) mcrypt_generic_init Maksymalna długość klucza powinna być pobrana poprzez wywołane funkcji mcrypt_enc_get_key_size() i wszystkie wartości mniejsze od uzyskanej są dopuszczalne. int mcrypt_enc_is_block_mode (resource td) 1 dla cbc i ecb a 0 dla cfb i mcrypt_enc_self_test Uruchamia samotestowanie algorytmu określonego przez deskryptor przypadku błędu zwraca 1. gdy zwraca bajty (na przykład stream). Funkcja mcrypt_get_block_size() jest używana do pobierania wielkości bloku dla podanego szyfrowania. string key. IV jest wymagany w trybach CFB. Zwraca False w przypadku wystąpienia błędu a True w przypadku powodzenia operacji. 0 dla stream a 1 dla cbc.mcrypt_enc_is_block_algorithm_mode Zwraca 1. W mcrypt_generic Szyfruje dane. Funkcja wymaga dwóch argumentów. $cipher oraz $module i zwraca wielkość w bajtach. ale należy odczytać tą wielkość przy pomocy funkcji mcrypt_enc_get_iv_size(). można zainicjować go zerami. W przypadku wystąpienia błędu funkcja zwraca -1. gdy tryb zwraca bloki bajtów lub 0. Ten sam wektor IV musi być użyty do kodowania i rozkodowywania. int mcrypt_get_block_size (int cipher) int mcrypt_get_block_size (string cipher. cfb.2. CBC. w przeciwnym przypadku zwraca przykład. int mcrypt_generic_init (resource td. Musi być on losowy i niepowtarzalny. Funkcja ta musi zostać wywołana przed każdym wywołaniem mcrypt_generic() lub mdecrypt_generic(). drugi gdy libmcrypt 2.x. zwraca 0. ale nie musi być tajny. int mcrypt_enc_self_test (resource td) $td.Funkcje 304 . Dane są dopełniane znakami \0 do wielkości n dane.4. Funkcja zwraca zaszyfrowane mcrypt_generic_end Kończy szyfrowanie określone przez deskryptor szyfrowania ($td). Uwaga Wielkość zwracanego ciągu może być większa od danych wejściowych z powodu dopełniania danych. Patrz również: mcrypt_get_key_size(). string data) * blocksize.x. STREAM. Czyści wszystkie bufory i zamyka użyte moduły. string mcrypt_generic (resource td. $cipher. Jeżeli nie chcesz go używać.

mcrypt_get_cipher_name
Funkcja używana do pobierania nazwy podanego szyfrowania. Wymaga podania szyfrowania w postaci liczby (libmcrypt 2.2.x) lub pobiera nazwę szyfrowania jako argument i zwraca nazwę szyfrowania lub False, jeżeli nie istnieje ten sposób szyfrowania.
string mcrypt_get_cipher_name (int cipher) string mcrypt_get_cipher_name (string cipher)

Przykład: mcrypt_get_cipher_name()
<?php $cipher = MCRYPT_TripleDES; print mcrypt_get_cipher_name ($cipher); ?>

Przykład ten zwróci następujący napis:
TripleDES

mcrypt_get_iv_size
Pierwszy prototyp jest dla przypadku, gdy dołączona jest biblioteka libmcrypt 2.2.x, drugi gdy libmcrypt 2.4.x. Funkcja mcrypt_get_iv_size() zwraca wielkość wektora inicjalizacji (IV) w bajtach. W przypadku błędu zwraca FALSE. Jeżeli w podanym trybie IV jest ignorowany, funkcja zwraca 0. • • •
int mcrypt_get_iv_size (string cipher, string mode) int mcrypt_get_iv_size (resource td)

jest jedną ze stałych MCRYPT_ciphername. $Mode to jedna ze stałych MCRYPT_MODE_modename która może być: ecb, cbc, cfb, ofb, nofb lub stream.
$Cipher $Td jest podanym algorytmem.

mcrypt_get_key_size
Pierwszy prototyp jest dla przypadku, gdy dołączona jest biblioteka libmcrypt 2.2.x, drugi gdy libmcrypt 2.4.x. Funkcja używana do pobierania wielkości klucza dla podanego szyfrowania, $cipher. Funkcja mcrypt_get_key_size() wymaga podania jednego lub dwóch parametrów, $cipher oraz $module i zwraca wielkość w bajtach. Patrz również: mcrypt_get_block_size().
int mcrypt_get_key_size (int cipher) int mcrypt_get_key_size (string cipher, string module)

mcrypt_list_algorithms
Funkcja używana do pobrania tablicy wszystkich obsługiwanych algorytmów w $lib_dir. Posiada parametr opcjonalny, określający katalog w którym znajdują się wszystkie algorytmy. Jeżeli nie zostanie on podany, użyta zostanie wartość mcrypt.algorithms_dir z pliku php.ini.
array mcrypt_list_algorithms ([string lib_dir])

Przykład: mcrypt_algorithms()
<?php $algorithms = mcrypt_list_algorithms ("/usr/local/lib/libmcrypt"); foreach ($algorithms as $cipher) { echo $cipher."/n"; } ?>

Przykład ten utworzy listę wszystkich obsługiwanych algorytmów z katalogu /usr/local/lib/mcrypt.

mcrypt_list_modes
Funkcja używana do pobrania tablicy z wszystkimi obsługiwanymi trybami w $lib_dir. Posiada parametr opcjonalny, określający katalog w którym znajdują się wszystkie tryby. Jeżeli nie zostanie on podany, użyta zostanie wartość mcrypt.modes_dir z pliku php.ini.
array mcrypt_list_modes ([string lib_dir])

Przykład: mcrypt_list_modes()
<?php $modes = mcrypt_list_modes (); foreach ($modes as $mode) { echo "$mode </br>";

305

PHP – Kompendium wiedzy

} ?>

Przykład ten tworzy listę wszystkich obsługiwanych algorytmów w domyślnym katalogu trybów. Jeżeli nie jest ustawiony w pliku php.ini jako dyrektywa mcrypt.modes_dir, użyty zostanie domyślny katalog dla biblioteki mcrypt (/usr/local/lib/libmcrypt)

mcrypt_module_get_algo_block_size
Zwraca wielkość bloku w bajtach dla podanego algorytmu. W opcjonalnym parametrze podać miejsce, gdzie są zapisane moduły trybów.
int mcrypt_module_get_algo_block_size (string algorithm [, string lib_dir])

$lib_dir

można

mcrypt_module_get_algo_key_size
Zwraca największą obsługiwaną wielkość klucza w bajtach. W opcjonalnym parametrze podać miejsce, gdzie są zapisane moduły trybów.
int mcrypt_module_get_algo_key_size (string algorithm [, string lib_dir])

$lib_dir

można

mcrypt_module_get_algo_supported_key_sizes
Zwraca tablicę z wielkościami kluczy obsługiwanych przez podany algorytm. Jeżeli funkcja zwróci pustą tablicę, dopuszczalne są wszystkie rozmiary klucza pomiędzy 1 i mcrypt_get_algo_key_size().W opcjonalnym parametrze $lib_dir można podać miejsce, gdzie są zapisane moduły trybów.
array mcrypt_module_get_algo_supported_key_sizes (string algorithm [, string lib_dir])

mcrypt_module_is_block_algorithm
Zwraca True, jeżeli podany algorytm jest algorytmem blokowym i False, jeżeli jest algorytmem strumieniowym. W opcjonalnym parametrze $lib_dir można podać miejsce, gdzie są zapisane moduły trybów.
bool mcrypt_module_is_block_algorithm (string mode [, string lib_dir])

mcrypt_module_is_block_algorithm_mode
Zwraca True, jeżeli tryb używany jest z algorytmem blokowym, w przeciwnym wypadku zwraca 0 (na przykład 0 dla stream i 1 dla cbc, cfb, cfb). W opcjonalnym parametrze $lib_dir można podać miejsce, gdzie są zapisane moduły trybów.
bool mcrypt_module_is_block_algorithm_mode (string mode [, string lib_dir])

mcrypt_module_is_block_mode
Zwraca True, jeżeli tryb powoduje wysyłanie bloków bajtów lub False, gdy pojedynczych bajtów (na przykład: 1 dla cbc i ecb a 0 dla cfb i stream). W opcjonalnym parametrze $lib_dir można podać miejsce, gdzie są zapisane moduły trybów.
bool mcrypt_module_is_block_mode (string mode [, string lib_dir])

mcrypt_module_open
Otwiera moduł używanego algorytmu i trybu. Nazwa algorytmu jest podana w parametrze $algorithm, na przykład: twofish jest jedną ze stałych MCRYPT_ciphername. Biblioteka jest zamykana przez mcrypt_module_close() ale wywołanie tej funkcji jest niepotrzebne, jeżeli została wywołana funkcja mcrypt_generic_end(). Normalnie zwraca deskryptor szyfrowania lub False w przypadku wystąpienia błędu. Parametry $algorithm_directory i $mode_directory używane są do odnalezienia modułów szyfrowania. Jeżeli jeden z tych parametrów zostanie ustawiony na "", użyte zostaną wartości znajdujące się w dyrektywach mcrypt.algorithms_dir lub mcrypt.modes_dir. Jeżeli parametry nie zostaną ustawione, użyte zostaną wartości wkompilowane w bibliotekę libmcrypt (zwykle /usr/local/lib/libmcrypt).
resource mcrypt_module_open (string algorithm, string algorithm_directory,

Dodatek A - Funkcje

306

string mode, string mode_directory)

Przykład: mcrypt_module_open()
<?php $td = mcrypt_module_open (MCRYPT_DES, "", MCRYPT_MODE_ECB, "/usr/lib/mcrypt-modes"); ?>

Przykład ten będzie próbował otworzyć szyfrowanie DES z bieżącego katalogu i tryb ECB z katalogu /usr/lib/mcrypt-modes.

mcrypt_module_self_test
Uruchamia samotestowanie szyfrowania podanego szyfrowania. W opcjonalnym parametrze $lib_dir można podać miejsce, gdzie są zapisane moduły trybów. Funkcja zwraca True, jeżeli test się powiedzie i False, jeżeli się nie uda.
bool mcrypt_module_self_test (string algorithm [, string lib_dir])

mcrypt_ofb
Pierwszy prototyp jest dla przypadku, gdy dołączona jest biblioteka libmcrypt 2.2.x, drugi gdy libmcrypt 2.4.x. Funkcja mcrypt_ofb() szyfruje i deszyfruje (w zależności od trybu) dane $data za pomocą $cipher i $key w trybie szyfrowania OFB i zwraca wynikowy ciąg. • • • • •
string mcrypt_ofb (int cipher, string key, string data, int mode, string iv) string mcrypt_ofb (string cipher, string key, string data, int mode [, string iv])

jest jedną ze stałych MCRYPT_ciphername. $Key jest kluczem przekazywanym do algorytmu. Musi być tajny. $Data to dane do zaszyfrowania lub odszyfrownania. $Mode to jedna ze stałych MCRYPT_ENCRYPT lub MCRYPT_DECRYPT. $IV jest wektorem inicjalizacji. Patrz również: mcrypt_cbc(), mcrypt_cfb() i mcrypt_ecb().
$Cipher

md5
Wykonuje mieszanie ciągu
crc32().
string md5 (string str)

$str

metodą MD5 używaną przez RSA Data Cecurity Inc. Patrz również:

mdecrypt_generic
Odszyfrowuje dane.
Uwaga Długość zwracanego ciągu może być większa niż ciąg niezaszyfrowany z powodu wyrównywania danych.
string mdecrypt_generic (resource td, string data)

Przykład: mdecrypt_generic()
<?php $iv_size = mcrypt_enc_get_iv_size ($td)); $iv = @mcrypt_create_iv ($iv_size, MCRYPT_RAND); if (@mcrypt_generic_init ($td, $key, $iv) != -1) { $c_t = mcrypt_generic ($td, $plain_text); @mcrypt_generic_init ($td, $key, $iv); $p_t = mdecrypt_generic ($td, $c_t); } if (strncmp ($p_t, $plain_text, strlen($plain_text)) == 0) echo "ok"; else echo "błąd"; ?>

Przykład pokazuje w jaki sposób sprawdzić, czy dane przed szyfrowaniem są takie same jak po odszyfrowaniu. 307 PHP – Kompendium wiedzy

metaphone
Oblicza klucz metaphone dla $str. Podobnie jak soundex(), funkcja ta zwraca ten sam klucz dla podobnie brzmiących słów. Jest ona dokładniejsza od soundex(), ponieważ stosuje podstawowe zasady wymowy angielskiej. Klucze wygenerowane przez funkcję są zmiennej długości. Autorem algorytmu jest Lawrence Philips <lphilips@verity.com>. Został on opisany w książce „Practical Algorithms for Programmers”, Binstock & Rex, Addison Wesley, 1995.
string metaphone (string str)

method_exists
Funkcja zwraca True jeżeli dla obiektu przypadku zwraca False.
$object

zdefiniowana jest metoda

$method_name.

W przeciwnym

bool method_exists (object object, string method_name)

mhash
Uruchamia funkcję mieszającą określoną w $hash na danych $data i zwraca wynik mieszania.
string mhash (int hash, string data, string [ key ])

mhash_count
Zwraca największy dostępny identyfikator funkcji mieszającej. Są one numerowane od 0.
int mhash_count (void)

Przykład: Przeglądanie funkcji mieszających
<?php $nr = mhash_count(); for ($i = 0; $i <= $nr; $i++) { echo sprintf ("Wielkość bloku dla %s wynosi %d\n", mhash_get_hash_name ($i), mhash_get_block_size ($i)); } ?>

mhash_get_block_size
Funkcja używana do pobrania wielkości bloku dla podanej funkcji mieszającej. Wymaga podania jednego parametru, identyfikatora funkcji mieszającej i zwraca wielkość bloku w bajtach lub False jeżeli nie istnieje podana funkcja.
int mhash_get_block_size (int hash)

mhash_get_hash_name
Funkcja używana do pobrania nazwy podanej funkcji mieszającej. Wymaga podania jednego parametru, identyfikatora funkcji mieszającej i zwraca jej nazwę lub False jeżeli podana funkcja nie istnieje.
string mhash_get_hash_name (int hash)

Przykład: mhash_get_hash_name()
<?php $hash = MHASH_MD5; print mhash_get_hash_name ($hash); ?>

Uruchomienie przykładu spowoduje wypisanie następującego wyniku:
MD5

microtime
Zwraca ciąg „mikrosekundy sekundy” gdzie sekundy są bieżącym czasem wyrażonym w sekundach od początku epoki Uniksa (1 stycznia 1970, 0:00:00). Funkcja jest dostępna w systemach obsługujących funkcję systemową gettimeofday(). Parz również: time().
string microtime (void)

Dodatek A - Funkcje

308

min
Zwraca wartość najmniejszego numerycznie parametru. Jeżeli pierwszy parametr jest tablicą, min() zwraca najmniejszą wartość w tablicy. Jeżeli pierwszy parametr jest liczbą całkowitą, ciągiem lub liczbą double, funkcja wymaga co najmniej dwóch parametrów i zwraca najmniejszy z nich. Można porównywać nieograniczoną ilość wartości. Jeżeli jedna lub więcej wartości jest liczbą double, wszystkie wartości są traktowane jako double i zwracana jest liczba typu double. Jeżeli żadna z wartości nie jest liczbą double, wszystkie są traktowane jako liczby całkowite i również zwracana jest liczba całkowita.
number min (number arg1, number arg2 [, ...])

mkdir
Tworzy katalog określony o podanej nazwie.
Uwaga Prawdopodobnie będziesz chciał podać typ jako liczbę ósemkową, musisz więc dodać na jej początku zero.
int mkdir (string pathname, int mode)

Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. Patrz również:
rmdir().
mkdir ("/sciezka/do/nowego/katalogu", 0700);

mktime
Ostrzeżenie Zwróć uwagę na dziwną kolejność argumentów, która różni się od kolejności stosowanej w wywołaniu funkcji Uniksa mktime() która nie pomaga w opuszczaniu parametrów od prawej do lewej strony. Częstym błędem jest pomieszanie tych parametrów w skrypcie.

Zwraca znacznik czasu Uniksa odpowiadający podanym argumentom. Znacznik ten to liczba całkowita zawierająca ilość sekund od początku ery Uniksa (1 stycznia 1970) do podanego czasu. Argumenty mogą być opuszczane od prawej do lewej strony a opuszczone wartości będą zastępowane bieżącym czasem lokalnym.
int mktime (int hour, int minute, int second, int month, int day, int year [, int is_dst])

Parametr $is_dst może być ustawiony na 1 w przypadku, gdy obowiązuje czas zimowy, na obowiązuje czas letni lub na -1 (domyślnie) gdy nie wiadomo jaki czas obowiązuje.
Uwaga Parametr $is_dst został dodany w PHP 3.0.10.

0

gdy

Funkcja mktime() jest pożyteczna do obliczeń na datach oraz kontroli ich poprawności, ponieważ automatycznie oblicza właściwe wartości dla parametrów spoza zakresu. Na przykład: każdy z poniższych wierszy powoduje wypisanie ciągu Jan-01-1998. Przykład: mktime()
echo echo echo echo date date date date ("M-d-Y", ("M-d-Y", ("M-d-Y", ("M-d-Y", mktime mktime mktime mktime (0,0,0,12,32,1997)); (0,0,0,13,1,1997)); (0,0,0,1,1,1998)); (0,0,0,1,1,98));

Parametr $year może być liczbą dwu bądź czterocyfrową o wartościach 0–69 odpowiadających 2000– 2069 oraz 70–99 odpowiadających 1970–1999 (w systemach w których time_t jest 32-bitową liczą ze znakiem, czyli większości współczesnych, prawidłowym zakresem dla $year jest 1902–2037). Ostatni dzień dowolnego miesiąca może być podany jako dzień 0 miesiąca następnego. Poniższy przykład wypisze dwukrotnie Ostatnim dniem lutego 2000 jest: 29. Przykład: Ostatni dzień miesiąca:
$lastday = mktime (0,0,0,3,0,2000); echo strftime ("Ostatnim dniam lutego 2000 jest: %d", $lastday); $lastday = mktime (0,0,0,4,-31,2000);

309

PHP – Kompendium wiedzy

echo strftime ("Ostatnim dniam lutego 2000 jest: %d", $lastday);

Jeżeli jako rok, miesiąc i dzień podane zostaną wartości 0, data taka uznana zostanie za błędną. Jeżeli by tak nie było, odpowiadało by to dacie 30.11.1999, co wydawać by się mogło dziwnym działaniem. Patrz również: date() i time().

move_uploaded_file
Funkcja dostępna w PHP 3 powyżej wersji 3.0.16 i w PHP 4 powyżej 4.0.2. Funkcja sprawdza, czy plik określony przez $filename jest plikiem przesłanym na serwer (za pomocą mechanizmu przesyłania HTTP POST). Jeżeli plik jest prawidłowy zostaje on przeniesiony na ścieżkę określoną przez $destination. Jeżeli $filename nie jest prawidłowym plikiem załadowanym na serwer, nie jest wykonywana żadna operacja i funkcja move_upload_file() zwraca False. Jeżeli $filename jest prawidłowym plikiem załadowanym na serwer, ale z jakichkolwiek przyczyn nie może być on przeniesiony, nie jest wykonywana żadna operacja a funkcja move_upload_file() zwraca False. Dodatkowo wyświetlane jest ostrzeżenie. Sprawdzenie to jest szczególnie istotne w przypadkach, gdy istnieje jakakolwiek szansa, że zawartość przesyłanego pliku może być pokazana użytkownikowi, lub innym użytkownikom na tym samym systemie. Patrz również: is_uploaded_file() oraz część podręcznika sieciowego zatytułowaną: Handling file uploads.
bool move_uploaded_file (string filename, string destination)

msql
Zwraca dodatni identyfikator wyniku zapytania mSQL, lub False w przypadku wystąpienia błędu. Funkcja mSQL wybiera bazę danych i wykonuje na niej zapytanie. Jeżeli nie zostanie podany opcjonalny identyfikator połączenia, funkcja próbuje znaleźć otwarte połączenie do serwera mSQL. Jeżeli nie zostanie znalezione takie połączenie, funkcja spróbuje nawiązać je wywołując funkcję msql_connect() bez parametrów. Patrz również: msql_connect().
int msql (string database, string query, int link_identifier)

msql_affected_rows
Zwraca ilość wierszy biorących udział w zapytaniu (to znaczy ilość wierszy zwróconych przez SELECT, ilość wierszy zmienionych przez UPDATE lub ilość wierszy usuniętych przez DELETE). Patrz również: msql_query().
int msql_affected_rows (int query_identifier)

msql_close
Zwraca True w przypadku powodzenia operacji a False w przypadku błędu. Funkcja zamyka połączenie z bazą mSQL skojarzoną z podanym identyfikatorem połączenia. Jeżeli nie zostanie podany identyfikator połączenia, zostanie użyty ostatnio otwarte połączenie.
Uwaga Zwykle nie jest konieczne używanie tej funkcji, ponieważ połączenia nie otwarte jako trwałe są zamykane automatycznie po zakończeniu skryptu.

Funkja msql_close() nie zamyka połączeń trwałych wygenerowanych przez również: msql_connect() i msql_pconnect().
int msql_close (int link_identifier)

msql_pconnect().

Patrz

msql_connect
Zwraca dodatni identyfikator połączenia do mSQL, lub False w przypadku błędu. Funkcja msql_connect() nawiązuje połączenie z serwerem mSQL. Nawa komputera jest opcjonalna i jeżeli jest opuszczona, przyjmowana jest nazwa localhost. Drugie wywołanie msql_connect() z takimi samymi argumentami nie spowoduje zestawienia następnego połączenia. Zamiast tego zwrócony zostanie identyfikator istniejącego już połączenia. Dodatek A - Funkcje 310

Połączenie z serwerem zostanie zamknięte po zakończeniu wykonywania skryptu chyba, że wcześniej zostanie zamknięte za pomocą msql_close(). Patrz również: msql_pconnect() i msql_close().
int msql_connect ([string hostname [, string hostname[:port] [, string username [, string password]]]])

msql_createdb
Taka sama jak msql_create_db().
int msql_createdb (string database name [, int link_identifier])

msql_create_db
Tworzy bazę danych na serwerze skojarzonym z podanym identyfikatorem połączenia. Patrz również: msql_drop_db().
int msql_create_db (string database name [, int link_identifier])

msql_data_seek
Zwraca True w przypadku powodzenia operacji a False w przypadku błędu. Przesuwa wewnętrzny znacznik wiersza w wyniku mSQL skojarzonym z podanym identyfikatorem wyniku zapytania do wiersza o podanym numerze. Kolejne wywołanie funkcji msql_fetch_row() zwróci ten wiersz. Patrz również: msql_fetch_row().
int msql_data_seek (int query_identifier, int row_number)

msql_dbname
Zwraca nazwę bazy danych zapisaną na pozycji $i wskaźnika zwracanego przez funkcję Funkcja może być wykorzystana do sprawdzenia ilości dostępnych baz danych.
string msql_dbname (int query_identifier, int i)

msql_listdbs().

msql_dropdb
Patrz msql_drop_db().
int msql_dropdb (void)

msql_drop_db
Zwraca True w przypadku powodzenia operacji a False w przypadku błędu. Funkcja msql_drop_db() próbuje usunąć z serwera całą bazę danych skojarzoną z podanym identyfikatorem połączenia. Patrz również: msql_create_db().
int msql_drop_db (string database_name, int link_identifier)

msql_error
Błędy przychodzące z serwera mSQL nie są traktowane jako ostrzeżenia PHP. Zamiast tego należy używać tej funkcji do pobierania ciągu z opisem błędu.
string msql_error ()

msql_fetch_array
Zwraca tablicę odpowiadająca pobranemu wierszowi, lub False jeżeli nie ma już wierszy do pobrania. Funkcja msql_fetch_array() jest rozszerzeniem funkcji msql_fetch_row(). Oprócz zapamiętywania danych pod indeksami numerycznymi, dodatkowo dane są zapisywane pod indeksami asocjacyjnymi, używając nazw pól jako kluczy. Drugi argument, $result_type w funkcji msql_fetch_array() jest jedną z następujących stałych: MSQL_ASSOC, MSQL_NUM i MSQL_BOTH. Należy być uważym przy odczytywaniu wyników zapytania, które może zwrócić tylko jedno pole, które ma wartość 0 (pusty ciąg albo NULL). PHP – Kompendium wiedzy 311

które nie było jeszcze odczytane. Funkcja msql_fetch_field() może być użyta do pobrania danych na temat pól w wyniku. Patrz również: msql_fetch_array(). object msql_fetch_field (int query_identifier. int result_type]) msql_fetch_field Zwraca obiekt zawierający informacje o polu. Bardziej szczegółowo jest to opisane przy funkcji msql_fetch_row(). int i) msql_fieldlen Zwraca długość podanego pola. int msql_fetch_array (int query_identifier [. array msql_fetch_row (int query_identifier) msql_fieldflags Zwraca atrybuty podanego pola. primary key. int field_offset) • • • • • • Właściwości zwracanego obiektu są następujące: name — nazwa kolumny table — nazwa tabeli do której należy kolumna not_null — 1 jeżeli kolumna nie może być pusta primary_key — 1 jeżeli kolumna jest kluczem głównym unique — 1 jeżeli kolumna jest kluczem unikalnym type — typ kolumny msql_fetch_object Zwraca obiekt z właściwościami odpowiadającymi polom pobieranego wiersza lub False. Funkcja msql_fetch_object() jest podobna do msql_fetch_array() z jedną różnicą — zwracany jest obiekt a nie tablica. string msql_fieldflags (int query_identifier.Funkcje 312 . msql_fetch_object(). Drugi argument. Oznacza to.Uwaga Funkcja msql_fetch_array() NIE jest wyraźnie wolniejsza od funkcji msql_fetch_row(). Patrz również: msql_fetch_array() i msql_fetch_row(). kombinacja obu oraz pusty ciąg. int result_type]) msql_fetch_row Zwraca tablicę odpowiadająca pobranemu wierszowi. MSQL_NUM i MSQL_BOTH. jedynie dostarcza więcej wyników. Atrybutami są not null. int msql_fieldlen (int query_identifier. msql_data_seek() i msql_result(). Kolejne wywołanie msql_fetch_row() powoduje zwracanie kolejnych wierszy z wyniku lub False jeżeli nie ma już więcej wierszy. Funkcja jest identyczna wydajnościowo z msql_fetch_array() i prawie tak samo szybka jak msql_fetch_row() — różnica jest nieznaczna. int msql_fetch_object (int query_identifier [. Każda kolumna jest zapisywana w osobnym indeksie tablicy. int i) Dodatek A . rozpoczynając od 0. $result_type w funkcji msql_fetch_array() jest jedną z następujących stałych: MSQL_ASSOC. Wiersz jest zwracany w postaci tablicy. że możesz odwoływać się do pól poprzez nazwy a nie poprzez indeks( liczby nie są prawidłowymi nazwami właściwości). lub False jeżeli nie ma już wierszy do pobrania. jeżeli nie ma więcej wierszy do pobrania. Funkcja msql_fetch_row() pobiera jeden wiersz z wyniku określonego przez identyfikator zapytania. Jeżeli nie zostanie podane przesunięcie. odczytywane jest następne pole.

msql_fieldname Zwraca nazwę podanego pola. gdy nie chcemy zużywać zbyt wiele pamięci w czasie działania skryptu. int msql_free_result (int query_identifier) msql_listdbs Patrz msql_list_dbs(). Parametr $query_identifier jest identyfikatorem zapytania. int field) msql_fieldtable Zwraca nazwę tabel do której należy pole $field. Jeżeli następne wywołanie msql_fetch_field() nie będzie zawierało numeru pola. string msql_fieldtype (int query_identifier. int msql_fieldtable (int query_identifier. Argumenty są takie same. char lub real. ale zwracany jest typ pola. int field) msql_fieldtype Podobna do funkcji msql_fieldname(). Należy użyć funkcji do odczytania tego znacznika wyniku. Może być to int. msql_listtables( void ) msql_list_dbs msql_dbname() Zwraca znacznik wyniku zawierającego bazy danych dostępne dla demona msql. PHP – Kompendium wiedzy int msql_list_dbs (void) 313 . Patrz również: msql_fetch_field(). Po zakończeniu wykonywania żądania pamięć jest zwalniana automatycznie. int msql_field_seek (int query_identifier. Funkcja msql_fieldname($result. zostanie zwrócone to właśnie pole. a $field jest numerem kolejnym pola. string msql_fieldname (int query_identifier. int field_offset) msql_freeresult Patrz msql_free_result(). int i) msql_field_seek Przesuwa wskaźnik do podanego numeru pola. 2) zwróci nazwę drugiego pola z wyniku związanego z podanym identyfikatorem wyniku. msql_freeresult( void ) msql_free_result Zwalnia pamięć przydzieloną dla $query_identifier. Funkcja ta jest potrzebna tylko wtedy. msql_listfields( void ) msql_listtables Patrz msql_list_tables(). msql_listdbs( void ) msql_listfields Patrz msql_list_fields().

Funkcja msql_pconnect() działa bardzo podobnie do msql_connect() z dwiema różnicami. string hostname[:port] [. Zwracany jest znacznik wyniku. ciąg ten jest wypisywany na wyjście. msql_fieldname() i msql_fieldtype(). użyte zostanie ostatnio otwarte łącze. int msql_num_fields (int query_identifier) msql_num_rows Zwraca ilość wierszy w wyniku. string username [. msql_pconnect Zwraca dodatni identyfikator łącza trwałego lub False w przypadku wystąpienia błędu. Patrz również: msql(). Jeżeli zostanie ono znalezione. zostaje zwrócone zamiast nowego połączenia. Jeżeli identyfikator ten nie zostanie podany. msql_fieldlen(). Zwraca dodatni identyfikator zapytania mSQL lub False w przypadku wystąpienia błędu. Po drugie. int link_identifier) Dodatek A . Patrz również: msql(). połączenie do serwera mSQL nie jest zamykane po zakończeniu pracy skryptu. w czasie połączenia zamiast otwierać nowe połączenie funkcja próbuje znaleźć istniejące łącze (trwałe). Identyfikator zapytania jest dodatnią liczbą całkowitą. Po pierwsze. Patrz również: msql(). int msql_pconnect ([string hostname [. funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja msql_connect() a następnie używa łącza do wykonania zapytania. Jeżeli nie ma otwartego łącza. int msql_list_fields (string database. int msql_query (string query. który może być użyty w funkcjach msql_fieldflags(). Do msql_numfields Identyczna z msql_num_fields().msql_list_fields Pobiera dane na temat podanej tabeli. msql_query() i int msql_num_rows (int query_identifier) msql_fetch_row(). Ciąg opisujący błąd umieszczany jest w $phperrmsg i jeżeli funkcja nie została wywołana jako @msql_list_fields(). string password]]]]) msql_query Wysyła zapytanie do aktywnej bazy danych skojarzonej z podanym identyfikatorem łącza. W przypadku błędu funkcja zwraca -1. string tablename) msql_list_tables Pobiera jako argument nazwę bazy danych i zwraca znacznik wyniku podobnie do funkcji pobrania wyniku na podstawie znacznika powinna zostać użyta funkcja msql_table_name(). msql_fetch_field() i msql_num_rows(). msql_select_db() i msql_connect(). int msql_list_tables (string database) msql(). msql_query().Funkcje 314 . int msql_numfields (int query_identifier) msql_numrows Identyczna z msql_num_rows(). Patrz również: msql_error(). Łącze takie pozostaje otwarte do wykorzystania w przyszłości (msql_close() nie zamyka połączeń utworzonych przez msql_pconnect()). Parametrami są nazwa bazy danych i nazwa tabeli. int msql_numrows (void) msql_num_fields Zwraca ilość pól w wyniku.

Zalecanymi szybszymi funkcjami są: msql_fetch_row(). Funkcja msql_numrows() może być użyta do określenia ilości tabel w wyniku. numerze i wyniku mSQL. int i. Zamyka połączenie z bazą danych MS SQL Server. int msql_select_db (string database_name. użyte zostanie ostatnio otwarte łącze. $i++. nazwą pola lub nazwą w postaci tabela kropka pole (pole. Jeżeli kolumna otrzymała w zapytaniu alias (select foo as bar from . } ?> mssql_close Zwraca True w przypadku powodzenia a False w przypadku błędu.. funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja msql_connect() a następnie używa łącza do wybrania bazy danych. $i). która jest skojarzona z podanym identyfikatorem połączenia.. msql_pconnect() i msql_query(). Jeżeli identyfikator połączenia nie zostanie podany. Jeżeli nie ma otwartego łącza. Uwaga Nie jest to zwykle konieczne. int field) Przykład: msql_tablename() <?php msql_connect ("localhost"). msql_selectdb( void ) msql_select_db Zwraca True w przypadku powodzenia a False w przypadku błędu. Funkcja msql_result() zwraca zawartość jednej komórki z wyniku mSQL. używane jest ostatnio otwarte połączenie. Patrz również: msql_connect(). Funkcja mssql_close() nie zamyka połączeń trwałych otwartych za pomocą mssql_pconnect(). Podawanie numerów pól zamiast ich nazw powoduje szybsze działanie funkcji. msql_fetch_array() i msql_fetch_object(). Jeżeli identyfikator ten nie zostanie podany. 315 PHP – Kompendium wiedzy . while ($i < msql_numrows ($result)) { $tb_names[$i] = msql_tablename ($result.). int link_identifier) msql_tablename Na podstawie identyfikatora wyniku zwracanego przez msql_list_tables() oraz numeru kolejnego pobiera i zwraca nazwę tabeli. int msql_result (int query_identifier. msql_regcase( void ) msql_result Zwraca zawartość komórki w podanym wierszu. "<BR>". Ponieważ funkcje te zwracają zawartość wielu pól za pomocą jednego wywołania. ponieważ połączenia nietrwałe są automatycznie zamykane po zakończeniu wykonywania skryptu. Pracując na dużych wynikach należy rozważyć użycie jednej funkcji do wczytania całego wiersza. mixed field) msql_selectdb Patrz msql_select_db(). echo $tb_names[$i] .msql_regcase Patrz sql_regcase(). $result = msql_list_tables ("wisconsin"). Funkcja msql_select_db() ustawia na serwerze bieżącą aktywną bazę danych o podanym identyfikatorze łącza. string msql_tablename (int query_identifier. są one dużo szybsze od msql_result(). Kolejne wywołania msql_query() wykonywane są na aktywnej bazie danych. $i = 0.tabela). Argument $field może być numerem pola. należy użyć aliasu a nie oryginalnej nazwy kolumny.

jeżeli nie ma więcej wierszy do pobrania. string password]]]) mssql_data_seek Zwraca True w przypadku powodzenia a False w przypadku błędu. używając nazw pól jako kluczy. właściwość ta ma wartość computed#N. jedynie dostarcza więcej wyników. Połączenie z serwerem zostanie zamknięte po zakończeniu wykonywania skryptu chyba. Funkcja jest identyczna wydajnościowo z Dodatek A . Funkcja mssql_fetch_array() jest rozszerzeniem funkcji mssql_fetch_row(). Uwaga Funkcja mssql_fetch_array() NIE jest wyraźnie wolniejsza od funkcji mssql_fetch_row(). Funkcja mssql_fetch_field() może być użyta do pobrania danych na temat pól w wyniku. które nie było jeszcze odczytane. numeric — 1 gdy kolumna jest numeryczna. odczytywane jest następne pole. • • • • object mssql_fetch_field (int result [. Patrz również: mssql_pconnect() i mssql_close(). Jeżeli kolumna jest wynikiem działania funkcji. max_length — Maksymalna długość kolumny. int field_offset]) — Nazwa kolumny. name mssql_fetch_object Zwraca obiekt z właściwościami odpowiadającymi polom pobieranego wiersza lub False. Następne wywołanie funkcji mssql_fetch_row() zwróci ten wiersz.Funkcje 316 . int mssql_fetch_array (int result) mssql_fetch_field Zwraca obiekt zawierający informacje o polu. lub False jeżeli nie ma już wierszy do pobrania. Zamiast tego zwrócony zostanie identyfikator istniejącego już połączenia. int mssql_close ([int link_identifier]) mssql_connect Zwraca dodatni identyfikator połączenia do MS SQL. Drugie wywołanie mssql_connect() z takimi samymi argumentami nie spowoduje zestawienia następnego połączenia. Oznacza to. Bardziej szczegółowo jest to opisane przy funkcji mssql_fetch_row(). Funkcja mssql_connect() nawiązuje połączenie z serwerem MS SQL. int mssql_connect ([string servername [. że wcześniej zostanie zamknięte za pomocą mssql_close(). do wiersza o podanym numerze. int mssql_data_seek (int result_identifier. Argument $servername musi być prawidłową nazwą serwera zdefiniowaną w pliku interfejsów. Jeżeli nie zostanie podane przesunięcie. gdzie #N jest numerem seryjnym. że możesz odwoływać się do pól poprzez nazwy a nie poprzez indeks( liczby nie są prawidłowymi nazwami właściwości). Funkcja mssql_data_seek() przesuwa wewnętrzny wskaźnik wiersza w wyniku MS SQL. Oprócz zapamiętywania danych pod indeksami numerycznymi. dodatkowo dane są zapisywane pod indeksami asocjacyjnymi. int row_number) mssql_fetch_array Zwraca tablicę odpowiadająca pobranemu wierszowi. Patrz również: mssql_data_seek(). Funkcja mssql_fetch_object() jest podobna do mssql_fetch_array() z jedną różnicą — zwracany jest obiekt a nie tablica.Patrz również: mssql_connect() i mssql_pconnect(). string username [. column_source — Tabela z której pochodzi kolumna. lub False w przypadku błędu. skojarzonym z podanym identyfikatorem wyniku.

int mssql_num_fields (int result) mssql_db_query(). Kolejne wywołanie mssql_fetch_row() powoduje zwracanie kolejnych wierszy z wyniku lub False jeżeli nie ma już więcej wierszy. Funkcja ta jest potrzebna tylko wtedy. Wiersz jest zwracany w postaci tablicy. lub False jeżeli nie ma już wierszy do pobrania. Patrz również: mssql_num_rows(). mssql_fetch_array() int mssql_fetch_object (int result) mssql_fetch_row Zwraca tablicę odpowiadająca pobranemu wierszowi. mssql_data_seek(). int offset]) mssql_field_seek Przesuwa wskaźnik do określonego numeru pola. rozpoczynając od 0. Patrz również: mssql_fetch_array(). int offset]) mssql_field_name int mssql_field_name (int result [. mssql_fetch_lengths() i mssql_result(). gdy nie chcemy zużywać zbyt wiele pamięci w czasie działania skryptu. array mssql_fetch_row (int result) mssql_field_length int mssql_field_length (int result [.i prawie tak samo szybka jak mssql_fetch_row() — różnica jest nieznaczna. int offset]) mssql_free_result Zwalnia pamięć przydzieloną dla $result. Funkcja mssql_fetch_row() pobiera jeden wiersz z wyniku określonego przez identyfikator zapytania. mssql_query(). Po zakończeniu wykonywania żądania pamięć jest zwalniana automatycznie. int mssql_free_result (int result) mssql_get_last_message string mssql_get_last_message (void) mssql_min_error_severity void mssql_min_error_severity (int severity) mssql_min_message_severity void mssql_min_message_severity (int severity) mssql_num_fields Zwraca ilość pól w wyniku. Każda kolumna jest zapisywana w osobnym indeksie tablicy. Patrz również: mssql_fetch_array() i mssql_fetch_row(). mssql_fetch_object(). Patrz również: mssql_fetch_field(). mssql_fetch_field() i 317 PHP – Kompendium wiedzy . Jeżeli następne wywołanie mssql_fetch_field() nie będzie zawierało numeru pola. int mssql_field_seek (int result. zostanie zwrócone to właśnie pole. int field_offset) mssql_field_type string mssql_field_type (int result [.

połączenie do serwera MS SQL nie jest zamykane po zakończeniu pracy skryptu. mssql_pconnect() i mssql_query(). mssql_pconnect Zwraca dodatni identyfikator łącza trwałego lub False w przypadku wystąpienia błędu. string password]]]) mssql_query Zwraca dodatni identyfikator zapytania MS SQL lub False w przypadku wystąpienia błędu. jaka może być zwrócona przez funkcję mt_rand(). użyte zostanie ostatnio otwarte łącze. Argument $field może być numerem pola. srand() i getrandmax(). int link_identifier]) mt_getrandmax Zwraca maksymalną wartość. są one dużo szybsze od mssql_result(). funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja mssql_connect() a następnie używa łącza do wykonania zapytania. int mt_getrandmax (void) mt_rand(). Podawanie numerów pól zamiast ich nazw powoduje szybsze działanie funkcji. int mssql_query (string query [. Jeżeli nie ma otwartego łącza. Patrz również: mssql_connect(). mssql_select_db() i mssql_connect(). int mssql_result (int result. należy użyć aliasu a nie oryginalnej nazwy kolumny. mssql_fetch_array() i mssql_fetch_object(). Jeżeli nie ma otwartego łącza. string username [. Jeżeli kolumna otrzymała w zapytaniu alias (select foo as bar from . Pracując na dużych wynikach należy rozważyć użycie jednej funkcji do wczytania całego wiersza. Ponieważ funkcje te zwracają zawartość wielu pól za pomocą jednego wywołania. Patrz również: mt_rand Wiele generatorów liczb losowych ze starszych bibliotek libc miało problematyczną lub nieznaną charakterystykę i były powolne. int i. użyte zostanie ostatnio otwarte łącze.. Jeżeli identyfikator ten nie zostanie podany. Kolejne wywołania mssql_query() wykonywane są na aktywnej bazie danych. Jeżeli zostanie ono znalezione.Funkcje 318 . Patrz również: mssql_db_query(). nazwą pola lub nazwą w postaci tabela kropka pole (pole. Wysyła do aktywnej bazy danych zapytanie skojarzone z podanym identyfikatorem łącza. w czasie połączenia zamiast otwierać nowe połączenie funkcja próbuje znaleźć istniejące łącze (trwałe).tabela). funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja mssql_connect() a następnie używa łącza do wybrania bazy danych. rand(). Jeżeli identyfikator ten nie zostanie podany. mssql_pconnect() int mssql_pconnect ([string servername [. mssql_query() i int mssql_num_rows (string result) mssql_fetch_row(). Po drugie. zostaje zwrócone zamiast nowego połączenia. mixed field) mssql_select_db Zwraca True w przypadku powodzenia a False w przypadku błędu. int mssql_select_db (string database_name [.. Funkcja działa bardzo podobnie do mssql_connect() z dwiema różnicami. int link_identifier]) mssql_result Funkcja mssql_result() zwraca zawartość jednej komórki z wyniku MS SQL.).mssql_num_rows Zwraca ilość wierszy w wyniku. Zalecanymi szybszymi funkcjami są: mssql_fetch_row(). Funkcja mssql_select_db() ustawia na serwerze bieżącą aktywną bazę danych o podanym identyfikatorze łącza. Łącze takie pozostaje otwarte do wykorzystania w przyszłości (mssql_close() nie zamyka połączeń utworzonych przez mssql_pconnect()). Po pierwsze. mt_srand(). Domyślnie PHP korzysta z generatora liczb losowych z libc dostępnego za Dodatek A . Patrz również: mssql_db_query().

mt_srand Inicjuje generator liczb losowych wartością $seed. a zoptymalizowane źródła MT znajdują się pod adresem http://www.23. Funkcja nie działa dla wyrażeń typu SELECT. rand() i getrandmax(). drugi parametr oznaczał wielkość przedziału. string database [. aktywne pozostanie połączenie wcześniej podłączonego użytkownika. usunięte zostaną wszystkie wiersze z tabeli.scp. Jeżeli ostatnim zapytaniem było zapytanie DELETE bez klauzuli WHERE. int max) Jeżeli funkcja zostanie wywołana bez opcjonalnych parametrów $min i $max. 11). na przykład. Funkcja mysql_close() zamyka połączenie do bazy danych MySQL. resource link_identifier]]) mysql_close Zwraca True w przypadku powodzenia a False w przypadku błędu. 15). int mysql_affected_rows ([resource link_identifier]) mysql_change_user Zmienia użytkownika na bieżącym połączeniu lub połączeniu podanym przez identyfikator połączenia $link_identifier. Patrz również: mt_srand(). mt_getrandmax(). ale funkcja zwróci zero.html.pomocą funkcji rand(). string password [. używany jest ostatnio otwarte połączenie. mysql_affected_rows Zwraca ilość wierszy zmienionych przez ostatnie wyrażenie INSERT. Uwaga Funkcja została wprowadzona w PHP 3.ac. Patrz również: mt_rand().7. Jeżeli chcesz otrzymać liczby pomiędzy.math. że trzeba zainicjować generator liczb losowych przed użyciem funkcji mt_srand(). $randval = mt_rand().syr. która jest skojarzona z podanym identyfikatorem połączenia. Funkcja mt_rand() jest jej zamiennikiem.jp/~matumoto/emt. void mt_srand (int seed) Przykład: //inicjowanie mikrosekundami od ostatniej pełnej sekundy mt_srand((double) microtime() * 1000000). Strona domowa generatora Mersenne Twister znajduje się pod adresem http://www. Uwaga W wersjach wcześniejszych od 3. Jeżeli nie zostanie podany identyfikator łącza. Aby otrzymać te same wyniki. 5 a 15 (włącznie) użyj mt_rand(5. co w naszym krótkim przykładzie trzeba było wywołać funkcję mt_rand(5.edu/~marc/hawk/twister.keio.0. Jeżeli 319 PHP – Kompendium wiedzy . będzie ona ustawiona jako bieżąca baza danych.3. mt_getrandmax(). int mt_rand (void) int mt_rand (int min. Korzysta ona z generatora liczb losowych Mersenne Twister o znanej charakterystyce.0. rand() i getrandmax(). Jeżeli nie uda się autoryzacja nowego użytkownika. który generuje liczby losowe wystarczające do inicjowania niektórych rodzajów funkcji kryptograficznych (więcej informacji na stronie domowej) i jest średnio cztery razy szybszy od generatora dostarczanego w libc. int mysql_change_user (string user.13 i wymaga MySQL w wersji co najmniej 3.html. UPDATE lub DELETE na serwerze skojarzonym z podanym identyfikatorem łącza. jedynie dla wyrażeń zmieniających rekordy. Należy pamiętać. mt_rand() zwraca liczbę pseudolosową z przedziału 0 do RAND_MAX. należy użyć mysql_num_rows(). Aby pobrać ilość wierszy zwracanych przez zapytanie SELECT. srand(). srand(). Jeżeli zostanie podana baza danych.

Obsługa ":/sciezka/do/gniazda" została dodana w PHP 3. "marliesle". mysql_connect Zwraca dodatni identyfikator połączenia do MySQL. np. "secret") or die ("Nie można podłączyć"). że wcześniej zostanie zamknięte za pomocą mysql_close(). string password]]]) Przykład: MySQL_connect() <?php $link = mysql_connect ("kraemer". mysql_create_db Tworzy nową bazę danych na serwerze wskazywanym przez podany identyfikator łącza. Połączenie z serwerem zostanie zamknięte po zakończeniu wykonywania skryptu chyba. ?> Patrz również: mysql_pconnect() i mysql_close(). Ciąg z nazwą komputera może zawierać numer portu lub ścieżkę do gniazda. Użycie tej funkcji nie jest zwykle konieczne. print ("Podłączenie udane"). lub False w przypadku błędu. Zamiast tego zwrócony zostanie identyfikator istniejącego już połączenia. Patrz również: mysql_drop_db(). print ("Podłączenie udane"). ponieważ połączenia nietrwałe są automatycznie zamykane po zakończeniu wykonywania skryptu. if (mysql_create_db ("my_db")) { print ("Udane utworzenie bazy danych\n"). "geheim") or die ("Nie można podłączyć"). $username — nazwa użytkownika. Dodatek A . przyjmowane są następujące wartości domyślne: $host:port = 'localhost:3306'.: ":/sciezka/do/gniazda" dla komputera lokalnego. mysql_error ()). który jest właścicielem procesu i $password — pusty ciąg. int mysql_create_db (string database name [.10. mysql_close ($link). string username [. resource mysql_connect ([string hostname [:port] [:/path/to/socket] [. bool mysql_close ([resource link_identifier]) Przykład: MySQL_close() <?php $link = mysql_connect ("kraemer". } else { printf ("Błąd tworzenia bazy danych: %s\n". } ?> Aby zachować zgodność z poprzednimi wersjami można również używać funkcji mysql_createdb(). mysql_close ($link). Uwaga Funkcja mysql_close() nie zamyka połączeń trwałych otwartych za pomocą mysql_pconnect(). ?> Patrz również: mysql_connect() i mysql_pconnect().0. Uwaga Obsługa ":port" została dodana w PHP 3. resource link_identifier]) Przykład: Tworzenie bazy danych MySQL <?php $link = mysql_pconnect ("kron". Drugie wywołanie mysql_connect() z takimi samymi argumentami nie spowoduje zestawienia następnego połączenia. Funkcja mysql_connect() nawiązuje połączenie z serwerem MySQL. Jeżeli nie zostaną podane parametry domyślne. "secret") or die ("Nie można podłączyć").Funkcje 320 .0B4. "jutta". "marliesle". używane jest ostatnio otwarte połączenie.identyfikator połączenia nie zostanie podany. Można zapobiec generowaniu komunikatów błędu umieszczając znak @ przed nazwą funkcji.

int row_number) Przykład: Przesuwanie wskaźnika w wyniku <?php $link = mysql_pconnect ("kron". mysql_select_db ("samp_db") or die ("Nie można wybrać bazy danych"). Wybiera bazę danych i wykonuje na niej zapytanie. string query [. użyte zostanie ostatnio otwarte łącze. bool mysql_data_seek (resource result_identifier. 'password'). $i = 0. "jutta". Jeżeli wystąpi błąd. $i) . Nie mysql_db_query Zwraca dodatni identyfikator zapytania MySQL lub False w przypadku wystąpienia błędu. $cnt = mysql_num_rows($db_list). Funkcja mysql_drop_db() próbuje usunąć z serwera całą bazę danych skojarzoną z podanym identyfikatorem połączenia. first_name FROM friends". mysql_dbname(). $result = mysql_query ($query) or die ("Zapytanie nieudane"). continue. Parametr $row_number przyjmuje wartości rozpoczynające się od 0. } if(!($row = mysql_fetch_object ($result))) continue. $i)) { echo "Nie mogę przejść do wersza $i\n". int row [. echo ("$row->last_name $row->first_name<BR>\n".1. funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja mysql_connect() wywołana bez argumentów. mixed field]) Przykład: mysql_db_name() <?php error_reporting(E_ALL). Jeżeli nie ma otwartego łącza. "geheim") or die ("Nie można podłączyć"). Aby określić rodzaj błędu należy użyć funkcji mysql_errno() i mysql_error(). bool mysql_drop_db (string database_name [. Dla zachowania zgodności można również używać nazwy mysql(). # Pobieranie wierszy w odwrotnej kolejności for ($i = mysql_num_rows ($result) .mysql_data_seek Zwraca True w przypadku powodzenia a False w przypadku błędu. string mysql_db_name (resource result. resource link_identifier]) mysql_drop_db Zwraca True w przypadku powodzenia operacji a False w przypadku błędu. Patrz również: mysql_create_db(). Kolejne wywołanie funkcji mysql_fetch_row() zwróci ten wiersz. $query = "SELECT last_name. ?> mysql_db_name Jako pierwszego parametru wymaga wskaźnika wyniku zwracanego przez funkcję mysql_list_dbs(). $i >=0. Patrz również: mysql_connect(). } mysql_free_result ($result). Przesuwa wewnętrzny znacznik wiersza w wyniku MySQL skojarzonym z podanym identyfikatorem wyniku zapytania do wiersza o podanym numerze. Dla zachowania zgodności można równie używać funkcji mysql_dropdb(). Jeżeli opcjonalny identyfikator łącza nie zostanie podany. resource mysql_db_query (string database. } ?> Dla zachowania zgodności z poprzednimi wersjami można również używać nazwy jest to jednak zalecane. Parametr $row jest indeksem w wyniku. "\n". mysql_connect('dbhost'. 'username'. resource link_identifier]) 321 PHP – Kompendium wiedzy . $i++. $db_list = mysql_list_dbs(). while ($i < $cnt) { echo mysql_db_name($db_list. zwracana jest wartość False. $i--) { if (!mysql_data_seek ($result.

"<BR>". używając nazw pól jako kluczy. mysql_select_db("nonexistentdb"). $result = mysql_db_query ("database". int result_type]) Należy przypomnieć. $user. echo mysql_errno(). Uwaga Funkcja zwraca kod błędu dla ostatnio wykonanej funkcji MySQL (opócz mysql_error() i mysql_errno()). jedynie dostarcza więcej wyników. zamiast tego należy pobierać numery błędów za pomocą funkcji mysql_errno().mysql_error(). array mysql_fetch_array (resource result [. string mysql_error ([resource link_identifier]) Przykład: mysql_errno() <?php mysql_connect("marliesle"). ?> Patrz również: mysql_error(). Aby odczytać wartości kolumn o tych samych nazwach należy korzystać z indeksów numerycznych lub stworzyć aliasy dla kolumn. echo mysql_errno(). $conn = mysql_query("SELECT * FROM nonexistenttable")."<BR>"."select user_id. należy sprawdzać kod błędu przed wywołaniem kolejnej funkcji MySQL.mysql_error().": ". że funkcja mysql_fetch_array() NIE jest wyraźnie wolniejsza od funkcji mysql_fetch_row()."<BR>".": ".mysql_error(). mysql_error Zwraca komunikat błędu dla ostatnio wykonanej funkcji MySQL lub 0. echo mysql_errno(). Jeżeli chcesz jej użyć."<BR>"."<BR>". Opcjonalny drugi argument.": ".": ". echo mysql_errno(). Funkcja mysql_fetch_array() jest rozszerzeniem funkcji mysql_fetch_row().7). while ($row = mysql_fetch_array ($result)) { Dodatek A .": ". echo mysql_errno(). echo mysql_errno(). Patrz również: mysql_fetch_row() i mysql_fetch_assoc().mysql_errno Zwraca numer błędu dla ostatnio wykonanej funkcji MySQL lub 0. mysql_select_db("nonexistentdb"). fullname from table"). Oprócz zapamiętywania danych pod indeksami numerycznymi.0. Uwaga Funkcja zwraca kod błędu dla ostatnio wykonanej funkcji MySQL (opócz mysql_error() i mysql_errno()). Jeżeli chcesz jej użyć. mysql_fetch_array Zwraca tablicę odpowiadająca pobranemu wierszowi. jeżeli nie wystąpił żaden błąd. lub False jeżeli nie ma już wierszy do pobrania.mysql_error(). Jeżeli dwie lub więcej pól w wyniku ma takie same nazwy. zamiast tego należy pobierać komunikaty błędów za pomocą funkcji mysql_error().Funkcje 322 ."<BR>". $conn = mysql_query("SELECT * FROM nonexistenttable").mysql_error(). dodatkowo dane są zapisywane pod indeksami asocjacyjnymi. jeżeli nie wystąpił żaden błąd. ?> Patrz również: mysql_errno(). Przykład: mysql_fetch_array() <?php mysql_connect ($host. $password). należy sprawdzać kod błędu przed wywołaniem kolejnej funkcji MySQL.mysql_error().": ". $result_type może być jedną ze stałych: MYSQL_ASSOC. Błędy wysyłane przez serwer MySQL nie mogą być traktowane jako ostrzeżenia. MYSQL_NUM i MYSQL_BOTH (parametr ostał dodany w PHP 3. int mysql_errno ([resource link_identifier]) Przykład: mysql_errno() <?php mysql_connect("marliesle"). Błędy wysyłane przez serwer MySQL nie mogą być traktowane jako ostrzeżenia. zwrócona zostanie wartość ostatniego z nich.

} mysql_free_result ($result)."<br>\n"."select * from table"). Jeżeli nie zostanie podane przesunięcie. które nie było jeszcze odczytane. int field_offset]) • • • • • • • • • • • • Właściwości zwracanego obiektu są następujące: name — nazwa kolumny table — nazwa tabeli do której należy kolumna max_length — maksymalna długość pola not_null — 1 jeżeli kolumna nie może być pusta primary_key — 1 jeżeli kolumna jest kluczem głównym unique_key — 1 jeżeli kolumna jest kluczem unikalnym multiple_key — 1 jeżeli kolumna nie jest kluczem unikalnym numeric — 1 jeżeli kolumna jest numeryczna blob — 1 jeżeli kolumna jest typu BLOB type — typ kolumny unsigned — 1 jeżeli kolumna jest bez znaku zerofill — 1 jeżeli kolumna jest wypełniana zerami Przykład: mysql_fetch_field() <?php mysql_connect ($host. $password). $user. Aby odczytać wartości kolumn o tych samych nazwach należy użyć funkcji mysql_fetch_array() i skorzystać z indeksów numerycznych. Powoduje to zwrócenie tylko tablicy asocjacyjnej. Funkcja mysql_fetch_assoc() jest odpowiednikiem wywołania funkcji mysql_fetch_array() z parametrem MYSQL_ASSOC. ". Należy przypomnieć."<br>\n". # pobranie metadanych kolumny $i = 0. } 323 PHP – Kompendium wiedzy . Jeżeli dwie lub więcej pól w wyniku ma takie same nazwy. while ($row = mysql_fetch_assoc ($result)) { echo $row["user_id"]."<br>\n".$row[0]. Patrz również: mysql_fetch_row() i mysql_fetch_array(). ?> mysql_fetch_assoc Zwraca tablicę asocjacyjną odpowiadającą bieżącemu wierszowi lub False. $result = mysql_db_query ("database". zwrócona zostanie wartość ostatniego z nich. odczytywane jest następne pole."<br>\n". że funkcja mysql_fetch_assoc() NIE jest wyraźnie wolniejsza od funkcji mysql_fetch_row(). object mysql_fetch_field (resource result [. if (!$meta) { echo "Brak dostępnych danych<BR>\n". while ($i < mysql_num_fields ($result)) { echo "Informacje na temat kolumny: $i:<BR>\n". Funkcja mysql_fetch_field() może być użyta do pobrania danych na temat pól w wyniku.$row["user_id"]. jedynie dostarcza więcej wyników. echo $row["fullname"].$row["fullname"]. ". $meta = mysql_fetch_field ($result). ". jeżeli nie ma już więcej wierszy w wyniku. array mysql_fetch_assoc (resource result) Przykład: mysql_fetch_assoc() <?php mysql_connect ($host. ?> mysql_fetch_field Zwraca obiekt zawierający informacje o polu.echo echo echo echo "ID użytkownika: "ID użytkownika: "Pełna nazwa : "Pełna nazwa : ". Jest to sposób w jaki wcześniej działała funkcja mysql_fetch_array(). $user. $password) or die ("Nie można podłączyć"). "select * from table") or die ("Zapytanie nieudane"). $result = mysql_db_query ("database". } mysql_free_result ($result).$row[1].

int result_type]) Przykład: mysql_fetch_object() <?php mysql_connect ($host. "select * from table"). mysql_fetch_object(). więc można je łatwo rozdzielić za pomocą funkcji explode(). while ($row = mysql_fetch_object ($result)) { echo $row->user_id.echo "<PRE> blob: $meta->blob max_length: $meta->max_length multiple_key: $meta->multiple_key name: $meta->name not_null: $meta->not_null numeric: $meta->numeric primary_key: $meta->primary_key table: $meta->table type: $meta->type unique_key: $meta->unique_key unsigned: $meta->unsigned zerofill: $meta->zerofill </PRE>". Wiersz jest zwracany w postaci tablicy. Funkcja mysql_fetch_lengths() przechowuje długości każdej kolumny wyniku w ostatnim wierszu zwracanym przez mysql_fetch_row(). Każda kolumna jest zapisywana w osobnym indeksie tablicy. że możesz odwoływać się do pól poprzez nazwy a nie poprzez indeks( liczby nie są prawidłowymi nazwami właściwości). $result_type w funkcji mysql_fetch_array() jest jedną z następujących stałych: MYSQL_ASSOC. ?> Patrz również: mysql_fetch_array() i mysql_fetch_row(). Funkcja mysql_fetch_row() pobiera jeden wiersz z wyniku określonego przez identyfikator zapytania. } mysql_free_result ($result). Funkcja mysql_fetch_object() jest podobna do mysql_fetch_array() z jedną różnicą — zwracany jest obiekt a nie tablica. Funkcja jest identyczna wydajnościowo z mysql_fetch_array() i prawie tak samo szybka jak mysql_fetch_row() — różnica jest nieznaczna. $result = mysql_db_query ("database". MYSQL_NUM i MYSQL_BOTH. ?> mysql_fetch_lengths tablicę zawierającą długości pól z ostatniego wiersza odczytanego przez funkcję mysql_fetch_row() lub False w przypadku błędu. Patrz również: mysql_fetch_row(). Drugi argument. $i++. Atrybuty są zwracane w jednym ciągu rozdzielone spacjami.Funkcje 324 . mysql_fetch_array() i mysql_fetch_object() w tablicy rozpoczynającej się od indeksu 0. jeżeli nie ma więcej wierszy do pobrania. array mysql_fetch_lengths (resource result) Zwraca mysql_fetch_object Zwraca obiekt z właściwościami odpowiadającymi polom pobieranego wiersza lub False. mysql_data_seek() i mysql_result(). $password). mysql_fetch_row Zwraca tablicę odpowiadająca pobranemu wierszowi. } mysql_free_result ($result). echo $row->fullname. Zwracane są następujące atrybuty o ile twoja wersja MySQL je Dodatek A . object mysql_fetch_object (resource result [. rozpoczynając od 0. lub False jeżeli nie ma już wierszy do pobrania. Oznacza to. Kolejne wywołanie mysql_fetch_row() powoduje zwracanie kolejnych wierszy z wyniku lub False jeżeli nie ma już więcej wierszy. Patrz również: mysql_fetch_array(). $user. array mysql_fetch_row (resource result) mysql_field_flags Zwraca atrybuty podanego pola.

int field_index) $result jest identyfikatorem zapytania. Jeżeli następne wywołanie mysql_fetch_field() nie będzie zawierało numeru pola. string mysql_field_name (resource result. unsigned. Wykonanie tego przykładu spowoduje wypisanie następującego wyniku: user_id password Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldname(). Parametr numerem kolejnym pola. Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldflags(). unique_key. string mysql_field_flags (resource result. echo mysql_field_name($res. $fields = mysql_num_fields ($result). int mysql_field_len (resource result. string mysql_field_type (iresource result. auto_increment i timestamp. real. int field_offset) mysql_field_type Funkcja podobna do mysql_field_name(). Typami tymi mogą być int. Argumenty są identyczne. primary_key. int field_offset) mysql_field_name Zwraca nazwę podanego pola. echo mysql_field_name($res. int mysql_field_seek (resource result. 0) . blob i inne opisane w dokumentacji MySQL. Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldtable(). 2). ale zwracane są typy pól. multiple_key. Patrz również: mysql_fetch_field(). int field_offset) mysql_field_len Zwraca długość podanego pola. z której pochodzi podane pole. string mysql_field_table (resource result. indeks trzeciego pola będzie 2. a $field_index jest Przykład: mysql_field_name() // Tabela users składa się z trzech pól: // user_id // username // password. mysql_select_db ("wisconsin"). "\n".wszystkie obsługuje: not_null. $link). Na przykład. enum. Patrz również: mysql_fetch_field(). "select * from users". Uwaga Wartości $field_index rozpoczynają się od 0. Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldlen(). string. int field_offset) Przykład: Typy pól MySQL <?php mysql_connect ("localhost:3306"). binary. zostanie zwrócone to właśnie pole. $result = mysql_query ("SELECT * FROM onek"). czwartego — 3 itd. $res = mysql_db_query("users". int field_offset) mysql_field_table Zwraca nazwę tabeli. $i = 0. zerofill. $rows = mysql_num_rows ($result). blob. 325 PHP – Kompendium wiedzy . mysql_field_seek Przesuwa wskaźnik do podanego numeru pola.

. $i). $i).$len. Jeżeli kolumna AUTO_INCREMENT będzie miała typ BIGINT. $i). int mysql_insert_id ([resource link_identifier]) mysql_list_dbs Zwraca znacznik wyniku zawierającego bazy danych dostępne dla demona mysql. Jeżeli chcesz zachować tą wartość do późniejszego użycia trzeba pamiętać. 'secret'). przyjmowane jest ostatnio otwarte łącze. Funkcja ta jest potrzebna tylko wtedy. while ($row = mysql_fetch_object($db_list)) { echo $row->Database .$flags." rekordów <BR>". $len = mysql_field_len ($result.. wartości zwracane przez mysql_insert_id() będą nieprawidłowe. mysql_free_result Zwalnia pamięć przydzieloną dla $result. Jeżeli nie zostanie podany identyfikator łącza."<BR>". Dodatek A ." "." pól i ". $flags = mysql_field_flags ($result." ". Uwaga Wartość funkcji MySQL LAST_INSERT_ID() zawsze zawiera ostatnio wygenerowaną wartość AUTO_INCREMENT i nie jest ona kasowana pomiędzy zapytaniami. Uwaga Funkcja działa również z funkcjami mysql_fetch_row() lub podobnymi. gdy nie chcemy zużywać zbyt wiele pamięci w czasie działania skryptu. "\n". echo $type. aby wywołać funkcję natychmiast po zapytaniu generującym wartość. echo "Tabela '". ?> Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldtype(). Dla zachowania zgodności wstecz można używać również nazwy mysql_freeresult(). 'myname'. int mysql_free_result (resource result) mysql_insert_id Zwraca identyfikator generowany dla kolumn AUTO_INCREMENT przez ostatnie wyrażenie INSERT wykonane na podanym identyfikatorze łącza. Należy użyć funkcji mysql_tablename() do odczytania tego znacznika wyniku. Funkcja mysql_insert_id() konwertuje typ wartości zwracanej przez funkcję MySQL API na typ long. $db_list = mysql_list_dbs($link).$fields. $i). resource mysql_list_dbs ([resource link_identifier]) Przykład: mysql_list_dbs() $link = mysql_connect('localhost'.Funkcje 326 .$name. $name = mysql_field_name ($result. Funkcja mysql_insert_id() zwraca 0 jeżeli poprzednie zapytanie nie generowało wartości AUTO_INCREMENT. while ($i < $fields) { $type = mysql_field_type ($result. Zamiast tego można używać wewnętrznej funkcji MySQL — LAST_INSERT_ID()."' ma ".$table. } Przykład ten może dać następujące wyniki: database1 database2 database3 . Dla zachowania zgodności wstecz można używać również nazwy mysql_listdbs(). $i++. Po zakończeniu wykonywania żądania pamięć jest zwalniana automatycznie.$table = mysql_field_table ($result. } mysql_close(). echo "Tabela składa się z następujących pól: <BR>".$rows." ". $i).

Funkcja nawiązuje połączenie z serwerem MySQL. Patrz również: mysql_db_query(). resource link_identifier]) mysql_num_fields Zwraca ilość pól w wyniku. for ($i = 0. Jeżeli nie zostaną podane parametry domyślne.Dla zachowania zgodności wstecz można używać również nazwy mysql_numrows(). lub False w przypadku błędu. } Przykład ten może dać następujące wyniki: field1 fiels2 field3 . Identyfikator wyniku jest dodatnią liczbą całkowitą. Dla zachowania zgodności wstecz można używać również nazwy mysql_listfields(). resource mysql_pconnect ([string hostname [:port] [:/path/to/socket] [. Zwracany jest znacznik wyniku. int mysql_num_fields (resource result) mysql_num_rows Zwraca ilość wierszy w wyniku. mysql_query() i mysql_fetch_row(). Dla zachowania zgodności wstecz można używać również nazwy mysql_numfields(). $columns = mysql_num_fields($fields). $i) . Można zapobiec generowaniu komunikatów błędu umieszczając znak @ przed nazwą funkcji. resource mysql_list_fields (string database_name. $i < $columns. "table1". $username — nazwa użytkownika. przyjmowane są następujące wartości domyślne: $host:port = 'localhost:3306'. który jest właścicielem procesu i $password — pusty ciąg. UPDATE lub DELETE należy używać funkcji mysql_affected_rows().mysql_list_fields Pobiera dane na temat podanej tabeli. string username [. W przypadku błędu funkcja zwraca -1.. Dla zachowania zgodności wstecz można używać również nazwy mysql_listtables(). resource mysql_list_tables (string database [. string password]]]) 327 PHP – Kompendium wiedzy . "\n". $i++) { echo mysql_field_name($fields.. ciąg ten jest wypisywany na wyjście. resource link_identifier]) Przykład: mysql_list_fields() $link = mysql_connect('localhost'. Obsługa ":/sciezka/do/gniazda" została dodana w PHP 3. $fields = mysql_list_fields("database1".0B4. np. mysql_db_query(). mysql_fetch_field() i mysql_num_rows().. int mysql_num_rows (resource result) mysql_pconnect Zwraca dodatni identyfikator trwałego połączenia do MySQL. mysql_list_tables Pobiera jako argument nazwę bazy danych i zwraca znacznik wyniku podobnie do funkcji Do pobrania wyniku na podstawie znacznika powinna zostać użyta funkcja mysql_tablename(). Aby odczytać ilość wierszy zwracanych z wyrażeń INSERT. Patrz również: mysql_db_query(). mysql_query(). Ciąg z nazwą komputera może zawierać numer portu lub ścieżkę do gniazda.0.: ":/sciezka/do/gniazda" dla komputera lokalnego.10. mysql_pconnect() Uwaga Obsługa ":port" została dodana w PHP 3. 'secret'). string table_name [. $link). Parametrami są nazwa bazy danych i nazwa tabeli. 'myname'. mysql_fieldlen(). który może być użyty w funkcjach mysql_fieldflags(). mysql_fieldname() i mysql_fieldtype(). Ciąg opisujący błąd umieszczany jest w $phperrmsg i jeżeli funkcja nie została wywołana jako @mysql_list_fields(). Funkcja działa jedynie dla wyrażeń SELECT.

Dlatego ten typ połączenia nazywany jest „trwałym”. należy użyć aliasu a nie oryginalnej nazwy kolumny.). Funkcja mysql_query() zwraca True (wartość różną od zera) jeżeli zapytanie udało się lub False gdy nie udało się. numerze i wyniku MySQL. mixed field]) Dodatek A . ?> Kolejne zapytanie może być niepoprawne. Jeżeli kolumna otrzymała w zapytaniu alias (select foo as bar from . Jest możliwe wykonanie poprawnego zapytania. Dla wyrażeń SELECT funkcja mysql_query() zwraca nowy identyfikator wyniku. Podawanie numerów pól zamiast ich nazw powoduje szybsze działanie funkcji. zostaje zwrócone zamiast nowego połączenia. Po drugie. Jeżeli nie ma otwartego łącza.Funkcja mysql_pconnect() działa bardzo podobnie do mysql_connect() z dwiema różnicami. Patrz również: mysql_affected_rows(). połączenie do serwera MySQL nie jest zamykane po zakończeniu pracy skryptu. Zwrócenie wartości True wskazuje tylko. Jeżeli identyfikator ten nie zostanie podany. REPLACE lub UPDATE. które nie zwróci żadnych wierszy. jeżeli nie masz wystarczających uprawnień do tabel na których operuje zapytanie. mysql_select_db() i mysql_connect(). Zakładając. jeżeli kolumna my_col nie będzie istniała w tabeli my_tbl i w takim przypadku mysql_query() zwróci False. Pracując na dużych wynikach należy rozważyć użycie jednej funkcji do wczytania całego wiersza. Uwaga Ciąg z zapytaniem nie może kończyć się średnikiem. można wywołać funkcję mysql_num_rows() aby sprawdzić ile wierszy zwróciło zapytanie SELECT lub mysql_affected_rows() aby sprawdzić ile wierszy zostało zmienionych przez wyrażenie DELETE. resource mysql_query (string query [.tabela).Funkcje 328 . Zalecanymi szybszymi funkcjami są: mysql_fetch_row(). mysql_free_result(). Po zakończeniu pracy na wyniku można zwolnić zasoby z nim związane wywołując mysql_free_result(). ?> Funkcja mysql_query() może się również nie udać i zwrócić False. w czasie połączenia zamiast otwierać nowe połączenie funkcja próbuje znaleźć istniejące łącze (trwałe). są one dużo szybsze od mysql_result(). resource link_identifier]) Poniższe zapytanie jest niepoprawne składniowo. że zapytanie się uda. funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja mysql_connect() wywołana bez parametrów a następnie używa łącza do wykonania zapytania.. int row [. mixed mysql_result (resource result. więc funkcja mysql_query() zwróci False. Argument $field może być numerem pola. Nie mówi to nic na temat ilości zmienionych lub zwróconych wierszy. nazwą pola lub nazwą w postaci tabela kropka pole (pole. mysql_query Wysyła zapytanie do aktywnej bazy danych skojarzonej z podanym identyfikatorem łącza. Przykład: mysql_query() <?php $result = mysql_query ("SELECT my_col FROM my_tbl") or die ("Nieprawidłowe zapytanie"). użyte zostanie ostatnio otwarte łącze. że zapytanie może być wykonane przez serwer. Jeżeli zostanie ono znalezione. który może być przekazany do funkcji mysql_result(). mysql_result().. Przydzielona pamięć jest jednak automatycznie zwalniana po zakończeniu skryptu. mysql_fetch_array() i mysql_fetch_object(). Po pierwsze. Wywołania funkcji mysql_result() nie powinny być mieszane z wywołaniami innych funkcji operujących na wyniku. mysql_result Zwraca zawartość komórki w podanym wierszu. INSERT. Przykład: mysql_query() <?php $result = mysql_query ("SELECT * WHERE 1=1") or die ("Nieprawidłowe zapytanie"). mysql_db_query(). Łącze takie pozostaje otwarte do wykorzystania w przyszłości (mysql_close() nie zamyka połączeń utworzonych przez mysql_pconnect()). Ponieważ funkcje te zwracają zawartość wielu pól za pomocą jednego wywołania.

png". $i++. echo "\nSortowanie w porządku naturalnym\n". Więcej informacji na temat tego algorytmu można znaleźć na stronie http://www. Różnica pomiędzy sortowaniem naturalnym a zwykłym algorytmem sortowania pokazana jest w przykładzie zastosowania funkcji natsort(). Funkcja mysql_select_db() ustawia na serwerze bieżącą aktywną bazę danych o podanym identyfikatorze łącza. while ($i < mysql_num_rows ($result)) { $tb_names[$i] = mysql_tablename ($result. int i) Przykład: mysql_tablename() <?php mysql_connect ("localhost:3306"). Kolejne wywołania mysql_query() wykonywane są na aktywnej bazie danych. Dla zgodności z poprzednimi wersjami można korzystać z nazwy mysql_selectdb(). Patrz również: mysql_connect(). sort($array1).mysql_select_db Zwraca True w przypadku powodzenia a False w przypadku błędu. Funkcja mysql_numrows() może być użyta do określenia ilości tabel w wyniku.png [2] => img2. print_r($array1). mysql_pconnect() i mysql_query().com. "img10. void natsort (array array) Przykład: natsort() $array1 = $array2 = array ("img12. strnatcmp() i strnatcasecmp().png". Jeżeli identyfikator ten nie zostanie podany. natsort(). Jest on nazwany „porządkowaniem naturalnym”.png". która nie rozróżnia wielkości liter. Jest on nazwany „porządkowaniem naturalnym”. Różnica pomiędzy sortowaniem naturalnym a zwykłym algorytmem sortowania pokazana jest na poniższym przykładzie. string mysql_tablename (resource result. Jeżeli nie ma otwartego łącza. void natcasesort (array array) natsort Stosuje algorytm sortowania ciągów w sposób w jaki robią to ludzie. echo "Zwykłe sortowanie\n". użyte zostanie ostatnio otwarte łącze. print_r($array2). Funkcja natcasesort() jest wersją funkcji natsort().png 329 PHP – Kompendium wiedzy . } ?> natcasesort Stosuje algorytm sortowania ciągów w sposób w jaki robią to ludzie.png").au/projects/natsort/. Patrz również: sort().png [1] => img10. Wykonanie tego kodu da następujący wynik: Zwykłe sortowanie Array ( [0] => img1. natsort($array2). $result = mysql_list_tables ("wisconsin"). resource link_identifier]) mysql_tablename Na podstawie identyfikatora wyniku zwracanego przez mysql_list_tables() oraz numeru kolejnego pobiera i zwraca nazwę tabeli.png [3] => img2. funkcja próbuje utworzyć połączenie identycznie jak robi to funkcja mysql_connect() a następnie używa łącza do wybrania bazy danych.png [2] => img12. "img2. $i = 0. $i).png ) Sortowanie w porządku naturalnym Array ( [3] => img1. echo $tb_names[$i] . bool mysql_select_db (string database_name [. "<BR>". "img1.linuxcare.

liczba jest z $decimals cyfr po przecinku. string number_format (float number [. Jeżeli tablica zawiera pusty element lub element o wartości klucza 0. Jeżeli chcesz przetworzyć zawartość bufora musisz użyć funkcji ob_get_contents() przed ob_end_flush(). next Zwraca element tablicy znajdujący się na następnym miejscu wskazywanym przez wewnętrzny wskaźnik tablicy lub False. Aby prawidłowo przeglądać tablice.au/projects/natsort/. Jeżeli podany został jeden parametr. Patrz również: ob_end_flush(). Next() przesuwa wewnętrzny wskaźnik tablicy o jeden element dalej. z kropką dziesiętną i przecinkami pomiędzy grupami tysięcy. end(). http://www. ob_get_contents() i ob_end_clean().png [0] => img12. Patrz również: curent(). prev() i reset(). Jeżeli są podane wszystkie cztery parametry. należy użyć funkcji each().[1] => img10. string ob_get_contents (void) False. string dec_point [.com. funkcja wróci False po napotkaniu takiego elementu. htmlentities() string nl2br (string string) <BR> wstawionymi przed wszystkimi znakami nowej linii. mixed next (array array) nl2br Zwraca ciąg ze znacznikami htmlspecialchars(). jeżeli nie ma już więcej elementów. next() zwraca False. ale z przecinkami pomiędzy kolejnymi grupami tysięcy. Patrz również: i word_wrap(). liczba jest formatowana z $decimals cyfr po przecinku. ze znakiem $dec_point zamiast kropki dziesiętnej i znakiem $thousand_sep zamiast przecinka pomiędzy grupami tysięcy. dwoma lub czterema parametrami (nie z trzema).png ) Więcej informacji można znaleźć na stronie poświęconej temu algorytmowi. Jeżeli przesunięcie wskaźnika spowoduje wyjście wskaźnika poza tablicę. int decimals [. ponieważ zawartość bufora jest usuwana po wywołaniu ob_get_contents(). void ob_end_flush (void) ob_get_contents Zwraca zawartość bufora wyjściowego lub również: ob_start() i ob_get_length(). string thousands_sep]]]) ob_end_clean Usuwa zawartość bufora wyjściowego i wyłącza buforowanie wyjścia.linuxcare. Patrz Dodatek A . Patrz również: natcasesort(). Funkcja może być wywołana z jednym. które mogą zawierać puste elementy lub klucze o wartości 0. Jeżeli podane są dwa parametry. jeżeli buforowanie wyjścia nie jest aktywne.Funkcje 330 . void ob_end_clean (void) ob_start() i ob_end_flush Wysyła zawartość bufora wyjściowego (o ile istnieje) na wyjście i wyłącza buforowanie wyjścia. number_format Zwraca liczbę $number w sformatowanej postaci. z jedną różnicą. liczba $number jest formatowana bez części ułamkowej. Funkcja next() zachowuje się podobnie do current(). Patrz również: ob_start(). strnatcmp() i strnatcasecmp().

while (OCIFetchInto($stmt. Możliwymi wartościami są: OCI_B_FILE (plik binarny). 2222 => "Bill". "returning ROWID into :rid").-1. ob_start() i ob_end_flush(). OCIBindByName($update."select * from emp where empno in (1111.&$ename. ob_end_flush(). void ob_start ([string output_callback]) OCIBindByName Łączy zmienną PHP $variable z obszarem zablokowanym $ph_name. czy zostanie on użyty jako wejście czy jako wyjście jest określane w czasie pracy i wtedy przydzielana jest niezbędna pamięć. int type]) Przykład: OCIDefineByName <?php /* przykład uzycia OCIBindByPos. OCI_B_BLOB (binarny LOB) i OCI_B_ROWID (ROWID).32). OCI_B_CLOB (znakowy LOB). Patrz również: ob_start() i ob_get_contents(). Gdy aktywne jest buforowanie wyjścia. $sal = 10000. thies@thieso. $data = array(1111 => "Larry". int OCIBindByName (int stmt. należy wywołać funkcję ob_end_flush().&$rowid. string ph_name. ob_end_clean() i ob_implict_flush().32). Ukryte opróżnianie bufora powoduje opróżnianie bufora po każdej operacji wyjścia. OCIBindByName($stmt. int length [. OCI_B_CFILE (plik znakowy). OCIExecute($stmt). while (list($empno.&$arr.OCI_D_ROWID). BFILE).2222. ROWID. Patrz również: flush(). więc nie są potrzebne jawne wywołania funkcji flush().$ename) = each($data)) { OCIExecute($stmt). void ob_implicit_flush ([int flag]) ob_start Włącza buforowanie wyjścia. To. OCIBindByName() do ustawienia długości użyje bieżącego rozmiaru $variable. OCIFreeStatement($stmt).":sal". Aby wysłać na wyjście dane zebrane w buforze. Zawartość tego bufora może być skopiowana do zmiennej za pomocą ob_get_contents().OCI_ASSOC)) { 331 PHP – Kompendium wiedzy . domyślnie włącza opcję).-1. string ob_get_length (void) ob_implicit_flush Włącza lub wyłącza ukryte opróżnianie bufora wyjściowego (jeżeli nie podany został znacznik $flag. Jeżeli musisz dołączyć abstrakcyjny typ danych (LOB. $update = OCIParse($conn.:ename) ". Włączenie ukrytego opróżniania powoduje wyłączenie buforowania wyjścia i zawartość bufora wyjściowego jest wysyłana tak samo.":rid".OCI_B_ROWID). OCIBindByName($stmt. "values (:empno. Parametr $length nie jest używany dla abstrakcyjnych typów danych i powinien być ustawiony na -1. Parametr $type określa typ używanego deskryptora. Patrz również: ob_get_contents(). mixed &variable. OCIExecute($update). OCIBindByName($update.":rid". i używa ROWID do zmiany rekordów zaraz p ich wstawieniu */ $conn = OCILogon("scott". ze skryptu nie są przesyłane żadne dane wyjściowe. } $rowid->free().ob_get_length Zwraca ilość danych w buforze wyjściowym lub False. ename) "."tiger"). Zamiast tego są one zbierane w wewnętrznym buforze.&$empno.OCI_B_ROWID). Jeżeli ustawisz $length na -1.&$rowid. $stmt = OCIParse($conn. jak po wywołaniu funkcji ob_end_flush(). $rowid = OCINewDescriptor($conn.":empno". $stmt = OCIParse($conn.&$sal. OCIBindByName($stmt."insert into emp (empno.":ename". 3333 => "Jim").32). Można również usunąć całą zawartość bufora za pomocą funkcji ob_end_clean()."update emp set sal = :sal where ROWID = :rid").3333)"). musisz je najpierw zarezerwować za pomocą funkcji OCINewDescriptor(). Parametr $length określa maksymalną długość dla połączenia. OCIFreeStatement($update). jeżeli buforowanie wyjścia nie jest aktywne.net (980221) wstawia trzy rekordy do emp.

print "<TD>$column_name</TD>".3333)"). print "<TH>Typ</TH>". int col) Przykład: OCIColumnName() <?php print "<HTML><PRE>\n". mixed column) Przykład OCIColumnSize() <?php print "<HTML><PRE>\n". $conn = OCILogon("scott". print "<TABLE BORDER=\"1\">".var_dump($arr). ?> OCIColumnSize Zwraca rozmiar kolumny Oracle.Funkcje 332 . print "<TH>Nazwa</TH>". Dodatek A . /* usunięcie naszych "śmieci" t tabeli emp. } OCIFreeStatement($stmt). for ( $i = 1. int OCIColumnIsNULL (int stmt.. $column_size = OCIColumnSize($stmt. print "<TH>Typ</TH>". OCILogoff($conn). print "</TR>". print "<TR>". */ $stmt = OCIParse($conn."select * from emp"). print "<TD>$column_type</TD>". OCIExecute($stmt). ponieważ nie jest potrzebne dodawanie apostrofów na zmiennych. Patrz również: OCINumCols().$i). string OCIColumnName (int stmt. $stmt = OCIParse($conn. "tiger"). $ncols = OCINumCols($stmt). mixed column) OCIColumnName Zwraca nazwę kolumny odpowiadającą przekazanemu numerowi kolumny (numerowane od 1). print "</TR>"."select * from emp"). print "</PRE>". Wszystkie apostrofu i cudzysłowy dodane w sposób automatyczny zostaną zapisane w bazie. print "<TR>".$i). Można użyć numerów kolumn (numerowane od 1) lub nazw. } OCIFreeStatement($stmt)."delete from emp where empno in (1111. ponieważ funkcja OciBindByName() nie potrafi odróżnić apostrofów dodanych automatycznie od tych dodanych z rozmysłem. Patrz również: OCINumCols(). print "</HTML>\n". OCIColumnIsNULL Zwraca True. print "<TR>". print "<TH>Długość</TH>". Do parametru $col można użyć numeru kolumny (numerowane od 1) lub nazwy kolumny. print "<TH>Długość</TH>". $i++ ) { $column_name = OCIColumnName($stmt. print "<TH>Nazwa</TH>". "tiger").$i). $column_type = OCIColumnType($stmt. int OCIColumnSize (int stmt. OCIColumnName() i OCIColumnSize(). print "<TABLE BORDER=\"1\">". OCIColumnType() i OCIColumnSize().. $i <= $ncols. print "<TD>$column_size</TD>". $conn = OCILogon("scott". ?> Jednoczesne użycie magic-quotes i OciBindByName() jest bardzo niedobrym pomysłem. jeżeli kolumna $column znajdująca się w wyniku z wyrażenia $stmt ma wartość NULL.2222. OCIExecute($stmt). OCIFreeStatement($stmt). OCIExecute($stmt).. OCILogoff($conn). $stmt = OCIParse($conn.

$i). OCIColumnName() i Przykład: OCIColumnType() <?php print "<HTML><PRE>\n". ROWID. print "<TD>$column_type</TD>". "tiger"). print "<TD>$column_name</TD>"."select * from emp"). $ncols = OCINumCols($stmt).$i). int col) OCINumCols(). print "</TR>". print "<TR>". $column_type = OCIColumnType($stmt. int type]) Przykład: OCIDefineByName() <?php /* przykład użycia OCIDefineByPos.$i). $column_type = OCIColumnType($stmt. print "<TD>$column_size</TD>". Funkcja OCIDefineByName() oczekuje. $conn = OCILogon("scott". OCILogoff($conn). Jeżeli musisz zdefiniować abstrakcyjny typ danych (LOB. print "<TH>Typ</TH>". $i++ ) { $column_name = OCIColumnName($stmt. print "</TR>". OCIExecute($stmt). thies@thieso. $i <= $ncols. int OCIDefineByName (int stmt. nie zostanie wygenerowany żaden błęd. print "<TR>". } print "</TABLE>". mixed variable [. ?> OCICommit Zatwierdza wszystkie zaległe zapytania dla połączenia do Oracle $connection. for ( $i = 1. print "<TR>".print "</TR>".$i). OCIFreeStatement($stmt). print "<TABLE BORDER=\"1\">". print "<TD>$column_size</TD>". BFILE) musisz najpierw użyć funkcji OCINewDescriptor(). $i <= $ncols. że Oracle zapisuje nazwy kolumn zawsze wielkimi literami a wyrażenia SELECT najczęściej piszemy małymi literami. Patrz również: OCIBindByName().$i). $stmt = OCIParse($conn. print "</PRE>". print "<TD>$column_type</TD>". string Column-Name. } OCIFreeStatement($stmt). $i++ ) { $column_name = OCIColumnName($stmt. print "</HTML>\n". $column_size = OCIColumnSize($stmt. print "</HTML>\n". $column_size = OCIColumnSize($stmt. ?> OCIColumnType Zwraca typ danych kolumny o podanym numerze Patrz również: OCIColumnSize(). for ( $i = 1. int OCICommit( int connection ) OCIDefineByName Powoduje przesłanie zawartości kolumn SQL do zmiennych PHP. print "</PRE>". $ncols = OCINumCols($stmt). OCILogoff($conn). Jeżeli zdefiniujesz zmienna nie istniejącą w wyrażeniu SELECT. print "</TR>".net (980219) */ 333 PHP – Kompendium wiedzy . mixed OCIColumnType (int stmt. print "<TH>Długość</TH>". print "<TH>Nazwa</TH>". że $column-name będzie zapisana wielkimi literami.$i). Należy pamiętać. print "<TD>$column_name</TD>".

} OCIFreeStatement($stmt). zwracany jest ostatni błąd. int OCIFetch (int statement) OCIFetchInto Pobiera kolejny wiersz (dla wyrażeń SELECT) do tabeli $result. Jeżeli nie napotkano błędu. OCILogoff($conn).$ename). if ( $nrows > 0 ) { print "<TABLE BORDER=\"1\">\n". $nrows = OCIFetchStatement($stmt. OCIDefineByName($stmt. Opcjonalny parametr $mode pozwala określić tryb wykonania (domyślnie jest to OCI_COMMIT_ON_SUCCESS). ?> OCIError Zwraca ostatni napotkany błąd. komunikat błędu. Jeżeli nie chcesz aby wyrażenia były automatycznie zatwierdzane."select empno."select * from emp"). while ( list( $key. int OCIFetchInto (int stmt.com (990624) */ $conn = OCILogon("scott".Funkcje 334 . int mode]) OCIFetch Pobiera kolejny wiersz (dla wyrażeń SELECT) do wewnętrznego bufora wyniku. $stmt = OCIParse($conn.$empno. OCIEror() zwraca False.$empno). array &result [. OCIExecute($stmt). mbritton@verinet. $val ) = each( $results ) ) { Dodatek A ."ENAME". OCIExecute($stmt)."\n". Funkcja zwraca błąd w tablicy asocjacyjnej. /* ta definicja MUSI znajdować się przed ociexecute! */ OCIDefineByName($stmt. Funkcja OCIFetchInto() nadpisuje poprzednią zawartość tablicy $result."\n". Funkcja int OCIFetchStatement (int stmt. na przykład: OCI_ASSOC+OCIRETURN_NULLS. array OCIError ([int stmt|conn|global]) OCIExecute Wykonuje zanalizowane wyrażenie (OCIParse()). array &variable) Przykład: OCIFetchStatement() <?php /* przykład OCIFetchStatement. Jeżeli nie podany zostanie parametr opcjonalny $stmt|conn|global. int OCIExecute (int statement [. int mode]) • • • • Możliwymi wartościami znacznika są: OCI_ASSOC — zwraca tablic asocjacyjną OCI_NUM — zwraca tablicę o indeksach numerycznych rozpoczynających się od 1 (domyślnie) OCI_RETURN_NULLS — zwraca puste kolumny OCI_RETURN_LOBS — zwraca wartości LOB zamiast deskryptorów OCIFetchStatement Pobiera OCIFetchStatement() wszystkie wiersze wyniku do tablicy zwraca ilość pobranych wierszy. zdefiniowanej przez użytkownika.$conn = OCILogon("scott". Domyślnie $result zawiera tablicę (numerowaną od 1) wszystkich kolumn mających wartości inne niż NULL."tiger"). ename from emp"). Parametr $mode pozwala zmienić domyślny tryb pracy."EMPNO". Można podać więcej niż jeden znacznik dodając wartości.$results). print "<TR>\n". należy zastosować tryb OCI_DEFAULT.$ename. echo "ename:"."tiger"). natomiast $message. $stmt = OCIParse($conn. W tablicy $code zawiera numer błędu Oracle. while (OCIFetch($stmt)) { echo "empno:".

string db]) Przykład: OCILogon() <?php print $db = $c1 = $c2 = "<HTML><PRE>". int OCILogOff (int connection) OCILogon Zwraca identyfikator połączenia niezbędny we większości funkcji OCI. $i < $nrows. 1 aby je włączyć. ?> OCIFreeCursor Zwraca True. jeżeli funkcja się udała lub False. Poniższy przykład pokazuje sposób współdzielenia połączeń. OCILogoff($conn). Oznacza to. string password [. Należy ustawić parametr debugera. void OCIInternalDebug (int onoff) $onoff na 0 aby wyłączyć wyjście OCILogOff Zamyka połączenie do Oracle. Używając funkcji OCILogon() połączenia są współdzielone na poziomie strony. jeżeli funkcja się udała lub False.$db).print "<TH>$key</TH>\n". jeżeli funkcja się udała lub False.$db). PHP używa zmiennej środowiskowej ORACLE_SID (instancja Oracle) lub TWO_TASK (tnsnames. int OCIFreeDesc (object lob) OCIFreeStatement Zwraca True."tiger".ora. "". ocilogon("scott". jeżeli się nie udała. ocilogon("scott". } else { echo "Brak danych<BR>\n". int OCILogon (string username. } print "Wybano $nrows rekordów<BR>\n". print "<TD>$data[$i]</TD>\n". Opcjonalny trzeci parametr może zawierać nazwę lokalnej instancji Oracle. print "<TR>\n". } print "</TR>\n". for ( $i = 0. int OCIFreeCursor (int stmt) OCIFreeDesc Zwraca True. $i++ ) { reset($results). } print "</TR>\n". Jeżeli nie zostanie podany trzeci parametr. int OCIFreeStatement (int stmt) OCIInternalDebug Włącza wyjście wewnętrznego debugera. do której funkcja ma się przyłączyć lub nazwę wpisu w pliku tnsnames. jeżeli skrypt tworzy wiele połączeń. jeżeli się nie udała. że operacje CONNECT i ROLLBACK działają dla wszystkich otwartych transakcji nawet.ora) do określenia bazy danych do której ma się przyłączyć. while ( $column = each($results) ) { $data = $column['value']. jeżeli się nie udała. OCIFreeStatement($stmt). } print "</TABLE>\n"."tiger". 335 PHP – Kompendium wiedzy .

"). że procedura przechowywana info. OCIFreeCursor($curs).&$curs.'DD-MON-YY HH24:MI:SS'))")." <".hallo values('$conn' || ' ' || to_char(sysdate. ociexecute($stmt). echo $conn. ociexecute($stmt. } function insert_data($conn) { $stmt = ociparse($conn. ocibindbyname($stmt. // zatwierdzenie na c1 select_data($c1)." wycofane\n\n". // brak wierszy commit($c1). } function select_data($conn) { $stmt = ociparse($conn." tabela usunięta\n\n"." zatwierdzone\n\n"."----wybieranie\n\n". // Oba inserty ostały wycofane select_data($c2). ociexecute($stmt. } create_table($c1)." usunięte dane przykładowe\n\n".hallo"). // zwrócony jest wynik inserta na c2 delete_data($c1). insert_data($c1). // wycofanie przy uzyciu c1 select_data($c1). // brak wierszy drop_table($c1). rollback($c1). print "</PRE></HTML>". // Zwracamy wynik obu wyrażeń INSERT select_data($c2).output zwraca kursor ref w :data $conn = OCILogon("scott". ociexecute($stmt).">\n\n". echo $conn."insert into scott. ociexecute($stmt). } function commit($conn) { ocicommit($conn). } function drop_table($conn) { $stmt = ociparse($conn. insert_data($c2). } OCIFreeStatement($stmt)."drop table scott.ociresult($stmt. } function rollback($conn) { ocirollback($conn). echo $conn. ociexecute($curs).hallo")." tabela utworzona\n\n"."tiger"). echo $conn.hallo"). echo $conn. echo $conn."----gotowe\n\n". } function delete_data($conn) { $stmt = ociparse($conn. ?> Patrz również: OCIPLogon() i OCINLogon().OCI_DEFAULT)."select * from scott. // usunięcie wszystkich wierszy w tabeli za pomocą c1 select_data($c1). // Wstawienie wiersza za pomocą c2 commit($c2). $curs = OCINewCursor($conn). while (ocifetch($stmt)) echo $conn. // brak wierszy select_data($c2)."begin info."create table scott."delete from scott."data". OCILogoff($conn).OCI_DEFAULT). OCINewCursor Przydziela nowy uchwyt wyrażenia do podanego połączenia."TEST").-1. while (OCIFetchInto($curs. int OCINewCursor (int conn) Przykład: Użycie kursora REF z procedury przechowywanej <?php // zakładamy. Dodatek A .OCI_DEFAULT).&$data)) { var_dump($data). echo $conn.OCI_B_CURSOR). // Wstawienie wiersza za pomocą c2 select_data($c1).hallo (test varchar2(64))")." wstawione dane przykładowe\n\n". // Wstawienie wiersza za pomocą c1 insert_data($c2). $stmt = OCIParse($conn.output(:data).Funkcje 336 . // zatwierdzanie za pmocą c2 select_data($c1). ociexecute($stmt. end. echo $conn.function create_table($conn) { $stmt = ociparse($conn. // brak wierszy select_data($c2).

OCI_ASSOC)) { print "<TR>".OCI_D_ROWID). ociexecute($data[ "EMPCNT" ]). print "<TABLE BORDER=\"1\">".&$rowid. OCI_D_LOB i OCI_D_ROWID."select deptno. OCIExecute($delete). OCILogoff($conn). $delete = OCIParse($conn. (używać rozważnie. print "<TH>NAZWA WYDZIAŁU</TH>". print "<TD>$deptno</TD>". print "<TH># PRACOWNIKÓW</TH>". Skrypt usuwa wybrae wiersze * korzystając z ROWID i zatwierdza operacje po * $commitsize wierszy. OCIExecute($stmt)."delete from $table where ROWID = :rid").$count_cursor"). "where emp.":rid". brak możliwości wycofania) */ $conn = OCILogon($user.deptno) as EMPCNT from dept". if ( ($nrows % $commitsize) == 0 ) { OCICommit($conn). OCILogoff($conn). * Wymaga przekazania zmiennych$user. print "$nrows\n".php3" method="post" enctype="multipart/form-data"> <input type="file" name="lob_upload"> 337 PHP – Kompendium wiedzy . Dla deskryptorów LOB z deskryptorami związane są metody load. ?> <?php /* * * * Skrypt pokazuje sposób ładowania plików do kolumn LOB Formularz używany w tym przykładzie jes następujący <form action="upload."select rowid from $table $where"). OCIFreeStatement($stmt).OCI_ASSOC)) { $num_emps = $subdata["NUM_EMPS"]. OCIBindByName($delete. int type]) Przykład: OCINewDescriptor() <?php /* Skrypt ten jest zaprojektowany do wywoływania z formularza HTML. $rowid = OCINewDescriptor($conn. } } $nrows = OCIRowCount($stmt). while (OCIFetchInto($data[ "EMPCNT" ]. $stmt = OCIParse($conn. $where i * $commitsize z formularza. $table.&$subdata.dname. $deptno = $data["DEPTNO"]. print "usunięto $nrows . $conn = OCILogon("scott".&$data. print "</BODY></HTML>"."ROWID". print "<TR>". } print "</TABLE>". } print "</TR>"."tiger"). OCIDefineByName($stmt. OCIFreeStatement($stmt).deptno = dept.OCI_B_ROWID). $dname = $data["DNAME"]. Przyjrzyj się uwagom z komentarzy w drugim przykładzie. print "<TD>$num_emps</TD>". Prawidłowymi wartościami są: OCI_D_FILE. save i savefile. print "<TH>NR #</TH>". ociexecute($stmt).&$rowid). Dla BFILE istnieje tylko metoda load.\n". print "</TR>". $type string OCINewDescriptor (int connection [. ?> OCINewDescriptor Przydziela pamięć do przechowywania deskryptorów lub lokalizatorów LOB. while (OCIFetchInto($stmt. $count_cursor = "CURSOR(select count(empno) num_emps from emp " . $stmt = OCIParse($conn.?> Przykład: Użycie kursora REF z wyrażenia SELECT <?php print "<HTML><BODY>". while ( OCIFetch($stmt) ) { $nrows = OCIRowCount($stmt). $password). $password.-1. print "<TD>$dname</TD>".

$db). } function insert_data($conn) { $stmt = ociparse($conn."insert into $table (id.ora. EMPTY_BLOB()) returning the_blob into :the_blob"). Jeżeli posiadasz kilka połączeń otwartych za pomocą OCINLogon() wszystkie operacje CONNECT i ROLLBACK działają tylko dla podanego połączenia." usunięte dane przykładowe\n\n". jeżeli używa się funkcji OCIPLogon(). echo $conn. echo $conn. echo $conn.."tiger". echo "Udane przesłanie BLOB-a \n". } function commit($conn) { ocicommit($conn). string db]) Przykład: OCINLogon() <?php print "<HTML><PRE>".OCI_DEFAULT). $password). OCIExecute($stmt. OCILogoff($conn).<input type="reset"> </form> <?php } else { // $lob_upload zawieera nazwę pliku tymczasowego przesłanego pliku $conn = OCILogon($user." tabela usunięta\n\n".hallo"). echo $conn. } Dodatek A . do której funkcja ma się przyłączyć lub nazwę wpisu w pliku tnsnames. OCI_DEFAULT). } ?> OCINLogon Zwraca identyfikator nowego połączenia do bazy Oracle 8 i loguje się do bazy."drop table scott. ':the_blob'. int OCINLogon (string username."create table scott. Domyślnie połączenia są współdzielone na poziomie strony. Jeżeli nie zostanie podany trzeci parametr. ociexecute($stmt). Patrz również: OCILogon() i OCIPLogon().hallo (test varchar2(64))"). PHP używa zmiennej środowiskowej ORACLE_SID (instancja Oracle) lub TWO_TASK (tnsnames. $stmt = OCIParse($conn." tabela utworzona\n\n". OCIFreeStatement($stmt). gdy musisz odizolować transakcje. the_blob) values(my_seq. ociexecute($stmt. ociexecute($stmt)."delete from scott.'DD-MON-YY HH24:MI:SS'))").hallo"). */ if(!isset($lob_upload) || $lob_upload == 'none'){ ?> <form action="upload. echo $conn.$db)." wstawione dane przykładowe\n\n". function create_table($conn) { $stmt = ociparse($conn. Opcjonalny trzeci parametr może zawierać nazwę lokalnej instancji Oracle. Funkcja OCINLogon() wymusza powstanie nowego połączenia.NEXTVAL. } function drop_table($conn) { $stmt = ociparse($conn. Powinno być to używane jedynie wtedy. -1. } OCIFreeDesc($lob). string password [.* ."insert into scott.OCI_DEFAULT). $c1 = ocilogon("scott".ora) do określenia bazy danych do której ma się przyłączyć. jeżeli używa się funkcji OCILogon() lub na poziomie serwera WWW.Funkcje 338 ."tiger". $db = "". OCI_D_LOB). OCI_B_BLOB).. OCIBindByName($stmt.php3" method="post" enctype="multipart/form-data"> Prześlij plik: <input type="file" name="lob_upload"><br> <input type="submit" value="Wyśłij"> .hallo values('$conn' || ' ' || to_char(sysdate. }else{ echo "Nieudane przesłanie BLOB-a \n". Poniższy przykład pokazuje sposób separowania połączeń. ociexecute($stmt. $lob = OCINewDescriptor($conn. $c2 = ocinlogon("scott". } function delete_data($conn) { $stmt = ociparse($conn. &$lob." zatwierdzone\n\n". if($lob->savefile($lob_upload)){ OCICommit($conn).

select_data($c1).$i). jeżeli nie jest. while (ocifetch($stmt)) echo $conn. $stmt = OCIParse($conn. Opcjonalny trzeci parametr może zawierać nazwę lokalnej instancji Oracle.">\n\n". string query) OCIPLogon Zwraca identyfikator trwałego połączenia do serwera Oracle 8 i loguje się do bazy. $ncols = OCINumCols($stmt). $i++ ) { $column_name = OCIColumnName($stmt. $i <= $ncols. PHP używa zmiennej środowiskowej ORACLE_SID 339 PHP – Kompendium wiedzy . ?> OCIParse Analizuje zapytanie $query korzystając z połączenia $conn.ociresult($stmt." wycofane\n\n". OCILogoff($conn)." <". $column_value . select_data($c2).function rollback($conn) { ocirollback($conn). print "</HTML>\n". drop_table($c1).OCI_DEFAULT).$i). $column_value = OCIResult($stmt. "tiger"). select_data($c2). ': ' . print $column_name ."select * from emp"). commit($c2). ociexecute($stmt. select_data($c1). echo $conn. do której funkcja ma się przyłączyć lub nazwę wpisu w pliku tnsnames. commit($c1). } function select_data($conn) { $stmt = ociparse($conn."TEST")."select * from scott. int OCINumCols (int stmt) Przykład: OCINumCols() <?php print "<HTML><PRE>\n". int OCIParse (int conn. } OCIFreeStatement($stmt). select_data($c2). while ( OCIFetch($stmt) ) { print "\n". OCIExecute($stmt). Zwraca identyfikator wyrażenia. echo $conn. print "</PRE>". select_data($c2). print "</PRE></HTML>". } print "\n". jeżeli zapytanie jest prawidłowe lub False. for ( $i = 1.ora. select_data($c1)."----gotowe\n\n".hallo"). $conn = OCILogon("scott". rollback($c1). insert_data($c1). Parametr $query może zawierać dowolne prawidłowe zapytanie SQL. ?> OCINumCols Zwraca ilość kolumn w wyrażeniu. } create_table($c1)."----wybieranie\n\n". echo $conn. delete_data($c1). "\n". select_data($c1). insert_data($c2). select_data($c1). Jeżeli nie zostanie podany trzeci parametr.

$conn = OCILogon("scott"."tiger"). if ( OCIStatementType($stmt) == "DELETE" ) { die "Nie możesz usuwać z tej tabeli<BR>". print "Wersja serwera: " . LOB. $stmt = OCIParse($conn. " wierszy. $sql = "delete from emp where deptno = 10".OCIRowCount($stmt) . int OCIPLogon (string username. ?> OCIStatementType string OCIStatementType (int stmt) Funkcja OCIStatementType() zwraca jedną z następujących wartości: SELECT INSERT ALTER UNKNOWN UPDATE CREATE BEGIN DELETE DROP DECLARE Przykład: <?php print "<HTML><PRE>". " wierszy. $stmt = OCIParse($conn.(instancja Oracle) lub TWO_TASK (tnsnames. int OCIRowCount (int statement) Przykład: OCIRowCount() <?php print "<HTML><PRE>". OCIFreeStatement($stmt). mixed OCIResult (int statement. OCIExecute($stmt). mixed column) OCIesult() zwraca OCIRollback Wycofuje zmiany wykonane poprzez połączenie $connection. int OCIRollback (int connection) OCIRowCount Zwraca ilość wierszy zmienionych przez wyrażenie SQL. OCIExecute($stmt)."drop table emp2"). OCICommit($conn). Dodatek A . OCIServerVersion($conn). OCIExecute($stmt).<BR>". $stmt = OCIParse($conn. ?> OCIServerVersion string OCIServerVersion (int conn) Przykład: OCIServerVersion() <?php $conn = OCILogon("scott". $conn = OCILogon("scott". OCILogOff($conn)."tiger"). Funkcja wszystko poza typami abstrakcyjnymi (ROWID. OCIFreeStatement($stmt). Patrz również: OCILogon() i OCINLogon(). string password [. Funkcja nie zwraca ilości wierszy zwracanych przez wyrażenie SELECT."tiger"). OCIFreeStatement($stmt). string db]) OCIResult Zwraca dane z kolumny $column w bieżącym wierszu (patrz OCIFetch()). print"usunięto "."delete from emp2").Funkcje 340 ."create table emp2 as select * from emp").<BR>". $stmt = OCIParse($conn.$sql). OCILogOff($conn).ora) do określenia bazy danych do której ma się przyłączyć. print "</PRE></HTML>". OCIRowCount($stmt) . print " wstawiono ". FILE) w postaci ciągów.

?> octdec Zwraca dziesiętny odpowiednik liczby ósemkowej reprezentowanej przez argument $octal_string. Funkcja octdec() konwertuje ciąg ósemkowy na liczbę dziesiętna. automatyczne zatwierdzanie jest włączane. Domyślnie automatyczne zatwierdzanie jest włączone dla połączenia. ustawienia te są wartościami domyślnymi dla nowych wyników. Patrz również: odbc_commit() i odbc_rollback(). jeżeli ma wartość False — wyłączane. Obsługa kolumn binarnych jest również realizowana przez odbc_longreadlen(). int OnOff]) odbc_binmode int odbc_binmode (int result_id. • ODBC_BINMODE_RETURN — Zwraca w takiej postaci jak otrzymał • ODBC_BINMODE_CONVERT — Konwertuje znaki i końce linii. Patrz również: decoct(). Znaki te są znakami ASCII reprezentującymi liczbę w postaci szesnastkowej. jeżeli jest wyłączone lub wystąpił błąd. int octdec( string octal_string ) odbc_autocommit Funkcja wywołana bez parametru $onoff zwraca stan mechanizmu automatycznego zatwierdzania dla połączenia $connection_id. int odbc_autocommit (int connection_id [. print "</PRE></HTML>". Jeżeli $result_id jest równy 0. Jeżeli parametr $onoff ma wartość True. Największą liczbą możliwą do skonwertowania jest 17777777777 lub dziesiętnie 2147483647. Obsługa typu LONGVARBINARY longreadlen Wynik Tryb binarny ODBC_BINMODE_PASSTHRU 0 przelotka ODBC_BINMODE_RETURN 0 przelotka ODBC_BINMODE_CONVERT 0 przelotka ODBC_BINMODE_PASSTHRU 0 przelotka ODBC_BINMODE_PASSTHRU >0 przelotka ODBC_BINMODE_RETURN >0 zwraca w niezmienionej postaci ODBC_BINMODE_CONVERT >0 zwraca jako ciąg znaków Jeżeli zostanie użyta funkcja odbc_fetch_into(). Na przykład. Jeżeli automatyczne zatwierdzanie jest włączone. Wyłączenie automatycznego zatwierdzania jest ekwiwalentem rozpoczęcia transakcji. Zwraca True w przypadku sukcesu i False w przypadku błędu. każdy bajt (8 bitów) źródła jest reprezentowany jako dwa znaki ASCII. odbc_close Zamyka połączenie do serwera bazy danych skojarzonego z podanym identyfikatorem łącza. Uwaga 341 PHP – Kompendium wiedzy . VARBINARY i LONGVARBINARY) • ODBC_BINMODE_PASSTHRU — Dane BINARY są przekazywane dalej. Uwaga Wartością domyślną dla longreadlen jest 4096 a tryb binarny ODBC_BINMODE_RETURN. że dla tych kolumn zwracany jest pusty ciąg. „przelotka” oznacza.} OCILogoff($conn). int mode) (Funkcja ma wpływ na typy SQL ODBC: BINARY. Gdy dane binarne SQL są konwertowane do danych znakowych C. zwraca True natomiast False. liczba binarna 00000001 jest konwertowana na "01" natomiast 11111111 na "FF".

Funkcje 342 . odbc_columns Tworzy listę kolumn w określonym zakresie. W takim przypadku połączenie pozostanie otwarte. int odbc_columns (int connection_id [. jeżeli na tym połączeniu są otwarte transakcje. Możesz mieć jednocześnie wiele połączeń. Patrz również: odbc_columnprivileges(). void odbc_close_all (void) odbc_columnprivileges False Zwraca listę kolumn i uprawnień do nich dla podanej tablicy.Funkcja ta się nie uda. W takim przypadku połączenie pozostanie otwarte. string column_name]]]]) Wynik zawiera następujące kolumny: • • • • • • • TABLE_QUALIFIER TABLE_OWNER TABLE_NAME GRANTOR GRANTEE PRIVILEGE IS_GRANTABLE Wynik jest uporządkowany według TABLE_QUALIFIER. string owner [. jaki jest używany na tym połączeniu. Argument $column_name. int odbc_columnprivileges (int connection_id [. string table_name [. Identyfikator połączenia zwracany przez tą funkcję jest wymagany przez inne funkcje ODBC. Uwaga Funkcja ta się nie uda. TABLE_OWNER i TABLE_NAME. string column_name]]]]) Wynik składa się z następujących kolumn: TABLE_QUALIFIER COLUMN_NAME PRECISION RADIX TABLE_OWNER DATA_TYPE LENGTH NULLABLE TABLE_NAME TYPE_NAME SCALE REMARKS Wynik jest uporządkowany według TABLE_QUALIFIER. odbc_commit Zwraca True w przypadku sukcesu lub False w przypadku błędu. Zwraca identyfikator wyniku ODBC lub w przypadku wystąpienia błędu. Wszystkie transakcje rozpoczęte poprzez $connection_id są zatwierdzane. string qualifier [. jeżeli na tym połączeniu są otwarte transakcje. int odbc_commit (int connection_id) odbc_connect Zwraca identyfikator połączenia ODBC lub 0 (False) w przypadku błędu. Zwraca identyfikator wyniku ODBC lub False w przypadku wystąpienia błędu. Opcjonalny czwarty parametr określa typ kursora. string table_name [. string owner [. string qualifier [. Parametr ten nie jest Dodatek A . void odbc_close (int connection_id) odbc_close_all Zamyka wszystkie połączenia do serwera bazy danych. TABLE_OWNER i TABLE_NAME. Argument $column_name pozwala na stosowanie wzorców przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). $table_name i $column_name pozwalają na stosowanie wzorców przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak).

int odbc_connect (string dsn. Jeżeli nie ma już wierszy. int rownumber. wykonywanie skomplikowanych procedur przechowywanych mogą powodować błąd Cannot open a cursor on a stored procedure that anything other than a single select statement in it. ale może być użyteczny przy obchodzeniu problemów ze sterownikami ODBC. string odbc_cursor (int result_id) odbc_do Uruchamia zapytanie na podanym połączeniu. Aby więcej niż raz odczytać wyniki zapytania. string query_string) odbc_execute Wykonuje zapytanie przygotowanie za pomocą odbc_prepare(). Zwraca identyfikator wyniku ODBC. ale może być to dowolny typ. int odbc_fetch_into (int result_id [. int odbc_exec (int connection_id. należy wywołać odbc_fetch_row() z $row_number równym 1 i kontynuować pobieranie danych za 343 PHP – Kompendium wiedzy . array result_array]) odbc_fetch_row Jeżeli funkcja się powiedzie (był wiersz wyniku) zwracana jest wartość True. funkcja próbuje pobrać kolejny wiersz wyniku. Parametr SQL_CUR_USE_ODBC może również pomóc w tym przypadku. Patrz również: odbc_prepare() i odbc_execute() dla wielokrotnego wykonania wyrażenia SQL. Po wywołaniu odbc_fetch_row() pola z wyniku są dostępne dla funkcji odbc_result(). Tablica zawiera wartości kolumn pod indeksami rozpoczynającymi się od 0. Funkcja pobiera wiersz danych zwróconych przez funkcję odbc_do() lub odbc_exec(). int odbc_do (int conn_id. array parameters_array]) odbc_fetch_into Zwraca ilość kolumn w wyniku lub False w przypadku wystąpienia błędu. Funkcja odbc_exec() wysyła wyrażenie SQL do serwera bazy danych wskazywanego przez $connection_id. string password [. ponieważ zostanie skonwertowany na typ tablicowy. Zwraca True w przypadku udanego wykonania. W przypadku niektórych sterowników ODBC. Tablica $parameters_array jest potrzebna.zwykle wymagany. Jeżeli nie zostanie podany parametr $row_number. Niektóre sterowniki nie obsługują opcjonalnego parametru $row_number w odbc_fetch_row(). Wywołania funkcji odbc_fetch_row() z parametrem $row_number i bez niego mogą być mieszane. int odbc_execute (int result_id [. Parametr ten musi być prawidłowym identyfikatorem zwracanym przez odbc_connect() lub odbc_pconnect(). string query) odbc_exec Zwraca False w przypadku wystąpienia błędu. string user. Użycie SQL_CUR_USE_ODBC może pomóc uniknąć błędu. jeżeli udało się poprawnie wykonać wyrażenie SQL. int cursor_type]) Dla parametru $cursor_type zdefiniowane są następujące stałe: • • • • SQL_CUR_USE_IF_NEEDED SQL_CUR_USE_ODBC SQL_CUR_USE_DRIVER SQL_CUR_DEFAULT Dla połączyć trwałych patrz odbc_pconnect(). jeżeli w wyrażeniu SQL występują parametry. zwracana jest wartość False. Tablica $result_array musi być przekazana przez referencję. False w przeciwnym przypadku. odbc_cursor Zwraca nazwę kursora dla podanego $result_id.

int field_number) odbc_field_name Zwraca nazwę pola wskazywanego przy pomocy numeru w wyniku ODBC o podanym identyfikatorze. Dodatek A . Zwraca identyfikator wyniku ODBC lub błędu. int field_number) odbc_field_num Zwraca numer kolumny o podanej nazwie w wyniku ODBC o podanym identyfikatorze. string odbc_field_precision (int result_id. int field_number) odbc_field_scale Zwraca skalę kolumny o podanym numerze w wyniku ODBC o podanym identyfikatorze. int odbc_field_len (int result_id. do których się odwołują. string odbc_field_scale (int result_id.pomocą odbc_fetch_row() bez parametru $row_number. Jeżeli zarówno $pk_table jak i $fk_table zawierają nazwy tabel. W większości przypadków będzie to tylko jeden klucz. string fk_owner. int row_number]) odbc_field_len Zwraca długość pola wskazywanego przy pomocy numeru w wyniku ODBC o podanym identyfikatorze. string pk_qualifier. int odbc_foreignkeys (int connection_id. Numerowanie pól rozpoczyna się od 1. odbc_foreignkeys() zwraca klucze obce z tabeli określonej przez $fk_table odwołujące się do klucza głównego z tabeli $pk_table. string field_name) odbc_field_precision Zwraca dokładność kolumny o podanym numerze w wyniku ODBC o podanym identyfikatorze. Patrz również: odbc_field_scale(). Jeżeli $fk_table zawiera nazwę tabeli. string fk_qualifier. string odbc_field_type (int result_id. int odbc_field_num (int result_id. string pk_table. string odbc_field_name (int result_id. odbc_foreignkeys() zwraca w wynik zawierający klucz główny i wszystkie klucze obce odwołujące się do tej tabeli. odbc_foreignkeys() zwraca wynik zawierający wszystkie klucze obce w podanej tabeli oraz klucze główne. Patrz również: odbc_field_scale(). string fk_table) False w przypadku Wynik składa się z następujących kolumn: PKTABLE_QUALIFIER PKCOLUMN_NAME FKTABLE_NAME UPDATE_RULE PK_NAME PKTABLE_OWNER FKTABLE_QUALIFIER FKCOLUMN_NAME DELETE_RULE PKTABLE_NAME FKTABLE_OWNER KEY_SEQ FK_NAME Jeżeli parametr $pk_table zawiera nazwę tabeli. Numerowanie pól rozpoczyna się od 1. W przypadku wystąpienia błędu zwraca False.Funkcje 344 . W przypadku wystąpienia błędu zwraca False. string pk_owner. int odbc_fetch_row (int result_id [. Numerowanie pól rozpoczyna się od 1. Jeżeli sterownik nie obsługuje odczytywania wiersza o podanym numerze. parametr ten jest ignorowany. int field_number) odbc_foreignkeys Odczytuje dane na temat kluczy obcych. int field_number) odbc_field_type Zwraca typ SQL pola wskazywanego przy pomocy numeru w wyniku ODBC o podanym identyfikatorze. Numerowanie pól rozpoczyna się od 1.

gdy skrypt zużywa zbyt dużo pamięci podczas pracy. dane z kolumn long są przepuszczane do klienta. Uwaga Obsługa kolumn LONGVARBINARY jest również realizowana przez odbc_binmode(). (patrz odbc_autocommit()) i wywołasz odbc_free_result() przed zatwierdzeniem. int odbc_free_result (int result_id) odbc_gettypeinfo Pobiera dane na temat typów danych obsługiwanych przez źródło danych. int odbc_longreadlen (int result_id. W przypadku wystąpienia błędu funkcja zwraca -1. Zwraca identyfikator wyniku ODBC lub False w przypadku wystąpienia błędu. int length) odbc_num_fields Zwraca ilość pól (kolumn) w wyniku ODBC. że nie będziesz już używał danych z wyniku. Dla wyrażeń SELECT zwraca ilość zwracanych wierszy. UPDATE Uwaga Użycie funkcji odbc_num_rows() do sprawdzenia ilości wierszy dostępnych po wykonaniu wyrażenia SELECT zwróci dla wielu sterowników -1.odbc_free_result Zawsze zwraca True. INSERT. Jeżeli jesteś pewien. Można użyć opcjonalnego parametru $data_type do ograniczenia danych do jednego typu. Funkcja zwraca -1 w przypadku wystąpienia błędu. Dla wyrażeń i DELETE funkcja zwraca ilość zmienionych wierszy. int odbc_num_rows (int result_id) 345 PHP – Kompendium wiedzy . możesz wywołać funkcję odbc_free_result(). odbc_longreadlen (Funkcja ma wpływ na typ SQL ODBC LONG i LONGVARBINARY) Ilość bajtów zwracanych do PHP jest określana przez wartość parametru. Uwaga Jeżeli automatyczne zatwierdzanie jest zablokowane. aby zwolnić pamięć przydzieloną do $result_id. int odbc_num_fields (int result_id) odbc_num_rows Zwraca ilość wierszy w wyniku ODBC. wszystkie otwarte transakcje zostaną wycofane. int data_type]) Wynik składa się z następujących kolumn: TYPE_NAME LITERAL_PREFIX NULLABLE UNSIGNED_ATTRIBUTE LOCAL_TYPE_NAME DATA_TYPE LITERAL_SUFFIX CASE_SENSITIVE MONEY MINIMUM_SCALE PRECISION CREATE_PARAMS SEARCHABLE AUTO_INCREMENT MAXIMUM_SCALE Wynik jest uporządkowany według DATA_TYPE i TYPE_NAME. Argumentem jest prawidłowy identyfikator wyniku zwracany przez odbc_exec(). int odbc_gettypeinfo (int connection_id [. Jeżeli ma wartość 0. Cała pamięć przydzielona do wyniku jest automatycznie zwalniana po zakończeniu działania skryptu. Wywołanie tej funkcji jest wymagane jedynie wtedy.

int odbc_pconnect (string dsn.Funkcje 346 . string owner [. Funkcja jest podobna do odbc_connect(). int odbc_procedurecolumns (int connection_id [. zwraca identyfikator wyniku ODBC lub False w przypadku błędu. string owner. string password [.odbc_pconnect Zwraca identyfikator połączenia ODBC lub 0 (False) w przypadku wystąpienia błędu. Dodatek A . poza tym. string table) Wynik posiada następujące kolumny: TABLE_QUALIFIER COLUMN_NAME TABLE_OWNER KEY_SEQ TABLE_NAME PK_NAME odbc_procedurecolumns Zwraca listę parametrów wejściowych i wyjściowych oraz kolumn będących wynikiem działania procedury. i COLUMN_TYPE. PROCEDURE_QUALIFIER. int cursor_type]) odbc_prepare Zwraca False w przypadku błędu. string proc [. string qualifier [. string user. Więcej informacji na temat połączeń trwałych znajduje się w PHP FAQ. int odbc_primarykeys (int connection_id. Zwraca identyfikator wyniku ODBC lub False w przypadku błędu. Opis opcjonalnego parametru $cursor_type znajduje się przy opisie funkcji odbc_connect(). że połączenie nie jest zamykane po zakończeniu skryptu. jeżeli PHP jest użyty jako program CGI. int odbc_procedures (int connection_id [. Zwraca identyfikator wyniku ODBC lub przypadku błędu. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). string name]]]) False w Wynik zawiera następujące kolumny: PROCEDURE_QUALIFIER NUM_INPUT_PARAMS REMARKS PROCEDURE_OWNER NUM_OUTPUT_PARAMS PROCEDURE_TYPE PROCEDURE_NAME NUM_RESULT_SETS Argumenty $owner. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej odbc_procedures Tworzy listę procedur w określonym zakresie. string owner [. Zwraca identyfikator wyniku ODBC dla poprawnie przygotowanego wyrażenia SQL. Argumenty $owner. string qualifier [. Kolejne żądania połączenia z tą samą kombinacją $dsn. Wynikowy identyfikator może być użyty do uruchomienia wyrażenia za pomocą odbc_execute(). int odbc_prepare (int connection_id. string query_string) odbc_primarykeys Zwraca nazwy kolumn składających się na klucz główny tabeli. $user i $password (poprzez odbc_connect() i odbc_pconnect()) powodują ponowne wykorzystanie połączenia trwałego. Uwaga Połączenia trwałe nie działają. string column]]]]) Wynik posiada następujące kolumny: PROCEDURE_QUALIFIER COLUMN_NAME TYPE_NAME SCALE REMARKS PROCEDURE_OWNER COLUMN_TYPE PRECISION RADIX PROCEDURE_NAME DATA_TYPE LENGTH NULLABLE PROCEDURE_NAME Wynik jest posortowany według kolumn znaków i _ zastępuje jeden znak). string qualifier.

0. jeżeli podana nazwa nie jest nazwą pola znajdującego się w wyniku. odbc_setoption ($conn. na którym chcesz zmienić opcje. int odbc_setoption (int id. int function. Błąd wystąpi. $field może być liczbą określającą numer pola lub ciągiem string odbc_result (int result_id. Funkcja została napisana w celu umożliwienia znalezienia obejścia problemów ze sterownikami ODBC zawierającymi błędy. Przykład: $item_3 = odbc_result ($Query_ID. Przykład: ODBC SetOption // 1. $item_val = odbc_result ($Query_ID. Wartością może być: 1 dla SQLSetConnectOption() i 2 dla SQLSetStmtOption(). // Wartość 1 dla SQL_AUTOCOMMIT to SQL_AUTOCOMMIT_ON. Parametr $function jest używaną funkcją ODBC. Zwraca True w przypadku pomyślnego odbc_setoption Funkcja pozwala operować opcjami ODBC dla połączenia lub wyniku zapytania. $sql). 1). Opcja 0 dla SQLSetStmtOption() wynosi SQL_QUERY_TIMEOUT. Wynikiem funkcji jest tabela HTML. Funkcja odbc_result_all() powoduje wydruk wszystkich wierszy z wyniku tworzonego za pomocą odbc_exec(). 347 PHP – Kompendium wiedzy . odbc_result_all Zwraca ilość wierszy w wyniku lub False w przypadku błędu. "val"). Numery pól rozpoczynają się od 1. 2. 30). Patrz również: odbc_binmode() i odbc_longreadlen(). Dla SQLSetConnectOption() jest to identyfikator połączenia. int param) Ponieważ efekty mogą bardzo zależeć od sterownika ODBC. Parametr $param jest wartością dla podanej opcji. true). // Przykład ten jest analogiczny do wywołania // odbc_autocommit($conn. Podobnie błąd wystąpi. Różne wersje sterowników obsługują różne opcje. 1. gdy jesteś programistą ODBC i znasz konsekwencje ustawiania różnych opcji. Dodatkowe formatowanie tabeli może być realizowane za pomocą opcjonalnego ciągu $format. zwracane są dane binarne lub long. Dla SQLSetStmtOption() jest to identyfikator wyniku. Powinieneś używać tej funkcji jedynie wtedy. Niektóre opcje ODBC nie są dostępne dla tej funkcji. $result = odbc_prepare ($conn. Parametr zawierającym nazwę pola. Jednak może ona pomóc w konkretnym przypadku. int option. 3). W zależności od trybu obsługi kolumn long. string format]) odbc_rollback Wycofuje transakcje otwarte poprzez połączenie wykonania operacji lub False w przypadku błędu. jeżeli numer kolumny dla jest mniejsza od jeden lub przekracza ilość kolumn w bieżącym rekordzie.odbc_result Zwraca zawartość pola. Parametr $id jest identyfikatorem połączenia lub identyfikatorem wyniku. 102. // Przykład ustawia czas wygaśnięcia zapytania na 30 sekund. // 2. używanie tej funkcji w skryptach udostępnianych publicznie nie jest zalecane. odbc_execute ($result). int odbc_rollback (int connection_id) $connection_id. mixed field) Pierwsze wywołanie odbc_result() zwraca wartość trzeciego pola w bieżącym rekordzie Drugie wywołanie funkcji odbc_result() zwraca wartość pola o nazwie val w bieżącym rekordzie w wyniku. odbc_setoption ($result. Parametr $option jest wartością ustawianej opcji. Powinieneś również posiadać dobry podręcznik ODBC zawierający objaśnienie wszystkich opcji i ich wartości. Opcje 102 dla SQLSetConnectOption() wynosi SQL_AUTOCOMMIT. int odbc_result_all (int result_id [. ponieważ muszą być ustawiane przed nawiązaniem połączenia lub przygotowania zapytania.

string qualifier. wynik zawiera listę kwalifikatorów dla źródła danych (wszystkie kolumny poza TABLE_QUALIFIER zawierają wartości Dodatek A . string name]]]) Wynik zawiera następujące kolumny: TABLE_QUALIFIER GRANTOR IS_GRANTABLE TABLE_OWNER GRANTEE TABLE_NAME PRIVILEGE Wynik jest uporządkowany według kolumn: TABLE_QUALIFIER. int scope. int odbc_statistics (int connection_id. Funkcja zwraca identyfikator wyniku ODBC lub False w przypadku błędu.odbc_specialcolumns Gdy wartością parametru $type wynosi SQL_BEST_ROWID. odbc_tables Tworzy listę tabel w żądanym zakresie. int type. Argumenty $owner. funkcja odbc_specialcolumns() zwraca optymalną kolumnę lub zestaw kolumn. TYPE. Jeżeli $qualifier zawiera jeden znak procentu (%) natomiast $owner i $name są pustymi ciągami. TABLE_QUALIFIER. string qualifier [. które jednoznacznie identyfikują każdy wiersz tabeli. string qualifier. odbc_statistics Odczytuje statystyki na temat tablicy i indeksów. Zwraca identyfikator wyniku ODBC lub błędu. Argumenty $owner. funkcja odbc_specialcolumns() zwraca kolumnę lub kolumny. string owner. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). int odbc_tableprivileges (int connection_id [. string name [. string owner [. string table. string table_name. TABLE_OWNER . string types]]]]) False w przypadku Wynik zawiera następujące kolumny: TABLE_QUALIFIER TABLE_TYPE TABLE_OWNER REMARKS TABLE_NAME i TABLE_NAME. INDEX_QUALIFIER. string qualifier [. TABLE_OWNER INDEX_QUALIFIER SEQ_IN_INDEX CARDINALITY TABLE_NAME INDEX_NAME COLUMN_NAME PAGES NON_UNIQUE. INDEX_NAME Wynik jest uporządkowany według kolumn: i odbc_tableprivileges Tworzy listę tabel w żądanym zakresie oraz uprawnień związanych z każdą tabelą. int odbc_tables (int connection_id [. $name i $table_type. int accuracy) False w Wynik zawiera następujące kolumny: TABLE_QUALIFIER NON_UNIQUE TYPE COLLATION FILTER_CONDITION SEQ_IN_INDEX. która po odczytaniu wartości kolumny lub kolumn pozwala na jednoznaczną identyfikację wierszy z tablicy. int nullable) Wynik zawiera następujące kolumny: SCOPE TYPE_NAME SCALE COLUMN_NAME PRECISION PSEUDO_COLUMN DATA_TYPE LENGTH Wynik jest uporządkowany według kolumny SCOPE. int odbc_specialcolumns (int connection_id. Aby obsłużyć wyliczanie kwalifikatorów. string owner [. Zwraca identyfikator wyniku ODBC lub przypadku błędu. TABLE_OWNER i TABLE_NAME. int unique. string owner.Funkcje 348 Wynik jest uporządkowany według: TABLE_TYPE. właścicieli i typów tabel dostępna jest specjalna składnia parametrów $qualifier. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). $owner. Jeżeli $typ wynosi SQL_ROWVER. Zwraca identyfikator wyniku ODBC lub False w przypadku błędu.

readdir() i rewinddir().. LOG_PERROR Wysyła komunikaty dziennika również na standardowe wyjście błędów. LOG_AUTHPRIV Komunikaty systemu bezp