background image

Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63

e-mail: helion@helion.pl

PEAR.
Programowanie w PHP

Przewodnik po najbardziej przydatnych pakietach PEAR

• Poznaj najpopularniejsze pakiety repozytorium PEAR
• Korzystaj z baz danych za pomoc¹ MDB2
• U¿ywaj gotowych komponentów do szybkiego tworzenia aplikacji w PHP

Jednym z g³ównych powodów popularnoœci PHP jest szeroki dostêp do bibliotek
i rozszerzeñ tego jêzyka. Najwa¿niejszym ich Ÿród³em jest PEAR — internetowe 
repozytorium komponentów i aplikacji jêzyka PHP. Pakiety dostêpne w PEAR zawieraj¹ 
gotowe rozszerzenia umo¿liwiaj¹ce wykonanie niemal wszystkich standardowych 
operacji w PHP. Rozszerzenia te przechodz¹ przez œcis³y system kontroli jakoœci,
a ich autorzy musz¹ stosowaæ siê do okreœlonych zaleceñ. Dlatego pisanie programów
z wykorzystaniem pakietów jest nie tylko szybsze, ale prowadzi te¿ do powstawania 
lepszych i bardziej spójnych aplikacji.

Dziêki ksi¹¿ce „PEAR. Programowanie w PHP” nauczysz siê wykonywaæ codzienne 
zadania programistyczne przy u¿yciu klas z popularnych pakietów PEAR. Dowiesz siê, 
jak obs³ugiwaæ bazy danych za pomoc¹ pakietu MDB2, a tak¿e jak wyœwietlaæ dane 
zapisane w ró¿nych formatach. Poznasz sposoby tworzenia i analizowania dokumentów 
XML oraz przekszta³cania obiektów PHP na format XML i z powrotem. Zobaczysz,
jak tworzyæ w³asne us³ugi WWW oraz u¿ywaæ interfejsów udostêpnianych w us³ugach 
autorstwa innych producentów.

• Praca z bazami danych
• Wyœwietlanie informacji w ró¿nych formatach
• Tworzenie i przetwarzanie plików XML
• Przygotowywanie i udostêpnianie us³ug WWW
• Korzystanie z gotowych us³ug WWW
• Praca z datami

Zwiêksz swoj¹ produktywnoœæ, korzystaj¹c z gotowych komponentów

Autorzy: Stephan Schmidt, Stoyan Stefanov,
Carsten Lucke, Aaron Wormus
T³umaczenie: S³awomir Dzieniszewski
ISBN: 978-83-246-0897-3
Tytu³ orygina³u: 

PHP Programming with PEAR

Format: B5, stron: 304

background image

Spis tre

Ăci

O autorach

7

Przedmowa

11

Rozdzia

ï 1. MDB2

15

Krótka historia MDB2

16

Warstwy abstrakcji

16

Warstwa abstrakcji dla interfejsu bazy danych

16

Warstwa abstrakcji dla kodu SQL

17

Warstwa abstrakcji dla typów danych

17

Uwarunkowania zwi

Èzane z prÚdkoĂciÈ

17

Konstrukcja pakietu MDB2

18

Zaczynamy prac

Ú z MDB2

19

Instalowanie MDB2

19

’Èczenie siÚ z bazÈ danych

20

Tworzenie instancji obiektu MDB2

21

Opcje

21

Definiowanie trybu pobierania danych

23

RozïÈczanie siÚ z bazÈ danych

23

Korzystanie z MDB2

24

Przykïad

24

Wykonywanie zapytañ

25

Pobieranie danych

25

Skróty uïatwiajÈce pobieranie danych

26

Skróty metod query*()

26

Skróty metod get*()

27

Typy danych

29

Ujmowanie wartoĂci i identyfikatorów w cudzysïowy

31

Iteratory

32

Wyszukiwanie bïÚdów

33

background image

 

PEAR. Programowanie w PHP

 

4

Warstwa abstrakcji kodu SQL w MDB2

34

Sekwencje

34

OkreĂlanie limitów zapytañ

35

ZastÚpowanie zapytañ

36

Obsïuga subselektów

36

Instrukcje preparowane

37

Transakcje

41

Modu

ïy MDB2

42

Moduï Manager

43

Moduï Function

46

Moduï Reverse

47

W

ïasne rozszerzenia pakietu MDB2

49

Wïasny mechanizm rejestracji w dzienniku

49

Wïasne klasy pobierajÈce dane

51

Wïasne klasy wyników

52

Wïasne iteratory

55

Wïasne moduïy

56

Pakiet MDB2_Schema

57

Instalowanie i tworzenie instancji

57

Tworzenie kopii bazy danych

58

Zmienianie bazy danych

61

Podsumowanie

61

Rozdzia

ï 2. WyĂwietlanie danych

63

Tabele HTML

64

Format tabel HTML

64

Tworzenie prostego kalendarza za pomocÈ HTML_Table

65

Pakiet HTML_Table_Matrix rozszerzajÈcy moĝliwoĂci pakietu HTML_Table

69

Arkusze kalkulacyjne Excela

71

Format Excela

71

Nasz pierwszy arkusz kalkulacyjny

72

Sïowo o komórkach

73

Przygotowywanie strony do wyĂwietlenia

74

Dodawanie formatowania

74

Kolory

75

Wypeïnianie barwnym deseniem

77

Formatowanie liczb

77

Formuïy

79

Wiele arkuszy kalkulacyjnych, obramowania, obrazki

80

Inne techniki tworzenia arkuszy kalkulacyjnych

83

Komponent siatki danych DataGrid

84

½ródïa danych DataSource

85

Renderery

85

Prosta siatka danych DataGrid

86

Stronicowanie wyników

87

Korzystanie ze ěródïa danych DataSource

87

Korzystanie z renderera

88

background image

 

Spis tre

Ğci

 

5

Estetyczne formatowanie siatki danych

89

Poszerzanie moĝliwoĂci DataGrid

90

Dodawanie kolumn

91

Generowanie plików PDF

92

Kolory

95

Czcionki

96

Komórki

96

Tworzenie nagïówków i stopek

97

Podsumowanie

98

Rozdzia

ï 3. Praca z formatem XML

99

Pakiety PEAR wspomagaj

Èce pracÚ z XML

100

Tworzenie dokumentów XML

101

Tworzenie obiektów przechowujÈcych informacje o nagraniach

102

Tworzenie dokumentów XML za pomocÈ klasy XML_Util

106

Tworzenie dokumentów XML za pomocÈ pakietu XML_FastCreate

110

Tworzenie dokumentów XML za pomocÈ pakietu XML_Serializer

118

Tworzenie aplikacji Mozilli za pomocÈ pakietu XML_XUL

133

Przetwarzanie dokumentów XML

142

Analizowanie danych XML za pomocÈ pakietu XML_Parser

143

Przetwarzanie kodu XML za pomocÈ pakietu XML_Unserializer

155

Analizowanie danych RSS za pomocÈ pakietu XML_RSS

169

Podsumowanie

173

Rozdzia

ï 4. Usïugi WWW

175

Korzystanie z us

ïug WWW

176

Korzystanie z usïug WWW opartych na XML-RPC

177

SiÚganie do interfejsu API Google

182

Korzystanie z usïug WWW opartych na REST

185

Tworzenie wïasnych usïug WWW opartych na REST

199

Oferowanie us

ïug WWW

208

Oferowanie usïug WWW opartych na protokole XML-RPC

208

Oferowanie usïug WWW opartych na protokole SOAP

216

Oferowanie usïug opartych na protokole REST za pomocÈ pakietu XML_Serializer

223

Podsumowanie

232

Rozdzia

ï 5. Praca z datami

235

Praca z pakietem Date

235

Pakiet Date

236

