Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00070 006110 13848762 na godz. na dobę w sumie
PHP 5. Narzędzia dla ekspertów - książka
PHP 5. Narzędzia dla ekspertów - książka
Autor: Liczba stron: 424
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-2860-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> php - programowanie
Porównaj ceny (książka, ebook, audiobook).

Osiągnij wyższy poziom zaawansowania w PHP!

Język PHP to ulubione środowisko wielu programistów tworzących aplikacje i strony internetowe. Jego wykorzystanie pozwala na błyskawiczne osiągnięcie efektów, a nauka nie przysparza trudności. Trudno wskazać moment, w którym PHP zdobył tak ogromną popularność. Chwilami można odnieść wrażenie, jakby w sieci był obecny od zawsze. Piąta wersja tego języka zawiera wszystko to, co powinien posiadać nowoczesny język programowania - możliwość programowania obiektowego, wsparcie dla formatu XML oraz rozbudowane mechanizmy wejścia-wyjścia. PHP 5 może z powodzeniem konkurować z 'dużymi' rozwiązaniami, dostępnymi od lat na rynku aplikacji internetowych.

Niniejsza książka to pozycja przeznaczona dla programistów, którzy znają już podstawy tego języka. To unikalny podręcznik, dzięki któremu nauczysz się tworzyć efektywny, profesjonalny i łatwy w utrzymaniu kod. W trakcie lektury zdobędziesz wiedzę na temat systemów kontroli wersji, testów jednostkowych, szkieletów aplikacji oraz narzędzi wspomagających proces debugowania. Ponadto dowiesz się, w jaki sposób tworzyć dokumentację z wykorzystaniem phpDocumentor, jak wybrać najlepszy szkielet aplikacji oraz wdrożyć aplikację w środowisku produkcyjnym. Dzięki tej książce osiągniesz wyższy poziom zaawansowania w programowaniu w języku PHP!

Ta książka pomoże Ci stać się lepszym programistą!

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

Darmowy fragment publikacji:

