informatyka php 5 narzedzia dla ekspertow dirk merkel ebook

background image
background image

Idź do

• Spis treści
• Przykładowy rozdział

• Katalog online

• Dodaj do koszyka

• Zamów cennik

• Zamów informacje

o nowościach

• Fragmenty książek

online

Helion SA
ul. Kościuszki 1c
44-100 Gliwice
tel. 32 230 98 63
e-mail: helion@helion.pl

© Helion 1991–2010

Katalog książek

Twój koszyk

Cennik i informacje

Czytelnia

Kontakt

• Zamów drukowany

katalog

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ą!

background image

Spis tre

Ăci

O autorze

9

O recenzentach

11

Przedmowa

13

O czym jest ta ksi

Èĝka?

13

Co jest potrzebne, aby skorzysta

Ê z ksiÈĝki?

14

Dla kogo jest ta ksi

Èĝka?

14

Konwencje

15

Uwagi Czytelników

15

Przyk

ïadowy kod

16

Rozdzia

ï 1. Standardy i styl pisania kodu

17

Co uwzgl

ÚdniÊ przy tworzeniu standardów?

17

Zalety

18

Wady

19

Standard pisania kodu PHP

19

Formatowanie

20

Konwencje nazewnicze

25

Metodologia

29

Weryfikacja zgodno

Ăci ze standardami pisania kodu

35

Automatyczna kontrola zgodnoĂci za pomocÈ narzÚdzia PHP_CodeSniffer

35

Podsumowanie

46

Rozdzia

ï 2. Dokumentowanie za pomocÈ narzÚdzia phpDocumentor

49

Dokumentacja w tre

Ăci kodu

50

Poziomy szczegóïowoĂci

51

Wprowadzenie do programu phpDocumentor

52

Instalacja programu phpDocumentor

52

Bloki DocBlock

54

Szablony DocBlock

55

background image

Spis tre

Ğci

4

Samouczki

56

Dokumentowanie projektu

59

Opcje programu phpDocumentor

74

Katalog tagów

78

Tagi stosowane w PHP4

94

Tagi uĝytkownika

94

Podsumowanie

95

Rozdzia

ï 3. Eclipse — zintegrowane Ărodowisko programistyczne

97

Dlaczego Eclipse?

98

Wprowadzenie do PDT

100

Instalacja Eclipse

100

Wymagania

100

Wybór pakietu

102

Dodawanie pluginu PDT

102

Podstawowe poj

Úcia zwiÈzane z Eclipse

104

Przestrzeñ robocza (Workspace)

104

Widoki (Views)

105

Perspektywy

107

Przyk

ïadowy projekt PDT

108

Mo

ĝliwoĂci funkcjonalne pluginu PDT

111

Edytor

111

Inspekcja

115

Debugowanie

117

Preferencje PDT

120

Inne moĝliwoĂci funkcjonalne

127

Pluginy Eclipse

128

Zend Studio dla Eclipse

129

Wsparcie

131

Refaktoring

131

Generowanie kodu

131

Testowanie za pomocÈ PHPUnit

131

Obsïuga programu phpDocumentor

132

Integracja ze szkieletem Zend Framework

133

Integracja z serwerem Zend

133

Podsumowanie

133

Rozdzia

ï 4. ZarzÈdzanie kodem ěródïowym i wersjami

135

Typowe przypadki u

ĝycia

135

Krótka historia kontroli kodu

ěródïowego

136

CVS

139

Wprowadzenie do Subversion

141

Instalacja klienta

141

Konfiguracja serwera

142

PojÚcia zwiÈzane z Subversion

143

Lista poleceñ Subversion

147

Tworzenie projektu Subversion

157

background image

Spis tre

Ğci

5

Sposób pracy z systemem kontroli wersji

164

Bliĝsze spojrzenie na repozytorium

169

OdgaïÚzienia i scalanie

171

Aplikacje klienckie

177

Konwencje i najlepsze praktyki przy pracy z Subversion

183

Przystosowywanie Subversion do wïasnych potrzeb

184

Powiadamianie programistów o zatwierdzonych plikach

za pomocÈ skryptu post-commit

187

Podsumowanie

187

Rozdzia

ï 5. Debugowanie

189

Pierwsza linia obrony — kontrola sk

ïadni

189

Dzienniki

191

Opcje konfiguracyjne

192