Obsïuga stref czasowych za pomocÈ klasy Date_Timezone

246

Pakiet PEAR::Date — podsumowanie

250

Pakiet Date_Holidays

250

Wyliczanie ĂwiÈt

254

Czy dziĂ mamy ĂwiÚto?

258

Tïumaczenie nazw ĂwiÈt na inne jÚzyki

259

Pakiet Date_Holidays — podsumowanie

264

background image

 

PEAR. Programowanie w PHP

 

6

Praca z pakietem Calendar

264

Podstawowe klasy i pojÚcia zwiÈzane z pakietem Calendar

265

Tworzenie obiektów

268

Sprawdzanie poprawnoĂci obiektów kalendarza

272

Modyfikowanie dziaïania standardowych klas

274

Generowanie danych w formie graficznej

275

Podsumowanie

282

Skorowidz 

283

background image

1

MDB2

W ci

Ègu ostatnich dziesiÚciu lat sieÊ WWW bardzo siÚ rozrosïa, jak równieĝ dojrzaïa i sprofesjo-

nalizowa

ïa, w zwiÈzku z czym pojawiïo siÚ zapotrzebowanie na coraz bardziej zïoĝone i dy-

namiczne witryny WWW. Dawniej zupe

ïnie wystarczaïo przechowywanie informacji w pliku

tekstowym lub prostej bazie danych, obecnie jednak ka

ĝdy programista piszÈcy profesjonalnÈ

aplikacj

Ú WWW musi posiadaÊ rzetelnÈ wiedzÚ na temat tego, jak komunikowaÊ siÚ z profe-

sjonalnymi relacyjnymi bazami danych.

Pocz

Èwszy  od  najwczeĂniejszych  wersji  jÚzyk  PHP  zawsze  sïuĝyï  programistom  solidnym

wsparciem  w  kontaktach  z  bazami  danych.  Niemniej  do  czasu  wprowadzenia  rozszerzenia
PDO (PHP Data Objects, obiekty danych PHP) nie istnia

ï ĝaden standardowy sposób korzy-

stania z najró

ĝniejszych sterowników baz danych dodawanych do jÚzyka PHP. Brak ujednoli-

conego  interfejsu  API  by

ï oczywiĂcie inspiracjÈ dla kilku projektów majÈcych na celu stwo-

rzenie  jakiej

Ă  warstwy  DBAL  (Database  Abstraction  Layer),  która  oferowaïaby  uniwersalny

poziom  abstrakcji  dla  wszystkich  baz  danych.  G

ïównym  celem  tych  wysiïków  byï  zamiar

u

ïatwienia ĝycia programistom, tak aby mogli oni pisaÊ kod komunikujÈcy siÚ z bazÈ danych,

który  b

Údzie  niezaleĝny  od  sytemu  bazy  danych  wykorzystywanego  przez  aplikacjÚ.  DziÚki

temu klienci lub u

ĝytkownicy mogliby uĝywaÊ aplikacji w poïÈczeniu z tym systemem zarzÈ-

dzania bazami danych, który im najbardziej odpowiada.

Trzy najwa

ĝniejsze z rozpoczÚtych w tamtych latach prób stworzenia warstwy abstrakcji dla

baz danych to: AdoDB, PEAR::DB i Metabase. W ostatnich latach kolejnym bardzo mocnym
kandydatem na uniwersaln

È warstwÚ abstrakcji dla baz danych byï pakiet PEAR::MDB. Ni-

niejszy rozdzia

ï poĂwiÚcony bÚdzie kolejnej inkarnacji MDB, a mianowicie MDB2.

background image

PEAR. Programowanie w PHP

16

Krótka historia MDB2

Wszystko zacz

Úïo siÚ, kiedy Lukas Smith, programista PEAR, opublikowaï kilka ïat do istnie-

j

Ècej juĝ warstwy abstrakcji bazy danych, Metabase. W którymĂ momencie miÚdzy Lukasem

a autorem Metabase wywi

Èzaïa siÚ dyskusja na temat, jakby opublikowaÊ Metabase w repo-

zytorium PEAR jako nowy pakiet. Celem nowego pakietu by

ïoby poïÈczenia funkcjonalnoĂci

oferowanych przez Metabase z interfejsem API istniej

Ècego juĝ i bardzo popularnego pakietu

PEAR::DB. Dzi

Úki temu programiĂci otrzymaliby bogatÈ w funkcje i znakomicie spisujÈcÈ siÚ

bibliotek

Ú abstrakcji bazy danych, co byïoby z wielkÈ korzyĂciÈ dla infrastruktury PEAR. W taki

w

ïaĂnie sposób narodziï siÚ przodek pakietu MDB2, czyli pakiet PEAR::MDB.

Po kilku latach pracy nad pakietem PEAR::MDB, dla autorów sta

ïo siÚ oczywiste, ĝe decyzja

utrzymywania interfejsu API pakietu w takiej formie, aby by

ï jak najbardziej zbliĝony do in-

terfejsów  API  Metabase  i  PEAR::DB,  nieuchronnie  stwarza  pewne  problemy,  które  utrud-
niaj

È  przeksztaïcenie  MDB  w  peïni  profesjonalnÈ  warstwÚ  abstrakcji  bazy  danych  (DBAL).

Poniewa

ĝ pakiet PEAR::MDB osiÈgnÈï juĝ w repozytorium PEAR stabilnÈ formÚ w peïni doj-

rza

ïego  pakietu  oprogramowania,  niemoĝliwe  byïo  usuniÚcie  pewnych  wad  bez  rezygnacji

z kompatybilno

Ăci z tym starszym moduïem, czego wïaĂnie autorzy starali siÚ za wszelkÈ cenÚ

unikn

ÈÊ. RozwiÈzaniem byïo wykorzystanie doĂwiadczeñ zdobytych podczas prac nad Meta-

base i MDB oraz zastosowanie ich w nowym pakiecie, który zawiera

Ê bÚdzie profesjonalnie

zaprojektowany i w pe

ïni nowoczesny interfejs API. Nowy pakiet otrzymaï nazwÚ MDB2.

Warstwy abstrakcji

Zanim przejdziemy do szczegó

ïowego omawiania, w jaki sposób pakiet MDB2 radzi sobie z two-

rzeniem abstrakcji dla bazy danych, powinni

Ămy najpierw zapoznaÊ siÚ przynajmniej pobieĝ-

nie  z  teori

È tworzenia warstw abstrakcji obudowujÈcych systemy baz danych, by zrozumieÊ

dok

ïadnie, w jaki sposób siÚ to robi. Na tworzenie warstw abstrakcji dla baz danych moĝna

spojrze

Ê z kilku perspektyw. Omówimy je teraz dokïadniej po kolei i opowiemy, jakie majÈ

wymagania.

Warstwa abstrakcji dla interfejsu bazy danych

Najwa

ĝniejszym etapem w tworzeniu abstrakcji systemu bazy danych jest przygotowanie od-

powiedniej abstrakcji dla interfejsu bazy danych. Dzi

Úki temu programista bÚdzie mógï siÚgaÊ do

baz danych zarz

Èdzanych przez róĝne systemy, uĝywajÈc tych samych metod. Oznacza to, ĝe

zarówno  tworzenie  po

ïÈczenia z bazÈ  danych,  wysyïanie  zapytania,  jak  i  pobieranie  danych

zawsze  przebiega

Ê  bÚdzie  identycznie,  niezaleĝnie  od  tego,  z  jakÈ  bazÈ  danych  bÚdziemy

wspó

ïpracowaÊ.

background image

Rozdzia

á 1. • MDB2

17

Warstwa abstrakcji dla kodu SQL

Wi

ÚkszoĂÊ  obecnie  uĝywanych  systemów  baz  danych  korzysta  ze  standardowego  zestawu

