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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

161

PHP – Kompendium wiedzy

Rysunek 13.2. Plik CSV w Excelu

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

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

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

Rozdział 13 – Fajny PHP

162

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Rozdział 13 – Fajny PHP

166

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Zwykle wyświetlanie danych z bazy danych jest dużo łatwiejsze od manipulowania danymi.8. Następne dwa rozdziały są zbudowane w oparciu o dane i przykłady tu zaprezentowane. która jest bardzo łatwa do zarządzania. Podsumowanie Tworzenie aplikacji WWW korzystających z bazy danych wymaga dokładnego projektowania i programowania.Rysunek 15. ale wynik jest wart zachodu. 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. Rozdział 15 – Witryny oparte o bazę danych 204 . ponieważ występuje tu mniej problemów i mniej możliwości wystąpienia błędu. konserwacja i utrzymanie aplikacji zostanie niezwykle uproszczone. Po stworzeniu systemu administracyjnego aplikacja może być w uaktualniania dowolnym momencie i z dowolnego miejsca świata. oraz zlokalizowanie wszystkich reguł biznesowych. Najważniejszym krokiem jest dokładne zaprojektowanie bazy danych. Jeżeli te elementy zostaną odpowiednio zaprojektowane i zaprojektowane.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Należy również szyfrować przechowywane dane oraz całą transmisję pomiędzy klientem i serwerem realizować za pomocą SSL. 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. Rozdział 17. Witryny handlu elektronicznego 220 .Podsumowanie Tworzenie aplikacji handlu elektronicznego nie jest zbytnim wyzwaniem patrząc jedynie od strony kodu. która jest jednocześnie bezpieczna i prosta w użyciu.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int uid) icap_fetch_event Pobiera zdarzenie określone przez $event_id ze strumienia kalendarza. która powodowała niezgodność z poprzednimi wersjami. string title — Ciąg zawierający tytuł zdarzenia. Zwracana jest tablica identyfikatorów zdarzeń z aktywnym alarmem o podanej godzinie. object start — Obiekt zawierający datę i czas. string icap_delete_event (int sream_id. Funkcja wymaga podania daty i czasu oraz strumienia kalendarza. int event_id [. int icap_list_alarms (int stream_id. Zwraca True. string category — Ciąg zawierający kategorię zdarzenia.Uwaga W PHP 4. int public — True jeżeli zdarzenie jest publiczne lub False. string description — Ciąg z opisem zdarzenia .0 wprowadzono zmianę. int icap_close (int icap_stream [. 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. int options]) • • • • • • • • • • • • • • Zwraca obiekt zdarzenia zawierający następujące atrybuty: int id — Identyfikator zdarzenia.timeformat w celu ulepszenia działania funkcji. gdy jest prywatne. int icap_fetch_event (int stream_id. object end — Obiekt zawierający datę i czas. array date.timeformat na ibase. int flags]) icap_delete_event Usuwa zdarzenie z kalendarza o identyfikatorze podanym w $uid.Funkcje 248 .dateformat i ibase.timestampformat oraz dodane zostały dyrektywy ibase. zmieniając nazwę dyrektywy konfiguracji ibase. icap_close Zamyka podany strumień icap. int alarm — Ilość minut przed zdarzeniem gdy wysyłane jest powiadomienie lub alarm. 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 description — Ciąg z opisem zdarzenia . Jeżeli podany jest parametr opcjonalny $options. string password. int alarm — Ilość minut przed zdarzeniem gdy wysyłane jest powiadomienie lub alarm. string username. string title — Ciąg zawierający tytuł zdarzenia. natomiast w przypadku wystąpienia błędu. string category — Ciąg zawierający kategorię zdarzenia. object end — Obiekt zawierający datę i czas. jest on również przekazany do otwieranej skrzynki pocztowej. string icap_store_event (int stream_id. Zwracana jest tablica identyfikatorów zdarzeń pomiędzy podanymi datami. Zwraca True. Funkcja icap_list_events() pobiera ze strumienia identyfikatory zdarzeń pomiędzy data początkową i końcową. string icap_snooze (int stream_id. Funkcja icap_open() otwiera połączenie ICAP do podanego w $calendar magazynu. int uid) icap_store_event Zapisuje zdarzenie w kalendarzu ICAP. string options) icap_snooze Włącza alarm dla zdarzenia kalendarza określonego przez $uid. int ifxus_close_slob (int bid) False w przypadku 249 PHP – Kompendium wiedzy .icap_list_events Zwraca tablicę identyfikatorów zdarzeń pomiędzy dwiema datami. False. gdy jest prywatne. array icap_list_events (int stream_id. int public — 1 jeżeli zdarzenie jest publiczne lub 0. object event) • • • • • • • • • • • • • • Obiekt zdarzenia zawiera następujące atrybuty: int id — Identyfikator zdarzenia. Zwraca wystąpienia błędu. object start — Obiekt zawierający datę i czas. int end_date]) • • • • • • Wszystkie pozycje z datą i czasem zawierają następujące atrybuty: int year — rok int month — miesiąc int mday — dzień miesiąca int hour — godzina int min — minuty int sec — sekundy icap_open W przypadku powodzenia zwraca strumień ICAP. stream icap_open (string calendar. ifxus_close_slob Usuwa obiekt slob dla podanego w $bid identyfikatora obiektu slob. True w przypadku powodzenia operacji. 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 begin_date [.

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

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

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

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

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

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

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

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

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

Patrz również: imap_binary()."To: you@your."Subject: test\r\n" . Działając na serwerze Cyrus IMAP."\r\n" .host\r\n" . Patrz również imap_qprint(). string imap_base64 (string text) 265 PHP – Kompendium wiedzy . "password"). Patrz również: ImageTTFBox(). string flags]) Przykład: imap_append() $stream = imap_open("{your. Gdy zostanie wywołana funkcja imap_alerts(). stos ostrzeżeń jest czyszczony. imap_base64 Dekoduje tekst zakodowany metodą BASE-64 (patrz RFC2045.7). proszę zignorować\r\n" ). Zwracane są następujące bity: IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP. $check = imap_check($stream).host\r\n" .Drafts" . trzeba użyć terminatorów linii „\r\n” zamiast „\n”. Zwraca ciąg quotedprintable."\n".host}INBOX.?> Funkcja wymaga bibliotek GD i FreeType. int imap_append (int imap_stream. $check = imap_check($stream)."username". aby komunikaty te były pokazywane użytkownikowi. $check->Nmsgs."{your. int imagetypes (void) Przykład: ImageTypes <?php if (ImageTypes() & IMG_PNG) { echo "Obsługa PNG jest aktywna". print "Ilość komunikatów po dołączeniu : ". print "Ilość komunikatów przed dołączeniem: ". imap_append($stream. lub operacja się nie powiedzie. array imap_alerts (void) imap_append Zwraca True w przypadku powodzenia i False w przypadku błędu.8). Zdekodowany komunikat jest zwracany w postaci ciągu.imap. 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. ImageTypes Funkcja zwraca maskę bitową związaną z formatami rysunków obsługiwanych przez bibliotekę GD dołączoną do PHP. string mbox."przesyłka testowa. funkcja dołącza również do skrzynki te znaczniki. sekcja 6."From: me@my. Jeżeli podane zostały opcjonalne znaczniki $flags. Funkcja dołącza ciąg komunikatu do skrzynki pocztowej $mbox.host}INBOX. $check->Nmsgs. } ?> imap_8bit Konwertuje ciąg 8-bitowy na ciąg quoted-printable (zgodnie z RFC2045. imap_alerts().imap. Specyfikacja IMAP wymaga."\n".Drafts". sekcja 6. string message [. imap_close($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. 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. Patrz również: imap_base64(). W przypadku błędu zwraca False. Posiada opcjonalny parametr $flag CL_EXPUNGE. string imap_binary (string string) imap_body Zwraca treść przesyłki o numerze $msg_number z bieżącej skrzynki pocztowej. sekwencja argumentów zawierająca UID zamiast numerów sekwencji. int imap_createmailbox (int imap_stream. Zwraca ciąg base64.host}". string mbox) Przykład: imap_createmailbox() $mbox = imap_open("{your. string sequence. Parametr $options jest maską bitową składającą się z następujących znaczników: ST_UID. int msg_number [. int flags]) imap_createmailbox Tworzy nową skrzynkę pocztową o nazwie $mbox. 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. \\Draft i \\Recent (według RFC2060)."password". sekcja 6. \\Deleted. int imap_close (int imap_stream [. int flags]) imap_check Zwraca dane na temat bieżącej skrzynki pocztowej. Zwraca True w przypadku powodzenia lub False w przypadku wystąpienia błędu."username". 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. \\Answered.8). Znacznikami do usuwania są: \\Seen. string flag. Patrz również: imap_renamemailbox(). string options) imap_close Zamyka strumień imap.OP_HALFOPEN) or die("nie można połączyć: ". Dodatek A . IMAP. imap_deletemailbox() i imap_open() gdzie znajduje się opis formatów nazw $mbox. który powoduje wyczyszczenie skrzynki przed zamknięciem poprzez usunięcie przesyłek zaznaczonych jako usunięte. 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. Nazwy zawierające znaki narodowe powinny być zakodowane przy pomocy funkcji imap_utf7_encode(). \\Flagged. string imap_clearflag_full (int stream. $flags string imap_body (int imap_stream. $name1 = "phpnewbox".imap.imap_last_error()).Funkcje 266 .imap_binary Konwertuje 8-bitowy ciąg na ciąg zakodowany metodą BASE-64 (zgodnie z RFC2045.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. poza tym. string owner [. Kolejne żądania połączenia z tą samą kombinacją $dsn. string owner. PROCEDURE_QUALIFIER. Funkcja jest podobna do odbc_connect(). $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. Argumenty $owner. Opis opcjonalnego parametru $cursor_type znajduje się przy opisie funkcji odbc_connect().odbc_pconnect Zwraca identyfikator połączenia ODBC lub 0 (False) w przypadku wystąpienia błędu. jeżeli PHP jest użyty jako program CGI. Wynikowy identyfikator może być użyty do uruchomienia wyrażenia za pomocą odbc_execute(). string qualifier. string qualifier [. int odbc_primarykeys (int connection_id. string proc [. Więcej informacji na temat połączeń trwałych znajduje się w PHP FAQ. Zwraca identyfikator wyniku ODBC dla poprawnie przygotowanego wyrażenia SQL. string user. int odbc_pconnect (string dsn. string owner [. $user i $password (poprzez odbc_connect() i odbc_pconnect()) powodują ponowne wykorzystanie połączenia trwałego. string password [. int odbc_prepare (int connection_id. string qualifier [. int odbc_procedurecolumns (int connection_id [. zwraca identyfikator wyniku ODBC lub False w przypadku błędu. że połączenie nie jest zamykane po zakończeniu skryptu. string table) Wynik posiada następujące kolumny: TABLE_QUALIFIER COLUMN_NAME TABLE_OWNER KEY_SEQ TABLE_NAME PK_NAME odbc_procedurecolumns Zwraca listę parametrów wejściowych i wyjściowych oraz kolumn będących wynikiem działania procedury. i COLUMN_TYPE. Dodatek A . int odbc_procedures (int connection_id [. Zwraca identyfikator wyniku ODBC lub False w przypadku błędu. $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). Uwaga Połączenia trwałe nie działają. string query_string) odbc_primarykeys Zwraca nazwy kolumn składających się na klucz główny tabeli.Funkcje 346 .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

float width) pdf_setmiterlimit Ustawia parametr miter limit na wartość większą lub równą 1. float miter) pdf_setrgbcolor pdf_setrgbcolor_stroke() Ustawia bieżący kolor wypełnienia i rysowania na podaną wartość koloru RGB. long linejoin) pdf_setlinewidth Ustawia szerokość linii na $width. void pdf_setgray_fill (int pdf_object. void pdf_setgray_stroke (int pdf_object. Patrz również: pdf_setrgbcolor_stroke(). void pdf_setflat (int pdf_object.Funkcje 362 . void pdf_setlinejoin (int pdf_object. void pdf_setgray (int pdf_object. narysowana zostanie ciągła linia. Patrz również: i pdf_setrgbcolor_fill(). void pdf_setlinewidth (int pdf_object. void pdf_setdash (int pdf_object. float black.?> pdf_setdash Ustawia wzór kreski na $white białych punktów i $black czarnych. void pdf_setlinecap (int pdf_object. float green_value. float blue_value) Dodatek A . float gray) pdf_setgray_fill Ustawia bieżący kolor wypełnienia na podaną wartość szarości. float gray) pdf_setgray_stroke Ustawia bieżący kolor na podaną wartość szarości. Jeżeli obie wartości są 0. int linecap) pdf_setlinejoin Ustawia parametr linejoin na wartość od 0 do 2. Patrz również: pdf_setrgbcolor_stroke(). float gray) pdf_setlinecap Ustawia parametr linecap na wartość od 0 do 2. void pdf_setrgbcolor (int pdf_object. void pdf_setmiterlimit (int pdf_object. float white) pdf_setflat Ustawia parametr płaskości na wartość od 0 do 100. float red_value. 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().

pdf_setrgbcolor_fill Ustawia wartość koloru RGB dla wypełnienia ścieżki. Patrz również: pdf_set_border_dash(). Jeżeli ostatni parametr jest ustawiony na 1. czcionka jest wbudowywana w dokument PDF. 1 — pdfdoc. float blue) pdf_set_border_dash Ustawia długości czarnych i białych obszarów linii przerywanej otaczającej łącza i komentarze. pomiędzy kolejnymi stronami. void pdf_setrgbcolor_stroke (int pdf_object