Dostosowywanie opcji konfiguracyjnych i panowanie nad nimi — PhpIni

194

Wy

Ăwietlanie informacji diagnostycznych

201

Funkcje

201

„Magiczne” staïe

205

Tworzenie wïasnej klasy diagnostycznej

205

Wprowadzenie do Xdebug

221

Instalacja Xdebug

221

Konfiguracja Xdebug

224

Natychmiastowe korzyĂci

225

Zdalne debugowanie

228

Podsumowanie

235

Rozdzia

ï 6. Szkielety aplikacji PHP

237

Pisanie w

ïasnego szkieletu

237

Ocena i wybór szkieletów

238

SpoïecznoĂÊ i akceptacja

239

MoĝliwoĂci funkcjonalne

239

Dokumentacja

240

JakoĂÊ kodu

240

Stosowanie i zgodnoĂÊ ze standardami pisania kodu

241

Dopasowanie do projektu

241

’atwoĂÊ w nauce i adaptacji

242

DostÚpnoĂÊ kodu ěródïowego

242

ZnajomoĂÊ szkieletu

243

Ich zasady

243

Popularne szkielety aplikacji PHP

243

Zend

244

CakePHP

244

CodeIgniter

245

Symfony

245

Yii

246

background image

Spis tre

Ğci

6

Aplikacja w szkielecie Zend Framework

247

Lista cech i funkcji

247

KrÚgosïup aplikacji

248

Usprawnienia

253

Podsumowanie

272

Rozdzia

ï 7. Testowanie

273

Metody testowania

273

Czarna skrzynka

274

Biaïa skrzynka

274

Szara skrzynka

275

Typy testowania

276

Testowanie jednostkowe

276

Testowanie integracyjne

277

Testowanie regresyjne

277

Testowanie systemowe

278

Testy akceptacji uĝytkowników

278

Wprowadzenie do PHPUnit

279

Instalacja PHPUnit

279

Przeszukiwanie ciÈgu tekstowego (przykïadowy projekt)

281

Analiza pokrycia kodu

306

Podklasy klasy TestCase

307

Podsumowanie

308

Rozdzia

ï 8. Wdraĝanie aplikacji

309

Cele i wymagania

309

Wdra

ĝanie aplikacji

311

Wymeldowywanie plików i wysyïanie ich na serwer

312

WyĂwietlanie informacji o niedostÚpnoĂci serwisu

313

Aktualizacja i instalacja plików

313

Aktualizacja schematu i zawartoĂci bazy danych

314

Rotacja plików dziennika i aktualizacja dowiÈzañ symbolicznych

314

Weryfikacja wdroĝonej aplikacji

315

Automatyzacja procesu wdro

ĝenia

315

Phing

315

Podstawowa skïadnia i struktura pliku

317

Typy

321

Wdraĝanie serwisu

322

Podsumowanie

339

Rozdzia

ï 9. Projektowanie aplikacji za pomocÈ jÚzyka UML

341

Metamodel i notacja a nasze podej

Ăcie do UML

342

Poziom szczegó

ïowoĂci i przeznaczenie

343

Narz

Údzia jedno- i dwukierunkowe

344

Podstawowe typy diagramów UML

345

Diagramy

346

background image

Spis tre

Ğci

7

Diagramy klas

347

Diagramy sekwencji

359

Przypadki uĝycia

364

Podsumowanie

368

Rozdzia

ï 10. CiÈgïa integracja

369

Systemy satelitarne

371

Kontrola wersji — Subversion

371

Testowanie — PHPUnit

372

Automatyzacja — Phing

373

Styl pisania kodu — PHP_CodeSniffer

374

Dokumentowanie — PhpDocumentor

375

Analiza pokrycia kodu — Xdebug

375

Przygotowanie

Ărodowiska

376

Czy potrzebujÚ dedykowanego serwera CI?

376

Czy potrzebujÚ narzÚdzia CI?

376

Narz

Údzia CI

377

XINC

377

phpUnderControl

377

Ci

Ègïa integracja z phpUnderControl

378

Instalacja

378

Konfiguracja CruiseControl

382

PrzeglÈd procesu i komponentów ciÈgïej integracji

382

Podsumowanie

404

Skorowidz

405

background image

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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

310

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.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

311

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ñ.

background image

PHP 5. Narz

Ċdzia dla ekspertów

312

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.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

313

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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

314

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.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

315

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

ĝ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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