podstawowych instrukcji SQL, dlatego te

ĝ wiÚkszoĂÊ kodu SQL pisanego przez programistów

powinna dzia

ïaÊ zawsze, niezaleĝnie od tego, z jakiej bazy danych bÚdÈ korzystaÊ. Niemniej

wiele  z  systemów  baz  danych  wprowadza  w

ïasne, specyficzne tylko dla danego systemu in-

strukcje SQL i pomocnicze funkcje, dlatego te

ĝ moĝe siÚ zdarzyÊ, ĝe kod SQL napisany spe-

cjalnie dla jednej bazy danych nie b

Údzie dziaïaï w innej. W miarÚ jak system zarzÈdzania ba-

z

È  danych  (ang.  Relational  Database  Management  System  —  RDBMS)  rozwija  siÚ,  czasami

implementuje funkcje, które nie s

È kompatybilne ze starszymi wersjami tej samej bazy danych.

Dlatego te

ĝ dla programisty pragnÈcego napisaÊ kod, który byïby zgodny ze wszystkimi wer-

sjami bazy danych (lub który móg

ïby wspóïdziaïaÊ z kilkoma róĝnymi systemami baz danych),

jedynym  rozwi

Èzaniem  jest  ograniczenie  siÚ  tylko  do  tych  instrukcji  kodu  SQL,  o  których

wiadomo, 

ĝe na pewno bÚdÈ dziaïaÊ na wszystkich platformach baz danych. LepszÈ opcjÈ jest

jednak skorzystanie ze specjalnej warstwy abstrakcji baz danych, która w razie potrzeby emuluje
odpowiednie funkcje, je

Ăli nie bÚdÈ dostÚpne na danej platformie.

Mimo i

ĝ nie jest wykonalne obudowanie kaĝdej moĝliwej funkcji SQL, pakiet MDB2 obsïu-

guje bardzo wiele powszechnie wykorzystywanych funkcji SQL. Funkcje te to mi

Údzy innymi

obs

ïuga  zapytañ  LIMIT,  subselektów  (podzapytañ  select)  i  zapytañ  preparowanych.  Korzy-

stanie z mechanizmu abstrakcji kodu SQL, oferowanego przez MDB2, daje nam gwarancj

Ú,

ĝe bÚdziemy mogli korzystaÊ z tych zaawansowanych funkcji — nawet wtedy, gdy baza da-
nych, z której korzystamy, samoistnie ich nie obs

ïuguje. W dalszej czÚĂci tego rozdziaïu opo-

wiemy o ró

ĝnych funkcjach oferujÈcych abstrakcjÚ dla zaawansowanych narzÚdzi SQL, które

zapewnia pakiet MDB2.

Warstwa abstrakcji dla typów danych

Na  koniec  wreszcie  konieczne  jest  przygotowanie  abstrakcji  dla  typów  danych  stosowanych
przez bazy. Wynika to z faktu, 

ĝe róĝne systemy baz danych czÚsto obsïugujÈ typy danych w zu-

pe

ïnie inny sposób.

Uwarunkowania zwi

Èzane z prÚdkoĂciÈ

Zapewne  czytelnikom  cieknie  ju

ĝ  Ălinka,  by  skosztowaÊ  tych  wspaniaïych  funkcji  wkompo-

nowanych w pakiet MDB2, niemniej najpierw nale

ĝy powiedzieÊ kilka sïów o zagadnieniach

zwi

Èzanych z prÚdkoĂciÈ i wydajnoĂciÈ. Warto wiedzieÊ, ĝe  gdy  korzystamy  z  warstwy  abs-

trakcji  bazy  danych,  cz

Ústo  za  bogactwo  funkcji  oferowanych  przez  pakiet  dokonujÈcy  abs-

trakcji musimy zap

ïaciÊ mniejszÈ wydajnoĂciÈ i szybkoĂciÈ dziaïania bazy danych. Nie jest to

background image

PEAR. Programowanie w PHP

18

tylko u

ïomnoĂÊ pakietu MDB2 ani teĝ warstw abstrakcji bazy danych, ale w ogóle wszelkiego

rodzaju warstw abstrakcji i systemów wirtualizacji.

Na  szcz

ÚĂcie,  inaczej  niĝ  w  przypadku  VMWare  lub  Miscrosoft  Virtual  PC,  które  dokonujÈ

abstrakcji ka

ĝdego wykonywanego wywoïania systemowego, pakiet MDB2 oferuje abstrakcjÚ

tylko wtedy, gdy dana funkcja nie jest dost

Úpna w okreĂlonym systemie baz danych. Oznacza

to, 

ĝe wydajnoĂÊ zaleĝeÊ bÚdzie od platformy, na której skorzystamy z MDB2. JeĂli szczegól-

nie zale

ĝy nam na szybkoĂci i wydajnoĂci, to naleĝy skorzystaÊ z pamiÚci podrÚcznej dla ko-

dów operacji (ang. opcode cache) lub w

ïÈczyÊ mechanizm przechowywania zapytañ w pamiÚci

podr

Úcznej w systemie baz danych, którego uĝywamy. DziÚki wykorzystaniu wspomnianych

mo

ĝliwoĂci jÚzyka PHP lub systemu baz danych bÚdziemy mogli w znacznym stopniu ograni-

czy

Ê negatywne efekty spowolnienia dziaïania bazy danych, nieodïÈcznie zwiÈzane z uĝyciem

warstwy abstrakcji.

Konstrukcja pakietu MDB2

Interfejs  API  pakietu  MDB2  zosta

ï zaprojektowany w taki sposób, aby gwarantowaÊ maksi-

mum wszechstronno

Ăci i elastycznoĂci. Poszczególnym obsïugiwanym systemom baz danych

i okre

Ălonym zaawansowanym funkcjom przypisano okreĂlone moduïy. Kaĝdy z licznych ste-

rowników

 (ang. drivers) dla baz danych jest osobnym i niezale

ĝnie rozwijanym moduïem PE-

AR. Oznacza to, 

ĝe kaĝdy pakiet sterownika funkcjonuje niezaleĝnie, a kolejne wersje i wersje

stabilne publikowane s

È we wïasnych, niezaleĝnych od innych sterowników cyklach. DziÚki

temu programi

Ăci odpowiedzialni za przygotowywanie poszczególnych sterowników mogÈ je

wypuszcza

Ê, ilekroÊ zachodzi taka potrzeba, bez koniecznoĂci czekania na publikacjÚ kolejnej

wersji g

ïównego pakietu MDB2. Pakiet MDB2 moĝe zatem zachowywaÊ stabilnoĂÊ, niezaleĝ-

nie od stanu prac nad pakietami obs

ïugujÈcymi poszczególne sterowniki. W efekcie zdarza siÚ

czasem, 

ĝe  stabilna  wersja  pakietu  oferuje  sterowniki  dla  niektórych  systemów  baz  danych

jedynie  w  wersji  beta.  Ponadto  w  chwili  wypuszczenia  nowego  sterownika  dla  bazy  danych
oznaczany jest on jako wersja alfa i pakiet podlega procedurze sprawdzania zgodnie ze stan-
dardami repozytorium PEAR.

Drugi rodzaj modu

ïów wbudowanych w pakiet MDB2 to moduïy dodajÈce specjalne, rozszerzone

funkcje oferowane przez pakiet MDB2. Zamiast do

ïÈczaÊ te funkcje do gïównego pakietu MDB2

lub  dodawa

Ê  do  niego  nowÈ  klasÚ  implementujÈcÈ  te  funkcje,  programista  ma  moĝliwoĂÊ

utworzenia nowej klasy w osobnym module i nast

Úpnie zaïadowanie jej do pakietu MDB2 za

pomoc

È metody 

