Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00101 009740 11027983 na godz. na dobę w sumie
PHP 5 w praktyce - książka
PHP 5 w praktyce - książka
Autor: , Liczba stron: 432
Wydawca: Helion Język publikacji: polski
ISBN: 83-246-0814-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> php - programowanie
Porównaj ceny (książka, ebook, audiobook).

Poznaj potęgę języka PHP 5

Chcesz poprawić działanie swoich aplikacji internetowych, jednocześnie wykorzystując pełnię możliwości oferowanych przez PHP 5? A może w projekcie natknąłeś się na problem i szukasz rozwiązania? Najnowsza wersja PHP to w pełni obiektowy język programowania, umożliwiający tworzenie rozbudowanych i stabilnych aplikacji internetowych. Dostępny bezpłatnie PHP 5 jest podstawowym narzędziem wielu programistów na całym świecie, ceniących jego prostą składnię, ogromny zakres zastosowań i szybkość działania.

'PHP 5 w praktyce' to zbiór porad, dzięki którym utworzysz ciekawe, wydajne i szybko działające aplikacje internetowe i witryny WWW. Znajdziesz tu rozwiązania najczęściej spotykanych zadań programistycznych oraz wskazówki dotyczące stosowania poszczególnych elementów języka PHP 5. Przeczytasz o przetwarzaniu tekstów, liczb i dat, programowaniu obiektowym, połączeniach z bazami danych, tworzeniu elementów interfejsu użytkownika oraz operacjach na plikach i katalogach. Dowiesz się także, jak korzystać z plików XML, przetwarzać grafikę i usuwać błędy z aplikacji PHP.

Dzięki książce poznasz:

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