316

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:

Q

create-skeleton — tworzy katalogi potrzebne na serwerze.

Q

checkout-site — wymeldowuje projekt z systemu Subversion.

Q

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”).

background image

Rozdzia

á 8. • WdraĪanie aplikacji

317

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
´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
´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>

background image

PHP 5. Narz

Ċdzia dla ekspertów

318

<!-- 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:

Q

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.

Q

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.

Q

InputTask

— prosi u

ĝytkownika o wprowadzenie danych, z których moĝna skorzystaÊ

przy wykonywaniu nast

Úpnych zadañ.

A oto przyk

ïady zadañ opcjonalnych:

Q

SvnExportTask

— eksportuje projekt z repozytorium Subversion do lokalnego

katalogu.

Q

ZipTask

/

UnzipTask

— dwa uzupe

ïniajÈce siÚ zadania tworzÈce archiwum ZIP z grupy

plików lub rozpakowuj

Èce pliki z istniejÈcego archiwum.

Q

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/.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

319

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Ê.

background image

PHP 5. Narz

Ċdzia dla ekspertów

320

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}"
´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.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

321

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:

Q

FileList

— uporz

Èdkowana lista plików w systemie plików. Pliki nie muszÈ istnieÊ

w systemie plików.

Q

FileSet

— nieuporz

Èdkowana lista plików, które istniejÈ w systemie plików.

Q

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

ĝnorodne dziaïania, jak:

Q

rozwijanie w

ïaĂciwoĂci w pliku,

Q

usuwanie znaków przej

Ăcia do nastÚpnego wiersza, komentarzy w wierszu lub

komentarzy PHP,

Q

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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

322

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:

Q

FlattenMapper

— usuwa katalogi z podanej

Ăcieĝki, pozostawiajÈc jedynie nazwy

plików.

Q

GlobalMapper

— przemieszcza pliki, nie zmieniaj

Èc ich nazw.

Q

IdentityMapper

— nie zmienia niczego.

Q

MergeMapper

— zmienia kilka plików tak, by mia

ïy tÚ samÈ nazwÚ.

Q

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:

background image

Rozdzia

á 8. • WdraĪanie aplikacji

323

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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

324

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

background image

Rozdzia

á 8. • WdraĪanie aplikacji

325

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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

326

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
´serwisu waferthin.com." default="deploy">

<!-- Inicjalizuje datownik, który b

Ċdzie uĪywany przy nadawaniu nazw róĪnym plikom

´

i katalogom.

-->

<tstamp/>

<target name="deploy" depends="get-env,create-skeleton,svn-export,
´stamp-config,disp-maint,backup-db,deploy-db,publish-site"
´description="Wdraĝa serwis na serwer WWW i wykonuje niezbÚdne zadania
´konsolidacyjne i aktualizacyjne.">
</target>

<target name="get-env" description="Pobiera Ărodowisko, do jakiego ma
´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

´

Ğrodowisk. -->

<input propertyname="environment" validargs="dev,test,prod"
´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"
´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
´Ărodowiska (${environment}.properties)" />
</else>
</if>
</target>

background image

Rozdzia

á 8. • WdraĪanie aplikacji

327

<target name="deploy-dev" description="Wdraĝa serwis w Ărodowisku
´programowania.">
<property name="environment" value="dev" override="true" />
<phingcall target="deploy" />
</target>

<target name="deploy-prod" description="Wdraĝa serwis w Ărodowisku
´docelowym.">
<property name="environment" value="prod" override="true" />
<phingcall target="deploy" />
</target>

<target name="deploy-test" description="Wdraĝa serwis w Ărodowisku
´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.

background image

PHP 5. Narz

Ċdzia dla ekspertów

328

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Ú
´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
´lokalnego katalogu docelowego.">

