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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. } 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. Można więc tak skonfigurować PHP. post2.To jest skrypt PHP. aby nie udostępniał tych zmiennych globalnych i tak pisać skrypty. Jeżeli bardzo przejmujesz się wydajnością serwera WWW. Na przykład możesz chcieć wyświetlić w czasie uruchamiania skryptu wartości wszystkich danych wysłanych z formularza. print( "Nazwa użytkownika: {$HTTP_POST_VARS['Username']}<br>" ). każda z tablic będzie zawierać zero lub więcej wartości.Trzy linie na dane adresowe.<td valign="top"> Wybierz kolory które lubisz: </td> <td valign="top"> <!-. DisplayArray( $HTTP_GET_VARS ). ponieważ PHP nie będzie musiał tworzyć zmiennych globalnych dla każdego z elementów formularza. print( "Hasło: {$HTTP_POST_VARS['Password']}<br>" ). Więcej na temat tej dyrektywy konfiguracji napisane zostało na końcu książki przy opisie opcji konfiguracji register_globals. ?> </body> </html> W niektórych przypadkach preferowane jest użycie zmiennych HTTP_GET_VARS lub HTTP_POST_VARS zamiast korzystania ze zmiennych globalnych.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"> <!-.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. 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.html --> <html> <head> <title>Wydruk: post2. aby korzystały z wartości zawartych w tablicach HTTP_GET_VARS i HTTP_POST_VARS. można tu nieco zyskać. Skrypt wyświetlający dane z wydruku 1 może zostać przepisany w następujący sposób: <!-.

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

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

Przykład użycia rysunku w formularzu <!-.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. Zmienne reprezentujące współrzędne będą się nazywały SubmitImg_x i SubmitImg_y. Nazwy zmiennych przechowujących współrzędne są tworzone poprzez dodanie _x i _y do nazwy elementu reprezentującego rysunek. czy jest to przycisk czy rysunek. 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.2. imgsubmit.Rysunek 3. Na przykład na wydruku 5 nazwą elementu rysunku jest SubmitImg.gif"> </form> </body> </html> 45 PHP – Kompendium wiedzy . PHP posiada obsługę przesyłania plików wbudowaną bezpośrednio w język. możesz użyć rysunku w miejsce przycisku HTML wysyłającego dane formularza do serwera.5.Strona HTML.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. Jest ona dokładniej opisana w rozdziale 5 „Wysyłanie plików przez formularz”. Użycie rysunku jako przycisku wysłania danych Jeżeli projekt aplikacji WWW tak przewiduje.html --> <html> <head> <title>Użycie rysunku zamiast przycisku</title> </head> <body> <form action="displayall. Wynik przesłania formularza wielowartościoweg o do displayall. Dla PHP nie ma znaczenia. Wydruk 3. Mechanizm ten jest wygodny do tworzenia map obrazów po stronie serwera.

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

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

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

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

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

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

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

case 2 : // htmlentities $aDisplayText = htmlentities( $TheText ). Rysunek 3. zawiera formularz wprowadzania danych. jeżeli nie ma filtrowania. Rysunki 3. } ?> <html> <head> <title>Bezpieczne wyświetlenie danych użytkownika</title> </head> <body> <?php print( $aDisplayText ).phtml --> <?php error_reporting( 255 ). Formularz wprowadzania danych 53 PHP – Kompendium wiedzy . do 3. case 1 : // strip_tags $aDisplayText = strip_tags( $TheText ). switch ( $FilterType ) { case 0 : // brak $aDisplayText = $TheText.5. pokazuje co się dzieje.6. pokazują formularz wejściowy i wyniki działania skryptu.6.<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> <!-.3. ?> </body> </html> Rysunki 3.4. i 3.3. break. pokazują wyniki filtrowania danych z formularza za pomocą funkcji odpowiednio strip_tags() i htmlentities().3. break. Rysunek 3. break. Rysunek 3.Skrypt safedisplay2.

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

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

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

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

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

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