PHP 5 w praktyce Autorzy: Elliott White, Jonathan D. Eisenhamer T³umaczenie: Piotr Gaczkowski, Rados³aw Meryk, Piotr Pietrzak ISBN: 978-83-246-0814-0 Tytu³ orygina³u: PHP 5 in Practice Format: B5, stron: 432 Poznaj potêgê jêzyka PHP 5 Chcesz poprawiæ dzia³anie swoich aplikacji internetowych, jednoczeœnie wykorzystuj¹c pe³niê mo¿liwoœci oferowanych przez PHP 5? A mo¿e w projekcie natkn¹³eœ siê na problem i szukasz rozwi¹zania? Najnowsza wersja PHP to w pe³ni obiektowy jêzyk programowania, umo¿liwiaj¹cy tworzenie rozbudowanych i stabilnych aplikacji internetowych. Dostêpny bezp³atnie PHP 5 jest podstawowym narzêdziem wielu programistów na ca³ym œwiecie, ceni¹cych jego prost¹ sk³adniê, ogromny zakres zastosowañ i szybkoœæ dzia³ania. „PHP 5 w praktyce” to zbiór porad, dziêki którym utworzysz ciekawe, wydajne i szybko dzia³aj¹ce aplikacje internetowe i witryny WWW. Znajdziesz tu rozwi¹zania najczêœciej spotykanych zadañ programistycznych oraz wskazówki dotycz¹ce stosowania poszczególnych elementów jêzyka PHP 5. Przeczytasz o przetwarzaniu tekstów, liczb i dat, programowaniu obiektowym, po³¹czeniach z bazami danych, tworzeniu elementów interfejsu u¿ytkownika oraz operacjach na plikach i katalogach. Dowiesz siê tak¿e, jak korzystaæ z plików XML, przetwarzaæ grafikê i usuwaæ b³êdy z aplikacji PHP. Dziêki ksi¹¿ce poznasz: (cid:129) Przetwarzanie danych tekstowych i liczbowych (cid:129) Operacje na tablicach (cid:129) Stosowanie funkcji (cid:129) Praca z systemem plików (cid:129) Tworzenie elementów witryn WWW (cid:129) Obs³uga formularzy HTML (cid:129) Sesje i pliki cookie (cid:129) Wysy³anie poczty elektronicznej (cid:129) Komunikacja z bazami danych (cid:129) Przetwarzanie plików XML (cid:129) Generowanie grafiki (cid:129) Szyfrowanie danych Wydawnictwo Helion ul. Koœciuszki 1c 44-100 Gliwice tel. 032 230 98 63 e-mail: helion@helion.pl I 1 2 3 O autorach .................................................................................... 9 Wprowadzenie ............................................................................ 11 Opis języka PHP ....................................................... 19 Ciągi znaków .............................................................................. 21 1.1. Dopasowywanie wzorców (wyrażenia regularne) 24 1.2. Usuwanie białych znaków 1.3. Rozwijanie tabulacji do spacji oraz konwersja spacji na tabulacje 1.4. Konwersja tekstu w formacie systemów Mac OS, Unix i Windows 1.5. Przetwarzanie dokumentów w formacie CSV 1.6. Obcinanie tekstu, by zmieścił się w określonej przestrzeni 1.7. Uzupełnianie tablic z danymi w celu wyświetlenia ich w kolumnach 1.8. Sprawdzanie pisowni słowa 1.9. Dopasowywanie podobnych ciągów znaków 1.10. Właściwe stosowanie wielkich liter w nazwach własnych 1.11. Generowanie unikatowych identyfikatorów 1.12. Zliczanie wystąpień określonego słowa w tekście 26 27 28 29 31 32 34 36 37 38 39 Liczby .......................................................................................... 41 43 2.1. Odczytywanie liczby na podstawie wartości znakowej 2.2. Wyświetlanie poprawnych form liczby mnogiej 44 45 2.3. Konwersja danych liczbowych na liczby rzymskie 46 2.4. Obliczanie odsetek 51 2.5. Symulacja rzutów kośćmi 2.6. Obliczenia długości i szerokości geograficznej 52 56 2.7. Konwersja jednostek metrycznych na angielskie 59 2.8. Konwersja temperatury 2.9. Tworzenie pakietu funkcji statystycznych 60 Godziny i daty ............................................................................ 63 66 3.1. Obliczanie różnicy czasu między dwiema datami 68 3.2. Wyznaczanie ostatniego dnia podanego miesiąca 68 3.3. Sprawdzenie, czy rok jest przestępny 3.4. Obsługa stref czasowych 69 4 PHP 5 w praktyce 3.5. Obsługa znaczników czasu w bazach danych lub plikach 3.6. Wyznaczanie liczby dni roboczych 3.7. Generowanie kalendarza dla określonego miesiąca 71 72 74 4 Zmienne ...................................................................................... 77 4.1. Sprawdzanie, czy zmienna jest równa innej zmiennej 78 4.2. Dostęp do zmiennych spoza funkcji (zmienne globalne) 4.3. Utrzymywanie trwałych wartości w obrębie funkcji (zmienne statyczne) 4.4. Odwołania do zmiennych (referencje) 4.5. Wykorzystywanie zmiennej do zapisania nazwy innej zmiennej 4.6. Deklaracje stałych zamiast zmiennych 4.7. Przeglądanie listy wartości w celu znalezienia pierwszej, która ma wartość różną od false 80 81 82 83 84 85 5 Tablice ........................................................................................ 87 92 5.1. Tablice superglobalne i ich zastosowanie 5.2. Implementacja stosu 5.3. Implementacja kolejki 5.4. Sortowanie z wykorzystaniem porównań definiowanych przez użytkowników 5.5. Sortowanie z wykorzystaniem różnych algorytmów 5.6. Rekurencyjna obsługa tablic wielowymiarowych 5.7. Wykonywanie operacji na zbiorach z wykorzystaniem tablic 5.8. Operacje na macierzach z wykorzystaniem tablic 93 95 97 99 103 104 106 6 Funkcje ..................................................................................... 113 6.1. Ustawianie opcjonalnych parametrów 114 6.2. Tworzenie funkcji rekurencyjnych 115 6.3. Wywoływanie funkcji z wykorzystaniem nazwy funkcji zapisanej w zmiennej 117 6.4. Dynamiczne tworzenie funkcji (styl lambda) 6.5. Wykorzystanie do obliczeń tablicy funkcji 6.6. Przekazywanie argumentów i zwracanie wartości przez referencje 6.7. Używanie zmiennej liczby argumentów 6.8. Wymaganie określonego typu parametru 118 120 121 122 123 7 Klasy i obiekty .......................................................................... 127 7.1. Automatyczne ładowanie plików źródłowych klasy 129 7.2. Ochrona danych obiektowych (modyfikatory public, private, protected) 7.3. Automatyczne uruchamianie kodu podczas tworzenia lub niszczenia obiektów 7.4. Dostęp do składowych klasy bez tworzenia egzemplarza 7.5. Rozszerzanie definicji klasy 7.6. Tworzenie klas abstrakcyjnych 7.7. Zastosowanie interfejsów obiektów 7.8. Dynamiczne i przeciążone nazwy zmiennych 7.9. Przeciążanie metod 7.10. Implementacja powiązanych list 7.11. Implementacja drzew binarnych 132 133 134 135 137 139 140 144 147 149 Spis treści 5 8 Pliki i katalogi .......................................................................... 155 158 8.1. Wygenerowanie pełnej zawartości katalogu 8.2. Wyświetlanie rozmiaru plików w naturalny sposób 8.3. Zmiana nazwy wszystkich plików w katalogu 8.4. Wyszukiwanie nazw plików w drzewie katalogów 8.5. Względne i bezwzględne ścieżki dostępu do plików 8.6. Czytanie pliku za pośrednictwem protokołów HTTP lub FTP 8.7. Obserwacja zawartości pliku w miarę wzrostu jego objętości (symulacja uniksowego polecenia tail -f) 8.8. Generowanie raportu z różnic między dwoma plikami 8.9. Blokowanie pliku w celu uzyskania wyłączności 8.10. Lokalne buforowanie zdalnych plików 8.11. Kompresowanie i dekompresowanie plików 8.12. Automatyczne włączanie określonych plików z drzewa nadrzędnego 159 162 164 165 167 168 170 174 178 181 183 II Aplikacje PHP ......................................................... 185 9 Tworzenie stron WWW / XHTML / CSS ................................. 187 9.1. Tworzenie wielowarstwowego, rozwijanego menu 189 9.2. Wyróżnianie sekcji witryny WWW aktualnie przeglądanej przez użytkownika 9.3. Wyświetlanie dynamicznych pasków postępu 9.4. Symulacja graficznych wykresów z wykorzystaniem XHTML / CSS 9.5. Podział wyników na strony 9.6. Optymalizacja działania serwera poprzez buforowanie generowanych stron WWW 9.7. Lokalizacja strony WWW dla różnych języków 9.8. Łączne wykorzystanie technologii Ajax i PHP do tworzenia interaktywnych stron WWW 9.8. Łączne wykorzystanie technologii Ajax 194 195 198 200 202 204 207 207 10 Obsługa formularzy internetowych ......................................... 211 212 10.1. Dostęp do danych formularzy 10.2. Wykorzystanie tablic wielowymiarowych z danymi wprowadzanymi za pośrednictwem formularzy 10.3. Jednoczesne korzystanie z danych formularzy przesyłanych metodą GET i POST 10.4. Obsługa przesyłania plików na serwer 10.5. Generowanie listy opcji do wyboru 10.6. Wykorzystanie pól obowiązkowych 10.7. Przetwarzanie tekstu do wyświetlenia na forach (BBCode) 10.8. Pobieranie od użytkownika danych i wyświetlanie ostrzeżeń dotyczących łączy 10.9. Zapobieganie wielokrotnemu przesyłaniu formularzy 213 215 216 218 221 223 224 226 11 Sprawdzanie poprawności danych i ich standaryzacja ........... 229 11.1. Numery telefonów 231 11.2. Kody pocztowe 11.3. Numery ubezpieczenia społecznego 233 234 6 PHP 5 w praktyce 11.4. Liczby 11.5. Numery kart kredytowych 11.6. Daty 11.7. Adresy e-mail 11.8. Adresy URL 235 236 238 239 240 12 Sesje i śledzenie użytkowników ............................................... 243 12.1. Używanie plików cookies do przechowywania danych 244 12.2. Zapisywanie danych użytkownika za pomocą sesji 12.3. Dostosowywanie wyglądu strony 12.4. Tworzenie bibliotek przechowujących dane o działaniach podjętych w serwisie przez użytkownika 12.5. Tworzenie prostego koszyka na zakupy 12.6. Przekazywanie danych z sesji między serwerami 12.7. Analizowanie danych o przeglądarkach na podstawie pliku dziennika 247 250 253 255 258 260 13 Usługi sieciowe i inne protokoły .............................................. 265 13.1. Przesyłanie żądań HTTP metodą POST z wykorzystaniem rozszerzenia cURL 13.2. Komunikacja z serwerami LDAP 13.3. Wykorzystanie usług sieciowych za pomocą protokołu SOAP 13.4. Nawiązywanie połączenia z serwerem FTP 13.5. Wykorzystanie PHP do utworzenia klienta FTP 13.6. Wykorzystanie gniazd do nawiązywania połączeń z serwerami internetowymi 13.7. Utworzenie prostego serwera WWW 267 268 269 272 273 278 279 14 Relacyjne bazy danych ............................................................. 283 284 14.1. Komunikacja z bazą danych MySQL 14.2. Komunikacja z bazą danych Oracle 14.3. Komunikacja z bazą danych PostgreSQL 14.4. Komunikacja z bazą danych Sybase 14.5. Komunikacja z bazą danych Microsoft SQL Server 14.6. Komunikacja z bazą danych SQLite 14.7. Komunikacja z bazami danych za pośrednictwem ODBC 14.8. Wykorzystanie warstwy abstrakcji do komunikacji z bazami danych (PDO) 14.9. Implementacja blogu z wykorzystaniem bazy danych SQLite 286 287 289 290 292 293 294 296 15 Inne metody przechowywania danych .................................... 301 15.1. Tworzenie i odczyt plików CSV 302 15.2. Zapisywanie danych w plikach tekstowych 15.3. Dostęp do baz danych DBM i ich aktualizacja 303 305 15.4. Zapisywanie danych za pośrednictwem operacji serializacji i deserializacji 307 15.5. Automatyczne tworzenie i aktualizacja włączanych plików PHP 308 16 Poczta elektroniczna ................................................................ 311 16.1. Wysyłanie wiadomości e-mail (tekst, HTML, format podwójny, wstawiane ilustracje, załączniki) 16.2. Sprawdzanie, czy istnieje konto pocztowe 16.3. Utworzenie automatu do masowego wysyłania wiadomości e-mail 312 321 323 Spis treści 7 16.4. Implementacja prostego programu obsługi list mailingowych 16.5. Ochrona adresów e-mail przed automatami pobierającymi je w celu przesyłania spamu 16.6. Utworzenie procesu Watchdog wysyłającego wiadomość e-mail w przypadku modyfikacji strony 327 329 330 17 XML .......................................................................................... 333 335 17.1. Przetwarzanie dokumentu XML w celu odczytania danych 17.2. Wyszukiwanie danych w dokumencie XML z wykorzystaniem języka XPath 17.3. Weryfikacja dokumentów XML 17.4. Przekształcanie dokumentów XML na XHTML z wykorzystaniem XSLT 17.5. Tworzenie dokumentów RSS 17.6. Tworzenie skryptu do wyświetlania kanałów RSS w witrynach WWW 336 338 341 343 344 18 Grafika ...................................................................................... 347 350 18.1. Generowanie obrazów połączonych z tekstem 18.2. Wskazówki i sztuczki dotyczące rysowania 18.3. Wykorzystanie przezroczystego tła w ilustracjach 18.4. Utworzenie biblioteki obsługi wykresów 18.5. Automatyczne tworzenie galerii fotografii z plików z aparatu cyfrowego (dane Exif) 354 356 357 364 19 Zgłaszanie błędów i debugowanie ........................................... 367 19.1. Definicja niestandardowej procedury obsługi błędów 369 19.2. Wykorzystanie wyjątków do obsługi błędów 19.3. Pomiar czasu wykonania skryptu 19.4. Wykorzystanie funkcji zamykających w celu obsługi awarii skryptów 19.5. Generowanie szczegółowego śladu w celu zgłaszania błędów 371 374 376 378 20 Uwierzytelnianie użytkowników i szyfrowanie ....................... 381 382 20.1. Generowanie losowych haseł 20.2. Wykorzystanie szyfrowania do ochrony danych 20.3. Zastosowanie technik CAPTCHA do wykrywania rzeczywistych użytkowników 20.4. Uwierzytelnianie użytkowników 383 385 388 III Dodatki ................................................................... 391 A Migracja do PHP 5 ................................................................... 393 394 Model obiektowy Moduł obsługi bazy danych MySQL CLI i CGI Uwzględnianie wielkości liter w nazwach klas, metod i funkcji Funkcje zwracające wartości przez referencję 394 395 395 396 B SPL ............................................................................................ 397 Podstawowy interfejs 397 Tworzenie własnych iteratorów Rozszerzanie iteratorów i iteratory połączone 400 402 8 PHP 5 w praktyce Zagadnienia bardziej złożone Iteratory rekurencyjne Definiowanie klasy umożliwiającej rekurencyjną iterację 404 404 405 C Częste komunikaty o błędach .................................................. 407 Poziomy błędów 407 Wynik działania skryptu: pusta strona 408 Skorowidz ................................................................................. 415 PLIKACJE, KTÓRE WYKONUJĄ operacje związane z czasem, są szczególnie często używane w in- ternecie. Godziny przesłania formularza, dane wprowadzane przez użytkowników, na przykład data urodzenia, a także aktualizacja i usuwanie stron w przypadku, gdy są prze- starzałe — to zaledwie kilka przykładów. Chociaż obliczenia dotyczące dat w PHP mogą wydawać się skomplikowane, w rzeczywistości są dość proste. W tym rozdziale głównie opisano podstawowe funkcje przetwarzania dat i godzin. Funkcje te zapewniają wykonywanie wszystkich podstawowych operacji na datach i go- dzinach, takie jak pobieranie, formatowanie i konwersja dat. W PHP jest dostępne także inne rozszerzenie — Calendar, które służy do konwersji między różnymi systemami ka- lendarzy, na przykład między kalendarzem gregoriańskim i żydowskim. Są to na przykład funkcje cal_to_jd() i cal_from_jd() opisane w punkcie „Szybkie wskazówki”. Zagadnienie planowania zadań — na przykład tworzenie harmonogramu spotkań i zda- rzeń — wykracza poza zakres tego rozdziału. Własności te są dostępne dzięki rozszerzeniu MCAL. Więcej informacji na ten temat można znaleźć pod adresem http://php.net/mcal. Aby w pełni wykorzystać możliwości przetwarzania dat i godzin w PHP, trzeba wiedzieć, w jaki sposób w środowisku PHP mierzy się czas. Interpreter PHP odlicza czas w postaci liczby sekund, jakie upłynęły od północy 1 stycznia 1970 roku — tzw. epoki Unix. W związ- ku z tym każdy moment w czasie jest zapamiętywany w postaci prostej liczby typu integer. Czas zapisany w ten sposób to tzw. znacznik czasu (ang. time stamp). Jak się przekona- my, wiele funkcji albo zwraca znacznik czasu albo wykorzystuje go jako argument. Należy jednak zachować ostrożność w przypadku czytania dokumentacji lub komentarzy w ko- dzie. W zależności od kontekstu, termin znacznik czasu może być używany także w sensie bardziej ogólnym: jako czas, kiedy coś się wydarzyło. Gdy mowa na przykład o plikach dzienników serwera WWW, terminem znacznik czasu określa się czas, w którym zareje- strowano zdarzenie. Szybkie wskazówki Odczytanie znacznika czasu dla bieżącej godziny: $timestamp = time(); Funkcja nie pobiera parametrów. Zwraca bieżący czas, tzn. czas, w którym wy- wołano funkcję time(). Pełna dokumentacja: http://php.net/time. 64 Rozdział 3. Godziny i daty Odczytanie bieżącego znacznika czasu z dokładnością do mikrosekund: $result = microtime($format); Funkcja zwraca uniksowy znacznik czasu z dokładnością do mikrosekund. Jeśli argument $format ma wartość false (domyślnie), funkcja zwraca czas w postaci ciągu znaków sekundy mikrosekundy , gdzie sekundy mają tę samą wartość, co zwrócona przez funkcję time(), a mikrosekundy oznaczają ułamek sekund. Jeśli argument $format ma wartość true, funkcja zwraca czas w postaci liczby zmiennoprzecinkowej. Pełna dokumentacja: http://php.net/microtime. Utworzenie znacznika czasu dla określonej daty i godziny: $timestamp = mktime($godzina, $minuta, $sekunda, $miesiac, $dzien, $rok); Zwraca znacznik czasu odpowiadający określonej dacie i godzinie. Pełna dokumentacja: http://php.net/mktime. Formatowanie określonego czasu: $string = date($format, $timestamp); Zwraca znakową reprezentację podanego znacznika czasu z wykorzystaniem zdefi- niowanego formatu. Jeśli nie określi się argumentu $timestamp, funkcja wyko- rzystuje bieżący czas. Pełna dokumentacja: http://php.net/date. Sformatowanie daty i godziny. Dostosowanie wyników do formatu Greenwich Mean Time (GMT): $string = gmdate ($format, $timestamp); Funkcja równoważna do date(). Jednak czas jest przedstawiany jako reprezen- tacja GMT podanej godziny. Pełna dokumentacja: http://php.net/gmdate. Odczytanie różnych informacji na temat podanego czasu: $time_array = getdate($timestamp); Zwraca tablicę różnych wartości dotyczących podanego znacznika czasu. Indek- sami tablicy są seconds, minutes, hours, mday, wday, mon, year, yday, weekday i month. Pełna dokumentacja: http://php.net/getdate. Odczytywanie i ustawianie strefy czasowej używanej w funkcjach czasowych: $string = date_default_timezone_get(); date_default_timezone_set($string); 3.1. Obliczanie różnicy czasu między dwiema datami 65 Powyższa para funkcji służy do odczytywania (ustawiania) identyfikatora strefy czasowej. Pełna dokumentacja: http://php.net/date_default_timezone_set i http://php.net/date_default_timezone_get. Zamiana czasu z postaci tekstowej w języku angielskim na znacznik czasu: $timestamp = strtotime($english_time); Funkcja pobiera tekstowy opis daty i godziny w języku angielskim i zwraca od- powiadający jej znacznik czasu. Pełna dokumentacja: http://php.net/strtotime. Sprawdzenie poprawności daty według kalendarza gregoriańskiego: $isvalid = checkdate($month, $day, $year); Zwraca true, jeśli określoną datę można znaleźć w kalendarzu gregoriańskim. Przydaje się do sprawdzania, czy czas wprowadzany przez użytkownika bądź czas wyliczony są poprawne. Pełna dokumentacja: http://php.net/checkdate. Godzina wschodu i zachodu słońca we wskazanej lokalizacji: $time_rise = date_sunrise($day_ts, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude); $time_set = date_sunset($day_ts, SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude); Powyższa para funkcji zwraca godziny wschodu i zachodu słońca dla wskazanej lokalizacji. Użycie stałej SUNFUNCS_RET_TIMESTAMP powoduje, że funkcja zwra- ca godzinę w postaci znacznika czasu. Pełna dokumentacja: http://php.net/date.sunrise i http://php.net/date.sunset. Konwersja daty między różnymi kalendarzami a kalendarzem juliańskim: $jday count = cal_to_jd($calendar, $rnonth, $day, $year); $date_array = cal_from_jd($jday_count, $calendar); Powyższa para funkcji umożliwia konwersję daty wyrażonej w określonym systemie kalendarza na kalendarz juliański — i odwrotnie. Funkcje obsługują następujące ty- py kalendarzy: CAL_GREGORIAN, CAL_JULIAN, CAL_JEWISH oraz CAL_FRENCH. Pełna dokumentacja: http://php.net/cal_to_jd i http://php.net/cal_from_jd. 66 Rozdział 3. Godziny i daty W programach bardzo często trzeba znaleźć liczbę tygodni, dni, a nawet sekund dzielą- cych dwie daty. W niektórych systemach baz danych są dostępne procedury umożliwiają- ce porównywanie dat i wykonywanie działań arytmetycznych na datach. Jednak w PHP takie operacje trzeba wykonywać samodzielnie. Jak powiedziano we wprowadzeniu, w PHP daty są reprezentowane w formacie epoki UNIX. Oznacza to, że są zapisywane w postaci liczby sekund, jaka upłynęła od północy 1 stycznia 1970 roku. Dzięki temu można z łatwością obliczyć liczbę sekund, jaka upły- nęła między dwoma punktami w czasie. Wystarczy odjąć od siebie dwa znaczniki czasu. Wykonanie popularniejszego działania — obliczenie liczby dni — wymaga jednak dodat- kowych czynności. Podczas działań arytmetycznych na datach trzeba pamiętać o latach przestępnych, miesiącach o różnej liczbie dni, miesiącach obejmujących pięć tygodni, latach z 53. tygo- dniem, zmianie czasu z letniego na zimowy i innych tego rodzaju zagadnieniach. W prze- ciwnym razie algorytm będzie obsługiwał jedynie większość przypadków — nie wszystkie. Rozpocznijmy od omówienia częstego problemu wyznaczenia liczby dni dzielących dwie daty. Zwróćmy uwagę, że w kodzie z listingu 3.1.1 do utworzenia znaczników czasu wykorzystano funkcję strtotime(). Funkcja umożliwia pobranie wielu różnych postaci tekstowej reprezentacji daty i przekształcenie jej na znacznik czasu. Uwaga Począwszy od wydania PHP w wersji 5.1, przed wywołaniem jakiejkolwiek funk- cji operacji na datach trzeba wywołać funkcję date_default_timezone_set(), która służy do określenia strefy czasowej, dla jakiej mają być wykonane obli- czenia. W innym przypadku generowany jest błąd trybu STRICT, ponieważ in- terpreter próbuje odgadnąć strefę czasową. Więcej informacji na temat stref czasowych można znaleźć w podrozdziale 3.4, „Obsługa stref czasowych” w dal- szej części tego rozdziału. Jeśli tworzony kod ma działać zarówno w środowisku PHP 5.0, jak i PHP 5.1, powstaje problem, ponieważ w PHP 5.0 funkcja date_ default_Timezone_set() jest niedostępna. Z tego względu można użyć funkcji function_exists() i za jej pomocą sprawdzić, czy funkcja date_default_ Timezone_set() istnieje. Jeśli tak, można ją wywołać. Alternatywnie można ustawić domyślną strefę czasową w pliku konfiguracyjnym na serwerze PHP 5.1. W takiej sytuacji nie trzeba się martwić ustawieniami strefy czasowej. Listing 3.1.1. Liczba dni między dwoma datami ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Funkcja zwraca liczbę dni między dwoma przekazanymi datami. function count_days($a, $b) { // Najpierw należy przekształcić daty na części składowe: $a_dt = getdate($a); $b_dt = getdate($b); 3.1. Obliczanie różnicy czasu między dwiema datami 67 // Odtworzenie znaczników czasu z wykorzystaniem południa każdego dnia. // Dokładny czas nie ma znaczenia, ale musi to być ta sama godzina w każdym dniu. $a_new = mktime(12, 0, 0, $a_dt[ mon ], $a_dt[ mday ], $a_dt[ year ]); $b_new = mktime(12, 0, 0, $b_dt[ mon ], $b_dt[ mday ], $b_dt[ year ]); // Odjęcie dwóch liczb i podzielenie przez liczbę sekund przypadającą na dzień. // Zaokrąglenie wyniku, ponieważ przekroczenie granicy zmiany czasu z letniego na zimowy (lub odwrotnie) // spowoduje różnicę w czasie o godzinę lub dwie. return round(abs($a_new - $b_new) / 86400); } // Przygotowanie kilku dat $date1 = strtotime( 12/3/1973 8:13am ); $date2 = strtotime( 1/15/1974 10:15pm ); $date3 = strtotime( 2/14/2005 1:32pm ); // Obliczenie różnic. Powinniśmy uzyskać wyniki 43 i 11353 echo p Upłynęło , count_days($date1, $date2), dni. /p ; echo p Upłynęło , count_days($date2, $date3), dni. /p ; ? Problem z pozoru wydaje się prosty: odjęcie dwóch liczb i podzielenie przez liczbę sekund przypadającą na dzień. To prawda i w ten sposób uzyskamy prawidłowe wyniki, jeśli in- teresuje nas ściśle matematyczna definicja dnia. Weźmy jednak za przykład dwie daty: 11 listopada, godz. 23.00 i 12 listopada, godz. 1.00. Zgodnie z ogólnie przyjętą interpretacją dat, różni je jeden dzień. Jednak jeśli odejmiemy od siebie znaczniki czasowe odpowia- dające obu datom, okaże się, że wymienione daty dzielą tylko dwie godziny. Rozwiązanie polega na sprowadzeniu dat do wspólnej godziny — na przykład połu- dnia. Teraz można odjąć od siebie znaczniki czasu. Aby kolejność dat nie miała znaczenia, można posłużyć się wartością bezwzględną. Aby otrzymać liczbę dni, uzyskany wynik należy podzielić przez liczbę sekund przypadającą na dzień (86 400). Byłoby to niemal doskonałe rozwiązanie, gdyby nie to, że nie uwzględnia zmiany czasu z letniego na zi- mowy bądź odwrotnie. Jeśli między datami, dla których wykonujemy obliczenia, nastą- piła zmiana czasu, dokładny wynik może się różnić o jedną lub dwie godziny. Aby po- zbyć się błędu spowodowanego zmianą czasu, wystarczy zaokrąglić wynik do najbliższej liczby całkowitej. Podobną strategię można również wykorzystać do obliczenia liczby tygodni, miesięcy i lat dzielących dwie daty. Spotyka się jednak dwa różne punkty widzenia na te większe jednostki czasu. Na przykład mówimy czasami, że coś miało miejsce tydzień temu, mając na myśli siedem dni. W takim przypadku, by obliczyć liczbę tygodni między dwiema da- tami, wystarczy skorzystać z utworzonej przed chwilą funkcji count_days() i podzielić uzyskany wynik przez 7. Innym razem pod tym samym pojęciem rozumie się zdarzenie, które miało miejsce w ubiegłym tygodniu. W takiej sytuacji należy skorzystać z podobnego mechanizmu, jak w przypadku obliczania różnicy w liczbie dni, kiedy sprowadziliśmy oba dni do tej samej godziny. Można sprowadzić daty do niedzieli danego tygodnia i wtedy wykonać obliczenia. Przykład podobnej operacji zamieszczono w podrozdziale 3.6 „Wy- znaczanie liczby dni roboczych”, w dalszej części tego rozdziału. 68 Rozdział 3. Godziny i daty Czasami trzeba sprawdzić, jaki jest ostatni dzień określonego miesiąca. Do sprawdzenia dnia można wykorzystać tabelę przeglądową (choć w dalszym ciągu trzeba uwzględnić la- ta przestępne dla lutego), ale często potrzebny jest znacznik czasu szukanego dnia. Na szczęście dzięki funkcji mktime() uzyskanie znacznika czasu nie jest trudne. Funkcja po- biera argumenty określające kolejno godzinę, minutę, sekundę, miesiąc, dzień i rok. Zale- tą funkcji mktime() jest automatyczna prawidłowa obsługa argumentów ujemnych lub zerowych. Tak więc, jeśli wprowadzimy argument dla miesiąca równy 3 (marzec), a dla dnia równy 1, uzyskamy prawidłowy znacznik czasu dla 1 marca. W przypadku wprowadze- nia parametru dnia równego 0 otrzymamy znacznik czasu poprzedniego dnia, czyli ostat- ni dzień lutego. Na listingu 3.2.1 pokazano, jak można wykorzystać funkcję mktime() do obliczenia znaczników czasu ostatniego dnia miesiąca. Listing 3.2.1. Wyznaczanie znacznika czasu ostatniego dnia miesiąca ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Funkcja zwraca znacznik czasu ostatniego dnia miesiąca podanego roku function last_day($month, $year) { // Wykorzystanie funkcji mktime do utworzenia znacznika czasu dla następnego miesiąca, ale o jeden dzien // wcześniej. // Ustawienie godziny na bliską północy, tak by // uzyskany znacznik można było wykorzystać jako granicę miesiąca. return mktime(23, 59, 59, $month + 1, 0, $year); } // Wyznaczenie znacznika czasu dla ostatniego dnia lutego 2006 roku. $stamp = last_day(2, 2006); // Wyświetlenie wyników: 28 echo p Ostatni dzień lutego 2006 roku przypada na: , date( d , $stamp) , /p ; ? Często wykonywanym zadaniem, dla którego w PHP nie ma wbudowanej funkcji, jest sprawdzenie, czy określony rok jest przestępny. Choć można to wyliczyć z prostego wzo- ru, wiele osób zapomina o niektórych jego elementach. Rok jest przestępny tylko wtedy, jeśli dzieli się przez 4, ale nie dzieli się przez 100, chyba że dzieli się przez 400. Funkcję sprawdzającą, czy określony rok jest przestępny, zaimplementowano na listingu 3.3.1. 3.4. Obsługa stref czasowych 69 Listing 3.3.1. Sprawdzanie, czy rok jest przestępny ?php // Funkcja sprawdza, czy określony rok jest przestępny, czy nie: function is_leap_year($y) { // Jeśli rok dzieli się przez 4, ale nie dzieli się przez 100 lub dzieli się przez 400: return ((($y 4) == 0) ((($y 100) != 0) || (($y 400) == 0))); } // Sprawdzenie, czy lata z podanego zakresu są przestępne: foreach (range(1999, 2009) as $year) { // Wyświetlenie wyników: echo p {$year} = , is_leap_year($year) ? Rok przestępny : rok zwykły , /p ; } ? Obsługa stref czasowych może sprawiać wiele problemów. Na szczęście w PHP dostępne są mechanizmy, które ją ułatwiają. Wiele z nich wykorzystuje własność środowiska PHP w wersji 5.1 polegającą na wykorzystaniu funkcji date_default_timezone_get() w celu określenia strefy czasowej, dla której są wykonywane obliczenia. W tym punkcie omówimy kilka innych metod. Każda z nich doskonale nadaje się do wykonywania różnych zadań. We wszystkich tych przykładach założymy, że bieżąca strefa czasowa to Europe/Warsaw (GMT+1:00), a strefa czasowa, dla której wykonujemy obliczenia, to Asia/Tokyo (GMT+9:00). Aby dowiedzieć się, jaki jest odpowiednik określonego czasu w innej strefie czasowej, można skorzystać z kombinacji funkcji ustawiającej domyślną strefę czasową i funkcji mktime(), która umożliwia wygenerowanie czasu w innej strefie czasowej i wyświetlenie go w strefie domyślnej (listing 3.4.1). Listing 3.4.1. Obliczanie czasu w różnych strefach czasowych ?php // Sprawdzenie, która godzina jest w Warszawie w czasie, gdy w Tokio jest 8 rano. // Ustawienie domyślnej strefy czasowej na czas tokijski. date_default_timezone_set( Asia/Tokyo ); // Wygenerowanie znacznika czasu w tej strefie czasowej dla 1 stycznia 2000 roku. $stamp = mktime(8, 0, 0, 1, 1, 2000); // Ustawienie domyślnej strefy czasowej z powrotem na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Wyświetlenie daty w formacie standardowym (RFC1123). Funkcja wyświetli następujący ciąg: // Fri, 31 Dec 1999 18:00:00 EST echo p , date(DATE_RFC1123, $stamp) , /p ; ? 70 Rozdział 3. Godziny i daty Także funkcja strtotime() ułatwia wykonywanie konwersji między strefami czasowymi. W ciągach znaków opisujących czas można wprowadzić modyfikatory stref czasowych. Funkcja strtotime() analizuje skróty stref czasowych, na przykład EST (ang. Eastern Standard Time). Nie zaleca się jednak ich stosowania, ponieważ mogą wystąpić trudności z ich interpretacją w różnych językach. Akceptuje również przesunięcie strefy względem czasu UTC, na przykład +0100 dla strefy Europe/Warsaw oraz +0900 dla strefy Asya/ Tokyo. Przykład użycia tych mechanizmów do wykonywania operacji na strefach czaso- wych pokazano na listingu 3.4.2. Listing 3.4.2. Wyznaczanie czasu w różnych strefach czasowych z wykorzystaniem funkcji strtotime() ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Wygenerowanie znacznika czasu dla 1 stycznia 2000 o 8 rano w Tokio. // Użycie notacji ze skrótem JST (Japan Standard Time) $stamp1 = strtotime( 1/1/2000 8am JST ); // Użycie modyfikatora określającego relację względem GMT: +9 godzin w stosunku do czasu UTC. $stamp2 = strtotime( Jan 1 2000 08:00 +0900 ); // Wyświetlenie daty w formacie standardowym (RFC1123). Funkcja wyświetli następujący ciąg: // Fri, 31 Dec 1999 18:00:00 EST echo p , date(DATE_RFC1123, $stamp1) , /p ; echo p , date(DATE_RFC1123, $stamp2) , /p ; ? Wykonywanie konwersji w ten sposób może okazać się kłopotliwe. Często się zdarza, że ktoś przechowuje dane w postaci lokalnego czasu i chce wyświetlić go w innych strefach czasowych. Aby to zrobić, wystarczy skorzystać z tabeli konwersji zawierającej właściwe przeliczniki. Takie tabele nie uwzględniają jednak wielu nietypowych sytuacji, takich jak zmiana czasu z letniego na zimowy, która w różnych miejscach występuje w różnym cza- sie. Na listingu 3.4.3 do zmiany stref czasowych wykorzystano tabelę przeglądową. Listing 3.4.3. Wyznaczanie czasu w różnych strefach czasowych z wykorzystaniem tabeli przeglądowej ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Utworzenie tabeli przeglądowej względem strefy Europe/Warsaw. $locals = array( Seattle = -7, Londyn = 1, Tokyo = 10); // Wygenerowanie daty i godziny we wskazanych lokalizacjach na podstawie czasu lokalnego. $now = time(); foreach ($locals as $place = $offset) { // Wyświetlenie daty i godziny po konwersji. echo p Czas w miejscowości {$place} to: , date( m/d/Y H:i , $now + 3600 * $offset) , /p ; } ? 3.5. Obsługa znaczników czasu w bazach danych lub plikach 71 Znaczniki czasu często zapisuje się w plikach. Ich format jest poza naszą kontrolą, jednak trzeba je odczytać w środowisku PHP i zinterpretować jako daty. Daty można przetwa- rzać za pomocą wyrażeń regularnych, jednak w wielu przypadkach format czasu powi- nien być zgodny z funkcją strtotime(). TakZdarza się tak bardzo często, ponieważ funkcja strtotime() obsługuje wiele formatów czasu. Na listingu 3.5.1 zamieszczono przykład je użycia do przetwarzania daty odczytanej z pliku dziennika serwera Apache: 127.0.0.1 - - [02/Nov/2005:22:04:41 -0500] GET / HTTP/1.1 200 41228 Listing 3.5.1. Przetwarzanie wierszy z pliku dziennika serwera Apache za pomocą funkcji strtotime() ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Symulacja odczytu wiersza z pliku dziennika serwera Apache. $logline = 127.0.0.1 - - [02/Nov/2005:22:04:41 -0500] GET / HTTP/1.1 200 41228 ; // Odczytanie fragmentu dotyczącego daty za pomocą wyrażenia regularnego. $matches = array(); preg_match( /[(.*?)]/ , $logline, $matches); // Pobranie daty i jej konwersja. $timestamp = strtotime($matches[1]); // Ponowne wyświetlenie daty w celu potwierdzenia jej prawidłowego odczytania: echo date(DATE_RFC1123, $timestamp); ? Podobnym problemem, z jakim często spotykają się programiści, jest zapisywanie dat w ba- zach danych i odczytywanie ich z baz danych. Każda baza danych charakteryzuje się własną preferowaną metodą prezentacji dat. Na szczęście większość formatów dat można przetworzyć za pomocą funkcji strtotime() (w bazach danych występują również specyficzne komendy pozwalające na zwracanie dat w formatach wskazanych przez użytkowników). Format dat różni się w zależności od baz danych. W związku z tym szczegółowych informacji dotyczących formatu baz danych należy szukać w dokumentacji określonej bazy danych. Prawdziwy problem występuje podczas zapisywania dat ze środowiska PHP do bazy danych. W każdej bazie danych obowiązuje specyficzny format dat. Należy jednak zwró- cić uwagę, że niemal we wszystkich typach baz danych domyślny format daty można zmienić na serwerze. Z tego względu bezpieczniej korzystać z własnych funkcji konwersji ciągów znaków na daty. W ten sposób zyskuje się pewność, że za każdym razem zapisze- my do bazy danych prawidłową wartość daty. Poniżej wyszczególniono kilka przykładów instrukcji date() w PHP, które formatują ciągi znaków na domyślny format dat w róż- nych typach baz danych: 72 Rozdział 3. Godziny i daty t Oracle — date( d-M-Y H:i , $timestamp); t t MySQL — date( Y-m-d H:i , $timestamp); Sybase and SQL Server — date( m/d/Y H:i , $timestamp). Choć w podrozdziale 3.1 „Obliczanie różnicy czasu między dwiema datami” zaprezento- wano sposób obliczania liczby dni między dwiema datami, skrypt ten na niewiele się zda w świecie biznesu, w którym ważne są dni robocze — w większości miejsc na świecie są to dni od poniedziałku do piątku. Dni robocze czasami uwzględniają święta, a jeśli ich nie uwzględniają, szczegółowe zasady są różne dla różnych firm. Z tego względu skoncen- trujemy się na podstawowej definicji. Jednym ze sposobów obliczania liczby dni roboczych między dwiema datami jest przetwarzanie w pętli wszystkich dni między datami i sprawdzanie, czy określony dzień nie należy do weekendu. Metoda ta jest jednak nieefektywna. Istnieją lepsze rozwiązania, na przykład to, które zaimplementowano w listingu 3.6.1. Wiemy, że tydzień roboczy ma pięć dni. W celu obliczenia liczby dni roboczych wystarczy obliczyć liczbę pełnych tygodni między dwiema datami i pomnożyć przez 5. Następnie należy dodać liczbę dni w pierw- szym i ostatnim tygodniu. Listing 3.6.1. Obliczanie liczby dni między dwiema datami ?php // Ustawienie domyślnej strefy czasowej na Europe/Warsaw. date_default_timezone_set( Europe/Warsaw ); // Funkcja zwracająca liczbę dni roboczych między dwiema datami. function count_business_days($a, $b) { // Sortowanie dat. Trzeba się dowiedzieć, która z dat przypada wcześniej. if ($a $b) { $first = $a; $second = $b; } else { $first = $b; $second = $a; } // Rozłożenie znaczników czasu na składowe. $f = getdate($first); $s = getdate($second); // Obliczenie liczby pozostałych dni roboczych w początkowym tygodniu. // W tym celu należy odjąć numer dnia w tygodniu od pięciu. $f_days = 5 - $f[ wday ]; // W przypadku soboty lub niedzieli uzyskamy wynik -1 lub 5, ale wtedy przyjmujemy do obliczeń wartość 0. if (($f_days == 5) || ($f_days 0)) { $f_days = 0; } // Wykonanie podobnej operacji dla końcowego tygodnia, z tą różnicą, że liczymy od // początku tygodnia. Trzeba się tylko upewnić, że sobota liczy się jako 5. $s_days = ($s[ wday ] 5) ? 5 : $s[ wday ]; // Obliczenia znacznika czasu dla południa w niedzielę początkowego tygodnia. 3.6. Wyznaczanie liczby dni roboczych 73 $f_sunday = mktime(12, 0, 0, $f[ mon ], $f[ mday ] + ((7 - $f[ wday ]) 7), $f[ year ]); // Obliczenia znacznika czasu dla południa w niedzielę poprzedzającą datę końcową. $s_sunday = mktime(12, 0, 0, $s[ mon ], $s[ mday ] - $s[ wday ], $s[ year ]); // Obliczenie liczby pełnych tygodni między dwiema datami poprzez odjęcie od siebie // znaczników czasu i podzielenie przez liczbę sekund w tygodniu. Uzyskany wynik należy // zaokrąglić po to, by zawsze uzyskać liczbę całkowitą. W innym przypadku z powodu zmiany czasu // z letniego // na zimowy (lub odwrotnie) uzyskany wynik może być niedokładny. $weeks = round(($s_sunday - $f_sunday) / (3600*24*7)); // Zwrócenie liczby dni poprzez pomnożenie liczby tygodni przez 5 i dodanie // dni roboczych z początkowego i końcowego tygodnia. return ($weeks * 5) + $f_days + $s_days; } // Kilka przykładów: $date1 = strtotime( 12/3/1973 8:13am ); $date2 = strtotime( 1/15/1974 10:15pm ); $date3 = strtotime( 2/14/2005 1:32pm ); // Obliczenie liczby dni roboczych. Prawidłowe wyniki to: 31 8109. echo p Daty dzieli , count_business_days($date1, $date2), dni roboczych. /p ; echo p Daty dzieli , count_business_days($date2, $date3), dni roboczych. /p ; ? Jak widać z powyższego listingu, najpierw wyznaczono liczbę dni między niedzielami przypadającymi po dacie początkowej i przed datą końcową. Na tej podstawie obliczono liczbę pełnych tygodni między dwiema datami. Aby to zrobić, wystarczy podzielić liczbę sekund, jakie dzielą obie niedziele, przez liczbę sekund w tygodniu. Wynik należy zaokrą- glić do najbliższej liczby całkowitej. Zaokrąglenie jest potrzebne, jeśli między datą po- czątkową a końcową wystąpiła zmiana czasu z zimowego na letni lub odwrotnie. Jeśłi nie przeprowadzono by operacji zaokrąglania, wystąpiłby błąd godziny lub dwóch. Na koniec należy dodać dni robocze z pierwszego i ostatniego tygodnia i otrzymujemy wynik. Wzór jest poprawny nawet wtedy, gdy oba dni należą do tego samego tygodnia. Co prawda, najpierw są liczone dni pozostałe do końca tygodnia i dni od początku tygo- dnia, co powoduje liczenie niektórych dni kilka razy. W związku z tym wynik zawsze jest większy o 5 dni. Jednak z obliczeń liczby pełnych tygodni uzyskuje się -1. W związku z tym odejmujemy nadmiarowe 5 dni, uzyskując poprawny wynik. Do zaimplementowanego algorytmu można wprowadzić modyfikację polegającą na uwzględnieniu dni świątecznych. Należałoby za pomocą odpowiedniego algorytmu obli- czyć liczbę dni świątecznych między podanymi datami, a następnie odjąć ją od końcowego wyniku. 74 Rozdział 3. Godziny i daty Daty są cześcią naszego życia, a z nimi nierozerwalnie wiążą się kalendarze. Ludzie cenią sobie możliwość patrzenia na kalendarz, który umożliwia wizualną ocenę relacji między określonymi datami. Z tego powodu kalendarz jest dostępny w wielu aplikacjach interneto- wych. Funkcja zamieszczona na listingu 3.7.1 pobiera parametry w postaci miesiąca i roku i wyświetla kalendarz w formacie prostej tabeli HTML. Zamieszczony algorytm można łatwo zmodyfikować w celu uwzględnienia specyficz- nych wymagań. W obecnej postaci wprowadzono jedną dyrektywę konfiguracyjną umożli- wiającą wskazanie numeru dnia, od którego rozpocząć tabelę. Jej domyślna wartość wynosi 0 (niedziela). Listing 3.7.1. Generowanie kalendarza w formacie HTML ?php // Funkcja wyświetla kalendarz w formacie HTML dla wskazanego miesiąca i roku. function print_calendar($month, $year, $weekdaytostart = 0) { // O miesiącu, dla którego generujemy kalendarz, potrzebne są pewne informacje, na przykład znacznik // czasu ostatniego dnia. $last = idate( d , last_day($month, $year)); // Potrzebna jest również informacja o tym, w jaki dzień tygodnia przypada pierwszy dzień miesiąca. // Nazwę miesiąca uzyskamy automatycznie. $firstdaystamp = mktime(0, 0, 0, $month, 1, $year); $firstwday = idate( w , $firstdaystamp); $name = date( F , $firstdaystamp); // Aby ułatwić realizację funkcji rozpoczęcie od dowolnego dnia tygodnia , potrzebna jest // tablica numerów dni tygodnia w używanym porządku drukowania. $weekorder = array(); for ($wo = $weekdaytostart; $wo $weekdaytostart + 7; $wo++) { $weekorder[] = $wo 7; } // Początek tabeli HTML. echo table tr th colspan= 7 {$name} {$year} /th /tr ; // Wyświetlenie wiersza z nazwami dni. // Wykorzystanie systemu do uzyskania nazw dni tygodnia. echo tr ; // Przetwarzanie w pętli pełnego tygodnia począwszy od dnia numer 1. foreach ($weekorder as $w) { $dayname = date( D , mktime(0, 0, 0, $month, 1 - $firstwday + $w, $year)); echo th {$dayname} /th ; } echo /tr ; // Zainicjowanie liczników i wykonanie obliczeń. $onday = 0; $started = false; // Pętla do ostatniego dnia miesiąca. 3.7. Generowanie kalendarza dla określonego miesiąca 75 while ($onday = $last) { // Rozpoczęcie następnego wiersza w tabeli. echo tr ; // Pętla od 0 do 6 dla dni tygodnia, ale w wybranym porządku; // do tego celu wykorzystano operator mod. foreach ($weekorder as $d) { // Jeśli jeszcze nie rozpoczęto: if (!($started)) { // Czy dzień bieżący odpowiada pierwszemu dniu tygodnia, od którego należy rozpocząć? if ($d == $firstwday) { // Ustawienie zmiennej wskazującej na fakt rozpoczęcia generowania kalendarza // i inkrementacja licznika. $started = true; $onday++; } } // Wyświetlenie pustej komórki, jeśli numer dnia wynosi zero lub // jest większy od numeru ostatniego dnia. if (($onday == 0) || ($onday $last)) { echo td nbsp; /td ; } else { // W innym przypadku wyświetlenie numeru dnia i inkrementacja licznika. echo td {$onday} /td ; $onday++; } } // Zakończenie wiersza tabeli. echo /tr ; } // Zakonczenie tabeli. echo /table ; } // Wygenerowanie dyrektyw formatujących. echo style table, td, th { border: 1px solid black; } /style ; // Wygenerowanie kilku przykładowych tabel. // Listopad 2005 z niedzielą jako pierwszym dniem. print_calendar(11, 2005); echo br / ; // Utworzenie całorocznego kalendarza dla roku 2006 z poniedziałkiem jako pierwszym dniem. foreach(range(1, 12) as $m) { print_calendar($m, 2006, 1); echo br / ; } ? Skrypt rozpoczyna się od pobrania potrzebnych informacji. Do wyznaczenia ostatniego dnia miesiąca wykorzystano funkcję last_day() utworzoną na listingu 3.2.1. Potrzebne są również informacje na temat dnia tygodnia pierwszego dnia miesiąca. Ponieważ funkcja ma przetwarzać w pętli dni tygodnia, potrzebny jest łatwy sposób wykonywania takiej operacji. Gdyby funkcja zawsze przetwarzała dni od niedzieli do so- 76 Rozdział 3. Godziny i daty boty (0 do 6), nie byłoby problemu. Ponieważ jednak kalendarz można rozpocząć od do- wolnego dnia tygodnia, funkcja musi określić porządek przetwarzania pętli. Na przykład, jeśli kalendarz ma się zacząć od środy, dni tygodnia powinny być przetwarzane w nastę- pującej kolejności: 3, 4, 5, 6, 0, 1, 2. Aby to było możliwe, funkcja tworzy w pętli tablicę zawierającą te liczby, począwszy od wskazanego dnia początkowego. Pętla wykonuje się 7 razy. W każdej iteracji wykonywana jest operacja licznika pętli modulo 7. Do odczytania nazw miesięcy i dni tygodnia wykorzystano wbudowane funkcje. Dzięki temu funkcja zawsze drukuje kalendarz we właściwej wersji językowej. Pozostała jeszcze pętla przetwarzająca tygodnie i wyświetlająca kolejne dni. Trzeba zadbać o to, by pierwszy dzień wyświetlić na właściwej pozycji. Wcześniej wy- świetlamy puste komórki. Odpowiednią liczbę pustych komórek trzeba także wyświetlić w ostatnim wierszu.
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

PHP 5 w praktyce
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


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