<!-- Konstruuje poprawne URL dla Subversion -->
<property name="svn.url" value="${svn.proto}
´${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>

background image

Rozdzia

á 8. • WdraĪanie aplikacji

329

<then>
<!-- Prosi u

Īytkownika o podanie hasáa dostĊpu do Subversion. -->

<input propertyname="svn.password" promptChar=":">Podaj hasïo
´dla uĝytkownika ${svn.user}, aby pobraÊ projekt
´${svn.project} z repozytorium Subversion
´${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,

background image

PHP 5. Narz

Ċdzia dla ekspertów

330

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
´wïaĂciwoĂciami konfiguracyjnymi.">
<copy todir="${site.root}.${DSTAMP}${TSTAMP}/includes/classes">
<filterchain>
<expandproperties />
</filterchain>

background image

Rozdzia

á 8. • WdraĪanie aplikacji

331

<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
´lokalnego katalogu docelowego.">
<!-- Sprawdza, czy plik .htaccess ju

Ī istnieje. -->

<available file="${site.root}/htdocs/.htaccess"
´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>

background image

PHP 5. Narz

Ċdzia dla ekspertów

332

</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
´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
´uĝytkownika ${db.user} dla bazy ${db.name}</input>
</then>
</if>

<!-- Wykonuje zewn

Ċtrzne polecenie mysqldump, aby utworzyü kopiĊ zapasową bazy

´

danych.

-->

background image

Rozdzia

á 8. • WdraĪanie aplikacji

333

<exec command="${extern.mysqldump} --quick --password=${db.password} –
´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 specjalne pow

ïoki systemowej majÈ zostaÊ poprzedzone znakiem uciecz-

ki przed wykonaniem polecenia. Opis innych atrybutów obs

ïugiwanych przez zadanie

exec

mo

ĝna znaleěÊ w dokumentacji.

Pliki zrzutu bazy danych s

È po prostu plikami tekstowymi i jako takie doskonale nadajÈ siÚ do

kompresji, która pozwoli zaoszcz

ÚdziÊ miejsce na dysku. Na szczÚĂcie Phing udostÚpnia za-

danie kompresuj

Èce pliki za pomocÈ algorytmu ZIP. Podobnie jak wczeĂniejsze zadanie

copy

,

zadanie

zip

zawiera w sobie znacznik

fileset

okre

ĂlajÈcy, jakie pliki majÈ zostaÊ wïÈczone do

archiwum. W naszym przypadku kompresji poddajemy jeden plik.

Wreszcie po skompresowaniu pliku zrzutu bazy danych mo

ĝemy usunÈÊ oryginalny (nie-

skompresowany) plik, u

ĝywajÈc zadania

delete

. Co prawda zadanie

delete

obs

ïuguje kilka

innych atrybutów, ale tutaj u

ĝywamy jedynie atrybutu

file

wskazuj

Ècego plik przeznaczony

do usuni

Úcia.

Warto te

ĝ zwróciÊ uwagÚ, ĝe katalog, w którym przechowujemy kopie zapasowe, to jeden

z katalogów utworzonych wcze

Ăniej w celu

create-skeleton

.

background image

PHP 5. Narz

Ċdzia dla ekspertów

334

Migracje bazy danych

Po utworzeniu kopii zapasowej bazy danych mo

ĝemy zastosowaÊ wszelkie zmiany do jej

schematu i zawarto

Ăci. W tym celu Phing udostÚpnia bardzo przydatne zadanie

dbdeploy

. Po-

zwala ono utworzy

Ê pliki zawierajÈce zmiany w bazie danych. W plikach tych wstawia siÚ kod

SQL potrzebny do zaktualizowania bazy oraz kod SQL potrzebny, by wycofa

Ê wprowadzone

zmiany. Te dwie sekwencje kodu SQL s

È oddzielone sekwencjÈ

-- //@UNDO

.

Nazwa pliku powinna opisywa

Ê jego dziaïanie. Musi takĝe zaczynaÊ siÚ od liczby, która wska-

zuje na kolejno

ĂÊ, w jakiej poszczególne pliki migracji majÈ byÊ przetwarzane. Pliki o niĝszym

numerze s

È wykonywane wczeĂniej.

Aby „pami

ÚtaÊ”, która migracja zostaïa zastosowana, narzÚdzie

dbdeploy

wymaga w

ïasnego

mechanizmu

Ăledzenia:

CREATE TABLE `changelog` (
`change_number` bigint(20) NOT NULL,
`delta_set` varchar(10) NOT NULL,
`start_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
´CURRENT_TIMESTAMP,
`complete_dt` timestamp NULL DEFAULT NULL,
`applied_by` varchar(100) NOT NULL,
`description` varchar(500) NOT NULL,
PRIMARY KEY (`change_number`,`delta_set`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Aby wygenerowa

Ê tabelÚ

users

, utworzy

ïem plik db/deltas/1-create-users.sql o nastÚpujÈcej

zawarto

Ăci:

CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`login` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`email` varchar(100) DEFAULT ‘',
`active` tinyint(1) NOT NULL DEFAULT ‘1',
`date_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
´CURRENT_TIMESTAMP,
`date_added` timestamp NOT NULL DEFAULT ‘0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `unique_login` (`login`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-- //@UNDO

DROP TABLE IF EXISTS `users`;

Instrukcja

CREATE TABLE

reprezentuje aktualizacj

Ú, a

DROP TABLE

wycofanie tej aktualizacji —

tworzy to dwukierunkow

È ĂcieĝkÚ migracyjnÈ.

background image

Rozdzia

á 8. • WdraĪanie aplikacji

335

Zadanie

dbdeploy

nie wykonuje zapytania SQL, tylko je tworzy. To dlatego potrzebne jest za-

danie

exec

, które wykona wygenerowane zapytanie aktualizuj

Èce za poĂrednictwem klienta

tekstowego MySQL. Oto kod celu aktualizuj

Ècego bazÚ danych:

<target name="deploy-db" description="Uruchamia migracje SQL aktualizujÈce
´schemat i zawartoĂÊ bazy danych.">
<!--

àaduje zadanie dbdeploy. -->

<taskdef name="dbdeploy"
´classname="phing.tasks.ext.dbdeploy.DbDeployTask"/>

<!-- Generuje SQL aktualizuj

ący bazĊ danych do najnowszej migracji. -->

<dbdeploy url="mysql:host=${db.fqdn};dbname=${db.name}"
userid="${db.user}"
password="${db.password}"
dir="${site.root}.${DSTAMP}${TSTAMP}/db/deltas"
outputfile="${site.home}/build/db-upgrade-${DSTAMP}${TSTAMP}.sql"
undooutputfile="${site.home}/build/
´db-downgrade-${DSTAMP}${TSTAMP}.sql" />

<!-- Wykonuje kod SQL za pomoc

ą tekstowego klienta mysql. -->

<exec
command="${extern.mysql} -h${db.fqdn} -u${db.user} -p${db.password}
´${db.name} &lt; ${site.home}/build/db-upgrade-
´${DSTAMP}${TSTAMP}.sql"
dir="${site.home}/build"
checkreturn="true" />
</target>
...

Udost

Úpnianie serwisu

To ju

ĝ prawie koniec. WymeldowaliĂmy i zmodyfikowaliĂmy serwis, utworzyliĂmy kopiÚ zapa-

sow

È bazy i dokonaliĂmy jej aktualizacji. Pozostaïo teraz „przeïÈczyÊ” siÚ ze starej wersji ser-

wisu na nowo utworzon

È. Tym zajmuje siÚ cel

publish-site

:

<target name="publish-site" description="Aktywuje nowÈ wersjÚ serwisu
´i restartuje serwer Apache, aby uaktywniÊ wszystkie zmiany.">
<!-- Dowi

ązanie symboliczne do zewnĊtrznej biblioteki. -->

<exec command="${extern.ln} -s ${zend_dir}"
dir="${site.root}.${DSTAMP}${TSTAMP}/includes/libraries"
escape="false" />
<!-- Usuwa dowi

ązanie symboliczne do aktywnej kopii serwisu. -->

<delete file="${site.root}" />
<!-- Dowi

ązanie symboliczne do najnowszej wersji serwisu. -->

<exec command="${extern.ln} -s ${site.fqdn}.${DSTAMP}${TSTAMP}
´${site.fqdn}"
dir="${site.home}"
escape="false" />

background image

PHP 5. Narz

Ċdzia dla ekspertów

336

<!-- Przeprowadza p

áynny restart serwera Apache, aby uwzglĊdniü wszystkie zmiany.

´

Nowa wersja serwisu staje si

Ċ dostĊpna!!! -->

<exec command="${extern.sudo} ${extern.apachectl} graceful"
´escape="false" />
</target>

Na pocz

Ètku, ponownie za pomocÈ zadania

exec

, tworzymy dowi

Èzanie symboliczne do kopii

szkieletu Zend, która jest wymagana, by serwis móg

ï dziaïaÊ. Potem zadaniem

delete

usu-

wamy dowi

Èzanie symboliczne, które wskazuje na poprzedniÈ wersjÚ serwisu. NastÚpnie,

znowu zadaniem

exec

, tworzymy nowe dowi

Èzanie symboliczne do wersji serwisu, która wïa-

Ănie zostaïa wymeldowana z Subversion i przygotowana do wdroĝenia.

W ostatnim kroku nakazujemy serwerowi Apache prze

ïadowanie plików konfiguracyjnych,

aby upewni

Ê siÚ, ĝe wszystkie zmiany zostanÈ od razu zastosowane. Poniewaĝ serwer Apache

nie dzia

ïa w przypadku mojego uĝytkownika, muszÚ zastosowaÊ polecenie

sudo

, które spowo-

duje wy

Ăwietlenie proĂby o podanie hasïa administratora w celu wykonania tej czynnoĂci.

Ostateczna wersja pliku konsolidacyjnego

Skoro skonstruowali

Ămy poszczególne cele, moĝemy je poïÈczyÊ w finalnÈ wersjÚ pliku build.xml.

Kompletny listing mo

ĝna zobaczyÊ w doïÈczonych do ksiÈĝki przykïadach kodów z tego rozdziaïu.

Po uruchomieniu tego pliku w

Ărodowisku programowania z wiersza poleceñ otrzymujÚ na-

st

ÚpujÈcy rezultat, który rozbiïem na dwa zrzuty, aby wszystko pomieĂciÊ.

background image

Czytaj dalej...

Rozdzia

á 8. • WdraĪanie aplikacji

337

Ca

ïkiem niezïy wynik. W nieco ponad dziewiÚÊ sekund udaïo mi siÚ wymeldowaÊ projekt

z Subversion, utworzy

Ê kilka plików z szablonów, wstawiÊ stronÚ z informacjÈ o niedostÚpnoĂci

serwisu, utworzy

Ê kopiÚ zapasowÈ bazy i zaktualizowaÊ bazÚ, utworzyÊ róĝne dowiÈzania symbo-

liczne i katalogi, po czym zrestartowa

Ê serwer WWW. Wliczam w to czas poĂwiÚcony na wpi-

sanie has

ïa administratora przed restartem serwera.

Spójrzmy teraz na zmienion

È strukturÚ katalogów serwisu. Moĝemy cofnÈÊ siÚ o parÚ stron i po-

równa

Ê go do stanu sprzed zmiany jego struktury w celu uïatwienia aktualizacji.

Aby dowie

ĂÊ, jak ïatwo moĝemy teraz wdraĝaÊ serwis, doïÈczyïem w listingu skrypty aktualizujÈce

baz

Ú danych i cofajÈce jej aktualizacjÚ (db-upgrade.xxxx.sql i db-upgrade.xxxx.sql), a takĝe gïówne

katalogi wcze

Ăniej wdroĝonych aplikacji, które zostaïy teraz zarchiwizowane (dev.waferthin.

com.xxxx). Niestety, listing jest tak d

ïugi, ĝe muszÚ podzieliÊ go na dwa zrzuty ekranowe (rysunki

na nast

Úpnej stronie).


Wyszukiwarka

Podobne podstrony:
PHP 5 Narzedzia dla ekspertow php5ne
PHP 5 Narzedzia dla ekspertow php5ne
PHP 5 Narzedzia dla ekspertow php5ne
PHP 5 Narzedzia dla ekspertow 2
PHP 5 Narzedzia dla ekspertow
informatyka postgresql receptury dla administratora simon riggs ebook
informatyka php receptury wydanie ii adam trachtenberg ebook(1)
informatyka word i excel dla seniorow magdalena gunia ebook
informatyka analiza techniczna dla bystrzakow barbara rockefeller ebook
informatyka php obiekty wzorce narzedzia wydanie iii matt zandstra ebook
informatyka wzorzec mvc w php dla profesjonalistow chris pitt ebook
TRIKI do Systemu, Windows+Informatyka, WXP dla Ekspertow
informatyka programowanie aplikacji dla urzadzen mobilnych z systemem windows mobile jacek matulewsk
informatyka php i jquery receptury vijay joshi ebook
informatyka budowa robotow dla srednio zaawansowanych wydanie ii david cook ebook
informatyka excel 2010 pl rozwiazywanie problemow dla kazdego witold wrotek ebook
informatyka php nuke tworzenie witryn www douglas paterson ebook
informatyka komputer pc podstawy obslugi dla seniorow lukasz suma ebook
informatyka php i html tworzenie dynamicznych stron www jacek ross ebook

więcej podobnych podstron