loadModule()

. Gdy ju

ĝ nowy moduï zostanie zaïadowany do pakietu MDB2,

do jego metod b

Údzie moĝna siÚgaÊ w taki sam sposób, jakby byïy metodami wbudowanymi

w pakiet MDB2. Pakiet MDB2 stosuje to rozwi

Èzanie, aby jego wewnÚtrzne pakiety dziaïaïy

tak szybko, jak to tylko mo

ĝliwe, a jednoczeĂnie by pozostawiÊ uĝytkownikom swobodÚ doïÈ-

czania do pakietu MDB2 swoich w

ïasnych klas. Szczegóïowe informacje o tym, jak we wïasnym

zakresie rozwija

Ê pakiet MDB2, moĝna znaleěÊ w dalszej czÚĂci tego rozdziaïu.

background image

Rozdzia

á 1. • MDB2

19

Zaczynamy prac

Ú z MDB2

Poni

ĝej omówimy podstawowe kroki, które trzeba wykonaÊ, by zainstalowaÊ  pakiet  MDB2,

utworzy

Ê obiekt MDB2 oraz skonfigurowaÊ kilka opcji definiujÈcych tryb pobierania danych.

Na koniec powiemy, jak roz

ïÈczaÊ siÚ z bazÈ danych.

Instalowanie MDB2

Podczas  instalowania  pakietu  MDB2  nale

ĝy pamiÚtaÊ, ĝe nie zawiera on ĝadnych sterowni-

ków  baz  danych,  dlatego  trzeba  je  b

Údzie  zainstalowaÊ  póěniej  osobno.  Pakiet  MDB2  jest

rozprowadzany w wersji stabilnej, niemniej, jak ju

ĝ wspomnieliĂmy, niektóre z wchodzÈcych

w jego sk

ïad moduïów sterowników i rozszerzeñ mogÈ byÊ rozwijane w niezaleĝnych cyklach,

dlatego  niektóre  z  wykorzystywanych  przez  nas  modu

ïów mogÈ byÊ dopiero w wersji beta,

alfa lub nawet jeszcze w fazie programowania. Nale

ĝy o tym pamiÚtaÊ podczas instalowania

pakietów zawieraj

Ècych sterowniki poszczególnych baz danych.

Najpro

Ăciej jest zainstalowaÊ MDB2 korzystajÈc z programu instalacyjnego repozytorium PEAR:

> pear install MDB2

To polecenie zainstaluje klasy tworz

Èce rdzeñ MDB2, natomiast nie zainstaluje ĝadnego z do-

st

Úpnych sterowników baz danych. Aby zainstalowaÊ sterownik wïaĂciwy dla systemu baz da-

nych, którego u

ĝywamy, naleĝy skorzystaÊ z polecenia:

> pear install MDB2_Driver_mysql

To  akurat  polecenie  zainstaluje  sterownik  dla  bazy  MySQL.  Aby  zainstalowa

Ê sterownik dla

bazy SQLite, nale

ĝy wpisaÊ:

> pear install MDB2_Driver_sqlite

Oto pe

ïna lista dostÚpnych aktualnie sterowników:

■ 

fbsql

 — Front Base

■ 

ibase

 — InterBase

■ 

mssql

 — MS SQL Server

■ 

mysql

 — MySQL

■ 

mysqli 

— system MySQL korzystaj

Ècy z rozszerzenia mysqli PHP; wiÚcej

informacji pod adresem: http://php.net/mysqli

■ 

oci8

 — Oracle

■ 

pgsql

 — PostgreSQL

■ 

querysim

 — Querysim

■ 

sqlite

 — SQLite

background image

PEAR. Programowanie w PHP

20

’Èczenie siÚ z bazÈ danych

Aby po

ïÈczyÊ siÚ z wybranÈ bazÈ danych juĝ po udanym zainstalowaniu pakietu MDB2 i mo-

du

ïu sterownika, konieczne bÚdzie najpierw okreĂlenie nazwy ěródïa danych, DSN (Data Source

Name). Nazwa DSN mo

ĝe mieÊ postaÊ ïañcucha lub tablicy i definiuje parametry poïÈczenia

z baz

È danych takie jak: nazwa bazy danych, typ systemu RDBMS (systemu zarzÈdzajÈcego rela-

cyjn

È bazÈ danych), nazwa uĝytkownika i hasïo wykorzystywane do ïÈczenia siÚ z bazÈ danych itp.

Nazwa DSN jako tablica

Je

Ăli nazwa ěródïa danych, DSN, jest definiowana w formie tablicy, bÚdzie wyglÈdaÊ mniej

wi

Úcej tak:

$dsn = array ( 'phptype' => 'mysql',
               'hostspec' => 'localhost:3306',
               'username' => 'user',
               'password' => 'pass',
               'database' => 'mdb2test'
              );

Oto lista ró

ĝnych kluczy parametrów uĝywanych w tablicy nazwy DSN:

■ 

phptype

 — nazwa wykorzystywanego sterownika; innymi s

ïowy: nazwa definiujÈca

system RDBMS

■ 

hostspec

 — (specyfikacja hosta) okre

Ăla nazwÚ hosta, na którym dziaïa baza danych;

mo

ĝe przyjmowaÊ postaÊ 

host:port

 lub te

ĝ podawaÊ tylko samÈ nazwÚ hosta, a port

b

Údzie wtedy definiowany osobno w kluczu 

port

■ 

database

 — nazwa bazy danych, z któr

È siÚ ïÈczymy

■ 

dbsyntax

 — je

Ăli uĝywana skïadnia jest inna niĝ wïaĂciwa dla systemu 

phptype

■ 

protocol

 — wykorzystywany protokó

ï komunikacyjny, na przykïad TCP

■ 

socket

 — gniazdo, które nale

ĝy okreĂliÊ, jeĂli ïÈczymy siÚ za poĂrednictwem gniazd

■ 

mode

 — s

ïuĝy do definiowania trybu otwierania pliku bazy danych

Nazwa DSN jako 

ïañcuch

Szybszym i bardziej przyjaznym dla cz

ïowieka sposobem (gdy juĝ siÚ do niego przyzwycza-

imy)  jest  definiowanie  nazw  DSN  za  pomoc

È ïañcucha tekstowego wyglÈdajÈcego podobnie

do adresu URL. Zasadniczo, jego sk

ïadnia wyglÈda tak:

phptype://nazwa-uĝytkownika:hasïo@specyfikacja-hosta/baza-danych

gdzie 

phptype

 to oczywi

Ăcie typ systemu baz danych. Dla systemu MySQL ïañcuch nazwy DSN

mo

ĝe wyglÈdaÊ na przykïad tak:

$dsn = 'mysql://user:pass@localhost:3306/mdb2test';

background image

Rozdzia

á 1. • MDB2

21

Wi

Úcej informacji na temat nazw DSN oraz inne przykïady prawidïowych ïañcuchów DSN

mo

ĝna znaleěÊ w podrÚczniku repozytorium PEAR, dostÚpnym pod adresem: http://pear.php.net/

¦

manual/en/package.database.mdb2.intro-dsn.php

.

Tworzenie instancji obiektu MDB2

Istniej

È trzy metody umoĝliwiajÈce tworzenie (instancjacjÚ) obiektu MDB2:

$mdb2 =& MDB2::connect($dsn);
$mdb2 =& MDB2::factory($dsn);
$mdb2 =& MDB2::singleton($dsn);

Metoda 

connect()

 tworzy obiekt i 

ïÈczy siÚ z bazÈ danych. Metoda 

factory()

 tworzy obiekt,

natomiast po

ïÈczenie utworzy dopiero, gdy bÚdzie ono potrzebne. Wreszcie metoda 

single-

ton()

  dzia

ïa podobnie jak metoda 

