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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Podsumowanie Tworzenie aplikacji handlu elektronicznego nie jest zbytnim wyzwaniem patrząc jedynie od strony kodu. Witryny handlu elektronicznego 220 . oraz integruje w sobie wszystkie niezbędne technologie. Rozdział 17. która jest jednocześnie bezpieczna i prosta w użyciu. 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Patrz również: mysql_fetch_row(). ?> 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. $result_type w funkcji mysql_fetch_array() jest jedną z następujących stałych: MYSQL_ASSOC. MYSQL_NUM i MYSQL_BOTH.Funkcje 324 . rozpoczynając od 0. Funkcja jest identyczna wydajnościowo z mysql_fetch_array() i prawie tak samo szybka jak mysql_fetch_row() — różnica jest nieznaczna. Oznacza to. object mysql_fetch_object (resource result [. while ($row = mysql_fetch_object ($result)) { echo $row->user_id. Drugi argument. $user. więc można je łatwo rozdzielić za pomocą funkcji explode(). Kolejne wywołanie mysql_fetch_row() powoduje zwracanie kolejnych wierszy z wyniku lub False jeżeli nie ma już więcej wierszy. Każda kolumna jest zapisywana w osobnym indeksie tablicy. Funkcja mysql_fetch_object() jest podobna do mysql_fetch_array() z jedną różnicą — zwracany jest obiekt a nie tablica. ż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_free_result ($result). echo $row->fullname. lub False jeżeli nie ma już wierszy do pobrania. Funkcja mysql_fetch_row() pobiera jeden wiersz z wyniku określonego przez identyfikator zapytania. jeżeli nie ma więcej wierszy do pobrania. Funkcja mysql_fetch_lengths() przechowuje długości każdej kolumny wyniku w ostatnim wierszu zwracanym przez mysql_fetch_row(). ?> Patrz również: mysql_fetch_array() i 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. mysql_fetch_object(). $result = mysql_db_query ("database". int result_type]) Przykład: mysql_fetch_object() <?php mysql_connect ($host. $password). mysql_data_seek() i mysql_result(). mysql_fetch_row Zwraca tablicę odpowiadająca pobranemu wierszowi. mysql_fetch_array() i mysql_fetch_object() w tablicy rozpoczynającej się od indeksu 0. Atrybuty są zwracane w jednym ciągu rozdzielone spacjami. "select * from table").echo "<PRE> blob: $meta->blob max_length: $meta->max_length multiple_key: $meta->multiple_key name: $meta->name not_null: $meta->not_null numeric: $meta->numeric primary_key: $meta->primary_key table: $meta->table type: $meta->type unique_key: $meta->unique_key unsigned: $meta->unsigned zerofill: $meta->zerofill </PRE>". Wiersz jest zwracany w postaci tablicy. Zwracane są następujące atrybuty o ile twoja wersja MySQL je Dodatek A . array mysql_fetch_row (resource result) mysql_field_flags Zwraca atrybuty podanego pola. } mysql_free_result ($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(). int field_offset) Przykład: Typy pól MySQL <?php mysql_connect ("localhost:3306"). string mysql_field_type (iresource result. int field_offset) mysql_field_type Funkcja podobna do mysql_field_name(). Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldflags(). $i = 0. mysql_select_db ("wisconsin"). int field_offset) mysql_field_name Zwraca nazwę podanego pola. "select * from users". int mysql_field_len (resource result. unique_key. Typami tymi mogą być int. 2). $link). auto_increment i timestamp. string mysql_field_name (resource result. czwartego — 3 itd. Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldlen(). zostanie zwrócone to właśnie pole. indeks trzeciego pola będzie 2. Dla zachowania zgodności wstecz można używać również nazwy mysql_fieldtable(). Parametr numerem kolejnym pola. primary_key. string mysql_field_table (resource result. Na przykład. int field_index) $result jest identyfikatorem zapytania. Jeżeli następne wywołanie mysql_fetch_field() nie będzie zawierało numeru pola. string. echo mysql_field_name($res. "\n". Argumenty są identyczne. enum. real. multiple_key. ale zwracane są typy pól. int field_offset) mysql_field_len Zwraca długość podanego pola. string mysql_field_flags (resource result. Patrz również: mysql_fetch_field(). z której pochodzi podane pole. blob i inne opisane w dokumentacji MySQL. $result = mysql_query ("SELECT * FROM onek"). 325 PHP – Kompendium wiedzy . unsigned. $res = mysql_db_query("users". 0) . mysql_field_seek Przesuwa wskaźnik do podanego numeru pola. a $field_index jest Przykład: mysql_field_name() // Tabela users składa się z trzech pól: // user_id // username // password.wszystkie obsługuje: not_null. Uwaga Wartości $field_index rozpoczynają się od 0. $fields = mysql_num_fields ($result). zerofill. int mysql_field_seek (resource result. binary. echo mysql_field_name($res. blob. $rows = mysql_num_rows ($result). Patrz również: mysql_fetch_field(). int field_offset) mysql_field_table Zwraca nazwę tabeli.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

void pdf_setgray_stroke (int pdf_object. void pdf_setflat (int pdf_object. float flatness) pdf_setgray pdf_setrgbcolor_stroke() Ustawia bieżący kolor rysowania i wypełnienia na podaną wartość szarego koloru Patrz również: i pdf_setrgbcolor_fill(). void pdf_setlinecap (int pdf_object. void pdf_setgray_fill (int pdf_object. Jeżeli obie wartości są 0. long linejoin) pdf_setlinewidth Ustawia szerokość linii na $width. Patrz również: i pdf_setrgbcolor_fill(). float gray) pdf_setgray_fill Ustawia bieżący kolor wypełnienia na podaną wartość szarości. void pdf_setmiterlimit (int pdf_object. float blue_value) Dodatek A . float white) pdf_setflat Ustawia parametr płaskości na wartość od 0 do 100. narysowana zostanie ciągła linia. void pdf_setdash (int pdf_object.?> pdf_setdash Ustawia wzór kreski na $white białych punktów i $black czarnych. float gray) pdf_setlinecap Ustawia parametr linecap na wartość od 0 do 2. void pdf_setgray (int pdf