17 ). Skrypt przetwarzający zapytanie whois <?php /* whois.36. 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.3. Potok może być użyty do odczytu danych wyjściowych z programu lub skryptu. Wydruk 4. ?> </body> </html> Użycie potoków Tak jak w przypadku gniazd. } pclose( $aFile ). print( "$aLine<br>" ). "r" ) ) { // odczytanie wszystkich danych z potoku while ( !feof( $aFile ) ) { $aLine = fgets( $aFile. Jedyną różnicą pomiędzy plikiem i potokiem jest to. } print( "<hr>" ). exit. że potok jest jednokierunkowym strumieniem danych. potoki są traktowane jak kolejny uchwyt pliku. Skrypt ten ilustruje również częstą praktykę używania tego samego skryptu do wyświetlenia formularza i przetworzenia jego danych.164".php */ // ścieżka do programu whois $whois_prog = '/usr/bin/whois'. if ( !is_file( $whois_prog ) ) { // nie udało się znaleźć programu echo "Nie mogę znaleźć $whois_prog!<br>". 1024 ).4. } else { echo "Nie mogę otworzyć $whois do odczytu!<br>". } ?> <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 .Wydruk 4.129.4 pokazane jest użycie potoku do odczytania wyniku zapytania do polecenia whois. Na wydruku 4. które jest dostępne w większości systemów Unix. 1024 ). print( "$aLine<br>" ). } fclose( $aFile ). // odczytanie wszystkich danych ze strumienia 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". Ten prosty skrypt i formularz pozwalają na wprowadzenie zapytania dla whois.

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

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

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

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

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

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

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. Mimo. Najlepiej posiłkować się dokumentacją odmiany SQL zaimplementowanej w używanej przez ciebie bazie danych. Pseudokod opisujący pobieranie danych z dowolnego systemu bazy danych przedstawiony jest na wydruku 6. autorzy PHP uważają obsługę baz danych za jedną z najważniejszych i najsilniejszych cech PHP. Jest to spowodowane tym. ODBC wybrałem. 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. Wprowadzenie Jak można wywnioskować na podstawie dokumentacji. wybierz_bazę(). wyślij_wyrażenie_SQL(). że każda z baz danych ma własny zestaw funkcji.1. Funkcje baz danych Każda z obsługiwanych baz danych posiada własny zestaw funkcji PHP. 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. które również nie zostanie odpowiednio dokładnie opisane w tej książce. jak na przykład indeksowanie. PHP pozwala na dostęp do danych przy użyciu bogatego zestawu funkcji związanych z bazami danych. że czytelnicy znają podstawy SQL w stopniu wystarczającym do zrozumienia przykładów zamieszczonych na wydrukach. istnieje wspólny model dostępu do każdego z typów baz danych. język SQL jest sam w sobie niezwykle bogatym i wydajnym narzędziem. Pseudokod opisujący pobieranie danych z bazy <?php połącz_z_Bazą(). PHP może zostać użyty do prawdopodobnie dowolnej istniejącej bazy danych. Wydruk 6. 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. że systemy zarządzania relacyjnymi bazami danych (SZRBD) posiadają wiele bardzo wydajnych i niezwykle użytecznych mechanizmów zarządzania danymi. ponieważ do większości baz danych dostępne są sterowniki tego standardu. W rozdziale tym skupimy się na przykładach użycia MySQL i ODBC. Dodatkowo. Zakładamy w tym rozdziale. . kaskadowe operacje wykonywane na danych i wiele innych.Rozdział 6.1. obsługa transakcji. Przykłady ilustrują zastosowanie języka PHP i nie zawsze pokazują najlepsze zastosowania SQL oraz działania na bazach danych. relacje pomiędzy danymi. 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).

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

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

} ?> 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.3. ale dla naszych potrzeb kod ten nie został rozmyślnie wprowadzony. $aResult = -3. Ten typ aplikacji powinien zawierać o wiele więcej kodu odpowiedzialnego za obsługę błędów. Rozdział 6 – Współpraca z bazami danych 70 . Kod błędu = $aResult<br>" ). } } else { // print( "Błąd wyboru bazy danych<br>" ). } return $aResult. Więcej przykładów użycia baz danych w aplikacjach WWW można znaleźć w rozdziale 15 „Witryny oparte o bazę danych”. if ( $aQResult == True ) { $aResult = mysql_insert_id( $aDBLink ). funkcja IndertRecord() zawiera całą logikę wstawienia nowego rekordu do bazy danych. ID = $aResult<br>" ). } print( "<hr>" ). $aDBLink ) == True ) { $aQResult = mysql_query( $aSQL. "root". } else { print( "Błąd funkcji InsertRecord. $Address. $aResult = -2. $LastName.com". $Position ). "" ). if ( !empty( $aDBLink ) ) { if ( mysql_select_db( "mydb". $aDBLink ).server. } } else { // print( "Błąd przy podłączaniu do bazy danych<br>" ). Ponieważ pole id w tabeli employees jest polem typu auto_increment. } else { // print( "Błąd wykonania zapytania<br>" ). Realistycznie patrząc. if ( $aResult > 0 ) { print( "Dodano nowy wiersz. 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. W naszym przykładzie wartość ta jest odczytywana za pomocą funkcji mysql_insert_id(). Przykład ten miał na celu pokazanie prostoty korzystania z baz danych w PHP. na przykład sprawdzanie pustych pól. Znajdują się tam bardziej złożone przykłady zawierające obsługę błędów i skomplikowane zapytania. $aResult = -1. MySQL automatycznie generuje jednoznaczne wartości tego pola przy każdym wstawieniu rekordu. } ?> <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.$aDBLink = @mysql_connect( "db.

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

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

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

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

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

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

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

„Zarządzanie projektem przy tworzeniu aplikacji WWW” zawiera więcej informacji na temat inżynierii programowania dla aplikacji WWW. Potrzebna jest zwykle nowoczesna baza danych. ale pokazuje w jaki sposób wykorzystując odpowiednio SQL można uniknąć pisania sporej ilości kodu oraz poprawić wydajność aplikacji. Na początku wyniku znajdą się osoby o wieku najbliższym 30 lat. uprawnieniami użytkownika. czy na osobnych maszynach. który to mechanizm musi posiadać baza danych. Zadaniem było powielenie kilku wierszy danych z tabeli zmieniając w nowych wierszach zawartość kilku pól. Ponieważ PHP obsługuje wiele typów baz danych. przyjrzyj się dokładniej swojemu zapytaniu SQL. (10-ABS((30-ROUND(((TO_DAYS(NOW()) . będącą liczbą od 0 do 10. Fragment ten wymaga 1+ (2*ilość wierszy) odwołań do bazy danych. to w pętli odczytać wyniki i wyświetlić je na ekranie. Każdy. Niezależnie od tego. Następna duża część książki. ' '. obliczana w oparciu o to jak blisko wiek osoby jest zbliżony do założonych wymagań wiekowych. Dodatkowo każdej osobie przypisywana była wartość. inne_pola FROM tabela Wyrażenie to opiera się na generatorze sekwencji do wygenerowania nowego klucza głównego. Wszystko czego potrzebujemy. 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. Zamieszczona została również krótka dyskusja na temat inżynierii programowania i wykorzystaniu możliwości baz danych. Podsumowanie Rozdział ten zawiera opis użycia baz danych razem z PHP.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ść. Dalsze informacje na temat Rozdział 6 – Współpraca z bazami danych 78 . jak bardzo jej wiek jest zbliżony do 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. baza danych pełni o wiele ważniejszą rolę. większość nowoczesnych baz danych posiada ogromną ilość funkcji. 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. W mojej ostatniej stałej pracy trafiłem na świetny przykład. Jeżeli zdarzy ci się pisać kod formatujący. skupiliśmy się na bazie MySQL oraz dostępowi poprzez ODBC. surneme) as fullname. którego wiek był oddalony od założonego o więcej niż 10 lat otrzymywał tą samą ocenę. który pisał ten fragment. Oprócz wykonywania tych krytycznych funkcji.W przypadku tworzenia aplikacji dla środowiska wielowarstwowego. 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ą. ale fragment ten prezentuje styl kodowania brute-force częsty u młodych lub niedoświadczonych programistów. ROUND(MAX(0. transakcjami i to odbierając wiele równoczesnych żądań w tym samym czasie. Na przykład. powinieneś wszędzie tam gdzie jest to możliwe wykorzystywać siłę systemu zarządzania bazą 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. ale otrzymujemy wszystkie potrzebne dane bez potrzeby pisania dodatkowego kodu manipulującego wynikami: SELECT concat (firstname. Możesz skorzystać z wbudowanych funkcji bazy danych lub zastosować bardziej skomplikowany kod SQL do osiągnięcia oczekiwanych wyników. czy serwer bazy danych i serwer WWW umieszczony jest na tym samym komputerze. filtrujący bądź sortujący dane pobierane z bazy danych. Poniższe wyrażenie może wyglądać na dosyć skomplikowane. musiałem określić pozycję rekordu osoby w oparciu o to.nextval AS PRIMARY KEY. które pomagają w pisaniu aplikacji.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

AuthType Basic <Limit GET> require valid-user </Limit> Rysunek 8. Zmienne autoryzacji w PHP Schemat autoryzacji Apache zapewnia podstawowy stopień bezpieczeństwa witryny. Możesz skorzystać ze zmiennych $PHP_AUTH_USER oraz $PHP_AUTH_PW do odczytania nazwy użytkownika i hasła. Wydruk 8. serwer WWW wysyła żądanie 401 do przeglądarki a przeglądarka odpytuje użytkownika i odsyła wprowadzone przez niego dane do serwera. Przeglądarka wysyła wprowadzone dane do serwera podczas żądania sprowadzenia wszystkich kolejnych stron aż do zakończenia pracy przeglądarki. ?> </body> </html> Rysunek 8.1.2. chroniony zasób jest udostępniony użytkownikowi.2. Wydruk 8. Jest on szczególnie użyteczny w sytuacjach. Ten rodzaj uwierzytelniania wymaga współpracy pomiędzy przeglądarką i serwerem. Mechanizm ten wygląda następująco: gdy użytkownik musi zostać autoryzowany. gdy chcesz chronić wszystkie strony i inne zasoby znajdujące się we fragmencie drzewa Rozdział 8 – Uwierzytelnianie 96 . Jeżeli serwer zaakceptuje uwierzytelnianie.1.3 zawiera stronę wyświetlająca dane autoryzacji.3. 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. print( "PHP_AUTH_PW: $PHP_AUTH_PW<br>" ). PHP posiada zmienne globalne. pokazana jest zawartość tej strony po przejściu do niej poprzez łącze znajdujące się na stronie z wydruku 8. Na rysunku 8. 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>" ).

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

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

3. Można również skorzystać z dostarczanej przez The Webmasters Net klasy Htgroup do tworzenia i zarządzania grupami użytkowników. 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). 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. a jedynie pokazuje sposób wykorzystania klasy Htpasswd."> <br><br> Zmiana nazwy zaznaczonego użytkownika: <input type="text" name="RenameName"><input type="button" value="Zmiana nazwy" onClick="DoSubmit( 'rename' ). skrypt ten nie jest kompletnym narzędziem zarządzającym użytkownikami. 99 PHP – Kompendium wiedzy . 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.</select> </td> <td> Usunięcie zaznaczonego użytkownika: <input type="button" value="Usuń" onClick="DoSubmit( 'delete' ).3."><br><br> </td> </tr> </table> </form> </body> </html> Na rysunku 8. pokazana jest strona bezpośrednio o dodaniu użytkownika scott. Rysunek 8."><br><br> Zmiana hasła dla zaznaczonego użytkownika: <input type="password" name="ChangePass"><input type="button" value="Zmiana hasła" onClick="DoSubmit( 'changepass' ). Jak mówiliśmy wcześniej.

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

pokazana jest interakcja pomiędzy klientem. jakich aplikacja wymaga do prawidłowej autoryzacji użytkownika.PHPLIB sprawdza zalogowanie użytkownika. // użycie cookie sesji var $that_class = "MySQLCt". var $lifetime = 0. var $database_table = "active_sessions". var $lifetime = 20. var $Database = "mydb". Po pierwsze. $SurName. include( "auth. 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. 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. $aDB = new MySQLDB. } class Sample_Auth extends Auth { var $classname = "Sample_Auth". include( "ct_sql. $aSQL = "select * from MyAuth where ( FirstName = ". PHPLIB wyświetla zdefiniowaną przez użytkownika stronę. W naszym przypadku dane autoryzacji znajdują się w tabeli bazy danych MySQL. ). serwerem WWW (i tym razem jest to 1U z Penguin Computing) oraz aplikacją PHP. } class MySQLCt extends CT_Sql { var $classname = "MySQLCt". include( "session. var $Password = "root".inc" ). $Password. include( "db_mysql. // 20 minut (0 == ciągle) function auth_loginform() { include( ".inc" ). var $User = "root". var $database_class = "MySQLDB".4. Przygotowanie klas używanych przez klasę PHPLIB Auth <?php include( "page. // Obsługa przechowywania var $mode = "cookie". class MySQLDB extends DB_Sql { var $Host = "localhost"./sample_lform. Następnie PHPLIB wywołuje dostarczoną przez użytkownika funkcję sprawdzającą uprawnienia użytkownika.htinc" ). $aSQL . NOT NULL.inc" ).inc" ). // wybór kontenera var $allowcache_expire = 0. } function auth_validatelogin() { global $FirstName. Rysunek 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.= "'$FirstName' ) and ( SurName = '$SurName' )". Jeżeli funkcja ta zaakceptuje użytkownika. Na rysunku 8. SurName) Wydruk 8.9. Strona ta pobiera dowolne dane. na wydruku 8. NOT NULL. PHPLIB wyświetla stronę a w przeciwnym wypadku następuje ponowne uwierzytelnianie. Jeżeli użytkownik nie podawał wcześniej danych autoryzacji. których używaliśmy w rozdziale 7). NOT NULL.inc" ). } class MySqlSession extends Session { var $classname = "MySqlSession". 101 PHP – Kompendium wiedzy .4.

$aSQL . } ?> <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. Zdefiniowane są odpowiednie funkcje auth_loginform() i auth_validatelogin().10 pokazany jest plik użyty w tym przykładzie.htinc) <?php global $FirstName. } } } ?> Klasa Sample_Auth dziedzicząca po klasie bazowej Auth zapewnia działanie specyficzne dla bieżącej aplikacji. $aCurFirstName = "". $aDB->query( $aSQL ). Na wydruku 8. </td> </tr> <?php } ?> </table> Rozdział 8 – Uwierzytelnianie 102 . if ( !empty( $FirstName ) ) { $aCurFirstName = $FirstName. Możesz użyć instrukcji print() do stworzenia formularza HTML potrzebnego do zalogowania. Wydruk 8. $aCurSurName = "".10. if ( $aDB->num_rows() > 0 ) { return $FirstName. } if ( !empty( $SurName ) ) { $aCurSurName = $SurName.= "and ( Password = '$Password' )". spróbuj jeszcze raz. Funkcja auth_loginform() jest wywoływana. global $SurName. } else { return False. ale zwykle dołączenie pliku jest łatwiejsze. gdy klasa Auth wymaga uwierzytelnienia użytkownika.. Przykładowy formularz logowania (sample_lform.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Wydruk 11.scrooge. oraz listę dostępnych metod i właściwości.Rysunek 11.Scrooge"). Przykładowy plik RTF modułu Scrooge Użycie modułu Scrooge jest łatwe i proste. $sR2H->setOptWrapHTML( False ).<BR>"). $aOutput = $aR2H->convert( implode( "". Po przesłaniu danych formularza sprawdzany jest typ pliku i jeżeli jest prawidłowy tworzony jest obiekt Scrooge. } else { print ("Wybrany plk nie jest plikiem <b>RTF</b>.betabeans. Dołączona dokumentacja zawiera nazwę klasy Javy. za pomocą którego użytkownik może przesłać plik RTF. 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.8. $aArray = file ( $rtffile ).2. } } ?> <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. print( $aOutput ).8 pokazane jest wykorzystanie tego modułu. $aArray) ). W skrypcie z wydruku 11. Rozdział 11 – Ponowne wykorzystanie kodu 140 .

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

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

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

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

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

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

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

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

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

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

Również jeżeli przesyłany jest identyfikator sesji lub inny identyfikator specyficzny dla aplikacji. że za zmiany projektu witryny odpowiada programista PHP. 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.Rysunek 12. który generuje kod HTML. 151 PHP – Kompendium wiedzy . niezbędne będzie dołączenie części znaczników HTML do kodu PHP. Używając przedstawionych technik i wykorzystując przy projektowaniu pliki CSS. Dołączane pliki HTML powinny zawierać jedynie kod HTML. a dołączane pliki PHP — jedynie kod PHP. trzeba dynamicznie generować wszystkie łącza. Jednak czasami trzeba dynamicznie wygenerować niektóre znaczniki HTML. na przykład może być to generowany dynamicznie znacznik łącza. 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. cel ten jest nieomal osiągnięty. Celem oddzielenia HTML od PHP jest uproszczenie aplikacji. które nie spełniają prawdziwych potrzeb. Celem oddzielenia HTML od PHP może być całkowite oddzielenie projektu od logiki aplikacji.3. W tych przypadkach jeżeli wykorzystywana będzie opisana technika integracji. Należy unikać kodu PHP. Utrudnia to również wprowadzanie hurtowych zmian w wyglądzie całej witryny WWW. Choć pozwala to na pisanie kodu PHP nie zawierającego znaczników HTML. Ułatwia to rozdzielenie odpowiedzialności programistów PHP i projektantów interfejsu. podział odpowiedzialności pomiędzy projektantami i programistami oraz ułatwiają konserwację aplikacji. powoduje to. Czasami programiści przesadzają w swoim zapale pisania kodu i tworzą mechanizmy.

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

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

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

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

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

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

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

Jakiś czas temu zdałem sobie sprawę. Bibliografia Roger Fournier. 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. Steve McConnell. rozdział ten ma podłoże czysto osobiste. który pozwala na pełne oddzielenie wszystkich elementów projektu od kodu. 1998. A Mehodology for Client/Server and Web Application Development. New Jersey: Prentice Hall PTR. 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. ponieważ warstwa prezentacji jest odpowiedniej jakości a ja nie muszę jej tworzyć ani zmieniać samemu. że nigdy nie będę projektantem graficznym ani artystą. Tak zupełnie na marginesie. Seattle: Microsoft Press. 159 PHP – Kompendium wiedzy . Code Complete. Z powodu elastyczności PHP cel modularnego tworzenia witryn WWW może być osiągnięty wieloma sposobami. Wykorzystuję klasę FastTemplate w nieomal wszystkich moich obecnych projektach. Zalecaną w tym rozdziale metodą jest wykorzystanie systemu szablonów. 1993. Pozwala to osiągnąć ogólną poprawę witryny.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.

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

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

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

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

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

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

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

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

Rozdział 13 – Fajny PHP 174 .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. Istnieją również rozszerzenia do tworzenia rysunków. tworzenia plików PDF i wielu innych zadań. Ponieważ PHP jest tak rozszerzalny i rozwijany przez ogromną grupę programistów. analizy XML.

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

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

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

Rysunek 14. Wydruk 14.8. Strona wygenerowana przez skrypt z wydruku 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 . Nowy plik szablonu „base” <html> <head> <title>{TITLE}</title> <link rel="STYLESHEET" type="text/css" href="new_base.2.7.

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

w postaci zmiennej szablonu. Inny arkusz stylu pokazujący możliwość modyfikacji znaczników <body>. Mimo. że nie jest to optymalne rozwiązanie dla wszystkich typów witryn.Rysunek 14. Arkusz stylu pokazujący możliwość modyfikacji znaczników <body>. <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.4. pozwala zrealizować kolejny poziom konfiguracji wyglądu tworzonej aplikacji. Pliki CSS mogą być nawet dołączane dynamicznie. <td> i <h3> Rysunek 14.5. Rozdział 14 – Witryny oparte o szablony 180 .

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

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

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

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

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

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

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

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

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

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

a każda z kategorii może zawierać jeden lub więcej produktów. null. Jego implementacja w SQL zamieszczona jest na wydruku 15.1. null. not null. a każdy z tych sprzedawców może mieć wiele kategorii produktów. Pełny model danych katalogu towarów Wydruk 15. null. null. CREATE TABLE mcCategories ( merchant_id int category_id int name varchar(50) not not not not default 0.2 pokazany jest kompletny model danych katalogu produktów. null. null. Na rysunku 15. null.0 not not not not not null. Ogólny schemat tej bazy danych jest pokazany na rysunku 15.2. Na tym poziomie szczegółowości można stworzyć kompletny model danych. 191 PHP – Kompendium wiedzy . not null. Rysunek 15.1.1.jednej bazie danych fragmenty danych przypisane do różnych sprzedawców. not null. index( name ). null.1. Rysunek 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 ). każdy sprzedawca może mieć jedną lub więcej kategorii produktów. index( mgr_username ) ).1. Podstawowy model danych katalogu towarów Rozwijając model z rysunku 15.

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

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

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

php" ). "\n" ). pokazana jest strona z dwiema kategoriami testowego sprzedawcy.sprzedawcy. Jeżeli istnieje co najmniej jedna kategoria. exit. // niejawne ustawienie zmiennej sesji $aMerchantID if ( empty( $aMerchantID ) == True ) { header( "Location: login.phtml?retpage=" .phtml) <?php session_start(). na rysunku 15.3. urlencode( $REQUEST_URI ) . Wydruk 15. szablony dodawania kategorii oraz skrypt umieszczone są na wydrukach 9.3. Szablon zarządzania danymi aplikacji — dodawanie kategorii (mgmt_cat_add. Rysunek 15.10.FastTemplate. i 10. 195 PHP – Kompendium wiedzy .3. } include( "class. Aplikacja zarządzająca danymi — dodawanie kategorii (mgmt_cat_add. Na rysunku 15. każda z nich posiada własne łącza ZMIEŃ i USUŃ.9. Strona zarządza nia kategoria mi katalogu produktó w Dodawanie kategorii jest zrealizowane za pomocą kliknięcia w łącze.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. skrypt pobiera te dane i generuje tabelę istniejących kategorii. skrypt ten pobiera kategorie z bazy danych. Następnie używając identyfikatora jako filtru. Jeżeli istnieją kategorie.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

według definicji w /etc/services. mt_srand() int getrandmax( void ) Zwraca maksymalną wartość. rand(). $dat["ru_utime. Patrz również: getservbyport(). $dat["ru_majflt"]. string gettext( string message ) Przykład: gettext() <?php // Ustaw język na niemiecki putenv( "LANG=de").tv_sec"]. // wybierz domenę textdomain( "myPHPApp"). int getservbyname( string service. Zwraca tablicę asocjacyjną zawierającą dane zwracane przez wywołanie systemowe. int getprotobynumber( string name ) $number według pliku /etc/protocols. Patrz również: rand(). getrusage Jest to interfejs do getrusage(2). mt_rand().getprotobynumber Zwraca nazwę protokołu skojarzonego z protokołem getprotobyname(). // wypisz komunikat testowy print (gettext( "Welcome to My PHP Application")).tv_usec"]. jeżeli tłumaczenie nie zostanie znalezione. Jako Znaków zastępczych można używać podkreślenia. • 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 ./locale"). Jeżeli $who jest równe 1. getrusage zostanie wywołane z RUSAGE_CHILDREN. ?> gettimeofday Jest to interfejs do gettimeofday(2). Zwraca przetłumaczony ciąg lub oryginalny ciąg. 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. $dat["ru_nswap"]. $protocol może być TCP lub UDP. ". string protocol) gettext Funkcja szuka tłumaczenia ciągu w jednej z tablic tłumaczeń. array getrusage( [int who] ) Przykład: getrusage() $dat echo echo echo echo = getrusage(). Zwraca tablicę asocjacyjną zawierającą dane zwrócone przez wywołanie systemowe. // Określ połozenie tablic tłumaczeń bindtextdomain( "myPHPApp". $dat["ru_utime. jaka może być zwrócona przez funkcję oraz mt_getrandmax(). # # # # 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). Patrz również: getrandmax srand().

get_cfg_var Zwraca wartość zmiennej konfiguracji PHP określonej przez $varname.ini) można znaleźć w FAQ do PHP pod adresem http://www. aby odczytać możliwości innej przeglądarki). object get_browser( [string user_agent]) Przykład: get_browser() <?php function list_array ($array) { while (list ($key. cookie itd.0)<br> <b>parent:</b> IE 5. Jest to realizowane przez odszukanie danych na temat przeglądarki w pliku browscap.ini.Funkcje 226 . że plik browscap. JavaScript. ?> Wynik działania tego skryptu może wyglądać następująco Mozilla/4.php. Windows NT 5.5. identyfikator.= "<b>$key:</b> $value<br>\n". Mimo.0<br> <b>version:</b> 5. czy system Dodatek A . obsługa ramek.0 (compatible. lub False w przypadku wystąpienia błędu. Aby sprawdzić. echo list_array( (array) $browser). Windows NT 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. to jednak użytkownik musi dbać o jego aktualność. wartości True lub False dla takich własności jak. Domyślnie używana jest wartość zmiennej $HTTP_USER_AGENT.net/FAQ.0 (compatible. na przykład numer wersji. return $str. $value) = each($array)) $str .gettype Zwraca typ zmiennej PHP $var. aby wskazywała na katalog z plikiem browscap. $browser = get_browser(). get_browser Odczytuje możliwości przeglądarki użytkownika. Zwracany jest obiekt zawierający dane opisujące. ale można przekazać dowolną dowolny parametr $user_agent (na przykład.ini zawiera dane o wielu przeglądarkach. MSIE 5. Funkcja ta nie zwraca danych konfiguracji ustawionych przy kompilacji PHP lub poprzez pliki konfiguracyjne Apache (przy użyciu dyrektywy php3_configuration_option).5. 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(). Format pliku jest bardzo prosty.ini. Więcej informacji (w tym adresy skąd można ściągnąć plik browscap. Poniższy przykład pokazuje przykładowe dane zwracane dla przeglądarki użytkownika. MSIE 5\.0)<hr> <b>browser_name_pattern:</b> Mozilla/4\.php. } echo "$HTTP_USER_AGENT<hr>\n".

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

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

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

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

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

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

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

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

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

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

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

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

. czy możliwy jest dostęp do dokumentu.array} objectID. Jeżeli $max_hits ma wartość -1. W przeciwieństwie do pozostałych funkcji zapytań. array hw_GetObjectByQuery( int connection. Zapytanie działa jedynie na atrybutach posiadających indeksy. Patrz również: i hw_GetChildCollObj(). string query. int max_hits ) hw_GetObjectByQueryCollObj Przeszukuje obiekty w kolekcji o identyfikatorze $objectID i zwraca tablicę rekordów obiektów. Zapytanie działa jedynie na atrybutach posiadających indeksy. funkcja zwróci tablicę rekordów obiektów. array hw_GetObjectByQueryColl( int connection. maksymalna ilość zwracanych obiektów nie jest ograniczona. array hw_GetChildDocCollObj( int connection. Jeżeli drugi parametr jest tablicą liczb całkowitych. int objectID. hw_GetObjectByQuery Przeszukuje wszystkie obiekty na serwerze i zwraca tablicę identyfikatorów obiektów. Patrz również: hw_GetObjectByQueryObj(). W tym przypadku analizowany jest również trzeci parametr — ciąg zapytania. TypDokumentu . int objectID ) hw_GetChildDocCollObj hw_ChildrenObj() Zwraca tablicę rekordów obiektów dla dokumentów potomnych w kolekcji. Maksymalna ilość identyfikatorów jest ograniczona do $max_hits. Patrz również: hw_GetAndLock() i hw_GetObjectByQuery(). array hw_GetObjectByQueryCollObj( int connection. int objectID. to zapytanie może działać na atrybutach bez indeksów. Zapytanie działa jedynie na atrybutach posiadających indeksy. Autor. {int. Patrz również: hw_GetChildren() i hw_GetChildColl(). Patrz również: hw_GetObjectByQueryCollObj(). Ilość zwracanych rekordów obiektów zależy od zapytania i od tego. array hw_GetChldDocColl( int connection.. string query. int max_hits ) 239 PHP – Kompendium wiedzy . string query.hw_GetChildDocColl Zwraca tablicę identyfikatorów obiektów dokumentów potomnych w kolekcji. zwraca rekord obiektu dla obiektu o identyfikatorze $objectID.) */ <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. 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ł. Jeżeli $max_hits ma wartość -1. array hw_GetObject( int connection. int max_hits ) hw_GetObjectByQueryColl Przeszukuje obiekty w kolekcji o identyfikatorze $objectID i zwraca tablicę identyfikatorów obiektów. Jeżeli $max_hits ma wartość -1. Maksymalna ilość obiektów jest ograniczona do $max_hits. maksymalna ilość zwracanych identyfikatorów nie jest ograniczona. Maksymalna ilość identyfikatorów jest ograniczona do $max_hits. maksymalna ilość zwracanych identyfikatorów nie jest ograniczona. int objectID ) hw_GetObject Jeżeli drugi parametr jest liczą całkowitą. Patrz również: hw_GetObjectByQueryColl().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

\\Flagged. imap_deletemailbox() i imap_open() gdzie znajduje się opis formatów nazw $mbox. Posiada opcjonalny parametr $flag CL_EXPUNGE. string options) imap_close Zamyka strumień imap. sekcja 6. string imap_clearflag_full (int stream. 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. int flags]) imap_createmailbox Tworzy nową skrzynkę pocztową o nazwie $mbox. \\Deleted.8). int msg_number [. $name1 = "phpnewbox".host}".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. 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. Parametr $options jest maską bitową składającą się z następujących znaczników: ST_UID. Patrz również: imap_base64(). string sequence. Znacznikami do usuwania są: \\Seen. Dodatek A .imap. int imap_createmailbox (int imap_stream. string imap_binary (string string) imap_body Zwraca treść przesyłki o numerze $msg_number z bieżącej skrzynki pocztowej. IMAP. 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. Zwraca True w przypadku powodzenia lub False w przypadku wystąpienia błędu. \\Answered. Zwraca ciąg base64. 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. 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."username".Funkcje 266 . Nazwy zawierające znaki narodowe powinny być zakodowane przy pomocy funkcji imap_utf7_encode(). Patrz również: imap_renamemailbox(). \\Draft i \\Recent (według RFC2060). int imap_close (int imap_stream [. string mbox) Przykład: imap_createmailbox() $mbox = imap_open("{your.imap_last_error()). W przypadku błędu zwraca False. string flag.OP_HALFOPEN) or die("nie można połączyć: ". sekwencja argumentów zawierająca UID zamiast numerów sekwencji. który powoduje wyczyszczenie skrzynki przed zamknięciem poprzez usunięcie przesyłek zaznaczonych jako usunięte."password". $flags string imap_body (int imap_stream.

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

że argumenty $msg_number należy traktować jako identyfikatory UID. jeżeli wymagany jest pełny tekst przesyłki (na przykład.RFC822 powinien być w tym samym czasie wstępnie pobrany. rozmiar. Po wywołaniu imap_errors() stos błędów jest czyszczony. 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. która wskazuje funkcji. string part_number [. oraz podobne obiekty dla każdego załącznika MIME. FT_UID. jeżeli nie był wcześniej ustawiony • FT_INTERNAL — Zwracany ciąg jest w postaci wewnętrznej bez konwersji końców linii. flags flags]) imap_fetchheader Powoduje odczytanie całego. jako usunięte przez imap_delete(). string imap_fetchbody (int imap_stream.int imap_deletemailbox (int imap_stream. 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. 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. datę wewnętrzną. znaczniki i strukturę treści. int msg_number. int msgno. nieprzefiltrowanego RFC822 nagłówka formatu podanego komunikatu i zwrócenie go ciągu znaków. przesyłki zaznaczone Zwraca True. Pozwala to uniknąć dodatkowego RTT na połączeniu IMAP. object imap_fetchstructure (int imap_stream. które są indeksami w liście części.Funkcje 268 . Zwracany obiekt zawiera kopertę. Specyfikacja sekcji jest ciągiem liczb rozdzielonych kropkami. int msg_number [. • FT_PREFETCH — TEXT. 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 . operacja „zapis do pliku”) string imap_fetchheader (int imap_stream. int flags]) Tabela 1. Części z treścią nie są dekodowane przez tą funkcję. int flags) imap_fetchstructure Funkcja pobiera wszystkie informacje o strukturze podanej przesyłki. w sposób określony przez specyfikację IMAP4. Opcjonalny parametr $flags posiada tylko jedną opcję. 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().

3:application." . " . 7-other Rodzaje kodowania 0:7BIT."username". 3:BASE64.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. 2:BINARY. if(is_array($overview)) { reset($overview).imap. że nie mogą posiadać następnych obiektów parts. gdy parametr $flag zawiera FT_UID. 4:audio.$val) = each($overview)) { print $val->msgno . Parametr $sequence może zawierać sekwencję indeksów wiadomości lub identyfikatorów UID. } } imap_close($mbox)."password") or die("błąd połaczenia: ". 5:image. "\n". Parts jest tablicą obietów o identycznej strukturze jak nadrzędny obiekt. while( list($key.host:143}". $overview = imap_fetch_overview($mbox. $val->subject ." . $val->date . 5:OTHER imap_fetch_overview Pobiera nagłówki dla podanej sekwencji $sequence i zwraca skrót ich zawartości."2. 1: multipart. 6-video.imap_last_error()). 2:message.0).4:6". Podstawowe typy treści 0:text. string sequence [. z ograniczeniem. Parameters jest tablicą obiektów posiadających atrybuty $attribute i $value. 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. " . int flags]) Przykład: imap_fetch_overview() $mbox = imap_open("{your. 269 PHP – Kompendium wiedzy . 1:8BIT. 4:QUOTED-PRINTABLE.

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

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

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

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

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

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

podobnie do imap_header(). a które nie była udzielona odpowiedź UNDELETED — szuka wiadomości. 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. string content) imap_search Przeszukuje skrzynkę pocztową otwartą za pocą podanego strumienia IMAP. które nie są usunięte UNFLAGGED — szuka wiadomości.imap_rfc822_parse_headers Zwraca obiekt z różnymi elementami nagłówka."Hartmut Holzgraefe").html).Funkcje 276 . string host. string pattern.net"."cvs. string ref. string personal) RFC822 Przykład: imap_rfc822_write_address() print imap_rfc822_write_address("hartmut". na podstawie skrzynki pocztowej.php. hosta i danych osobistych. string defaulthost]) imap_rfc822_write_address Zwraca prawidłowo sformatowany adres e-mail według definicji w (http://www/faqs. ale bez znaczników i innych elementów pochodzących z serwera IMAP.org/rfcs/rfc2045. imap_scanmailbox Zwraca tablicę zawierającą nazwy skrzynek. ale dodatkowo sprawdza czy w danych skrzynki zawarty tekst $content. • • • • • • • • • • • • • • • • • • • • • • • • array imap_search (int imap_stream. na przykład FROM "jan kowalski". array imap_scanmailbox (int imap_stream. Parametr $criteria zawiera ciąg. które zawierają tekst przekazany w $string. Funkcja ta jest podobna do imap_listmailbox(). object imap_rfc822_parse_headers (string headers [. w którym dozwolone są zamieszczone poniżej słowa kluczowe rozdzielone spacjami. Wszystkie elementy wielowyrazowe muszą być otoczone apostrofami. string imap_rfc822_write_address (string mailbox. string criteria."\n". 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 . Opis parametrów $ref i $pattern można znaleźć przy funkcji imap_getmailboxes().

aby odnaleźć wszystkie wiadomości wysłanych przez Mama. imap_sort Zwraca tablicę numerów wiadomości posortowaną według podanego parametru."2. Przy przeszukiwaniu duże i małe litery nie są rozróżniane.4).imap.imap_last_error()). print $status. object imap_status (int imap_stream. 277 PHP – Kompendium wiedzy .imap_last_error())."username".5". który powoduje zwracanie tablicy zawierającej identyfikatory UID zamiast numerów kolejnych wiadomości. $status = imap_setflag_full($mbox."password") or die("błąd połączenia: ". string options) Przykład: imap_setflag_full() $mbox = imap_open("{your. int criteria. 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łą.Na przykład. która zmienia się.host:143}". string mailbox. Przykład: imap_status() • • • • • $mbox = imap_open("{your. int reverse. na które nie była udzielona odpowiedź."username". \\Flagged. która może być porównywana z przedstawionymi powyżej stałymi. należy użyć ciągu "UNANSWERED FROM Mama". array imap_sort (int stream. string imap_setflag_full (int stream.4. int options) $reverse jest 1. Podana lista warunków jest odczytana ze źródeł UW c-client i może być niekompletna lub nieprecyzyjna (patrz RFC2060 sekcja 6. \\Draft i \\Recent (według RFC2060). string flag. \\Deleted. • • • • • • • • • 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. imap_close($mbox).host}". string sequence. który powoduje zwracanie tablicy zawierającej identyfikatory UID zamiast numerów kolejnych wiadomości. Znaczniki jakie można ustawić to: \\Seen. \\Answered. imap_setflag_full Powoduje dodanie określonych znaczników do wiadomości z podanej sekwencji."\n".OP_HALFOPEN) or die("błąd połaczenia: ". Prawidłową wartością parametru $flags jest ST_UID."\\Seen \\Flagged")."password"."\n". print gettype($status). Jeżeli sortowanie jest odwrotne. Prawidłową wartością parametru $flags jest SE_UID. 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ą.

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

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

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

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

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

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

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

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

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

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

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

echo $attrs["count"]. ale nie gdy są używane jako indeksy tablicy). Ilość wartości można odczytać z wynikowej tablicy. False w przypadku błędu. Funkcja ldap_get_dn() jest używana do string ldap_get_dn (int link_identifier. int result_entry_identifier. W aplikacji można na stałe zapisać nazwy interesujących nas atrybutów (na przykład surname lub mail). więc można na przykład zapamiętywać kilka adresów e-mail w pozycji katalogu zawierającej określoną osobę. Funkcja wymaga identyfikatora pozycji wyniku. Funkcja ldap_get_values() jest używana do odczytania wszystkich wartości atrybutów z pozycji wyniku. 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. Wszystkie dane są zwracane za pomocą jednego wywołania funkcji we wielowymiarowej tablicy. for ($i=0. int result_identifier) ldap_get_values Zwraca tablicę wartości atrybutu lub False w przypadku wystąpienia błędu. Indeksy atrybutów są konwertowane do małych liter (wielkość liter w atrybutach ma znaczenie dla serwerów katalogów. $i++) echo $attrs[$i]. ldap_get_dn Zwraca DN pozycji wyniku lub sprawdzenia DN pozycji wyniku.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. Pozycja jest określona przez $result_entry_identifier. 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. $sr). $i<$attrs["count"]. LDAP pozwala na przechowywanie więcej niż jednej pozycji dla atrybuty. Struktura tablicy jest następująca." atrybutów w tej pozycji:<p>". $attrs = ldap_get_attributes($ds. Poszczególne wartości mogą być odczytane poprzez numeryczne indeksy tablicy."<br>". 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. int result_entry_identifier) ldap_get_entries Zwraca wszystkie dane pozycji w postaci wielowymiarowej tablicy lub w przypadku wystąpienia błędu. 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. $entry). Pierwszy indeks ma wartość 0. False. spod indeksu count. więc musi być poprzedzona przez jedną z funkcji wyszukujących i jedno z wywołań pobierających poszczególne pozycje. można również użyć funkcji ldap_get_attributes() do sprawdzenia jakie atrybuty istnieją dla danej pozycji. 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 .

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

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

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

Trzeci wariant. aby zamienić $str1 na $str2. int cost_rep. zamiany i usunięcia. gdzie m i n są długością ciągów $str1 i $str2 (całkiem nieźle w porównaniu do similar_text(). w jakim występują w ciągu. Algorytm ten ma złożoność O(m*n). string str2. function cost) W swojej najprostszej postaci funkcja wymaga jedynie dwóch ciągów jako parametry i oblicza ilość operacji wstawienia. ale nie jest on tak wydajny. int cost_del) int levenshtein (string str1. będzie najbardziej ogólny. Funkcja użytkownika posiadać musi następujące parametry: • operacja do wykonania: I. po zakończeniu każdego żądania. Użycie funkcji użytkownika pozwala na możliwość wzięcia pod uwagę różnicy pomiędzy znakami lub nawet kontekstu. zamiany lub usunięcia potrzebnych do zamiany $str1 na $str2. Będzie wywoływał funkcję napisaną przez użtkownika. ale również najwolniejszy. który jeszcze nie został zaimplementowany. string str2. Funkcja ta używana jest do sprawdzania. która będzie zwracała koszt każdej operacji. Patrz również: linkinfo(). Patrz również: soundex(). similar_text() i metaphone(). która ma złożoność O(max(n. Jednak wywoływanie tej funkcji do obliczenia kosztu każdej operacji. ale do tego celu może używać tylko niektórych z przekazanych argumentów. Uwaga Funkcja ta nie działa w systemie Windows int link (string target. Odległość Levenshtein jest definiowana jako minimalna ilość znaków jakie trzeba zamienić. 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). Drugi wariant potrzebuje trzech dodatkowych paramterów definiujących koszt operacji wstawienia. 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. powoduje utratę wszystkich optymalizacji użycia rejestrów procesora i pamięci podręcznej.m)**3).leak Powoduje „wyciek” określonej ilości pamięci. link Tworzy trwałe łącze. ale i tak jest to kosztowny algorytm) int levenshtein (string str1. które są zastosowane w poprzednich dwóch wariantach. 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. Jest to przydatne przy testowaniu zarządcy pamięci. Jest to bardziej ogólny i adaptowalny wariant funkcji. int cost_ins. string str2) int levenshtein (string str1. który automatycznie odzyskuje pamięć utraconą po „wycieku”. czy łącze (wskazywane przez $path) istnieje (wykorzystując metodę 293 PHP – Kompendium wiedzy . wstawić lub usunąć.

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

log Zwraca logarytm naturalny z $arg.ca". bool mail (string to. Wyniki tej funkcji są przechowywane w buforze. Szczegóły zostały opisane przy funkcji clearstatcache(). "Temat". string additional_parameters]]) $to. 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. \v. Patrz również: chop() i trim(). "Linia 1\nLinia 2\nLinia 3"). 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. \t. ltrim Usuwa znaki odstępu z początku ciągu i zwraca obcięty ciąg. string subject.bbb. \0 oraz spacja. Jest on zwykle używany do wstawiania do wiadomości dodatkowych nagłówków.ccc. Jeżeli zostanie przekazany czwarty argument ciąg ten jest wstawiany na końcu nagłówka.on. że gdy parametr $filename jest łączem symbolicznym. string long2ip (int proper_address) lstat Zbiera statystyki pliku lub łącza symbolicznego o podanej nazwie.ddd) na podstawie właściwej reprezentacji adresu. zwracany jest stan łącza a nie status pliku. float log10 (float arg) long2ip Generuje adres internetowy w postaci z kropkami (aaa. float log (float arg) log10 Zwraca logarytm o podstawie 10 z $arg. Obsługiwanymi znakami odstępu są: \n. Można podać wielu Przykład: wysyłanie poczty mail("rasmus@lerdorf. string message [. \r. string additional_headers [. Funkcja jest podobna do stat() poza tym. PHP – Kompendium wiedzy 295 . na który wskazuje łącze. 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 ltrim (string str [.

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

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

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

object mcal_fetch_event (int mcal_stream. int public — TRUE jeżeli zdarzenie jest publiczne.[. datetime recur_enddate — Data zakończenia powtarzania. int recur_type — Typ powtarzania. 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_type — Typ powtarzania. Zwraca True. object start — Obiekt zawierający początkową datę i czas. string title) mcal_expunge Usuwa wszystkie zdarzenia oznaczone jako usunięte. int min [. 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. string category — Ciąg z kategorią zdarzenia. object end — Obiekt zawierający końcową datę i czas. int event_id [. object start — Obiekt zawierający początkową datę i czas. int sec]]]]) mcal_event_set_title Ustawia tytuł w globalnej strukturze zdarzenia na podany ciąg. PHP – Kompendium wiedzy . string title — Ciąg z tytułem zdarzenia. string description — Ciąg z opisem zdarzenia. object end — Obiekt zawierający końcową datę i czas. int alarm — Ilość minut przed zdarzeniem do wysłania alarmu lub przypomnienia. int mcal_event_set_title (int stream. FALSE jeżeli jest prywatne. int options]) • • • • • • • • • • 299 Zwraca obiekt zdarzenia zawierający następujące atrybuty: int id — Identyfikator zdarzenia. int recur_interval — Okres powtarzania. int alarm — Ilość minut przed zdarzeniem do wysłania alarmu lub przypomnienia. int recur_data — Dane powtarzania. string description — Ciąg z opisem zdarzenia. string title — Ciąg z tytułem zdarzenia. int public — TRUE jeżeli zdarzenie jest publiczne. string category — Ciąg z kategorią zdarzenia.

Zwracana jest tablica identyfikatorów zdarzeń. int begin_month [. int options]) Dodatek A . int begin_day [. które posiadają ustawiony alarm pomiędzy datą początkową i końcową. Funkcja mcal_list_alarms() posiada opcjonalne parametry: datę początkowa końcową dla strumienia kalendarza. Po zestawieniu połączenia inicjowana jest również wewnętrzna struktura strumienia. int weekstart.• • • • • • • • • — Data zakończenia powtarzania. używane są daty z globalnej struktury zdarzeń. int mcal_popen (string calendar. array next) mcal_open Zwraca strumień MCAL lub False w przypadku błędu. objectbegin_date [. które mają alarm pomiędzy podanymi datami lub datami z wewnętrznej struktury zdarzeń. 0 gdy nie jest. Funkcja mcal_open() otwiera połączenie MCAL do określonego kalendarza. string username. lub jeżeli podano tylko strumień. Funkcja mcal_list_events() posiada opcjonalne parametry: datę początkowa końcową dla strumienia kalendarza. które są pomiędzy podanymi datami lub datami z wewnętrznej struktury zdarzeń. array mcal_list_events (int mcal_stream. Jeżeli podany zostanie opcjonalny parametr $options. lub jeżeli podano tylko strumień. int mcal_open (string calendar. int mcal_is_leap_year (int year) mcal_list_alarms Zwraca tablicę identyfikatorów zdarzeń. string password [. int recur_data — Dane powtarzania. int end_month [. object end_date]) mcal_next_recurrence Zwraca obiekt z kolejną datą wystąpienia zdarzenia po podanej dacie.Funkcje 300 . Jeżeli podany zostanie opcjonalny parametr $options. array mcal_list_alarms (int mcal_stream [. int begin_year [. string password [. Zwracana jest tablica identyfikatorów zdarzeń. 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. Funkcja mcal_open() otwiera połączenie MCAL do określonego kalendarza. używane są daty z globalnej struktury zdarzeń. int end_year [. jeżeli zdarzenie nie wystąpi lub wystąpił błąd. int options]) mcal_popen Zwraca strumień MCAL lub False w przypadku błędu. int end_day]]]]]]) mcal_list_events Zwraca tablicę identyfikatorów zdarzeń występujących pomiędzy datą początkową i końcową. int mcal_next_recurrence (int stream. funkcja przekazuje również ten parametr do skrzynki. Zwraca puste pole daty. Po zestawieniu połączenia inicjowana jest również wewnętrzna struktura strumienia. string username. Używa parametru $weekstart do określenia dnia rozpoczynającego tydzień. funkcja przekazuje również ten parametr do skrzynki.

mcrypt_ecb() i mcrypt_ofb(). $IV jest opcjonalnym wektorem inicjalizacji. $Data to dane do zaszyfrowania lub odszyfrowania. Jeżeli podany zostanie opcjonalny parametr $options.x. int mode [. int mode [. int seconds) False gdy jest to czas mcrypt_cbc Pierwszy prototyp jest dla przypadku. string mcal_rename_calendar (int stream.x. int mode [. string iv]) string mcrypt_cbc (string cipher. string key. • • • • • string mcrypt_cbc (int cipher. $IV jest opcjonalnym wektorem inicjalizacji. Musi być tajny. string iv]) jest jedną ze stałych MCRYPT_ciphername. minuta i sekunda tworzą prawidłowy czas. drugi gdy libmcrypt 2. Musi być tajny. string iv) string mcrypt_cfb (string cipher. gdy dołączona jest biblioteka libmcrypt 2. Zwraca True. Patrz również: mcrypt_cfb(). Patrz również: mcrypt_cbc(). int mcal_time_valid (int hour. $Cipher 301 PHP – Kompendium wiedzy . $Cipher mcrypt_cfb Pierwszy prototyp jest dla przypadku.mcal_rename_calendar Zmienia nazwę kalendarza z $old_name na $new_name. string key. • • • • • string mcrypt_cfb (int cipher. int mcal_reopen (string calendar [. int minutes. string key. funkcja przekazuje również ten parametr do skrzynki.x. string iv]) jest jedną ze stałych MCRYPT_ciphername. int mode. string data.x. nieprawidłowy. $Mode to MCRYPT_ENCRYPT lub MCRYPT_DECRYPT. gdy dołączona jest biblioteka libmcrypt 2. 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. mcrypt_ecb() i mcrypt_ofb(). $Data to dane do zaszyfrowania lub odszyfrowania. string old_name. 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. Zwraca przypadku powodzenia a False w przypadku błędu. string data. $Key jest kluczem przekazywanym do algorytmu. drugi gdy libmcrypt 2. string data. 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. $Mode to MCRYPT_ENCRYPT lub MCRYPT_DECRYPT.2. $Key jest kluczem przekazywanym do algorytmu.4. jeżeli podana godzina.4.2. string data. int mcal_store_event (int mcal_stream) True w mcal_time_valid Zwraca True. string new_name) mcal_reopen Funkcja mcal_reopen() ponownie otwiera połączenie MCAL do określonego kalendarza. string key.

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

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

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

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

Funkcje 312 . MSQL_NUM i MSQL_BOTH. jedynie dostarcza więcej wyników. primary key. Funkcja msql_fetch_row() pobiera jeden wiersz z wyniku określonego przez identyfikator zapytania. int result_type]) msql_fetch_row Zwraca tablicę odpowiadająca pobranemu wierszowi. int i) Dodatek A . Funkcja jest identyczna wydajnościowo z msql_fetch_array() i prawie tak samo szybka jak msql_fetch_row() — różnica jest nieznaczna. rozpoczynając od 0. Wiersz jest zwracany w postaci tablicy. Atrybutami są not null. Drugi argument. Każda kolumna jest zapisywana w osobnym indeksie tablicy. int msql_fieldlen (int query_identifier. int msql_fetch_object (int query_identifier [. $result_type w funkcji msql_fetch_array() jest jedną z następujących stałych: MSQL_ASSOC. lub False jeżeli nie ma już wierszy do pobrania. object msql_fetch_field (int query_identifier. Jeżeli nie zostanie podane przesunięcie. string msql_fieldflags (int query_identifier. array msql_fetch_row (int query_identifier) msql_fieldflags Zwraca atrybuty podanego pola. Patrz również: msql_fetch_array().Uwaga Funkcja msql_fetch_array() NIE jest wyraźnie wolniejsza od funkcji msql_fetch_row(). msql_fetch_object(). ż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). Oznacza to. 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. int result_type]) msql_fetch_field Zwraca obiekt zawierający informacje o polu. Patrz również: msql_fetch_array() i msql_fetch_row(). int msql_fetch_array (int query_identifier [. Funkcja msql_fetch_field() może być użyta do pobrania danych na temat pól w wyniku. int i) msql_fieldlen Zwraca długość podanego pola. odczytywane jest następne pole. Funkcja msql_fetch_object() jest podobna do msql_fetch_array() z jedną różnicą — zwracany jest obiekt a nie tablica. Bardziej szczegółowo jest to opisane przy funkcji msql_fetch_row(). które nie było jeszcze odczytane. jeżeli nie ma więcej wierszy do pobrania. 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. kombinacja obu oraz pusty ciąg.

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

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

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

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

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

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

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

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

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

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

$meta = mysql_fetch_field ($result). Funkcja mysql_fetch_assoc() jest odpowiednikiem wywołania funkcji mysql_fetch_array() z parametrem MYSQL_ASSOC.echo echo echo echo "ID użytkownika: "ID użytkownika: "Pełna nazwa : "Pełna nazwa : ". które nie było jeszcze odczytane. while ($row = mysql_fetch_assoc ($result)) { echo $row["user_id"]. że funkcja mysql_fetch_assoc() NIE jest wyraźnie wolniejsza od funkcji mysql_fetch_row(). jedynie dostarcza więcej wyników.$row["user_id"]. } 323 PHP – Kompendium wiedzy . 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.$row[1]. Funkcja mysql_fetch_field() może być użyta do pobrania danych na temat pól w wyniku. $password) or die ("Nie można podłączyć"). ?> mysql_fetch_assoc Zwraca tablicę asocjacyjną odpowiadającą bieżącemu wierszowi lub False. odczytywane jest następne pole."select * from table"). $result = mysql_db_query ("database". ". zwrócona zostanie wartość ostatniego z nich. "select * from table") or die ("Zapytanie nieudane")."<br>\n". $result = mysql_db_query ("database". $user. echo $row["fullname"]."<br>\n".$row[0]. while ($i < mysql_num_fields ($result)) { echo "Informacje na temat kolumny: $i:<BR>\n". Jeżeli dwie lub więcej pól w wyniku ma takie same nazwy. ". Należy przypomnieć. } mysql_free_result ($result). jeżeli nie ma już więcej wierszy w wyniku. } mysql_free_result ($result). object mysql_fetch_field (resource result [. Jest to sposób w jaki wcześniej działała funkcja mysql_fetch_array(). ". if (!$meta) { echo "Brak dostępnych danych<BR>\n". Aby odczytać wartości kolumn o tych samych nazwach należy użyć funkcji mysql_fetch_array() i skorzystać z indeksów numerycznych. $password)."<br>\n".$row["fullname"]. ?> mysql_fetch_field Zwraca obiekt zawierający informacje o polu. # pobranie metadanych kolumny $i = 0. Patrz również: mysql_fetch_row() i mysql_fetch_array(). array mysql_fetch_assoc (resource result) Przykład: mysql_fetch_assoc() <?php mysql_connect ($host. $user. Powoduje to zwrócenie tylko tablicy asocjacyjnej."<br>\n". Jeżeli nie zostanie podane przesunięcie.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 qualifier [. TABLE_OWNER i TABLE_NAME. string qualifier [. jeżeli na tym połączeniu są otwarte transakcje. Parametr ten nie jest Dodatek A . int odbc_columnprivileges (int connection_id [. jeżeli na tym połączeniu są otwarte transakcje. void odbc_close_all (void) odbc_columnprivileges False Zwraca listę kolumn i uprawnień do nich dla podanej tablicy. jaki jest używany na tym połączeniu. void odbc_close (int connection_id) odbc_close_all Zamyka wszystkie połączenia do serwera bazy danych. string table_name [. Uwaga Funkcja ta się nie uda. W takim przypadku połączenie pozostanie otwarte. Identyfikator połączenia zwracany przez tą funkcję jest wymagany przez inne funkcje ODBC. Patrz również: odbc_columnprivileges(). string owner [. Zwraca identyfikator wyniku ODBC lub w przypadku wystąpienia błędu. $table_name i $column_name pozwalają na stosowanie wzorców przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). 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. Możesz mieć jednocześnie wiele połączeń. Argument $column_name. string table_name [.Funkcje 342 . Zwraca identyfikator wyniku ODBC lub False w przypadku wystąpienia błędu.Funkcja ta się nie uda. Opcjonalny czwarty parametr określa typ kursora. int odbc_columns (int connection_id [. int odbc_commit (int connection_id) odbc_connect Zwraca identyfikator połączenia ODBC lub 0 (False) w przypadku błędu. Argument $column_name pozwala na stosowanie wzorców przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). Wszystkie transakcje rozpoczęte poprzez $connection_id są zatwierdzane. odbc_commit Zwraca True w przypadku sukcesu lub False w przypadku błędu. odbc_columns Tworzy listę kolumn w określonym zakresie. W takim przypadku połączenie pozostanie otwarte. string owner [.

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

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

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. Argumentem jest prawidłowy identyfikator wyniku zwracany przez odbc_exec(). (patrz odbc_autocommit()) i wywołasz odbc_free_result() przed zatwierdzeniem. Funkcja zwraca -1 w przypadku wystąpienia błędu. Dla wyrażeń i DELETE funkcja zwraca ilość zmienionych wierszy. Jeżeli ma wartość 0. Można użyć opcjonalnego parametru $data_type do ograniczenia danych do jednego typu. int odbc_num_fields (int result_id) odbc_num_rows Zwraca ilość wierszy w wyniku ODBC. że nie będziesz już używał danych z wyniku. dane z kolumn long są przepuszczane do klienta. Cała pamięć przydzielona do wyniku jest automatycznie zwalniana po zakończeniu działania skryptu. int length) odbc_num_fields Zwraca ilość pól (kolumn) w wyniku ODBC. int odbc_longreadlen (int result_id. Zwraca identyfikator wyniku ODBC lub False w przypadku wystąpienia błędu. Dla wyrażeń SELECT zwraca ilość zwracanych wierszy. 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. Uwaga Jeżeli automatyczne zatwierdzanie jest zablokowane. INSERT. W przypadku wystąpienia błędu funkcja zwraca -1. możesz wywołać funkcję odbc_free_result(). Uwaga Obsługa kolumn LONGVARBINARY jest również realizowana przez odbc_binmode(). int odbc_num_rows (int result_id) 345 PHP – Kompendium wiedzy . int odbc_gettypeinfo (int connection_id [. wszystkie otwarte transakcje zostaną wycofane. 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. Jeżeli jesteś pewien. gdy skrypt zużywa zbyt dużo pamięci podczas pracy. Wywołanie tej funkcji jest wymagane jedynie wtedy.odbc_free_result Zawsze zwraca True. aby zwolnić pamięć przydzieloną do $result_id. int odbc_free_result (int result_id) odbc_gettypeinfo Pobiera dane na temat typów danych obsługiwanych przez źródło danych.

jeżeli PHP jest użyty jako program CGI. Opis opcjonalnego parametru $cursor_type znajduje się przy opisie funkcji odbc_connect(). string owner. zwraca identyfikator wyniku ODBC lub False w przypadku błędu. int odbc_procedures (int connection_id [. int odbc_pconnect (string dsn. string user. Zwraca identyfikator wyniku ODBC lub False w przypadku błędu. Argumenty $owner. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej znaków i _ zastępuje jeden znak). int cursor_type]) odbc_prepare Zwraca False w przypadku błędu. int odbc_primarykeys (int connection_id.odbc_pconnect Zwraca identyfikator połączenia ODBC lub 0 (False) w przypadku wystąpienia błędu. string qualifier [. string password [. 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. string query_string) odbc_primarykeys Zwraca nazwy kolumn składających się na klucz główny tabeli. $proc i $column mogą zawierać wzorzec przeszukiwania (% zastępuje zero lub więcej odbc_procedures Tworzy listę procedur w określonym zakresie. Zwraca identyfikator wyniku ODBC lub przypadku błędu. 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). i COLUMN_TYPE. Wynikowy identyfikator może być użyty do uruchomienia wyrażenia za pomocą odbc_execute(). int odbc_procedurecolumns (int connection_id [. poza tym. string qualifier [. PROCEDURE_QUALIFIER. string owner [. $user i $password (poprzez odbc_connect() i odbc_pconnect()) powodują ponowne wykorzystanie połączenia trwałego. że połączenie nie jest zamykane po zakończeniu skryptu. Zwraca identyfikator wyniku ODBC dla poprawnie przygotowanego wyrażenia SQL. Uwaga Połączenia trwałe nie działają. string qualifier. int odbc_prepare (int connection_id. 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. string owner [. Więcej informacji na temat połączeń trwałych znajduje się w PHP FAQ. string proc [. Funkcja jest podobna do odbc_connect().Funkcje 346 . Dodatek A . Kolejne żądania połączenia z tą samą kombinacją $dsn.

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

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

LOG_ODELAY (domyślny) Opóźnia otwarcie połączenia do zapisu pierwszego komunikatu. Ciąg $ident jest dodawany do każdego komunikatu. Jeżeli $table_type nie jest pustym ciągiem. readdir() i rewinddir(). LOG_NDELAY Natychmiast otwiera połączenie z dziennikiem systemowym. NULL).. na przykład: 'TABLE'. LOG_PID Dodaje PID do każdego komunikatu. Podsystem poczty. Zarezerwowane. LOG_KERN Komunikaty jądra. Komunikaty generowane przez programy użytkownika. $owner i $name są pustymi ciągami. LOG_PERROR Wysyła komunikaty dziennika również na standardowe wyjście błędów. pisanie na konsolę i dodanie PID do każdego komunikatu należy użyć LOG_CONS | LOG_NDELAY | LOG_PID. musi zawierać listę wartości rozdzielonych przecinkami interesujących typów tabel Każda wartość może być otoczona apostrofami (') lub bez apostrofów. Urządzenia dla openlog() Stała Opis LOG_AUTH Komunikaty systemu bezpieczeństwa (należy użyć LOG_AUTHPRIV w systemach gdzie jest zdefiniowana ta stała). LOG_CRON Demony zegara (cron i at). Używając kilku opcji do ich łączenia należy użyć operatora OR. int openlog (string ident. Komunikaty generowane przez syslogd. opcji używanych przy generowaniu komunikatów. Na przykład. wynik jest listą typów tabel dla podanego źródła danych (wszystkie kolumny poza TABLE_TYPE zawierają wartości NULL). odbc_tables() nie zwraca wyników dla tego typu. LOG_DAEMON Inne demony systemowe. Wartości $option i $facility są wymienione w tabeli poniżej.VIEW.'VIEW' lub TABLE. Argument $option używany jest do wskazania.Jeżeli $owner zawiera znak procentu (%) a $qualifier i $name są pustymi ciągami. Podsystem UUCP.. PHP – Kompendium wiedzy 349 . LOG_CONS LOG_LOCAL7 LOG_LPR LOG_MAIL LOG_NEWS LOG_SYSLOG LOG_USER LOG_UUCP Opcje openlog() Stała Podsystem drukarki. LOG_AUTHPRIV Komunikaty systemu bezpieczeństwa (prywatne). int option. Pozwala to podać (w konfiguracji dziennika systemowego) w jaki sposób są obsługiwane komunikaty przychodzące z różnych urządzeń. aby uzyskać natychmiastowe otwarcie połączenia. Użycie funkcji openlog() jest opcjonalne. LOG_LOCAL0 . Jeżeli $table_type zawiera znak procentu (%) a $qualifier. Sposób odczytywania uprawnień opisany jest przy funkcji odbc_tableprivileges(). int facility) Opis Jeżeli wystąpił błąd przy wysyłaniu danych do dziennika systemowego dane są wypisywane na konsolę systemową. Można korzystać z więcej niż jednej z tych opcji. Jest ona wywoływana w razie potrzeby przez funkcję syslog() i w takim przypadku $ident ma wartość False. Jeżeli źródło danych nie obsługuje jakiegoś typu tabel. który jest później używany w funkcjach closedir(). opendir Zwraca uchwyt katalogu. resource opendir (string path) openlog Otwiera dla programu połączenie do dziennika systemowego. Podsystem USENET. wynik jest listą właścicieli dla podanego źródła danych (wszystkie kolumny poza TABLE_OWNER zawierają wartości NULL).

Ora_Bind Zwraca True jeżeli wiązanie udało się lub False w przeciwnym przypadku. "output". string PHP variable name. ora_bind($curs. ora_exec($curs). False w przeciwnym wypadku. int type]) Przykład: ora_bind() <?php ora_parse($curs. ":out". czy parametr ma być wyjściowy i wejściowy (0 — domyślnie). string SQL parameter name. int ora_close (int cursor) Ora_ColumnName Zwraca nazwę kolumny (pola) numer literami. są dostępne w odpowiednich związanych zmiennych.0. int column) Ora_ColumnSize Zwraca rozmiar kolumny (pola) numer $column z kursora $cursor. ":x". $len. syslog() i closelog(). $input = 765. Po wywołaniu ora_exec(). echo "Wynik: $result<BR>Wyjście: $output<BR>Wejście: $input". :x := 7. ":in". Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode().Patrz również: define_syslog_variables(). int ora_bind (int cursor. 2). $column z kursora $cursor. end. 5.1 można korzystać ze stałych ORA_BIND_INOUT. ?> Ora_Close Zwraca True jeżeli udało się zamknięcie. int column) Zwracany typ może być jedną z poniższych wartości: • • • • • • • • • VARCHAR2 VARCHAR CHAR NUMBER LONG LONG RAW ROWID DATE CURSOR Dodatek A . jeżeli są dostępne. Wartości wejściowe mogą być przekazywane poprzez przypisanie do związanych zmiennych PHP. int column) Ora_ColumnType Zwraca typ Oracle kolumny (pola) numer $column z kursora $cursor. Od wersji PHP 3. "input". wartości wyjściowe. int Ora_ColumnSize (int cursor. Za pomocą opcjonalnego parametru $type można zdefiniować. 5. "declare tmp INTEGER. "result".").77. wejściowy (10) lub wyjściowy (2). Funkcja zamyka kursor otwarty za pomocą ora_open(). ORA_BIND_IN i ORA_BIND_OUT zamiast liczb. :out := tmp. Parametr SQL musi mieć postać :nazwa. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). ora_bind($curs. string Ora_ColumnType (int cursor. Funkcja ora_bind() musi być wywołana po ora_parse() i przed ora_exec().Funkcje 350 . ora_bind($curs. int length [. begin tmp := :in. 2). 1). Funkcja ta wiąże nazwę zmiennej PHP z parametrem SQL. Zwracana nazwa zapisana jest wielkimi string Ora_ColumnName (int cursor.

ora_exec() i ora_fetch().0. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). Funkcja wyłącza automatyczne zatwierdzanie operacji po każdej funkcji ora_exec(). Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode().%s) violated" // *Cause: An update or insert statement attempted to insert a duplicate key // For Trusted ORACLE configured in DBMS MAC mode.4. wyłączenia automatycznego zatwierdzania lub nawiązania połączenia. int ora_commit (int conn) Ora_CommitOff Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. gdzie XXX jest źródłem błędu a NNNNN określa komunikat błędu. int ora_commitoff (int conn) Ora_CommitOn Funkcja włącza automatyczne zatwierdzanie operacji po każdej funkcji ora_exec() na podanym połączeniu. Patrz również: ora_parse().4.0. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode().Ora_Commit Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. Analizuje. Uwaga Obsługę identyfikatorów połączenia została dodana w PHP 3. // *Action: Either remove the unique restriction or do not insert the key Ora_ErrorCode Zwraca numeryczny kod błędu ostatniej wykonywanego wyrażenia na określonym kursorze lub połączeniu. "unique constraint (%s. int ora_do (int conn. Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. ora_exec() i ora_fetch(). int Ora_ErrorCode (int cursor_or_connection) 351 PHP – Kompendium wiedzy . Funkcja zatwierdza transakcję Oracle. wykonuje wyrażenie oraz pobiera pierwszy wiersz. Transakcja jest definiowana jako wszystkie zmiany wykonane poprzez połączenie od czasu ostatniej operacji COMMIT lub ROLLBACK. string Ora_Error (int cursor_or_connection) Na Oracle dla systemów Unix można znaleźć komunikaty błędów podobne do następujących: $ oerr ora 00001 00001. you may see // this message if a duplicate entry exists at a different level. string query) Ora_Error Zwraca komunikat błędu w postaci XXX-NNNNN. Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. Uwaga Obsługę identyfikatorów połączenia została dodana w PHP 3. int ora_commiton (int conn) Ora_Do Funkcja ta jest kombinacją funkcji ora_parse(). 00000.

liczba 0. Jeżeli nie wystąpił błąd. &$results).Funkcje 352 . W przypadku korzystania z modułu serwera. Wylogowuje użytkownika i odłącza od serwera. Patrz również: ora_parse(). ora_fetch() i ora_do(). ora_exec() i ora_do(). Jeżeli wystąpi błąd zwracana jest wartość False. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). ora_errorcode() zwraca 0. echo $results[0]. Jeżeli dane znakowe zawierają znaki spoza zakresu ASCII. Pobiera dane z kolumny lub wynik funkcji. Pobiera wiersz danych z podanego kursora. int ora_fetch (int cursor) Ora_Fetch_Into Pobiera wiersz do tablicy. mixed column) Ora_Logoff Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu.Ora_Exec Zwraca True w przypadku powodzenia operacji lub False w przypadku wystąpienia błędu. ora_fetch_into($cursor. ora_fetch() i ora_do(). Patrz również: ora_parse(). Uwaga Musisz przekazywać tablicę przez referencję. że sprawdzanie czy funkcja zwróciła wartość False powoduje. Należy pamiętać. zmienna ta powinna być ustawiona w środowisku serwera przed uruchomieniem serwera. że będą wykrywane również sytuacje gdy błąd nie wystąpił (wartość NULL. int flags]) Przykład: Pobranie wiersza wyniku Oracle do tablicy <?php array($results). powinieneś ustawić w systemie zmienną środowiska NLS_LANG. array result [. ?> Ora_GetColumn Zwraca dane kolumny. pusty ciąg. string password) Podając nazwę TNS i użytkownika połączenie może być zestawione za pomocą SQL*Net: $conn = Ora_Logon("user@TNSNAME". a ora_errorcode() zwraca niezerową wartość. int ora_logoff (int connection) Ora_Logon Zestawia połączenie pomiędzy PHP a bazą danych Oracle. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). ora_exec(). int ora_exec (int cursor) Ora_Fetch Zwraca True (został odczytany wiersz) lub False (brak wierszy lub wystąpił błąd). echo $results[1]. ciąg "0"). Patrz również: ora_logon(). mixed ora_getcolumn (int cursor. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). "pass"). korzystając z podanej nazwy użytkownika i hasła. int ora_fetch_into (int cursor. Patrz również: ora_parse(). int ora_logon (string user. W przypadku powodzenia operacji zwraca identyfikator Dodatek A .

Ora_Numcols Zwraca liczbę kolumn w wyniku. int ora_rollback (int connection) OrbitEnum Klasa ta reprezentuje wyliczenie identyfikowane przez parametr $id.d. int defer) Ora_pLogon Zestawia trwałe połączenie pomiędzy PHP a bazą danych Oracle. Parametr ten może być nazwą wyliczenia (na przykład: MyEnum) lub pełnym identyfikatorem repozytorium (na przykład: IDL:MyEnum:1:0) new OrbitEnum (string id) Przykład: przykładowy plik IDL enum MyEnum { a.połączenia lub False w przypadku wystąpienia błędu. ora_fetch() i ora_do(). int ora_plogon (string user. Patrz również: ora_parse(). string sql_statement. Patrz również: ora_logon(). /* wypisuje 2 */ echo $enum->e.c. int ora_numrows (int cursor_ind) Ora_Open Otwiera kursor Oracle skojarzony z połączeniem. string password) Ora_Rollback Wycofuje transakcję Oracle (definicja transakcji znajduje się przy funkcji ora_commit()). ora_exec(). int ora_parse (int cursor_ind. Zwraca 0 w przypadku powodzenia operacji lub -1 w przypadku błędu. Zwraca prawidłowe wartości jedyni po wykonaniu sekwencji parse – exec – fetch.Zwraca identyfikator kursora lub False w przypadku błędu. echo $enum->a.e }. ora_fetch() i ora_do(). korzystając z podanej nazwy użytkownika i hasła. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode().b. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). Przykład: kod PHP korzystający z MyEnum <?php $enum = new OrbitEnum ("MyEnum"). /* wypisuje 0 */ echo $enum->c. /* wypisuje 4 */ ?> 353 PHP – Kompendium wiedzy . Patrz również: ora_exec(). int ora_numcols (int cursor_ind) Ora_Numrows Zwraca ilość wierszy w wyniku. Zwraca identyfikator kursora lub False w przypadku błędu. Szczegóły na temat błędu mogą być pobrane za pomocą funkcji ora_error() i ora_errorcode(). int ora_open (int connection) Ora_Parse Analizuje wyrażenie SQL lub blok PL/SQL i łączy je z podanym kursorem.

Funkcje 354 . Zwraca ciąg binarny zawierający dane. } pack Pakuje podane argumenty do postaci ciągu binarnego zgodnie z formatem $format. Ciąg formatu składa się z kodów formatowania po których następują opcjonalne argumenty powtarzania.OrbitObject Klasa pozwalająca na dostęp do obiektu CORBA. $obj->SetValues ($initial_values). } Przykład: kod PHP korzystający z MyStruct <?php $obj = new OrbitObject ($ior). } Przykład: kod PHP korzystający z MyInterface <?php $obj = new OrbitObject ($ior). Jednak brakuje kilku kodów. $initial_values->shortvalue = 42. int ord (string string) $string.0"). Parametr $id może być nazwą struktury (na przykład MyStruct) lub pełnym identyfikatorem repozytorium (na przykład: IDL:MyStruct:1:0) new OrbitStruct (string id) Przykład: przykładowy plik IDL struct MyStruct { short shortvalue. A. $initial_values->stringvalue = "HGTTG". }. jest to bezwzględna pozycja na której należy umieścić Dodatek A . Funkcja jest odwrotnością chr(). $obj->value = 42. $values = $obj->GetValues(). na przykład kod Perla u.\n". new OrbitObject (string ior) $id powinien być ciągiem zawierającym Przykład: Przykładowy plik IDL interface MyInterface { void SetInfo (string info). $obj->SetInfo ("Obiekt"). interface SomeInterface { void SetValues (MyStruct values). Idea tej funkcji jest zapożyczona z języka Perl i wszystkie kody formatujące działają identycznie. Parametr Interoperable Object Reference (IOR) identyfikujący zdalny obiekt. Argument ten może być liczbą całkowita lub * dla powtarzania do końca danych wejściowych. attribute int value. string stringvalue. ?> OrbitStruct Klasa reprezentująca strukturę o identyfikatorze $id. string GetInfo(). echo $obj->value. h i H ilość powtórzeń określa ilość pobieranych znaków jednego argumentu danych. Dla kodów a. echo $obj->GetInfo(). MyStruct GetValues(). echo $values->shortvalue. $initial_values = new OrbitStruct ("IDL:MyStruct:1. Dla @. echo $values->stringvalue. Patrz Przykład: ord() if (ord($str) == 10) { echo "Pierwszym znakiem \$str jest znak nowego wiersza. ?> ord Zwraca wartość ASCII dla pierwszego znaku ciągu również: chr().

Uwaga Rozróżnienie pomiędzy wartościami ze znakiem lub bez znaku jest ważne jedynie dla funkcji unpack(). pierwszy jest bardziej znaczący półbajt c — litera ze znakiem C — litera bez znaku s — krótka liczba ze znakiem (zawsze 16 bitów. kolejność bajtów zależna od komputera) N — liczba długa bez znaku (zawsze 32 bity. z malejącym porządkiem bitów) v — krótka liczba bez znaku (zawsze 16 bitów.kolejne dane. kolejność bajtów zależna od komputera) L — liczba długa bez znaku (zawsze 32 bity. 0x34. 0x41 i 0x42. parse_str($str). 65. 0x78. zostanie ona skonwertowana do double. /* wypisuje "another" */ ?> parse_url port. z rosnącym porządkiem bitów) i — liczba całkowita ze znakiem (rozmiar i porządek bitów zależny od komputera) I — liczba całkowita bez znaku (rozmiar i porządek bitów zależny od komputera) l — liczba długa ze znakiem (zawsze 32 bity. pass. kolejność bajtów zależna od komputera) S — krótka liczba bez znaku (zawsze 16 bitów. echo $first. co może prowadzić do niespodziewanych wyników. parse_str Analizuje ciąg $str tak. z malejącym porządkiem bitów) V — liczba długa bez znaku (zawsze 32 bity. 0x5678. pierwszy jest mniej znaczący półbajt H — ciąg szesnastkowy. array arr]) Przykład: użycie parse_str() <?php $str = "first=value&second[]=this+works&second[]=another". że PHP wewnętrznie przechowuje wartości całkowite jako wartości ze znakiem o wielkości zależnej od komputera. host. Dla pozostałych kodów ilość powtórzeń określa ile argumentów jest pobieranych i pakowanych do wynikowego ciągu binarnego. kolejność bajtów zależna od komputera) n — krótka liczba bez znaku (zawsze 16 bitów. mixed args . void parse_str (string str [. query Zwraca tablicę asocjacyjną zawierającą różne składniki podanego adresu URL. string pack (string format [. Jeżeli zostanie przekazana zbyt duża wartość. /* wypisuje "this works" */ echo $second[1].. jakby był przekazany poprzez adres URL i ustawia zmienne w bieżącym zakresie widoczności. Należy zauważyć. PHP – Kompendium wiedzy array parse_url (string url) 355 . 0x56.]) • • • • • • • • • • • • • • • • • • • • • Zaimplementowane są następujące kody: a — ciąg dopełniany zerami A — ciąg dopełniany spacjami h — ciąg szesnastkowy.. user. Jeżeli podany jest drugi parametr $arr zmienne są umieszczane w przekazanej tablicy. /* wypisuje "value" */ echo $second[0]. z rosnącym porządkiem bitów) f — liczba zmiennoprzecinkowa (rozmiar i reprezentacja zależna od komputera) d — liczba double (rozmiar i reprezentacja zależna od komputera) x — bajt NUL X — cofnięcie o jeden bajt @ — wypełnienie znakami NUL do określonej pozycji Przykład: ciąg formatu dla pack() $binarydata = pack ("nvc*". 66). Wynikowy ciąg będzie miał 6 bajtów i zawierał sekwencję bajtów: 0x12. path. Są dostępne: scheme. 0x1234. i fragment. a funkcja pack() daje identyczne wartości dla kodów formatowania ze znakiem jak i bez.

void pdf_begin_page (int pdf_object. int parent] [. Ten fragment pamięci nie jest zwalniany przez żadną z funkcji PDF i jest to w gestii zarządcy pamięci PHP. musisz przekierować jego wyjście do pliku lub innego strumienia wyjściowego. float y. który potrafi bezpośrednio pisać do strumienia wyjściowego. void pdf_clip (int pdf_object) pdf_close Zamyka dokument pdf. umieszczana jest w nim wartość kodu powrotu wykonywanego polecenia. void passthru (string command [. gdy wynikiem działania polecenia są dane binarne. ponieważ inaczej PHP zatrzyma się czekając na zakończenie tego programu. string text [. co powoduje wymuszenie przydzielania pamięci przez PHP. Wynikiem jest identyfikator zakładki i może być on użyty jako obiekt nadrzędny dla innych zakładek. Uwaga Jeżeli uruchamiasz program przy pomocy tej funkcji i chcesz pozostawić go aby działał w tle. float r) pdf_clip Przycina rysunek do bieżącej ścieżki. pdf_stroke(). float alpha. Jeżeli podany jest parametr $return_var. które muszą być wysłane do przeglądarki. można stworzyć skrypt PHP bezpośrednio wyświetlający rysunki.Funkcje 356 . float beta) pdf_begin_page Rozpoczyna nową stronę o wysokości $height i szerokości $width. popen(). Ustawiając content-type na image/gif i wywołując pbmplus z opcją tworzenia pliku gif. Częstym zastosowaniem jest uruchomienie programu podobnego do pbmplus. float x. int return_var]) pdf_add_outline Dodaje zakładkę z tekstem $text wskazującą na bieżącą stronę. float x. że parametr $open jest różny od 0. Aby stworzyć prawidłowy dokument musisz co najmniej raz wywołać funkcję pdf_end_page(). Funkcja ta powinna być używana zamiast exec() lub system() dla przypadków. $y-coor) i promieniu $radius rozpoczynając pod kątem $start a kończąc na $end. Niestety pdflib nie tworzy kopii ciągu. Patrz również: pdf_arc() i void pdf_circle (int pdf_object. Dzięki temu można tworzyć hierarchię zakładek. int pdf_add_outline( int pdf_document. Patrz również: exec(). void pdf_close (int pdf_object) Dodatek A . float width. float height) pdf_circle Rysuje okrąg o środku w punkcie ($x-coor. Patrz również: pdf_circle() i pdf_stroke(). float r. Patrz również: pdf_open() i fclose(). EscapeShellCmd() oraz operator `. Zakładka jest wstawiana w postaci obiektu potomnego do $parent i jest domyślnie otwierana chyba. int open]) pdf_arc Rysuje łuk o środku w punkcie ($x-coor. float y. Patrz również: pdf_end_page(). void pdf_arc (resource pdf_object. $y-coor) i promieniu $radius. uruchamia polecenie podane w $command.passthru Podobna do funkcji exec().

wypełnia jej obszar bieżącym kolorem wypełnienia i rysuje ścieżkę. np. Skala 1. Patrz również: pdf_begin_page().pdf_closepath Zamyka bieżącą ścieżkę. Wiele funkcji. Patrz również: pdf_moveto(). że rysuje linię od bieżącego punktu do punktu. 357 PHP – Kompendium wiedzy . $y1) i ($x2. int image) pdf_open_xxx().0 powoduje wyświetlanie rysunku w oryginalnej wielkości. pdf_set_leading() i pdf_set_text_pos(). Patrz również: pdf_open_jpeg(). Po zakończeniu strony nie może być ona już modyfikowana. void pdf_end_page (int pdf_object) pdf_execute_image Wyświetla rysunek umieszczony w pliku PDF za pomocą funkcji pdf_put_image() na bieżącej stronie na podanych współrzędnych. float x3. pdf_moveto(). pdf_continue_text Umieszcza tekst przekazany w parametrze $text w kolejnym wierszu. w którym zostało rozpoczęte rysowanie ścieżki. Dodatkowo kasuje ścieżkę. Patrz również: pdf_closepath() i pdf_stroke(). Odstęp pomiędzy wierszami może być regulowany za pomocą funkcji pdf_set_leading(). Patrz również: pdf_closepath(). Rysunek może być przeskalowany podczas wyświetlania. pdf_setgray_fill(). pdf_circle() i pdf_rect() rozpoczyna nową ścieżkę. void pdf_closepath_stroke (int pdf_object) pdf_close_image Zamyka rysunek otwarty za pomocą funkcji pdf_open_gif() i pdf_open_memory_image(). pdf_stroke(). pdf_setrbgcolor_fill() i pdf_setrgbcolor(). ale jej nie zamyka. pdf_setgray(). Patrz również: pdf_closepath(). string text) pdf_curveto Rysuje krzywą Beziera od punktu bieżącego do punktu ($x3. $y3) używając jako punktów kontrolnych ($x1. Oznacza to. pdf_lineto() i pdf_stroke(). $y2). float y3) pdf_endpath Kończy bieżącą ścieżkę. void pdf_close_image (int pdf_object. Patrz również: pdf_show_xy(). float x1. void pdf_endpath( int pdf_document ) pdf_end_page Kończy stronę. void pdf_closepath (int pdf_object) pdf_closepath_fill_stroke Zamyka bieżącą ścieżkę. void pdf_closepath_fill_stroke (int pdf_object) pdf_closepath_stroke Połączenie pdf_closepath() i pdf_stroke(). float y2. pdf_fill(). float y1. void pdf_continue_text (int pdf_object. void pdf_curveto (int pdf_object. float x2.

200. string pdf_get_image_width (int pdf_object. float modifier]) Dodatek A . Patrz również: pdf_get_value(). 100. $pim. pdf_setgray_fill(). string pdf_get_parameter (int pdf_object. $pim. pdf_fill Wypełnia wnętrze bieżącej ścieżki za pomocą bieżącego koloru wypełnienia. pdf_stroke(). ). 100.01. $col1 = ImageColorAllocate( $im. pdf_fill(). Zwraca pikselch. $pim = pdf_open_memory_image( $pdf. pdf_close_image( $pdf. string key [. Zwraca pikselch. Parametr funkcji $modifier określa parametr do pobrania. string pdf_get_image_height (int pdf_object. 200. ImageFill( $im. 100 ). Jeżeli modyfikator nie jest potrzebny. $pim ) ?> 190 ). pdf_setgray_fill(). int image) pdf_get_parameter Pobiera kilka z parametrów pdflib będących ciągami. Patrz również: pdf_get_parametr(). pdf_setgray(). Jeżeli modyfikator nie jest potrzebny. Patrz również: pdf_closepath(). Patrz również: pdf_open_image_file(). 80. string key [. float pdf_get_value (int pdf_object. void pdf_fill_stroke (int pdf_object) pdf_get_image_height wysokość rysunku pdf w pdf_open_memory_image() i pdf_get_image_width(). float modifier]) pdf_get_value Pobiera kilka numerycznych parametrów pdflib. void pdf_fill_stroke (int pdf_object) pdf_fill_stroke Wypełnia wnętrze bieżącej ścieżki za pomocą bieżącego koloru wypełnienia i rysuje bieżącą ścieżkę. musi mieć wartość 0 lub nie podany.Uwaga Funkcja stanie się przestarzała w pdflib 2. Przykład: wielokrotne wyświetlanie rysunku <?php $im = ImageCreate( 100. $pim ). int image) pdf_get_image_width szerokość rysunku pdf w pdf_open_memory_image() i pdf_get_image_heigth(). Będzie jedynie wyświetlała ostrzeżenie. pdf_closepath(). 10. pdf_setgray(). Patrz również: pdf_stroke(). Patrz również: pdf_open_image_file(). pdf_set_value() i pdf_set_parameter(). pdf_execute_image( $pdf. 1 ). $col1 ). pdf_set_value() i pdf_set_parameter(). musi mieć wartość 0 lub nie podany. pdf_execute_image( $pdf. 45.Funkcje 358 . pdf_setrgbcolor_fill() i pdf_sergbcolor(). $pim pdf_put_image( $pdf. pdf_setrgbcolor_fill() i pdf_sergbcolor(). Parametr funkcji $modifier określa parametr do pobrania. 2 ). 10.

Odpowiedni plik musi być otwarty za pomocą fopen() i deskryptor pliku przekazany jako parametr $file. Jeżeli nie przekazane zostaną żadne parametry. pdf_open_memory_image(). jpeg i gif. pdf_curveto() i pdf_stroke(). 100. 100. 1 ). 100. void pdf_lineto (int pdf_object. pdf_moveto Ustawia punkt bieżący na $x i $y. Patrz również: pdf_close_image(). pdf_open_memory_image(). Uwaga Zwracana wartość jest potrzebna jako pierwszy parametr wszystkich pozostałych funkcji zapisujących pliki pdf. $im ). float y) pdf_open Otwiera dokument pdf. string imagetype. float x. pdf_execute_image(). i pdf_put_image(). float y) $y). pdf_place_image( $pdf. pdf_close_image( $pdf. Przykład: Dołączanie rysunku GIF pdf_open_jpeg(). tiff. pdf_close_image( $pdf. $filename. ?> pdf_open_image_file Otwiera rysunek o formacie $format. Patrz również: pdf_moveto(). $im. Formatem pliku musi być gif. Funkcja zwraca identyfikator rysunku pdf. float x. int pdf_open( int file ) pdf_open_gif Otwiera rysunek zapisany w pliku o nazwie identyfikator rysunku pdf. void pdf_moveto (int pdf_object. pdf_place_image() i pdf_put_image(). string filename [. string intparam]]) Przykład: wstawianie rysunku <?php $im = pdf_image_file( $pdf. Patrz również: fopen() i pdf_close(). Uwaga Funkcja nie powinna być już używana. "picture. Proszę używać zamiast niej funkcji pdf_open_image_file(). zapisany w pliku o nazwie $filename. int pdf_open_image_file (int PDF-document. pdf_place_image( $pdf. pdf_execute_image(). 100. "test. "png". Możliwymi formatami pliku są: png. $im ). string stringparam [.png" ). string filename ) <?php $im = pdf_open_gif( $pdf. dokument zostanie utworzony w pamięci a wynikowa strona wysłana do stdout lub przeglądarki WWW. ?> 359 PHP – Kompendium wiedzy . pdf_open_gif().gif" ).pdf_lineto Rysuje linię od punktu bieżącego do punktu o współrzędnych ($x. 1 ). int pdf_open_gif ( int pdf_document. $im. Funkcja zwraca pdf_place_image() Patrz również: pdf_close_image(). pdf_open_jpeg().

Patrz również: pdf_close_image(). Proszę używać zamiast niej funkcji pdf_open_image_file(). 100. 100. Proszę używać zamiast niej funkcji pdf_open_image_file(). int pdf_open_png ( int pdf_document. 1 ). pdf_place_image() i pdf_put_image(). "test.pdf_open_jpeg Otwiera rysunek zapisany w pliku o nazwie identyfikator rysunku pdf. $im.png" ). 100 ). pdf_execute_image(). 1 ). Proszę używać zamiast niej funkcji pdf_open_image_file(). 45. pdf_place_image() int pdf_open_tiff( int pdf_document. $im ). pdf_open_memory_image Pobiera rysunek utworzony za pomocą funkcji PHP tworzących rysunki i udostępnia go dla dokumentu pdf. string filename ) Przykład: dołączanie rysunku PNG <?php $im = pdf_open_png( $pdf. $pim = pdf_open_memory_image( $pdf. $col1 = ImageColorAllocate( $im. $filename. string filename ) Patrz pdf_open_png(). pdf_place_image( $pdf.Funkcje . $filename. Uwaga Funkcja nie powinna być już używana. $pim. pdf_close_image( $pdf. 80. Uwaga Funkcja nie powinna być już używana. 190 ). int image) Przykład: Dołączanie rysunku z pamięci <?php $im = ImageCreate( 100. pdf_open_memory_image(). 10. ?> pdf_open_tiff Otwiera rysunek zapisany w pliku o nazwie identyfikator rysunku pdf. 10. Formatem pliku musi być jpeg. int pdf_open_memory_image (int pdf_object. pdf_place_image( $pdf. Funkcja zwraca identyfikator rysunku pdf. pdf_place_image() i pdf_put_image(). pdf_open_gif(). pdf_execute_image(). pdf_execute_image(). $col1 ). 100. pdf_open_gif(). $pim ) ?> pdf_open_png Otwiera rysunek zapisany w pliku o nazwie identyfikator rysunku pdf. pdf_close_image( $pdf. pdf_execute_image(). $filename. ImageDestroy( $im ). $pim ).pdf_open_jpeg(). pdf_open_gif(). pdf_open_png(). pdf_place_image() i pdf_put_image(). 100. Formatem pliku musi być png. pdf_open_png(). string filename ) i pdf_put_image(). Uwaga Funkcja nie powinna być już używana. Funkcja zwraca również: pdf_close_image(). Formatem pliku musi być tiff. pdf_open_jpeg(). 360 Dodatek A . Funkcja zwraca Patrz również: pdf_close_image(). pdf_open_jpeg(). Funkcja zwraca Patrz również: pdf_close_image(). pdf_open_gif(). pdf_open_memory_image(). ImageFill( $im. int pdf_open_jpeg ( int pdf_document. pdf_open_memory_image().

1 ). float y. pdf_lineto( $pdf. 1. void pdf_restore (int pdf_object) <?php pdf_save( $pdf ). gdy chcesz przesunąć lub obrócić obiekt bez wpływania na inne obiekty. pdf_rect Rysuje prostokąt o dolnym lewym narożniku w punkcie ($x. Patrz również: pdf_stroke(). $y). Uwaga Funkcja stanie się przestarzała w pdflib 2. void pdf_place_image (int pdf_object. Funkcja jest użyteczna. Patrz również: pdf_put_image(). pdf_stroke( $pdf ). void pdf_rotate (int pdf_object. float x. float y. ?> pdf_save(). Użycie funkcji pdf_put_image() i pdf_execute_image() jest zalecane dla większych rysunków (kilka KB).01. float x. Zapisany rysunek może być wyświetlony za pomocą pdf_execute_image() dowolną ilość razy. float angle) pdf_save Zapisuje bieżące środowisko. Jest to użyteczne.0. pdf_place_image() i pdf_execute_image(). Jego szerokość wynosi $width a void pdf_rect (int pdf_object. Patrz również: pdf_restore(). float x-scale. float width. Działa podobnie do polecenia postscript restore. $y). Rysunek może być w tym czasie przeskalowany.0 ). Przykład: zapamiętywanie i przywracanie środowiska pdf_rotate Ustawia kąt obrotu w stopniach na $angle. Poniższy przykład powoduje przeskalowanie współrzędnych x i y o 72. jeżeli są pokazane w dokumencie więcej niż raz. Działa podobnie do polecenia postscript save. 72. void pdf_save (int pdf_object) pdf_scale Ustala współczynnik skalowania w obu kierunkach. float y-scale) Przykład: skalowanie <?php pdf_scale($pdf. float height) pdf_restore Przywraca środowisko zapisane za pomocą Patrz również: pdf_save(). Kolejna linia będzie miała dzięki temu długość jednego cala w obu kierunkach. int image. wysokość $height. Funkcja pdf_save() powinna zawsze posiadać swoją pdf_restore() odtwarzającą stan środowiska sprzed pdf_save(). Będzie jedynie wyświetlała ostrzeżenie. jeżeli ten sam rysunek jest wielokrotnie używany w celu zmniejszenia pliku wynikowego. 72. Patrz również: pdf_put_image(). void pdf_scale (int pdf_object. // wykonanie obrotów i innych transformacji pdf_restore( $pdf ). float scale) pdf_put_image Umieszcza rysunek w pliku PDF bez jego pokazywania.pdf_place_image Umieszcza rysunek na stronie na współrzędnych ($x. 361 PHP – Kompendium wiedzy .

Patrz również: pdf_setrgbcolor_stroke(). Jeżeli obie wartości są 0. float gray) pdf_setgray_fill Ustawia bieżący kolor wypełnienia na podaną wartość szarości.Funkcje 362 . float flatness) pdf_setgray pdf_setrgbcolor_stroke() Ustawia bieżący kolor rysowania i wypełnienia na podaną wartość szarego koloru Patrz również: i pdf_setrgbcolor_fill(). void pdf_setgray_stroke (int pdf_object. void pdf_setgray_fill (int pdf_object. Patrz również: pdf_setrgbcolor_stroke(). void pdf_setrgbcolor (int pdf_object. void pdf_setlinewidth (int pdf_object. float gray) pdf_setlinecap Ustawia parametr linecap na wartość od 0 do 2. void pdf_setmiterlimit (int pdf_object. float green_value. void pdf_setdash (int pdf_object. int linecap) pdf_setlinejoin Ustawia parametr linejoin na wartość od 0 do 2. float gray