factory()

,  ale  upewnia  si

Ú, ĝe istnieje tylko jeden obiekt

MDB2 o danej nazwie 

ěródïa danych, DSN. JeĂli wiÚc taki obiekt juĝ istnieje, metoda zwraca

ten obiekt, a je

Ăli nie, tworzy nowy.

Istnieje te

ĝ sposób „zakïócania” dziaïania metody 

singleton()

 za pomoc

È metody 

setDatabase()

,

która pozwala okre

ĂliÊ, ĝe bieĝÈca baza danych ma byÊ inna niĝ ta okreĂlona w nazwie DSN.

$dsn = 'mysql://root@localhost/mdb2test';
$mdb2_first =& MDB2::singleton($dsn);
$mdb2_first->setDatabase('inna_db');
$mdb2_second =& MDB2::singleton($dsn);

W tym przypadku b

Údziemy mieli dwie róĝne instancje MDB2.

Wszystkie  trzy  wspomniane  metody  tworz

È  obiekt  klasy  sterownika  bazy  danych.  JeĂli  na

przyk

ïad korzystamy ze sterownika bazy MySQL, zmienna 

$mdb

 zdefiniowana powy

ĝej bÚdzie

instancj

È klasy 

MDB2_Driver_mysql

.

Opcje

Pakiet MDB2 udost

Úpnia kilka opcji, które moĝna definiowaÊ przywoïujÈc metody 

connect()

,

factory()

 lub 

singleton()

 lub te

ĝ póěniej korzystajÈc z metody 

setOption()

 (by zdefiniowa

Ê

jedn

È opcjÚ) lub 

setOptions()

 (by zdefiniowa

Ê kilka opcji na raz). Na przykïad:

$options = array ( 'persistent' => true,
                   'ssl' => true,
                  );
$mdb2 =& $MDB2::factory($dsn, $options);

lub

$mdb2->setOption('portability', MDB2_PORTABILITY_NONE);

background image

PEAR. Programowanie w PHP

22

Pe

ïnÈ listÚ dostÚpnych opcji moĝna znaleěÊ w dokumentacji interfejsu API pakietu MDB2,

dost

Úpnej pod adresem: http://pear.php.net/package/MDB2/docs/. Przyjrzyjmy siÚ teraz dwóm

najwa

ĝniejszym opcjom.

Opcja „persistent”

Jest to opcja logiczna, która okre

Ăla, czy utworzone poïÈczenie powinno byÊ poïÈczeniem trwa-

ïym, czy teĝ nie.

W witrynie 

mysql.com

 mo

ĝna znaleěÊ bardzo dobry artykuï na temat zalet i wad korzystania z trwaïych

po

ïÈczeñ z bazÈ danych w systemie MySQL. Naleĝy zajrzeÊ pod adres:

 

http://www.mysql.com/news-and- events/

newsletter/2002-11/a0000000086.html

.

Domy

Ălnie przypisywana jest jej wartoĂÊ 

false

 (fa

ïsz), okreĂlajÈca, ĝe poïÈczenie nie powinno

by

Ê trwaïe. Podczas tworzenia obiektu moĝna zmieniÊ to domyĂlne ustawienie:

$options = array ( 'persistent' => true
                 );
$mdb2 =& MDB2::factory($dsn, $options);

Natomiast metoda 

setOption()

 pozwala definiowa

Ê opcje juĝ po utworzeniu obiektu:

$mdb2->setOption('persistent', true);

Opcja „portability”

Pakiet  MDB2  próbuje  poradzi

Ê sobie jakoĂ z róĝnicami w sposobie implementowania pew-

nych funkcji baz danych przez ró

ĝne systemy RDBMS. Opcja 

portability

 pozwala okre

ĂliÊ,

w jakim zakresie warstwa bazy danych ma dba

Ê o przenoĂnoĂÊ naszych skryptów.

ĝne  wartoĂci  opcji 

portability

  definiowane  s

È  jako  staïe  zaczynajÈce  siÚ  od 

MDB2_PORTABI-

LITY_*

, a domy

Ălna wartoĂÊ opcji to 

MDB2_PORTABILITY_ALL

 i oznacza „zrób wszystko, co tylko

mo

ĝliwe, by zagwarantowaÊ przenoĂnoĂÊ skryptów”. PeïnÈ listÚ staïych dla opcji 

portability

oraz  ich  opis  mo

ĝna  znaleěÊ  pod  adresem:  http://pear.php.net/manual/en/package.database.

¦

mdb2.intro-portability.php

.

Mo

ĝna definiowaÊ kilka wartoĂci opcji 

portability

, jak równie

ĝ definiowaÊ wyjÈtki za pomo-

c

È operatorów bitowych — dokïadnie w taki sposób, w jaki definiuje siÚ zasady raportowania

b

ïÚdów w jÚzyku PHP. To na przykïad ustawienie poleca dbaÊ o przenoĂnoĂÊ w peïnym zakre-

sie, z wyj

Ètkiem stosowania maïych liter:

MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_LOWERCASE

Je

Ăli natomiast nie interesujÈ nas wszystkie funkcje przenoĂnoĂci oferowane przez MDB2,

a  chcieliby

Ămy tylko usunÈÊ z wyniku spacje i zmieniÊ puste wartoĂci na ïañcuchy 

null

, to

nale

ĝy uĝyÊ opcji:

background image

Rozdzia

á 1. • MDB2

23

MDB2_PORTABILITY_RTRIM | MDB2_PORTABILITY_EMPTY_TO_NULL

Prawdopodobnie  najlepszym  rozwi

Èzaniem  bÚdzie  jednak  pozostawienie  domyĂlnego  usta-

wienia 

MDB2_PORTABILITY_ALL

. W ten sposób, w przypadku jakich

Ă problemów z aplikacjÈ, bÚ-

dziemy wiedzieli, 

ĝe kod zwiÈzany z siÚganiem do bazy danych zostaï dodatkowo sprawdzony

pod k

Ètem wspóïpracy z róĝnymi systemami baz danych.

Definiowanie trybu pobierania danych

Kolejnym  ustawieniem,  które  warto  zdefiniowa

Ê  na  poczÈtku,  jest  tryb  pobierania  danych

(ang. fetch mode) lub te

ĝ innymi sïowy — sposób, w jaki dane te bÚdÈ nam zwracane. Moĝe-

my otrzymywa

Ê dane w postaci uporzÈdkowanej listy (ustawienie domyĂlne), w formie tablic

asocjacyjnych lub w formie obiektów. Oto przyk

ïady definiowania trybu pobierania danych:

$mdb2->setFetchMode(MDB2_FETCHMODE_ORDERED);
$mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);
$mdb2->setFetchMode(MDB2_FETCHMODE_OBJECT);

Oczywi

Ăcie najbardziej przyjaznym dla czïowieka i najczÚĂciej stosowanym trybem pobiera-

nia danych b

Údzie pobieranie ich w tablicach asocjacyjnych, poniewaĝ wyniki umieszczane sÈ

wtedy w tablicy, której klucze odpowiadaj

È nazwom kolumn tabeli w bazie danych. Aby poka-

za

Ê, na czym polega róĝnica, przyjrzyjmy siÚ róĝnym sposobom pobierania danych zawartych

w naszym zbiorze wyników:

echo $result[0]; 

// uporz

ądkowana lub indeksowana tablica, domyĞlnie w MDB2

echo $result['name']; 

// tablica asocjacyjna

echo $result->name; 

// obiekt

Jest jeszcze jeden tryb pobierania danych, o nazwie 

MDB2_FETCHMODE_FLIPPED

 (tryb odwróco-

ny). Jest on cokolwiek nietypowy i jego dzia

ïanie zostaïo w dokumentacji API pakietu MDB2

opisane w nast

ÚpujÈcy sposób:

„W przypadku wyników wielowymiarowych, zazwyczaj pierwszy poziom tablic jest numerem
wiersza,  podczas  gdy  drugi  poziom  jest  indeksowany  wed

ïug nazwy bÈdě numeru kolumny.

Tryb 

MDB2_FETCHMODE_FLIPPED

 odwraca ten porz

Èdek, w efekcie czego pierwszy poziom tablic

b

Údzie nazwÈ kolumny, a drugi poziom — numerem wiersza”.

Roz

ïÈczanie siÚ z bazÈ danych

Aby roz

ïÈczyÊ siÚ z bazÈ danych, naleĝy uĝyÊ nastÚpujÈcego kodu:

$mdb2->disconnect();

Niemniej nawet je

Ăli sami nie zaznaczymy w kodzie, ĝe chcemy rozïÈczyÊ siÚ z bazÈ danych,

pakiet MDB2 zrobi to za nas automatycznie w swoim destruktorze.

background image

PEAR. Programowanie w PHP

24

Korzystanie z MDB2

Gdy ju

ĝ poïÈczymy siÚ z bazÈ danych i okreĂlimy odpowiednie opcje poïÈczenia oraz tryb po-

bierania danych, b

Údzie moĝna przystÈpiÊ do wykonywania zapytañ. Na potrzeby przykïadów

prezentowanych  w  tym  rozdziale  za

ïoĝymy, ĝe mamy tabelÚ o nazwie 

people

  (ludzie),  z  ko-

lumnami 

id

 (identyfikator), 

name

 (imi

Ú), 

family

 (nazwisko) i 

birth_date

 (data_urodzenia):

id

name

family

birth_date

1

Eddie

Vedder

1964-12-23

2

Mike

McCready

1996-04-05

3

Stone

Gossard

1966-07-20

Przyk

ïad

Oto prosty przyk

ïad pokazujÈcy, jak korzystaÊ z MDB2. W dalszej czÚĂci opowiemy o wszyst-

kim szczegó

ïowo, teraz jednak rzuÊmy okiem na kod, starajÈc siÚ zrozumieÊ w ogólnym zarysie,

jak on dzia

ïa.

<?php
require_once 'MDB2.php';

// przygotowania

$dsn = 'mysql://root:secret@localhost/mdb2test';
$options = array ('persistent' => true);
$mdb2 =& MDB2::factory($dsn, $options);
$mdb2->setFetchMode(MDB2_FETCHMODE_ASSOC);

// wykonujemy zapytanie

$sql = 'SELECT * FROM people';
$result = $mdb2->query($sql);

// wy

Ğwietlamy imiona

while ($row = $result->fetchRow())
{
echo $row['name'], '<br />';
}

// zwalniamy wykorzystywane zasoby

$result->free();

// wy

áączamy zapytania

$mdb2->setOption('disable_query', true);

// usuwamy trzeci rekord

$id = 3;
$sql = 'DELETE FROM people WHERE id=%d';

background image

Rozdzia

á 1. • MDB2

25

$sql = sprintf($sql, $mdb2->quote($id, 'integer'));
echo '<hr />Zmienione wiersze: ';
echo $mdb2->exec($sql);

// zamykamy po

áączenie

$mdb2->disconnect();
?>

Wykonywanie zapyta

ñ

Aby  wykona

Ê  zapytanie,  moĝna  uĝyÊ  metod 

query()

  lub 

exec()

.  Metoda 

query()

  zwraca

obiekt wyniku 

MDB2_Result

, natomiast metoda 

exec()

 zwraca liczb

Ú wierszy w tabelach zmie-

nionych  przez  zapytanie.  Dlatego  te

ĝ  metoda 

exec()

  b

Údzie  bardziej  odpowiednia  w  przy-

padku zapyta

ñ, które modyfikujÈ dane.

Mimo i

ĝ metoda 

query()

 pozwala wykona

Ê praktycznie kaĝdÈ operacjÚ na bazie danych, MDB2

oferuje  równie

ĝ inne metody, które lepiej nadajÈ siÚ do okreĂlonych, czÚsto wykonywanych

operacji.

Pobieranie danych

W przedstawionym wy

ĝej przykïadzie moĝna znaleěÊ nastÚpujÈce wiersze:

$sql = 'SELECT * FROM people';
$result = $mdb2->query($sql);

Zmienna 

$result

 jest obiektem wyniku typu 

MDB2_Result

 lub te

ĝ, ĂciĂlej mówiÈc, zaleĝnÈ od

konkretnego  sterownika  bazy  danych  klas

È,  która  jest  rozszerzeniem  typu 

MDB2_Result

,  na

przyk

ïad 

MDB2_Result_mysql

. Do przegl

Èdania zbioru wyników moĝna natomiast uĝyÊ w pÚtli

metody 

fetchRow()

, która pobiera pojedyncze wiersze.

while ($row = $result->fetchRow())
{
   echo $row['name'], '<br />';
}

Za ka

ĝdym razem gdy przywoïujemy metodÚ 

fetchRow()

, sprawdzi ona nast

Úpny rekord i zwróci

odwo

ïanie (ang. reference) do zawartych w nim danych. Oprócz metody 

fetchRow()

 jest jesz-

cze par

Ú innych metod z grupy 

fetch*()

:

■ 

fetchAll()

 zwraca od razu tablic

Ú zawierajÈcÈ wszystkie rekordy.

■ 

fetchOne()

 je

Ăli zostanie przywoïana bez ĝadnych parametrów, zwraca wartoĂÊ

pierwszego pola z bie

ĝÈcego wiersza. Natomiast jeĂli przeĂlemy jej odpowiednie

parametry, b

Údziemy mogli za jej pomocÈ pobraÊ dowolne pole z dowolnego

wiersza. Na przyk

ïad wywoïanie 

fetchOne(1,1)

 zwróci w naszym przyk

ïadzie imiÚ

Mike

, czyli drug

È kolumnÚ drugiego wiersza.

background image

PEAR. Programowanie w PHP

26

■ 

fetchCol($column)

 zwraca pola w kolumnie o numerze 

$column

 dla wszystkich

wierszy lub te

ĝ pierwszÈ kolumnÚ, jeĂli parametr 

$column

 nie zostanie okre

Ălony.

Warto zwróci

Ê uwagÚ, ĝe metody 

fetchRow()

 i 

fetchOne()

 przenosz

È wewnÚtrzny wskaěnik do

bie

ĝÈcego rekordu, podczas gdy metody 

fetchAll()

 i 

fetchCol()

 przenios

È go na koniec zbio-

ru wyników. Mo

ĝna równieĝ skorzystaÊ z wywoïania 

$result->nextResult()

, by z jego pomoc

È

przenie

ĂÊ  wskaěnik  do  nastÚpnego  rekordu  w  zbiorze  wyników  lub  z  wywoïania 

$result->

seek($rownum)

, by przenie

ĂÊ wskaěnik do wiersza okreĂlonego w parametrze 

$rownum

. W razie

w

ÈtpliwoĂci moĝna teĝ skorzystaÊ z wywoïania 

$result->rowCount()

, by sprawdzi

Ê, w którym

miejscu zbioru wyników aktualnie znajduje si

Ú nasz wskaěnik.

Mo

ĝna równieĝ ustaliÊ liczbÚ wierszy i liczbÚ kolumn w zbiorze wyników:

$sql = 'SELECT * FROM people';
$result = $mdb2->query($sql);
echo $result->numCols(); 

// wy

Ğwietla 4

echo $result->numRows(); 

// wy

Ğwietla 3

Skróty u

ïatwiajÈce pobieranie danych

Bardzo cz

Ústo znacznie wygodniej jest pobieraÊ dane w formie tablicy asocjacyjnej (lub zdefi-

niowa

Ê je jako preferowany tryb pobierania danych) i nie kïopotaÊ siÚ szczegóïami technicz-

nymi zwi

Èzanymi z przeglÈdaniem zbioru wyników. Pakiet MDB2 oferuje dwa zestawy metod

umo

ĝliwiajÈcych pobieranie danych „na skróty”: metody z grupy 

query*()

 i metody z grupy

get*().

  Za  ich  pomoc

È  nastÚpujÈce  czynnoĂci  wykonuje  siÚ  przy  uĝyciu  pojedynczego  wy-

wo

ïania metody:

 

1. Wykonywanie zapytania

 

2. Pobieranie zwracanych danych

 

3. Zwalnianie zasobów wykorzystywanych przez pobrany wynik

Skróty metod query*()

W  tej  grupie  mamy  do  dyspozycji  metody 

queryAll()

queryRow()

queryOne()

  i 

queryCol()

,

które  odpowiadaj

È analogicznym metodom z grupy 

fetch*()

,  omówionym  wy

ĝej. Oto przy-

k

ïad ilustrujÈcy, czym róĝni siÚ korzystanie z metod z grupy 

query*()

 od metod 

fetch*()

:

// instrukcja SQL

$sql = 'SELECT * FROM people';

// jeden ze sposobów pobierania wszystkich danych

$result = $mdb2->query($sql);
$data = $result->fetchAll();
$result->free(); 

// nie wymagane

// krótszy sposób

$data = $mdb2->queryAll($sql);

background image

Rozdzia

á 1. • MDB2

27

W obu przypadkach, je

Ăli wyĂwietlimy za pomocÈ metody 

print_r()

 zawarto

ĂÊ zmiennej 

$data

i korzystamy z trybu pobierania u

ĝywajÈcego tablic asocjacyjnych, otrzymamy:

Array ( [0] => Array ( [id] => 1
                       [name] => Eddie
                       [family] => Vedder
                       [birth_date] => 1964-12-23
                     )
        [1] => Array ( [id] => 2
                       [name] => Mike
                       [family] => McCready
                       [birth_date] => 1966-04-05
                      )
...
)

Skróty metod get*()

Oprócz metod z grupy 

query*()

 mo

ĝna jeszcze korzystaÊ ze skrótów oferowanych przez metody

get*()

. Metody z grupy 

get*()

 generalnie zachowuj

È siÚ w taki sam sposób jak metody z grupy

query*()

,  niemniej  pozwalaj

È równieĝ na stosowanie w zapytaniach parametrów. Rozwaĝmy

nast

ÚpujÈcy przykïad:

$sql = 'SELECT * FROM people WHERE id=?';
$mdb2->loadModule('Extended');
$data = $mdb2->getRow($sql, null, array(1));

W  tym  przyk

ïadzie znak zapytania pojawiajÈcy siÚ w instrukcji jest zmiennÈ, która zostanie

zast

Èpiona wartoĂciÈ przesïanÈ w trzecim parametrze metody 

getRow()

.

Mo

ĝna równieĝ korzystaÊ z parametrów posiadajÈcych wïasne nazwy:

$sql = 'SELECT * FROM people WHERE id=:the_id';
$mdb2->loadModule('Extended');
$data = $mdb2->getRow( $sql,
                       null,
                       array('the_id' => 1)
                      );

Warto zwróci

Ê uwagÚ na to, ĝe metody 

get*()

 s

È czÚĂciÈ moduïu Extended pakietu MDB2,

co oznacza, 

ĝe aby byïy dostÚpne, naleĝy je najpierw zaïadowaÊ uĝywajÈc polecenia 

$mdb2->

loadModule('Extended')

.

Dzi

Úki ïadowaniu  moduïów  mamy  moĝliwoĂÊ  przeciÈĝania  obiektów,  czego  nie  moĝna  byïo

robi

Ê  przed  pojawieniem  siÚ  PHP5.  Dlatego  w  wersji  PHP4  jÚzyka,  aby  siÚgnÈÊ  do  metod

modu

ïu Extended, trzeba je byïo przywoïywaÊ w nastÚpujÈcy sposób:

$mdb2->extended->getAll($sql);

background image

PEAR. Programowanie w PHP

28

Natomiast obecnie wystarczy wpisa

Ê:

$mdb2->getAll($sql);

getAsoc()

Kolejn

È uĝytecznÈ metodÈ z grupy 

get*()

, która nie ma bezpo

Ăredniego odpowiednika w grupie

fetch*()

 ani w grupie 

query*()

, jest metoda 

getAssoc()

. Zwraca ona wyniki w podobny spo-

sób  jak  metoda 

getAll()

,  niemniej  kluczami  w  tablicy  wyników  b

ÚdÈ  wartoĂci  z  pierwszej

kolumny  tabeli.  Dodatkowo  zbiór  wyników  zawiera  (w  naszym  przyk

ïadzie)  tylko  dwie  ko-

lumny,  poniewa

ĝ  jednÈ  wykorzystaliĂmy  juĝ  jako  indeks  tablicy.  Druga  kolumna  zostanie

zwrócona w formie 

ïañcucha (a nie w formie tablicy z jednym elementem). Oto kilka przykïadów

ilustruj

Ècych róĝnice pomiÚdzy metodami 

getAll()

 i 

getAssoc()

:

$sql = 'SELECT id, name FROM people';
$mdb2->loadModule('Extended');
$data = $mdb2->getAll($sql);

Metoda 

getAll()

 zwróci uporz

ÈdkowanÈ tablicÚ, w której kaĝdy z elementów bÚdzie tablicÈ

asocjacyjn

È zawierajÈcÈ wszystkie pola.

Array ( [0] => Array ( [id] => 1
                       [name] => Eddie
                     )
        [1] => Array ( [id] => 2
                       [name] => Mike
                     )
...
)

Je

Ăli wykonalibyĂmy to samo zapytanie za pomocÈ metody 

getAssoc()

, na przyk

ïad wpisujÈc

w kodzie 

$data=$mdb2->getAssoc($sql)

, to otrzymaliby

Ămy nastÚpujÈcy wynik:

Array ( [1] => Eddie
        [2] => Mike
        [3] => Stone
       )

Je

Ăli zapytanie zwraca wiÚcej niĝ dwie kolumny, to kaĝdy z wierszy bÚdzie tablicÈ, a nie skala-

rem. Oto kod wykonuj

Ècy takie zapytanie:

$sql = 'SELECT id, name, family FROM people';
$mdb2->loadModule('Extended');
$data = $mdb2->getAssoc($sql);

A oto wynik:

Array ( [1] => Array ( [name] => Eddie
                       [family] => Vedder
                     )
      ...
      )

background image

Rozdzia

á 1. • MDB2

29

Typy danych

Aby poradzi

Ê sobie z problemem wynikajÈcym z tego, ĝe róĝne systemy bazy danych obsïu-

guj

È róĝne typy danych dozwolone dla pól tabel, pakiet MDB2 dostarcza wïasnego, uniwer-

salnego  zestawu  typów  danych.  Programista  mo

ĝe  korzystaÊ  z  typów  danych  oferowanych

przez MDB2 i pozwoli

Ê, by sam pakiet MDB2 zadbaï o przenoĂnoĂÊ typów danych miÚdzy

ĝnymi systemami RDBMS, po prostu mapujÈc swoje typy na typy odpowiedniego systemu

baz danych.

Oto lista typów danych oferowanych przez MDB2 i ich domy

Ălne wartoĂci:

$valid_types = array ( 'text' => '',
                       'boolean' => true,
                       'integer' => 0,
                       'decimal' => 0.0,
                       'float' => 0.0,
                       'timestamp' => '1970-01-01 00:00:00',
                       'time' => '00:00:00',
                       'date' => '1970-01-01',
                       'clob' => '',
                       'blob' => '',
                     )

Wi

Úcej  informacji  na  temat  typów  danych  MDB2  moĝna  znaleěÊ  w  pliku  datatypes.html,

znajduj

Ècym  siÚ  w  podkatalogu  docs  w  katalogu,  w  którym  zainstalowaliĂmy  PEAR.  Doku-

ment ten jest równie

ĝ dostÚpny w internecie, w witrynie repozytorium PEAR CVS:

http://cvs.php.net/viewcvs.cgi/pear/MDB2/docs/datatypes.html?view=co

Okre

Ălanie typów danych

We wszystkich metodach s

ïuĝÈcych do pobierania danych, którym siÚ do tej pory przyglÈdali-

Ămy  (z  grup 

query*()

fetch*()

  i 

get*()

),  mo

ĝna  byïo  okreĂlaÊ  typ  zbioru  wyników,  który

chcemy  otrzyma

Ê,  i  pakiet  MDB2  automatycznie  konwertowaï  wartoĂci  na  odpowiedni  typ

danych. Na przyk

ïad metodzie 

query()

  mo

ĝna byïo przesïaÊ jako drugi parametr tablicÚ za-

wieraj

ÈcÈ oczekiwane typy danych dla pól:

$sql = 'SELECT * FROM people';
$types = array();
$result = $mdb2->query($sql, $types);
$row = $result->fetchRow();
var_dump($row);

W  tym  przypadku  tablica  typów 

$types

  by

ïa pusta, wiÚc metoda zachowaïa siÚ w domyĂlny

sposób (nie wykonuj

Èc ĝadnej konwersji typów danych) i wszystkie wyniki zostaïy zwrócone

w formie 

ïañcuchów. Przykïad ten zwraca nastÚpujÈce dane:

background image

PEAR. Programowanie w PHP

30

array(2)
{
    ["id"] => string(1) "1"
    ["name"]=> string(5) "Eddie"
...
}

Mo

ĝemy jednak zaĝyczyÊ sobie, aby pierwsze pole w kaĝdym zwracanym rekordzie byïo typu

integer

 (ca

ïkowitoliczbowego), a drugie typu 

text

 (tekstowego), definiuj

Èc tablicÚ 

$type

 w nast

Ú-

puj

Ècy sposób:

$types = array('integer', 'text');

W tym przypadku otrzymamy nast

ÚpujÈcy wynik:

array(2)
{
    ["id"]=> int(1)
    ["name"]=> string(5) "Eddie"
...
}

Podczas  okre

Ălania typów moĝna równieĝ uĝyÊ tablicy asocjacyjnej, w której kluczami bÚdÈ

poszczególne pola tabeli. W takim przypadku mo

ĝna nawet pominÈÊ niektóre pola, jeĂli nie

chcemy dla nich definiowa

Ê typów. Oto przykïady poprawnych definicji takiej tablicy:

$types = array( 'id' => 'integer',
                'name' => 'text'
               );
$types = array('name'=>'text');
$types = array('integer');

Okre

Ălanie typów danych podczas pobierania wyników

Je

Ăli nie chcemy okreĂlaÊ typów danych juĝ podczas przywoïywania metody 

query()

, mo

ĝemy

to  zrobi

Ê  póěniej.  Zanim  rozpoczniemy  pobieranie  danych,  moĝemy  okreĂliÊ  typy  danych

u

ĝywajÈc metody 

setResultTypes()

.

//

 

wykonujemy zapytanie

$sql = 'SELECT * FROM people';
$result = $mdb2->query($sql);

//

 

pobieramy pierwszy wiersz bez konwertowania typów

$row = $result->fetchRow();
var_dump($row['id']);

// wynik b

Ċdzie nastĊpujący: string(1) "1"

//

 

okre

Ğlamy typy

$types = array('integer');
$result->setResultTypes($types);

background image

Czytaj dalej...

Rozdzia

á 1. • MDB2

31

//

 

wszystkie nast

Ċpne pobrania bĊdą konwertowaü

//

 

pierwsz

ą kolumnĊ na liczbĊ caákowitą

$row = $result->fetchRow();
var_dump($row['id']);

// wynik b

Ċdzie nastĊpujący: int(2)

Okre

Ălanie typów danych dla metod get*() i query*()

Wszystkie  metody  z  grup 

get*()

  i 

query*()

,  które  omawiali

Ămy wyĝej w tym rozdziale, po-

zwalaj

È na okreĂlanie w drugim przesyïanym im parametrze, jakie typy danych majÈ zwracaÊ.

Dok

ïadnie tak samo jak w metodzie 

query()

.

Mo

ĝemy definiowaÊ parametr przesyïajÈcy typy danych nie tylko jako tablicÚ 

$types = array('in-

teger')

,  ale  równie

ĝ  jako  ïañcuch 

$types  =  'integer'

.  Jest  to  wygodne,  kiedy  pracujemy

z metodami,  które  maj

È zwracaÊ tylko jednÈ kolumnÚ danych, takimi jak 

getOne()

queryOne()

,

getCol()

  czy 

queryCol()

,  niemniej  nale

ĝy bardzo ostroĝnie korzystaÊ  z  tej  techniki  w  przy-

padku metod typu 

*All()

 i 

*Row()

, poniewa

ĝ wówczas ïañcuch w parametrze podajÈcym typ

okre

Ăli typ dla wszystkich pól w zbiorze danych.

Ujmowanie warto

Ăci i identyfikatorów w cudzysïowy

ĝne  systemy  RDBMS  zarzÈdzajÈce  relacyjnymi  bazami  danych  stosujÈ  róĝne  konwencje

ujmowania danych w cudzys

ïowy (na przykïad tam gdzie jedne uĝywajÈ pojedynczych cudzy-

s

ïowów 

'

,  inne  stosuj

È  podwójne  cudzysïowy 

"

).  Nie  ma  te

ĝ  ĝadnej  powszechnie  przyjÚtej

konwencji ujmowania w cudzys

ïowy typów danych. Na przykïad w systemie MySQL moĝe-

my  (je

Ăli  chcemy)  ujmowaÊ  wartoĂci  typu 

integer

  (ca

ïkowitoliczbowe)  w  cudzysïowy,  nato-

miast w innych systemach mo

ĝe to byÊ zabronione. Z tego powodu wïaĂnie lepiej pozostawiÊ

obs

ïugÚ cudzysïowów warstwie abstrakcji bazy danych, poniewaĝ pakiet MDB2 „wie”, jakie

konwencje stosuj

È tutaj róĝne systemy baz danych.

Pakiet  MDB2  oferuje  specjaln

È  metodÚ 

quote()

,  która  umo

ĝliwia  ujmowanie  danych  w  cu-

dzys

ïowy,  i  metodÚ 

quoteIdentifier()

  pozwalaj

ÈcÈ  na  ujmowanie  w  cudzysïowy  nazw  baz

danych, tabel i pól. Wszelkie cudzys

ïowy wstawione przez pakiet MDB2 bÚdÈ odpowiednie

dla wykorzystywanego systemu RDBMS. Oto przyk

ïad:

$sql = 'UPDATE %s SET %s=%s WHERE id=%d';
$sql = sprintf( $sql,
                $mdb2->quoteIdentifier('people'),
                $mdb2->quoteIdentifier('name'),
                $mdb2->quote('Eddie'), 

// domniemany typ danych

                $mdb2->quote(1, 'integer') 

// wyra

Ĩnie okreĞlony typ danych

               );

Je

Ăli teraz w bazie MySQL wykonamy polecenie 

echo $sql

, otrzymamy:

UPDATE `people` SET `name`='Eddie' WHERE id=1