PHP 5. Narzędzia dla ekspertów Autor: Dirk Merkel Tłumaczenie: Jarosław Dobrzański ISBN: 978-83-246-2860-5 Tytuł oryginału: Expert PHP 5 Tools Format: 170×230, stron: 450 Osiągnij wyższy poziom zaawansowania w PHP! • Jak tworzyć efektywny, łatwy w utrzymaniu kod PHP? • Jak automatycznie tworzyć dokumentację techniczną? • Jak debugować aplikację z Xdebug? Język PHP to ulubione środowisko wielu programistów tworzących aplikacje i strony internetowe. Jego wykorzystanie pozwala na błyskawiczne osiągnięcie efektów, a nauka nie przysparza trudności. Trudno wskazać moment, w którym PHP zdobył tak ogromną popularność. Chwilami można odnieść wrażenie, jakby w sieci był obecny od zawsze. Piąta wersja tego języka zawiera wszystko to, co powinien posiadać nowoczesny język programowania – możliwość programowania obiektowego, wsparcie dla formatu XML oraz rozbudowane mechanizmy wejścia-wyjścia. PHP 5 może z powodzeniem konkurować z „dużymi” rozwiązaniami, dostępnymi od lat na rynku aplikacji internetowych. Niniejsza książka to pozycja przeznaczona dla programistów, którzy znają już podstawy tego języka. To unikalny podręcznik, dzięki któremu nauczysz się tworzyć efektywny, profesjonalny i łatwy w utrzymaniu kod. W trakcie lektury zdobędziesz wiedzę na temat systemów kontroli wersji, testów jednostkowych, szkieletów aplikacji oraz narzędzi wspomagających proces debugowania. Ponadto dowiesz się, w jaki sposób tworzyć dokumentację z wykorzystaniem phpDocumentor, jak wybrać najlepszy szkielet aplikacji oraz wdrożyć aplikację w środowisku produkcyjnym. Dzięki tej książce osiągniesz wyższy poziom zaawansowania w programowaniu w języku PHP! • Standardy pisania kodu PHP • Opracowywanie własnych standardów • Przygotowanie profesjonalnego środowiska programistycznego • Dokumentowanie kodu za pomocą phpDocumentor • Zarządzanie kodem źródłowym i jego wersjami • Debugowanie aplikacji • Szkielety aplikacji PHP • Testy jednostkowe – tworzenie niezawodnego kodu • Wdrażanie aplikacji • Projektowanie aplikacji z wykorzystaniem UML • Proces ciągłej integracji Ta książka pomoże Ci stać się lepszym programistą! Idź do • Spis treści • Przykładowy rozdział Katalog książek • Katalog online • Zamów drukowany katalog Twój koszyk • Dodaj do koszyka Cennik i informacje • Zamów informacje o nowościach • Zamów cennik Czytelnia • Fragmenty książek online Kontakt Helion SA ul. Kościuszki 1c 44-100 Gliwice tel. 32 230 98 63 e-mail: helion@helion.pl © Helion 1991–2010 Spis treści O autorze O recenzentach Przedmowa O czym jest ta książka? Co jest potrzebne, aby skorzystać z książki? Dla kogo jest ta książka? Konwencje Uwagi Czytelników Przykładowy kod Rozdział 1. Standardy i styl pisania kodu Co uwzględnić przy tworzeniu standardów? Zalety Wady Standard pisania kodu PHP Formatowanie Konwencje nazewnicze Metodologia Weryfikacja zgodności ze standardami pisania kodu Automatyczna kontrola zgodności za pomocą narzędzia PHP_CodeSniffer Podsumowanie Rozdział 2. Dokumentowanie za pomocą narzędzia phpDocumentor Dokumentacja w treści kodu Poziomy szczegółowości Wprowadzenie do programu phpDocumentor Instalacja programu phpDocumentor Bloki DocBlock Szablony DocBlock 9 11 13 13 14 14 15 15 16 17 17 18 19 19 20 25 29 35 35 46 49 50 51 52 52 54 55 Spis treści Samouczki Dokumentowanie projektu Opcje programu phpDocumentor Katalog tagów Tagi stosowane w PHP4 Tagi użytkownika Podsumowanie Rozdział 3. Eclipse — zintegrowane środowisko programistyczne Dlaczego Eclipse? Wprowadzenie do PDT Instalacja Eclipse Wymagania Wybór pakietu Dodawanie pluginu PDT Podstawowe pojęcia związane z Eclipse Przestrzeń robocza (Workspace) Widoki (Views) Perspektywy Przykładowy projekt PDT Możliwości funkcjonalne pluginu PDT Edytor Inspekcja Debugowanie Preferencje PDT Inne możliwości funkcjonalne Pluginy Eclipse Zend Studio dla Eclipse Wsparcie Refaktoring Generowanie kodu Testowanie za pomocą PHPUnit Obsługa programu phpDocumentor Integracja ze szkieletem Zend Framework Integracja z serwerem Zend Podsumowanie Rozdział 4. Zarządzanie kodem źródłowym i wersjami Typowe przypadki użycia Krótka historia kontroli kodu źródłowego CVS Wprowadzenie do Subversion Instalacja klienta Konfiguracja serwera Pojęcia związane z Subversion Lista poleceń Subversion Tworzenie projektu Subversion 4 56 59 74 78 94 94 95 97 98 100 100 100 102 102 104 104 105 107 108 111 111 115 117 120 127 128 129 131 131 131 131 132 133 133 133 135 135 136 139 141 141 142 143 147 157 Spis treści Sposób pracy z systemem kontroli wersji Bliższe spojrzenie na repozytorium Odgałęzienia i scalanie Aplikacje klienckie Konwencje i najlepsze praktyki przy pracy z Subversion Przystosowywanie Subversion do własnych potrzeb Powiadamianie programistów o zatwierdzonych plikach za pomocą skryptu post-commit Podsumowanie Rozdział 5. Debugowanie Pierwsza linia obrony — kontrola składni Dzienniki Opcje konfiguracyjne Dostosowywanie opcji konfiguracyjnych i panowanie nad nimi — PhpIni Wyświetlanie informacji diagnostycznych Funkcje „Magiczne” stałe Tworzenie własnej klasy diagnostycznej Wprowadzenie do Xdebug Instalacja Xdebug Konfiguracja Xdebug Natychmiastowe korzyści Zdalne debugowanie Podsumowanie Rozdział 6. Szkielety aplikacji PHP Pisanie własnego szkieletu Ocena i wybór szkieletów Społeczność i akceptacja Możliwości funkcjonalne Dokumentacja Jakość kodu Stosowanie i zgodność ze standardami pisania kodu Dopasowanie do projektu Łatwość w nauce i adaptacji Dostępność kodu źródłowego Znajomość szkieletu Ich zasady Popularne szkielety aplikacji PHP Zend CakePHP CodeIgniter Symfony Yii 164 169 171 177 183 184 187 187 189 189 191 192 194 201 201 205 205 221 221 224 225 228 235 237 237 238 239 239 240 240 241 241 242 242 243 243 243 244 244 245 245 246 5 Spis treści Aplikacja w szkielecie Zend Framework Lista cech i funkcji Kręgosłup aplikacji Usprawnienia Podsumowanie Rozdział 7. Testowanie Metody testowania Czarna skrzynka Biała skrzynka Szara skrzynka Typy testowania Testowanie jednostkowe Testowanie integracyjne Testowanie regresyjne Testowanie systemowe Testy akceptacji użytkowników Wprowadzenie do PHPUnit Instalacja PHPUnit Przeszukiwanie ciągu tekstowego (przykładowy projekt) Analiza pokrycia kodu Podklasy klasy TestCase Podsumowanie Rozdział 8. Wdrażanie aplikacji Cele i wymagania Wdrażanie aplikacji Wymeldowywanie plików i wysyłanie ich na serwer Wyświetlanie informacji o niedostępności serwisu Aktualizacja i instalacja plików Aktualizacja schematu i zawartości bazy danych Rotacja plików dziennika i aktualizacja dowiązań symbolicznych Weryfikacja wdrożonej aplikacji Automatyzacja procesu wdrożenia Phing Podstawowa składnia i struktura pliku Typy Wdrażanie serwisu Podsumowanie Rozdział 9. Projektowanie aplikacji za pomocą języka UML Metamodel i notacja a nasze podejście do UML Poziom szczegółowości i przeznaczenie Narzędzia jedno- i dwukierunkowe Podstawowe typy diagramów UML Diagramy 6 247 247 248 253 272 273 273 274 274 275 276 276 277 277 278 278 279 279 281 306 307 308 309 309 311 312 313 313 314 314 315 315 315 317 321 322 339 341 342 343 344 345 346 Spis treści Diagramy klas Diagramy sekwencji Przypadki użycia Podsumowanie Rozdział 10. Ciągła integracja Systemy satelitarne Kontrola wersji — Subversion Testowanie — PHPUnit Automatyzacja — Phing Styl pisania kodu — PHP_CodeSniffer Dokumentowanie — PhpDocumentor Analiza pokrycia kodu — Xdebug Przygotowanie środowiska Czy potrzebuję dedykowanego serwera CI? Czy potrzebuję narzędzia CI? Narzędzia CI XINC phpUnderControl Ciągła integracja z phpUnderControl Instalacja Konfiguracja CruiseControl Przegląd procesu i komponentów ciągłej integracji Podsumowanie Skorowidz 347 359 364 368 369 371 371 372 373 374 375 375 376 376 376 377 377 377 378 378 382 382 404 405 7 8 Wdrażanie aplikacji Po zakończeniu pisania aplikacji i zadbaniu o to, by inwestorzy zatwierdzili jej odbiór, przychodzi czas na jej wdrożenie. W zasadzie w tym momencie powinniśmy już mieć za sobą kilkukrotne jej wdrożenie i cały proces powinien być w mniejszym lub większym stopniu zautomatyzowany. Większość projektów, w które byłem ostatnio zaangażowany, skorzystało na tym, że aplikacja była wielokrotnie wdrażana w różnych środowiskach, takich jak programistyczne, testowe i docelo- we. Automatyzacja tego procesu umożliwia szybkie uruchamianie kolejnych egzemplarzy aplikacji. Jest to nie tylko dobry sposób na wyeliminowanie wszelkich potencjalnych problemów przy wdrożeniu, ale także duży krok w kierunku poprawienia produktywności nowych programi- stów. Jeżeli proces wdrożenia został zoptymalizowany i dobrze udokumentowany, nowi członko- wie zespołu programistycznego nie będą musieli poświęcać wiele czasu na utworzenie wła- snego środowiska programistycznego. Zamiast tego mogą wykonać kilka prostych kroków, aby uzyskać aplikację działającą i gotową do dalszego rozwoju. Cele i wymagania Zastanówmy się, jakie powinny być nasze cele podczas wdrażania lub aktualizowania aplika- cji. Innymi słowy, co jest miarą sukcesu w tym procesie? Może nam przyjść do głowy twier- dzenie, że to, jak dobrze działa aplikacja, jest konsekwencją tego, jak dobrze przeprowadzone zostało wdrożenie. To jednak byłoby mylące. Na tym etapie nie interesuje nas już projekt funkcjonalny, programowanie ani testowanie. Działamy przy założeniu, że dysponujemy w pełni funkcjonującą aplikacją, która musi zostać wdrożona. To, czy aplikacja będzie działać zgodnie z oczekiwaniami, może, ale nie musi być naszym problemem i nie ma nic wspólnego z samym jej wdrażaniem. PHP 5. Narzędzia dla ekspertów Powstaje więc pytanie, na jakiej podstawie ustalić, czy wdrożenie przebiegło pomyślnie? Do czego powinniśmy dążyć, tworząc plan wdrożenia? Jak można się spodziewać, mam kilka przemyśleń na ten temat. Po pierwsze, wdrożenie powinno odbyć się szybko. Wszyscy ci, którzy wdrażają aplikacje ręcznie, będą zaskoczeni, ile z tego, co robią, można zautomatyzować przy odpowiednim pla- nowaniu. Kiedy wdrażamy aplikację po raz pierwszy, zwykle nie musimy się spieszyć i mo- żemy upewnić się, że wszystko działa, jak trzeba, zanim powiadomimy klienta o tym, iż stała się dostępna. Oczywiście szybkie wdrożenie staje się o wiele ważniejsze, kiedy aktualizujemy aplikację, będącą już w stałym użyciu. W takiej sytuacji naszym celem powinno być zmini- malizowanie lub najlepiej uniknięcie wszelkich niedogodności lub przerw w dostawie usług świadczonych przez aplikację. Właśnie wówczas szybkość staje się istotna. Drugim celem wdrożenia jest jego pełna odwracalność. Najlepiej zacząć traktować aktualizacje aplikacji jako transakcję znaną z systemów bazodanowych. Jeżeli coś się nie powiedzie w trakcie wdrożenia, powinniśmy być w stanie cofnąć wszystkie wykonane dotychczas kroki i przywrócić aplikację dokładnie do stanu sprzed rozpoczęcia wdrożenia. O ile wydaje się to sensowne i logicz- ne, czasami niełatwo osiągnąć to w praktyce. Weźmy na przykład sytuację, kiedy musimy zmodyfikować istniejącą tabelę bazy danych. Może to wymagać uruchomienia kilku zapytań, aby zmienić strukturę tabeli i pomanipulować danymi. Jeżeli popełnimy błąd lub pojawi się jakiś nieprzewidziany problem, to jak cofniemy zmiany? Jeżeli mamy plan, będziemy mogli przywrócić bazę z kopii zapasowej, którą zrobiliśmy przed rozpoczęciem wdrażania. Jednak w zależności od rozmiaru bazy ładowanie wszystkich da- nych do wszystkich tabel może potrwać dobre kilka minut. Możemy więc przywrócić z kopii zapasowej tylko naruszoną tabelę, ale do tego potrzebujemy specjalnego narzędzia. Jeżeli zrobiliśmy kopię zapasową w formie monolitycznego pliku zrzutu, znalezienie jednej tabeli i przywrócenie jej może być trudne. Inną opcją jest uruchamianie specjalnie przygotowanych zapytań cofających zmiany, które doprowadziły do problemu. W tym przypadku zapytania te trzeba będzie przygotować wcześniej i nie będziemy mieć na to czasu w sytuacji kryzysowej przy dużych naciskach na szybkie rozwiązanie problemu. Jak widać, jest wiele sposobów na to, by uczynić aktualizacje odwracalnymi. Konieczne jest dokładne planowanie, aby proces był odwracalny na każdym etapie. Podsumujmy nasze wymagania dotyczące wdrożenia lub aktualizacji: 1. Szybkość i automatyzacja w celu minimalizacji niedogodności dla użytkowników i błędów ludzkich. 2. Pełna odwracalność wszystkich czynności. Powtórzyłem to w punktach, ponieważ dalsze rozważania poświęcone planom wdrożenia, po- szczególnym czynnościom i pisaniu kodu, który pozwoli to zrealizować, będą osnute wokół konsekwencji tych wymogów. To na ich podstawie będziemy oceniać, na ile udało się osiągnąć cel. 310 Rozdział 8. • Wdrażanie aplikacji Wdrażanie aplikacji W poprzednim punkcie wspominaliśmy o możliwości odwracania poszczególnych kroków w trak- cie wdrażania, ale co właściwie kryje się pod pojęciem kroku? Przyjrzyjmy się kilku czynnościom, które są typowe podczas wdrażania lub aktualizowania aplikacji. W dalszej części rozdziału przejdziemy do implementacji tych zadań i próby ich maksymalnego zautomatyzowania. Poniższy diagram ilustruje kroki w procesie wdrażania aplikacji lub serwisu internetowego. Oczywiście w zależności od aplikacji możemy jakieś kroki dodać, a jakieś zignorować, ale kroki tu pokazane stanowią dobrą podstawę w przypadku większości wdrożeń. 311 PHP 5. Narzędzia dla ekspertów Zanim omówię szczegółowo każdy z powyższych kroków, zastanówmy się nad ogólnym prze- biegiem procesu ukazanego na diagramie. Zaczynamy od wymeldowania całego projektu z systemu kontroli wersji. W celu dostosowania się do środowiska, w którym aplikacja będzie wdrażana, niektóre pliki, a w szczególności pliki konfiguracyjne będą musiały zostać zmodyfi- kowane. Następnie w istniejącym serwisie internetowym publikujemy komunikat informujący użytkowników o trwających pracach konserwacyjnych. Po zainstalowaniu plików, dokonaniu od- powiednich zmian w bazie danych i rotacji plików dziennika usuwamy komunikat o przerwie w funkcjonowaniu serwisu, restartujemy serwer i ponownie udostępniamy stronę użytkownikom. Na koniec dokonujemy inspekcji serwisu, aby sprawdzić, czy aplikacja działa poprawnie. Wymeldowywanie plików i wysyłanie ich na serwer Zakładając, że nasz projekt rezyduje w jakimś systemie kontroli wersji, będziemy musieli naj- pierw „wydobyć” go stamtąd w takiej postaci, która będzie nadawać się do wdrożenia na do- celowy serwer. Jeżeli jako systemu kontroli wersji używamy narzędzia Subversion, omówio- nego w innym rozdziale tej książki, musimy wykonać polecenie export, aby uzyskać kopię pozbawioną wszystkich metadanych, jakie Subversion przechowuje zwykle w plikach ukry- tych w każdym z katalogów projektu. W innych systemach kontroli wersji może obowiązywać inna terminologia i inne polecenia, ale idea pozostaje taka sama. Konieczne jest utworzenie kopii projektu pozbawionej metadanych i wszelkich innych plików, które nie są przeznaczone do wdrożenia na serwer. Czasem jednak będzie nam zależeć na takim wdrożeniu, w ramach którego wdrożony kod źródłowy pozostaje powiązany z repozytorium. Posługując się terminologią Subversion, możemy wymeldować kod do lokalnej lub zdalnej kopii roboczej. Korzyści z takiego podejścia są dwoja- kie. Po pierwsze możemy używać informacji z repozytorium do przyspieszenia przyszłych procesów aktualizacji. Możemy na przykład zaktualizować wymeldowaną wersję do bieżącej wersji z repozytorium jednym poleceniem. Po drugie, jeżeli nasz proces wdrożeniowy obsłu- guje wymeldowania z repozytorium, można dzięki niemu szybko tworzyć środowiska progra- mowania i w ten sposób poprawiać produktywność nowych członków zespołu. Z tego względu proces, który opracujemy w tym rozdziale, będzie umożliwiał zarówno wdrożenie docelowe, jak i programistyczne. Prawdopodobnie będziemy musieli również zmienić jeden z kilku plików konfiguracyjnych, wprowadzając takie ustawienia, które odpowiadają środowisku docelowemu aplikacji. Bywa, że trzeba ustawić w ten sposób katalog główny projektu, parametry uwierzytelniające dla bazy danych, bazowy adres URL itp. Warto w tym momencie powrócić na chwilę do rozdziału poświęconego szkieletom aplikacji, ponieważ stworzona tam przykładowa aplikacja została specjalnie zaprojektowana tak, by działać w różnych środowiskach z użyciem stosownych sekcji w pliku konfiguracyjnym. Takie rozwiązanie przewiduje istnienie zautomatyzowanego procesu wdrożeniowego, obsługują- cego różne środowiska. 312 Rozdział 8. • Wdrażanie aplikacji Dysponując wdrażaną wersją projektu, możemy przesłać go na serwer. Zwykle następuje to za pośrednictwem protokołów FTP, SFTP lub SCP (SSH). Zalecam korzystanie z któregoś z bezpiecznych wariantów, aby nie eksponować danych uwierzytelniających. Jeżeli pracujemy na instalacji rezydującej na serwerze docelowym, możemy połączyć dwa kroki, czyli eksportowanie i wysyłanie plików na serwer, wykorzystując fakt, że wszystkie nowo- czesne systemy kontroli wersji obsługują operacje zdalne. Wystarczy wymeldować projekt z repozytorium wprost na docelowy komputer. Wyświetlanie informacji o niedostępności serwisu Zanim naciśniemy metaforyczny guzik „wyłączający” serwis, powinniśmy powiadomić użyt- kowników, że prowadzimy prace konserwacyjne na serwerze. Ja sam zwykle kieruję użytkowni- ków do standardowej strony HTML informującej o trwających pracach i sugerującej ponowną próbę połączenia za kilka minut. Jeżeli dobrze zaplanujemy i zautomatyzujemy aktualizacje, przerwa w dostępności usługi dla użytkowników powinna być minimalna lub wręcz żadna. W tym momencie może paść pyta- nie, po co wobec tego w ogóle wstawiamy informację o niedostępności serwisu. Otóż infor- macja ta nagle może stać się bardzo istotna w sytuacji, gdy coś przeszkodzi nam w płynnej realizacji dobrze zaplanowanego wdrożenia. W takiej chwili będziemy desperacko próbować ustalić źródło problemu i jak najszybciej go wyeliminować. Dużą ulgą będzie wówczas to, że nie musimy przejmować się informowaniem użytkowników i zamiast tego możemy skupić się na tym, co naprawdę wymaga naszej uwagi, czyli na rozwiązywaniu problemu. Po zakończeniu aktualizacji strona informująca o przerwie musi zostać usunięta. To również należy zautomatyzować, ponieważ jest to coś, o czym naprawdę nie chcielibyśmy zapomnieć. Aktualizacja i instalacja plików Kiedy pliki są już na serwerze, musimy udostępnić je dla użytkowników. Zastępowanie ist- niejących plików nowymi nie jest zgodne z naszą zasadą odwracalności. Można by zmienić nazwy plików i przenieść je do katalogu ze starymi plikami, po czym zastąpić oryginały no- wymi wersjami, ale istnieje szybsza metoda. W systemach, które dopuszczają stosowanie dowiązań symbolicznych (zwanych też aliasami lub skrótami), dobra praktyka polega na utworzeniu dowiązania symbolicznego wskazującego katalog zawierający pliki aplikacji. Gdy przychodzi czas aktualizacji, wystarczy przekierować dowiązanie na inny katalog, a nowe pliki staną się z miejsca dostępne. 313 PHP 5. Narzędzia dla ekspertów Aktualizacja schematu i zawartości bazy danych Większość współczesnych aplikacji korzysta z jakiejś formy bazy danych, wśród których prym wiedzie MySQL z uwagi na swoją popularność. Podczas pierwszego wdrożenia aplikacji zwykle jesteśmy także odpowiedzialni za prawidłowe utworzenie i udostępnienie bazy danych. W przy- padku aktualizacji istniejącej instalacji musimy znaleźć jakiś sposób modyfikacji schematu i zawartości bazy. Najczęściej polega to na utrzymywaniu pliku tekstowego, do którego pro- gramiści dodają zapytania wprowadzające w bazie zmiany wymagane przez zaktualizowany kod. W trakcie wdrażania administrator bazy lub programista jest wówczas odpowiedzialny za wykonanie tych zapytań w tym czasie, gdy wykonywane są wszystkie inne zadania związane z wdrożeniem. Mimo że takie podejście może się sprawdzać w przypadku aktualizacji lub tworzenia baz, nie spełnia ono postawionych wcześniej wymogów. Otóż nie umożliwia łatwej odwracalności, chyba że z góry to zaplanujemy. Poza tym wdrażając kolejne aktualizacje, napotykamy kolejne zmiany w bazie danych i wówczas przywrócenie poprzednich stanów staje się coraz bardziej skomplikowane. Jedno z rozwiązań może stanowić narzędzie umożliwiające definiowanie, zarządzanie i wyko- nywanie krokowych zmian w bazie danych. Owe krokowe zmiany zwane są migracjami, a na- rzędzie, za którego pomocą będziemy zarządzać migracjami, to DbDeploy. Ponieważ każde- mu krokowi aktualizującemu bazę odpowiada krok wstecz, powracający do poprzedniej wersji, możliwe jest przeskakiwanie od stanu do stanu bazy w dowolnym kierunku. Co wię- cej, zmiany można aplikować w sposób zautomatyzowany, co zaspakaja obydwa nasze wymogi dotyczące udanego wdrożenia. W szczegóły programu DbDeploy zagłębimy się w dalszej części rozdziału, przy okazji defi- niowania migracji bazy danych na potrzeby naszego przykładu. Rotacja plików dziennika i aktualizacja dowiązań symbolicznych W zależności od tego, gdzie i w jaki sposób nasza aplikacja przechowuje informacje, koniecz- na albo przynajmniej zalecana może być rotacja plików dziennika. Przede wszystkim trzeba się upewnić, czy serwer może zapisywać do plików dziennika, co nie jest pewne w przypad- ku, gdy pliki dziennika znajdują się w podkatalogu naszej aplikacji i uaktywniliśmy je na ser- werze docelowym, edytując dowiązanie symboliczne. Bywa, że do świeżo wdrożonej aplikacji trzeba skopiować inne biblioteki lub aplikacje wspoma- gające. Ja na przykład utrzymuję interfejs WWW do czytania poczty, który jest dostępny z po- ziomu katalogu głównego dokumentów serwera mojej strony WWW. Nie jest on jednak czę- ścią projektu w repozytorium Subversion i trzeba go skopiować lub przekierować dowiązanie symboliczne po każdym wdrożeniu nowej wersji strony. 314 Rozdział 8. • Wdrażanie aplikacji Weryfikacja wdrożonej aplikacji Krok ten może się wydawać oczywisty, ale jednocześnie jest to coś, o czym nie wypada zapo- mnieć. Powinniśmy sprawdzić, czy wszystko, co zostało wdrożone, działa tak, jak oczekujemy. W tym jednym kroku musimy dopuścić pewne odstępstwo od założonych wymogów. Co prawda możemy i chcemy pewne testy zautomatyzować, np. testowanie nagłówków odpo- wiedzi HTTP, ale niektóre rzeczy po prostu trzeba sprawdzić ręcznie. Czasami najprostszym sposobem na sprawdzenie, czy wszystko działa, jest otwarcie przeglądarki i skorzystanie z aplikacji tak, jak będą korzystać z niej użytkownicy. Dzięki temu z miejsca możemy wykryć wiele poważnych problemów. Automatyzacja procesu wdrożenia Skoro wiemy już, co chcemy osiągnąć, przejdźmy do omawiania narzędzi, za których pomocą dokonamy implementacji i automatyzacji naszego planu wdrożenia. Jest kilka pomniejszych narzędzi, które pomogą nam wykonać to zadanie, ale głównym narzędziem pozwalającym wszystko zautomatyzować i wykonującym większość zadań jest Phing. Phing Phing to system konsolidacji projektów. Nazwa to rekurencyjny akronim, którego pełne brzmienie w języku angielskim to Phing Is ot Gnu Make (Phing to nie GNU Make). Phing umożliwia wykonywanie różnych zadań związanych z konsolidacją oprogramowania. Szcze- gólnie dobry jest w automatyzacji zadań, która, jak można wnioskować po dotychczasowej lekturze tego rozdziału, jest dla nas bardzo ważna. Co prawda twórcy narzędzia Phing aktywnie zaprzeczają wszelkim związkom pomiędzy tym programem a narzędziem make, ale można bezpiecznie stwierdzić, że make leży w jakiejś części u podstaw Phing. Phing został jednak bardziej oparty na narzędziu Ant, które jest naj- częściej stosowanym systemem konsolidacyjnym w języku Java. W naszym przypadku przewaga Phing nad narzędziem Ant polega na tym, że obsługuje on różne zadania specyficzne dla programowania w PHP. Poza tym Phing jest napisany w PHP, co ułatwia programistom tego języka rozszerzanie funkcjonalności systemu. Phing jest sterowany tzw. celami (targets) zdefiniowanymi w pliku XML. Cele są w gruncie rzeczy działaniami wykonywanymi przez Phing. Plik XML definiujący owe cele i zależności między nimi zwykle ma nazwę build.xml. Cele składają się z kolei z jednego lub kilku zadań. Więcej o celach i zadaniach będzie w dalszej części rozdziału. 315 PHP 5. Narzędzia dla ekspertów Takie rozwiązanie ułatwia odrębne wykonywanie któregoś ze zdefiniowanych celów z auto- matyczną obsługą zależności. Przykładowe cele zdefiniowane przez użytkownika to: (cid:81) create-skeleton — tworzy katalogi potrzebne na serwerze. (cid:81) checkout-site — wymeldowuje projekt z systemu Subversion. (cid:81) update-db — wykonuje wstępnie zdefiniowane zapytania w celu aktualizacji struktury i zawartości bazy danych. Powyższych przykładowych celów użyjemy też między innymi w naszym projekcie. Instalacja narzędzia Phing Narzędzie Phing można zainstalować na kilka sposobów. Najprostszy i najbardziej bezbolesny sposób polega na wykorzystaniu instalatora Pear. Z repozytoriów i narzędzia Pear korzystali- śmy już wiele razy w tej książce. Przyczyna jest prosta — to działa i stało się ogólnie przyjęte do tego stopnia, że większość narzędzi, które tutaj omawiam, można w ten sposób pobrać i zainstalować. Zamiast od razu uruchamiać narzędzie pear, chciałbym zwrócić uwagę, jak świetny przykład stanowi ono w niniejszym rozdziale. Chwila zastanowienia i okazuje się, że wpisując pear in- stall phing/phing, robimy dokładnie to, czemu poświęcony jest ten rozdział — wdrażamy (instalujemy) aplikację, a konkretnie Phing. Innymi słowy, zależnie od typu aplikacji rozprowadza- nie jej za pośrednictwem kanału Pear może stanowić jeszcze jedno podejście do wdrażania. Teraz możemy przejść do praktyki i zainstalować Phing za pomocą Pear. Oto przebieg i re- zultat instalacji Phing z wiersza poleceń: Tak naprawdę są tu tylko dwa polecenia. Pierwsze, pear channel-discover pear.phing.info, informuje instalator Pear, że pod adresem pear.phing.info znajduje się repozytorium Pear. Drugie polecenie, pear install phing/phing, instaluje pakiet o nazwie phing (drugie wystą- pienie „phing”) poprzez kanał o nazwie phing (pierwsze wystąpienie „phing”). 316 Rozdział 8. • Wdrażanie aplikacji Inną metodą instalacji Phing jest bezpośrednie wymeldowanie go z repozytorium CVS pro- jektu. Zaletą jest to, że otrzymujemy w ten sposób najświeższą i najlepszą bazę kodu, w tym nieopublikowane jeszcze poprawki i ulepszenia. Z tej właśnie metody musimy skorzystać, jeżeli chcemy włożyć własną pracę w rozwój projektu, ponieważ będziemy wówczas mogli zatwierdzać zmiany z powrotem do repozytorium. Oczywiście zakładając, że otrzymamy uprawnienia do dokonywania zmian. Podstawowa składnia i struktura pliku Plik konsolidacyjny zawiera kod XML definiujący wszystkie działania i cele dostępne dla użyt- kownika. Zgodnie z konwencją plik ten otrzymuje nazwę build.xml. Jeżeli jednak korzystamy z opcji –buildfile [nazwa_pliku] w wierszu poleceń, możemy zmienić tę nazwę na dowolną inną. W naszym przykładzie pozostaniemy przy przyjętej konwencji nazewniczej. Przyjrzyjmy się ogólnej strukturze pliku konsolidacyjnego Phing. Poniższy szkielet takiego pliku nie definiuje żadnych działań. Jego celem jest jedynie zilustrowanie podstawowej struktu- ry takich plików. Wraz z postępem pracy nad naszym przykładem będziemy uzupełniać ko- lejne części tego pliku, zmierzając do opracowania w pełni zautomatyzowanego procesu wdrożeniowego. l?xml version= 1.0 ? project name= nazwaProjektu description= Opcjonalny opis pliku (cid:180)konsolidacyjnego. default= nazwaCeluDomyślnego property name= jakaśWłaściwośćGlobalna value= wartość override= true / type !-- globalna definicja typu -- /type target name= nazwaCeluDomyślnego depends= celPomoniczy description= Opis (cid:180)domyślnego zadania. property name= właściwośćLokalna value= wartość override= true / type !-- lokalna definicja typu -- /type task !-- definicja zadania -- /task !-- następne zadania (opcjonalnie) -- /target target name= celPomocniczy description= Opis celu pomocnicznego. task !-- definicja zadania -- /task 317 PHP 5. Narzędzia dla ekspertów !-- następne zadania (opcjonalnie) -- /target /project Jako programista zapewne znasz dobrze format XML, dlatego omówię szkielet pliku konsoli- dacyjnego bardzo krótko. Wydaje mi się też, że najlepiej zacząć omawianie hierarchii znacz- ników od wewnątrz. Zadania Sercem pliku konsolidacyjnego są zadania ujmowane w znacznikach task . Znaczniki te od- powiadają wprost działaniom. To tutaj wykonywana jest cała rzeczywista praca. Znaczniki task można traktować jako najdrobniejszą jednostkę wykonywanych działań. Dokumentacja Phing definiuje te podstawowe zadania jako te, które są niezbędne, by skonsolidować projekt. Dla odróżnienia zadania opcjonalne to te, które nie są niezbędne dla skonsolidowania pro- jektu. Moim zdaniem rozróżnienie to jest nieco sztuczne, szczególnie w związku z faktem, że PHP to język interpretowany, co oznacza, że proces konsolidacji nie zawiera w sobie fazy kompilacji. Oto przykładowe zadania: (cid:81) CopyTask — kopiuje pliki lub grupy plików albo katalogów z jednego miejsca w systemie plików w inne, z możliwością zmiany nazwy. (cid:81) ForeachTask — przechodzi przez listę i umożliwia ujęcie jednego lub kilku zadań w pętli i wykonanie każdego z nich dla każdego elementu z listy. (cid:81) InputTask — prosi użytkownika o wprowadzenie danych, z których można skorzystać przy wykonywaniu następnych zadań. A oto przykłady zadań opcjonalnych: (cid:81) SvnExportTask — eksportuje projekt z repozytorium Subversion do lokalnego katalogu. (cid:81) ZipTask/UnzipTask — dwa uzupełniające się zadania tworzące archiwum ZIP z grupy plików lub rozpakowujące pliki z istniejącego archiwum. (cid:81) PHPUnit2Task — uruchamia przypadki testowania lub zestawy testów za pośrednictwem systemu testującego PHPUnit2. Zadania przypominają nieco funkcje w tym sensie, że mogą przyjmować argumenty. Gdy tylko zaczniemy tworzyć nasz przykładowy skrypt konsolidacyjny do wdrażania aplikacji, zobaczy- my praktyczne przykłady zadań. Zamiast podawać listę wszystkich dostępnych zadań wraz z możliwymi opcjami, odsyłam Czytel- ników do bardzo dobrze napisanej dokumentacji online, zawierającej najświeższą i najlepszą listę zadań wraz z opisami, dostępnej pod adresem http://phing.info/docs/guide/. 318 Rozdział 8. • Wdrażanie aplikacji Wreszcie, jeżeli zestaw zadań udostępniany przez Phing nie zaspakaja naszych wymagań, mo- żemy bez problemu dodawać własne zadania. Jako narzędzie open source Phing jest z założe- nia rozszerzalny. Fakt, iż został napisany w PHP, potencjalnie ułatwi większości Czytelników tej książki dopisywanie kodu własnych zadań. Tak naprawdę dodanie własnego zadania w formie klasy przyjmującej argumenty i wykonującej pożądane operacje jest zaskakująco proste. Cele Cele (targets) to logicznie powiązane grupy zadań. Zadania grupowane są w formie celów, aby osiągnąć określony rezultat. Możemy na przykład mieć cel o nazwie backup-db, który grupuje zadanie tworzące kopię zapasową bazy danych, zadanie kompresujące otrzymany plik zrzutu bazy oraz zadanie przesyłające kopię poprzez FTP do miejsca, w którym zwykle przechowu- jemy kopie zapasowe. Zadania zawarte pomiędzy otwierającym i zamykającym znacznikiem target są wykonywa- ne w kolejności występowania. Cele mają trzy atrybuty — są to name (nazwa), description (opis) oraz depends (powiązania). Dzięki atrybutowi name możliwe jest wykonanie danego celu z wiersza poleceń. Oto przykładowe wywołanie celu upgrade-db w domyślnym pliku konsoli- dacyjnym build.xml: $ phing upgrade-db Nazwa celu jest opcjonalna w powyższym wywołaniu i jeżeli nie zostanie podana, wykonywany jest domyślny cel zdefiniowany w znaczniku project , który omówiony zostanie za chwilę. Atrybut description znacznika target zawiera krótkie podsumowanie działań wykonywanych w ramach celu. Wreszcie atrybut depends pozwala wskazać inne cele, które muszą zostać wykonane przed da- nym celem. Phing śledzi, które z celów zostały już wykonane, i automatycznie wywołuje cele, które są konieczne, aby spełnić ten wymóg. W przedstawionym wcześniej przykładowym szkielecie pliku build.xml cel o nazwie domyślnaNazwaCelu jest uzależniony od celu celPomocniczy. Jeżeli wywołamy cel domyślnaNazwaCelu, Phing zadba o to, by celPomocniczy został wykonany wcześniej. W atrybucie depends można podać więcej niż jeden cel zależny, oddzielając je przecinkami. Podobnie jak zadania, cele są wykonywane w kolejności występowania. Właściwości i plik właściwości W terminologii narzędzia Phing właściwości to odpowiedniki zmiennych. Można definiować je w globalnej przestrzeni nazw lub w lokalnej dla określonego celu. Globalne definicje wła- ściwości muszą następować poza obrębem znaczników target , a definicje lokalne w obrę- bie znacznika target , którego mają dotyczyć. 319 PHP 5. Narzędzia dla ekspertów Nieco dalej pojawi się kilka globalnych definicji właściwości i typów. Właściwości to w gruncie rzeczy zmienne, z których większość nie zmienia wartości w trakcie wykonywania skryptu. Są jednak również właściwości tworzone dynamicznie i używane przez skrypt konsolidacyjny do zachowania stanu w obrębie celu lub pomiędzy wykonaniem poszczególnych celów. Właściwości są definiowane i używane w pliku build.xml w następujący sposób: property name= svn.url value= https://${svn.server}/home/svn/${svn.project} (cid:180)override= true / W tym przykładzie definiujemy właściwość o nazwie svn.url. Wartość przypisywana tej wła- ściwości to adres URL, który z kolei jest konstruowany z kilku ciągów tekstowych i dwóch zdefiniowanych wcześniej właściwości: svn.server i svn.project. Jak widać, aby posłużyć się wartością przypisaną do danej właściwości, należy użyć składni z symbolem dolara, po którym następuje nazwa właściwości w nawiasach klamrowych: ${nazwa_właściwości}. Możliwe jest (i bardzo wygodne) przechowywanie właściwości w odrębnych plikach, zawie- rających wyłącznie pary nazwa-wartość. Pliki te są zgodne z konwencją nazewniczą, nakazującą, by nazwa kończyła się przyrostkiem .properties. Oto przykład prostego pliku właściwości: # Subversion svn.server=waferthin.com svn.proto=https:// # … definicje wielu innych właściwości … # ustawienia i parametry uwierzytelniające dla bazy danych db.server=localhost db.user=root db.password=psstdonttell db.name=state_secrets Jak widać, składnia jest bardzo prosta. Wartości są przypisywane nazwom właściwości za po- mocą znaku równości i w każdym wierszu musi występować tylko jedna para nazwa-wartość. Importowanie takiego pliku właściwości jest możliwe dzięki atrybutowi file zadania property: property file= propfile.properties / To wystarczy, by ustawić wszystkie właściwości wymienione w pliku propfile.properties dla przestrzeni nazw, w której występuje zadanie property. Używanie plików właściwości ma co najmniej dwie zalety. Po pierwsze, dzięki niemu plik build.xml staje się krótszy i bardziej przejrzysty. Składnia XML jest dość rozwlekła, więc utrzymywanie właściwości w odrębnym pliku poprawia czytelność i ułatwia zrozumienie sa- mego pliku konsolidacyjnego. Po drugie, pliki właściwości wprowadzają kolejny poziom abstrakcji, podobnie jak centralny plik lub obiekt konfiguracyjny dodaje poziom abstrakcji do aplikacji PHP. Aby wdrożyć aplikację gdzieś indziej, wystarczy dokonać edycji pliku właści- wości bez naruszania pliku build.xml. 320 Rozdział 8. • Wdrażanie aplikacji Rozwijając tę ideę, możemy zapewnić obsługę różnych środowisk. Jak zobaczymy później w na- szym przykładzie, możemy po prostu wskazać Phing środowisko, w jakim ma nastąpić wdro- żenie, a reszta ustawień będzie realizowana poprzez dołączenie pliku właściwości odpowia- dającemu danemu środowisku. Bardzo często spotyka się pliki właściwości o nazwach w stylu dev.properties, staging.properties lub production.properties, odzwierciedlające środowisko, dla którego konfigurowany jest proces konsolidacji lub wdrożenia. Typy Typy mogą reprezentować dane bardziej złożone niż właściwości. Na przykład typ może być odnośnikiem do plików w danym katalogu, którego nazwa musi pasować do podanego wyra- żenia regularnego. Oto przykład typu fileset, który zawiera odnośniki do wszystkich plików .properties w katalogu build projektu, poza plikiem o nazwie deprecated.properties. fileset dir= ${project.home}/build include name= *.properties / exclude name= deprecated.properties / /fileset Oto wbudowane typy Phing: (cid:81) FileList — uporządkowana lista plików w systemie plików. Pliki nie muszą istnieć w systemie plików. (cid:81) FileSet — nieuporządkowana lista plików, które istnieją w systemie plików. (cid:81) Path / ClassPath — służy do reprezentowania zbiorów ścieżek do katalogów. Dokładny opis funkcjonalności i atrybutów tych typów można znaleźć w dokumentacji narzę- dzia Phing. Filtry Jak sugeruje nazwa, filtry pozwalają filtrować i przekształcać w jakiś sposób zawartość pliku. Gdy pisałem tę książkę, było dostępnych 14 głównych filtrów, pozwalających wykonywać tak różnorodne działania, jak: (cid:81) rozwijanie właściwości w pliku, (cid:81) usuwanie znaków przejścia do następnego wiersza, komentarzy w wierszu lub komentarzy PHP, (cid:81) usuwanie lub dodawanie wierszy w pliku w zależności od ich lokalizacji w danym pliku lub usuwanie zawartości wiersza. Filtry muszą być zawarte pomiędzy znacznikami otwierającym i zamykającym filterchain. Nasz plik konsolidacyjny w podsekcji mappers również zawiera przykład zastosowania filtru. W dalszej części rozdziału zobaczymy jeszcze jeden przykład zastosowania filtrów w celu zmiany zawartości jednego lub kilku plików. 321 PHP 5. Narzędzia dla ekspertów Mapery O ile filtry operują na zawartości pliku, mapery działają podobnie, ale na nazwach plików. Obecnie istnieje w Phing pięć podstawowych maperów, które pozwalają wykonywać na ścież- kach i nazwach plików następujące operacje: (cid:81) FlattenMapper — usuwa katalogi z podanej ścieżki, pozostawiając jedynie nazwy plików. (cid:81) GlobalMapper — przemieszcza pliki, nie zmieniając ich nazw. (cid:81) IdentityMapper — nie zmienia niczego. (cid:81) MergeMapper — zmienia kilka plików tak, by miały tę samą nazwę. (cid:81) RegexpMapper — zmienia nazwę plików, posługując się wyrażeniami regularnymi. Oto przykład zmiany nazw plików szablonów na nazwy rzeczywistych plików PHP z wyko- rzystaniem filtru expandproperties oraz zmiany nazw plików za pomocą filtru GlobalMapper: copy todir= /includes filterchain expandproperties / /filterchain mapper type= glob from= *.php.tpl to= *.php / fileset dir= templates include name= *.php.tpl / /fileset /copy Jak zwykle, pełna lista wszystkich filtrów i maperów oraz dokładne opisy ich zastosowania i atrybutów są dostępne w doskonałej dokumentacji online narzędzia Phing. Znacznik project Najbardziej zewnętrzny znacznik to znacznik project , który zawiera atrybuty definiujące nazwę projektu, jego opis oraz nazwę celu, jaki ma być wykonywany domyślnie. Jak się za chwilę przekonamy, zawsze istnieje możliwość nakazania Phing wykonania celu innego niż zdefiniowany tutaj domyślny. Poza tym Phing korzysta z nazwy projektu, przekazując infor- macje użytkownikom. Wdrażanie serwisu Spróbujmy teraz wykorzystać właśnie zdobytą wiedzę na temat zadań, celów, właściwości, typów, filtrów, maperów oraz projektów i utworzyć plik konsolidacyjny, który płynnie wdroży aktualizację serwisu internetowego. Utworzymy także kilka szablonów i danych, które pozwolą nam dowolnie aktualizować i cofać aktualizacje bazy danych. Zamiast eksperymentować z czyjąś stroną, zdecydowałem się zautomatyzować wdrożenie mojej własnej strony internetowej waferthin.com. Oto struktura katalogów wdrożonego serwisu: 322 Rozdział 8. • Wdrażanie aplikacji Separowanie zewnętrznych zależności Sensowne wydaje się odseparowanie zewnętrznych zależności, które nie rezydują w naszym systemie kontroli wersji, od reszty projektu. Są to zwykle pliki i katalogi, które niekoniecznie muszą być aktualizowane za każdym razem, gdy przeprowadzamy wdrożenie. Separując te zależności, nie będziemy musieli martwić się o to, że przypadkowo je nadpiszemy lub uszko- dzimy. W przypadku mojej strony jest kilka katalogów oraz plików, które zostały po prostu skopiowane na serwer podczas pierwotnej ręcznej instalacji, takich jak Zend Library, Mantis (narzędzie do śledzenia problemów) i RoundCube (przeglądarkowy czytnik e-maili). Katalogi te będą musiały zostać albo przeniesione ze starej wersji serwisu do nowej, albo zastąpione dowiązaniem symbolicznym. Z tego samego powodu katalog logs będzie musiał być przenie- siony poza katalog projektu. Po ukończeniu naszego skryptu konsolidacyjnego i udanym wdrożeniu serwisu przyjrzymy się, jak zmieniła się jego struktura w porównaniu ze stanem sprzed wdrożenia. 323 PHP 5. Narzędzia dla ekspertów Tworzenie skryptu konsolidacyjnego Zacznijmy od utworzenia prostego skryptu konsolidacyjnego. Na szczęście cele dzielą skrypt na łatwiejsze do ogarnięcia części. Będziemy tworzyć kolejno po jednym celu, do momentu gdy wszystkie elementy tej „układanki” będą gotowe i możliwe stanie się wdrożenie serwisu jednym poleceniem. Środowisko i właściwości Zwykle pracuję na lokalnej kopii projektu, ale na koniec zdalnie wdrażam wersję testową i ostateczną. Tutaj każdy programista może preferować inny sposób pracy, ale niemal wszyscy spotkamy się z sytuacją, kiedy musimy wdrożyć tę samą aplikację w wielu różnych środowi- skach i serwerach. Przydałoby się, aby skrypt Phing był na tyle elastyczny, by uwzględniał owe różne wymagania w sposób nieangażujący użytkownika. Ponieważ większość, jeżeli nie wszystkie czynności, jakie trzeba wykonać, jest przy każdym wdrożeniu taka sama, napiszemy skrypt pozwalający wdrażać aplikację w różnych środowiskach poprzez prostą zmianę kilku właściwości, takich jak nazwa domeny, ścieżka do projektu na serwerze, ustawienia bazy danych itp. Typowe rozwiązanie tego problemu polega na utworzeniu plików właściwości, które odpo- wiadają różnym środowiskom, które chcemy obsłużyć. Następnie możemy utworzyć cele ła- dujące odpowiednie pliki właściwości lub wręcz pytające użytkownika, z którego pliku wła- ściwości należy skorzystać. Oto plik dev.properties, zawierający ustawienia dla wdrożenia wersji mojej strony w środowi- sku programistycznym na moim lokalnym komputerze: # wdrożenie site.fqdn=dev.waferthin.com site.fqdn.secure=dev.secure.waferthin.com site.home=/Users/dirk/Sites/${site.fqdn} site.root=/Users/dirk/Sites/${site.fqdn}/${site.fqdn} # system Subversion svn.bin=/usr/bin/svn svn.fqdn=svn svn.user=dirk svn.repo=/svn/ svn.proto=https:// svn.project=waferthin.com/trunk svn.password=donttellanybody # ustawienia połączenia z bazą i parametry uwierzytelniające db.user=root db.password=itsasecret db.name=waferthin db.fqdn=localhost 324 Rozdział 8. • Wdrażanie aplikacji db.port=3306 db.bin=/usr/local/mysql/bin/mysql db.backup.dir=${site.home}/backups # lokalizacja pliku dziennika aplikacji log=${site.home}/logs/waferthin.log # moduł szablonów Smarty smarty.templates_dir=${site.root}/smarty/templates smarty.compile_dir=${site.root}/smarty/templates_c smarty.configs_dir=${site.root}/smarty/configs smarty.cache_dir=${site.root}/smarty/cache smarty.plugins_dir=${site.root}/smarty/plugins smarty.plugins2_dir=${site.root}/includes/libraries/Smarty/plugins smarty.force_compile=true # zewnętrzne narzędzia extern.apachectl=/usr/sbin/apachectl extern.sudo=/usr/bin/sudo extern.ln=/bin/ln extern.mysqldump=/usr/local/mysql/bin/mysqldump # biblioteki zend_dir=/usr/local/lib/php/Zend Jak widać, plik składa się z sześciu sekcji definiujących następujący podział logiczny: 1. Właściwości z przedrostkiem site. odnoszą się do lokalizacji na serwerze, w jakiej ma zostać wdrożony serwis. 2. Właściwości z przedrostkiem svn. odnoszą się do dostępu do repozytorium Subversion przechowującego kod źródłowy. 3. Właściwości z przedrostkiem db. odnoszą się do parametrów połączenia i parametrów uwierzytelniających umożliwiających połączenie z bazą danych. 4. Właściwości z przedrostkiem smarty. odnoszą się do konfiguracji modułu szablonów Smarty. 5. Właściwości z przedrostkiem extern. odnoszą się do lokalizacji zewnętrznych plików wykonywalnych, wymaganych przez skrypt konsolidacyjny. 6. Właściwości log i zend_dir służą do zachowania jeszcze innych zewnętrznych zależności poprzez utworzenie dowiązań symbolicznych (więcej na ten temat w dalszej części rozdziału). Mam też podobne pliki dla środowiska docelowego (prod.properties) oraz testowego (test.properties). Wszystkie trzy pliki znajdują się w tym samym katalogu co plik build.xml. Po zaimplementowaniu obsługi plików właściwości i wielu różnych środowisk możemy dodawać dowolną liczbę środowisk wdrożeniowych poprzez utworzenie stosownych plików właściwości. 325 PHP 5. Narzędzia dla ekspertów Zacznijmy teraz od utworzenia pliku build.xml, który na razie inicjalizuje jedynie środowisko: ?xml version= 1.0 ? project name= waferthin.com description= Realizuje utrzymanie i wdrożenie (cid:180)serwisu waferthin.com. default= deploy !-- Inicjalizuje datownik, który będzie używany przy nadawaniu nazw różnym plikom (cid:180)i katalogom. -- tstamp/ target name= deploy depends= get-env,create-skeleton,svn-export, (cid:180)stamp-config,disp-maint,backup-db,deploy-db,publish-site (cid:180)description= Wdraża serwis na serwer WWW i wykonuje niezbędne zadania (cid:180)konsolidacyjne i aktualizacyjne. /target target name= get-env description= Pobiera środowisko, do jakiego ma (cid:180)nastąpić wdrożenie. !-- Czy środowisko zostało już ustawione? -- if not isset property= environment / /not then !-- Prosi użytkownika o wybranie środowiska z listy obsługiwanych (cid:180)środowisk. -- input propertyname= environment validargs= dev,test,prod (cid:180)promptChar= : Podaj środowisko /input /then /if !-- Sprawdza, czy istnieje plik właściwości dla danego środowiska. -- available file= ${environment}.properties property= env_prop_exists (cid:180)type= file / if equals arg1= ${env_prop_exists} arg2= true / then !-- Odczytuje pliki właściwości. -- property file= ${environment}.properties / /then else !-- Przerywa konsolidację i ukazuje komunikat dotyczący błędu. -- fail message= Nie znaleziono pliku właściwości dla wybranego (cid:180)środowiska (${environment}.properties) / /else /if /target 326 Rozdział 8. • Wdrażanie aplikacji target name= deploy-dev description= Wdraża serwis w środowisku (cid:180)programowania. property name= environment value= dev override= true / phingcall target= deploy / /target target name= deploy-prod description= Wdraża serwis w środowisku (cid:180)docelowym. property name= environment value= prod override= true / phingcall target= deploy / /target target name= deploy-test description= Wdraża serwis w środowisku (cid:180)testowym. property name= environment value= test override= true / phingcall target= deploy / /target /project Znacznik project zawiera opis celów pliku build.xml oraz identyfikuje cel deploy jako domyślny. Jedyną interesującą rzeczą związaną z celem deploy jest jego atrybut depends, który w tym przypadku informuje Phing, że wcześniej wykonany musi zostać cel get-env. Przyjrzyjmy się więc celowi get-env, który jak na razie jest jedynym celem wykonującym jakieś konkretne zadania. Oto, co się stanie, gdy uruchomimy wstępną wersję pliku build.xml z wiersza poleceń: W pliku występują również cele deploy-dev, deploy-test i deploy-prod. Ustawiają one wła- ściwość definiującą środowisko na dev, prod lub test w zależności od tego, czy wdrażamy aplikację odpowiednio w środowisku programowania, docelowym lub testowym, po czym wywołują cel deploy. Dzięki temu możliwe jest wdrażanie aplikacji w każdym z tych środo- wisk bez konieczności wpisywania jego nazwy ręcznie. 327 PHP 5. Narzędzia dla ekspertów Szkielet katalogów Sposób, w jaki wdrażamy naszą aplikację, zakłada istnienie określonej struktury katalogów. Jeżeli wdrażamy aplikację po raz pierwszy, musimy utworzyć katalogi, które będą potrzebne w następnych krokach. Jeżeli dokonujemy aktualizacji, wciąż musimy utworzyć wszelkie ka- talogi, których wcześniej brakowało. Oto cel, który zajmuje się tworzeniem katalogów: !-- Tworzy katalogi; żadne istniejące katalogi nie zostaną nadpisane. -- target name= create-skeleton description= Tworzy podstawową strukturę (cid:180)katalogów dla serwisu. mkdir dir= ${site.home} / mkdir dir= ${site.home}/build / mkdir dir= ${site.home}/backups / mkdir dir= ${site.home}/logs / mkdir dir= ${site.home}/tmp / /target ... Zadanie mkdir tworzy katalog określony za pomocą atrybutu dir. Eksportowanie i wymeldowywanie z Subversion Teraz przyszła pora na pobranie kodu z systemu kontroli wersji. Jako że w książce tej skupili- śmy się na Subversion jako przykładzie takiego systemu, będziemy tu trzymać się tego przy- kładu. Jeżeli jednak nasz projekt rezyduje w CVS, Git, Perforce lub jakimkolwiek innym sys- temie, opisane tu kroki będą wyglądać bardzo podobnie. Tak się składa, że Phing ma pewne wbudowane zadania opcjonalne, pozwalające na interakcję z Subversion. Jeżeli jednak korzy- stamy z nieco mniej popularnego typu repozytorium, możemy utworzyć własne zadanie Phing lub użyć zadania ExecTask, które pozwala uruchamiać pliki wykonywalne w wierszu poleceń. Oto fragment pliku build.xml definiujący cel svn-export: ... target name= svn-export description= Eksportuje pliki serwisu z Subversion do (cid:180)lokalnego katalogu docelowego. !-- Konstruuje poprawne URL dla Subversion -- property name= svn.url value= ${svn.proto} (cid:180)${svn.fqdn}${svn.repo}${svn.project} override= true / !-- Czy hasło dostępu do Subversion zostało podane w pliku właściwości? -- if not isset property= svn.password / /not 328 Rozdział 8. • Wdrażanie aplikacji then !-- Prosi użytkownika o podanie hasła dostępu do Subversion. -- input propertyname= svn.password promptChar= : Podaj hasło (cid:180)dla użytkownika ${svn.user}, aby pobrać projekt (cid:180)${svn.project} z repozytorium Subversion (cid:180)${svn.fqdn}${svn.repo} /input /then /if !-- Wymeldowuje projekt do środowiska programowania. -- if equals arg1= ${environment} arg2= dev / then echo Wymeldowywanie z svn zostało rozpoczęte... /echo svncheckout svnpath= ${svn.bin} repositoryurl= ${svn.url} todir= ${site.root}.${DSTAMP}${TSTAMP} username= ${svn.user} password= ${svn.password} / /then !-- Eksportuje projekt na potrzeby wdrożenia. -- else echo Eksport svn został rozpoczęty ... /echo svnexport svnpath= ${svn.bin} repositoryurl= ${svn.url} todir= ${site.root}.${DSTAMP}${TSTAMP} username= ${svn.user} password= ${svn.password} / /else /if /target Na początku za pomocą zadania property konstruowany jest prawidłowy ciąg URL dla Su- bversion wskazujący nasz projekt, po czym zostaje on zapisany we właściwości svn.url. Następnie sprawdzamy, czy właściwość svn.password została ustawiona. Dobra praktyka na- kazuje nie wpisywać haseł do plików właściwości, ale przerywa to pełną automatyzację. Na- sze rozwiązanie obsługuje obydwie możliwości — jeżeli nie podano w pliku wartości svn.password, Phing poprosi użytkownika za pośrednictwem znacznika inputTask o ręczne wpisanie hasła. Jeżeli nie chcemy za każdym razem wpisywać nazwy użytkownika i hasła SSH, zawsze możemy zainstalować swój publiczny klucz SHH na serwerze, na którym rezyduje repozytorium Subver- sion, i zmodyfikować plik build.xml tak, by nie prosił o podanie parametrów uwierzytelniających. Zastosowany sposób pobrania kodu z repozytorium zależy od tego, co mamy zamiar z nim zrobić. Użyliśmy tutaj instrukcji warunkowej if-then-else, ponieważ wymagane kroki są nieco inne w przypadku środowiska programowania. Jeżeli pracujemy w środowisku programowania, 329 PHP 5. Narzędzia dla ekspertów dokonujemy wymeldowania z Subversion za pomocą zadania svncheckout, które pozwoli nam zatwierdzić zmiany z powrotem do repozytorium. Jeżeli z kolei wdrażamy aplikację, zastosu- jemy zadanie svnexport, usuwające wszelkie dane, które w strukturze katalogów przechowuje na własne potrzeby system Subversion. Tworzenie plików na podstawie szablonów Każdy serwis lub aplikacja zawiera jakieś dane konfiguracyjne i istnieje wiele różnych sposo- bów przechowywania tych informacji i udostępniania ich na potrzeby aplikacji. Można się spotkać ze stosowaniem na potrzeby konfiguracji plików właściwości, plików XML lub glo- balnych zmiennych PHP. W moim serwisie korzystam z klasy Config zdefiniowanej w pliku Config.php, gdzie ustawienia konfiguracyjne są przechowywane albo jako stałe klasy albo jako prywatne właściwości statyczne. Normalnie oznaczałoby to konieczność ręcznej edycji takiego pliku, aby ustawić parametry odpowiednie dla środowiska, do którego następuje wdrożenie. Skoro jednak staramy się zautomatyzować proces wdrożeniowy, musimy znaleźć jakieś inne rozwiązanie. Rozwiązanie to będzie polegać na utworzeniu szablonu pliku Config.php, na którego podsta- wie tworzony będzie plik Config.php dostosowany do danego środowiska. Oto kilka pierwszych wierszy szablonu pliku Config.php: class Config { // ustawienia i parametry uwierzytelniające dla bazy danych const DB_VENDOR = ‘mysql ; const DB_HOSTNAME = ‘${db.fqdn} ; const DB_PORT = ${db.port}; const DB_USERNAME = ‘${db.user} ; const DB_PASSWORD = ‘${db.password} ; const DB_DATABASE_NAME = ‘${db.name} ; // lokalizacja pliku dziennika aplikacji const LOG_FILE = ‘${log} ; ... Bardzo łatwo rozpoznać powyższe bloki, które zostaną zastąpione wartościami przypisanymi do stałych klasy, ponieważ są to po prostu właściwości Phing. Następujący fragment pliku build.xml pobiera szablon pliku Config.php i zastępuje owe bloki wartościami, jakie reprezentują, po- chodzącymi wprost z pliku właściwości. target name= stamp-config description= Zapełnia klasę Config.php (cid:180)właściwościami konfiguracyjnymi. copy todir= ${site.root}.${DSTAMP}${TSTAMP}/includes/classes filterchain expandproperties / /filterchain 330 Rozdział 8. • Wdrażanie aplikacji fileset dir= ${site.root}.${DSTAMP}${TSTAMP}/config/templates include name= Config.php / /fileset /copy /target Zadanie copy przenosi szablon Config.php do podkatalogu includes/classes katalogu zdefinio- wanego jako katalog główny aplikacji. W zadaniu tym jednak dzieje się jeszcze kilka innych rzeczy wartych omówienia. Są tam dwa zagnieżdżone znaczniki. Pierwszy to zadanie filterchain, które pozwala przetwa- rzać kopiowane pliki. W tym przypadku za pomocą zadania expandproperties zastępujemy wszystkie bloki reprezentujące właściwości ich wartościami. Zadanie fileset pozwala tworzyć li- sty plików poprzez wyłączanie i włączanie różnych plików na podstawie różnych kryteriów, takich jak wyrażenia regularne, dopasowujące pliki do ścieżki lub nazwy pliku. W naszym przypadku lista zawiera tylko jeden plik, Config.php, który dołączamy na podstawie nazwy. Strona z komunikatem o niedostępności serwisu W tym momencie zakończyliśmy wszystkie kroki przygotowawcze związane z aktualizacją strony. Na potrzeby następnych działań musimy zadbać o to, by użytkownicy odwiedzający stronę nie zakłócali procesu aktualizacji. Stąd też konieczne jest poinformowanie użytkowni- ków o tymczasowej niedostępności serwisu poprzez przekierowanie całego ruchu na specjal- ną stronę, która pełni taką właśnie funkcję. W moim serwisie jest to strona maintenance.html w głównym katalogu publicznie dostępnej ścieżki /htdocs/. Korzystam z Apache w roli serwera WWW, który pozwala tworzyć pliki konfiguracyjne dedy- kowane dla konkretnego katalogu, zwykle nazywane .htaccess. Aby opisywana tu metoda za- działała, należy się upewnić, czy stosowanie plików .htaccess jest uaktywnione. Poniższy kod wymaga także włączenia na serwerze modułu mod_rewrite, za którego pomocą modyfikowane jest żądanie URL i przekierowywana jest przeglądarka użytkownika. Krótko mówiąc, tworzymy lokalny plik konfiguracyjny Apache, który za pomocą mod_rewrite tymczasowo przekierowuje wszystkie żądania na stronę maintenance.html. target name= disp-maint description= Eksportuje pliki serwisu z Subversion do (cid:180)lokalnego katalogu docelowego. !-- Sprawdza, czy plik .htaccess już istnieje. -- available file= ${site.root}/htdocs/.htaccess (cid:180)property= htaccess_exists type= file / if equals arg1= ${htaccess_exists} arg2= true / then !-- .htaccess istnieje; zmienia jego nazwę. -- move file= ${site.root}/htdocs/.htaccess tofile= ${site.home}/htdocs/.htaccess.bck overwrite= false / /then 331 PHP 5. Narzędzia dla ekspertów /if !-- nowy plik .htaccess na potrzeby komunikatu o przerwie w dostępności serwisu -- echo file= ${site.root}/htdocs/.htaccess append= false Options +FollowSymlinks RewriteEngine on RewriteCond {REQUEST_URI} !/maintenance.html$ RewriteCond {REMOTE_HOST} !^127\.0\.0\.1 RewriteRule $ /maintenance.html [R=302,L] /echo /target Powyższy kod zamiast od razu tworzyć plik .htaccess, najpierw sprawdza, czy plik taki już ist- nieje. Jeżeli istnieje, zmienia jego nazwę za pomocą zadania move. Następnie za pomocą za- dania echo z atrybutem file zapisuje niezbędne dyrektywy Apache w nowo utworzonym pliku .htaccess. Kopia zapasowa bazy danych Ponieważ zablokowaliśmy użytkownikom dostęp do serwisu, możemy mieć pewność, że baza danych, z której korzysta aplikacja, nie będzie używana. Jeżeli serwis, który wdrażamy, ma jakieś zautomatyzowane zadania, korzystające z bazy danych, najprawdopodobniej będziemy musieli tymczasowo je wyłączyć. Następnym krokiem jest sporządzenie kopii zapasowej bazy danych. Mimo że narzędzie, z które- go korzystamy do migracji, obsługuje możliwość aktualizowania i cofania aktualizacji do dowolnej wersji, dobrą praktyką jest tworzenie kopii zapasowej bazy zawsze, gdy coś ulega zmianie. Na szczęście mamy procedurę, która tworzy kopię zapasową bazy oraz całego serwisu. Oto fragment kodu tworzący kopię zapasową bazy danych: target name= backup-db description= Tworzy kopię zapasową bazy danych przez (cid:180)jej aktualizacją. !-- Czy hasło do bazy zostało podane w pliku właściwości? -- if not isset property= db.password / /not then !-- Prosi użytkownika o podanie hasła do bazy danych. -- input propertyname= db.password promptChar= : Podaj hasło (cid:180)użytkownika ${db.user} dla bazy ${db.name} /input /then /if !-- Wykonuje zewnętrzne polecenie mysqldump, aby utworzyć kopię zapasową bazy (cid:180)danych. -- 332 Rozdział 8. • Wdrażanie aplikacji exec command= ${extern.mysqldump} --quick --password=${db.password} – (cid:180)user=${db.user} ${db.name} ${db.name}.${DSTAMP}${TSTAMP}.sql dir= ${db.backup.dir} escape= false / !-- kompresja pliku zrzutu bazy -- zip destfile= ${db.backup.dir}/${db.name}.${DSTAMP}${TSTAMP}.sql.zip fileset dir= ${db.backup.dir} include name= ${db.name}.${DSTAMP}${TSTAMP}.sql / /fileset /zip !-- Usuwa oryginalny plik zrzutu, aby zaoszczędzić miejsce. -- delete file= ${db.backup.dir}/${db.name}.${DSTAMP}${TSTAMP}.sql / /target Zaczynamy od sprawdzenia, czy hasło do bazy danych zostało podane w pliku właściwości. Jeżeli nie, użytkownik jest proszony o jego wpisanie w trybie interaktywnym z wiersza pole- ceń. Rozwiązanie to powinno wydawać się już znajome, ponieważ podobne zostało zastoso- wane przy pobieraniu hasła do systemu Subversion. Następnie za pomocą zadania exec uruchamiane jest zewnętrzne polecenie, konkretnie na- rzędzie mysqldump, eksportujące schemat i zawartość bazy danych do pliku tekstowego. Plik ten jest kompletnym obrazem stanu bazy i może być użyty do przywrócenia bazy dokładnie do stanu z chwili jego utworzenia. Ponownie do bazy pliku dołączany jest datownik, aby było wiadomo, kiedy dokładnie został utworzony. Atrybut command zadania exec zawiera polecenie, jakie ma zostać wykonane w wierszu poleceń po przejściu do katalogu wskazanego atrybutem dir. Atrybut escape to wartość logiczna, która precyzuje, czy znaki specj
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

PHP 5. Narzędzia dla ekspertów
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ą: