Technologie - ADOdb kluczem do każdej bazy - Jak pisać uniwersalne skrypty PHP? 08-2004, Kurs SQL, sql
[ Pobierz całość w formacie PDF ]
C
M
Y
K
NA CD
NEWSY
Z OKýADKI
FIRMA
MAGAZYN
PROGRAMY
WARSZTAT
8
technologie
ADO
db
kluczem do każdej bazy danych
Tworzenie skryptw niezaleŇnych
od bazy danych naleŇy
do najtrudniejszych zadaı
programisty. Aby stworzone
programy mogþy wspþpracowaę
z kaŇdĢ bazĢ danych, potrzeba
spjnego interfejsu.
Dostarczy go biblioteka ADOdb,
ktrej przyjrzymy siħ bliŇej.
{
switch($db) {
case ÓmysqlÓ:
$connection = mysql_connect($host, $user, $pass);
mysql_select_db($database, $db);
break;
case ÓpgÓ:
$connection = pg_connect(Ñhost=$host port=5432
Æ
dbname=$database user=$user password=$passÑ);
break;
case ÓsqliteÓ:
$connection = sqlite_open(Ñ$database.sqliteÑ);
break;
}
return $connection;
}
?>
Funkcja connect() tworzy interfejs, warstwħ abstrakcyjnĢ sþuŇĢcĢ do poþĢ-
czenia z bazĢ danych. Lecz by mogþa dziaþaę, potrzebuje wprowadzenia na-
stħpujĢcych informacji: typ bazy danych (MySQL, PostgreSQL, czy SQLi-
te), nazwa bazy danych, adres serwera, nazwa uŇytkownika, hasþo. Gdy te
dane zostanĢ przekazane do funkcji, nastĢpi prba poþĢczenia z bazĢ danych:
$db = connect(ÓmysqlÓ, ÓbazaÓ, ÓlocalhostÓ,
Æ
ÓuzytkownikÓ, ÓhasloÓ);
Takim sposobem stworzyliĻmy najprostszĢ z moŇliwych abstrakcjħ sþu-
ŇĢcĢ do nawiĢzania poþĢczenia z bazĢ danych. W powyŇszym przykþadzie
prbujemy poþĢczyę siħ z bazĢ MySQL. Funkcja connect() na podstawie
zmiennej $db wybiera sekcjħ kodu, ktrĢ ma uruchomię. JeŇeli wszystko siħ
powiedzie, funkcja w zmiennej $db zwrci identyfikator poþĢczenia. Czy
speþniliĻmy zaþoŇony cel? Czy skrypt jest na etapie poþĢczenia przenoĻny?
Tak, poniewaŇ by poþĢczyę siħ z innĢ, ádowolnĢÑ bazĢ danych, wystarczy
jedynie zmodyfikowaę parametry przekazywane funkcji connect(). IdĢc da-
lej z naszym systemem abstrakcyjnym, naleŇaþoby stworzyę obsþugħ bþħ-
dw i dalsze funkcje (do wykonywania zapytaı, zwracania wynikw itd.).
SĢ to juŇ jednak znacznie trudniejsze zadania. Takim sposobem powstaþby
kompletny system abstrakcyjny do przeþĢczania siħ pomiħdzy obsþugiwany-
mi bazami danych. Jednak moŇna sĢdzię, Ňe produkt koıcowy byþby bardzo
niedoskonaþy i wymagaþby jeszcze wielu poprawek. Tak trafiamy na
ADOdb, czyli coĻ, co juŇ jest gotowe i z czego moŇemy korzystaę od zaraz.
Paweþ Grzesiak
nie dwch baz danych. Bardzo czħsto jesteĻmy skazani na My-
SQL. I tak powstajĢ skrypty, ktre pracujĢ wyþĢcznie na tej bazie.
Problem pojawia siħ, gdy MySQL przestaje speþniaę oczekiwania. Trudno
przecieŇ przewidzieę jak nasza strona siħ rozroĻnie i czego bħdziemy po-
trzebowali w przyszþoĻci. Gdy zdecydujemy siħ na zmianħ bazy danych,
staniemy przed koniecznoĻciĢ zmiany skryptw. Zwykle jednak okazuje
siħ to nierealne Î jest tyle zmian do dokonania, Ňe lepiej byþoby stworzyę
oprogramowanie caþkowicie od nowa. Takich sytuacji moŇna uniknĢę,
wprowadzajĢc poĻrednika pomiħdzy naszym skryptem a bazĢ danych.
Przyjrzymy siħ prostemu przykþadowi. PoþĢczymy siħ z trzema bazami
danych, by zobaczyę, jak wyglĢda nawiĢzywanie poþĢczenia w przypadku
(kolejno) MySQL, PostgreSQL i SQLite:
// MySQL
mysql_connect(ÓlocalhostÓ, ÓuzytkownikÓ, ÓhasloÓ);
mysql_select_db(ÓbazaÓ);
// PostgreSQL
pg_connect (Ñhost=localhost port=5432 dbname=baza
Æ
user=uzytkownik password=bazaÑ);
// SQLite
sqlite_open(Óbaza.sqliteÓ);
Znaczne rŇnice sĢ widoczne juŇ na pierwszy rzut oka. PoczĢwszy
od nazw funkcji, po przekazywane parametry to samo zadanie wyglĢda
skrajnie rŇnie. Jak rozwiĢzaę ten problem? Jak napisaę skrypt, ktry
prawidþowo poþĢczy siħ z wybranĢ bazĢ? NaleŇy stworzyę warstwħ abs-
trakcyjnĢ sþuŇĢcĢ do poþĢczenia z poszczeglnymi bazami danych:
<?php
function connect($db, $database, $host = ÓÓ,
Æ
$user = ÓÓ, $pass = ÓÓ)
O ADOdb
ADOdb (Active Data Objects Data Base) to oprogramowanie, ktre niwe-
luje setki rŇnic wystħpujĢcych pomiħdzy obsþugiwanymi przez tħ aplika-
cjħ bazami danych. A obsþuguje niemaþo, bo kilkadziesiĢt rozwiĢzaı bazo-
danowych, a wĻrd nich: MySQL, PostgreSQL, Interbase, Informix, Orac-
le, MS SQL 7, Foxpro, Access, SQLite, Sybase, DB2. ADOdb to pula
funkcji, za pomocĢ ktrych wykonuje siħ wszystkie operacje na bazie da-
nych. W efekcie wszystkie skrypty tworzone w oparciu o ADOdb stajĢ siħ
84
Przykłady i programy opisane
w tym artykule znajdują się na dołączonej
płycie CD w folderze Warsztat_ADOdb
INTERNET.sierpieı.2004
W
ykupujĢc miejsce na serwerze mamy dostħp do jednej, maksymal-
C
M
Y
K
7
WARSZTAT
PROGRAMY
MAGAZYN
FIRMA
Z OKýADKI
NEWSY
NA CD
technologie
bardziej przenoĻne Î niezaleŇne od bazy danych. SĢ takŇe i inne zalety, jak
moŇliwoĻę eksportowania wynikw do formatu CSV, czy rozbudowana
diagnostyka uþatwiajĢca usuwanie bþħdw i monitorowanie zapytaı wyko-
nywanych na bazie danych.
Obsþuga i korzystanie z ADOdb nie sĢ wcale trudniejsze od pracy ze
standardowymi rozszerzeniami PHP. Analogii i podobieıstw ADOdb moŇ-
na takŇe szukaę w standardzie ADO Microsoftu. W ADOdb znajdziemy
wiele uþatwieı, ktrych brakuje w standardowych API do obsþugi baz da-
nych dostħpnych w PHP.
WydajnoĻę komunikacji z bazami danych ma znaczny wpþyw na
szybkoĻę dziaþania skryptw. W ADOdb szybkoĻę wykonywania pole-
ceı jest bardzo duŇa. Na podstawie testw wydajnoĻci
(
) moŇna stwierdzię, Ňe ADOdb przewyŇsza wiele
podobnych rozwiĢzaı dostħpnych na rynku. Warto dodaę, Ňe ADOdb jest
lepszĢ, szybszĢ i bogatszĢ w opcje alternatywĢ dla PEAR DB
(
), konkurencyjnej biblioteki wpieranej przez or-
ganizacjħ PHP w ramach projektu PEAR. ADOdb jednak ustħpuje wy-
dajnoĻciĢ bibliotekom wbudowanym wprost w jħzyk PHP. To logiczne,
bo jest tylko skryptem PHP, ktry korzysta z dostħpnych w PHP biblio-
tek, by stworzyę wokþ nich warstwħ abstrakcyjnĢ. Nie moŇe wiħc prze-
wyŇszaę rozwiĢzaı, z ktrych sam korzysta.
Wreszcie, najwiħkszym atutem ADOdb jest wbudowany system buforo-
wania zapytaı. Zapisuje on do osobnych plikw na dysku twardym wyniki
pochodzĢce z zapytaı kierowanych do bazy danych. Gdy ponownie zosta-
nie wykonane to samo zapytanie na bazie danych, ADOdb pobierze wynik
zapytania bezpoĻrednio z pliku. Nietrudno dojĻę do wniosku, Ňe takie roz-
wiĢzanie znacznie zwiħksza wydajnoĻę budowanych na ADOdb aplikacji.
A przy tym tworzenie zapytaı buforowanych jest tak proste jak zwykþych.
ADOdb w rŇnych formatach (CHM, HTML). Wszystkie pliki dokumen-
tacji sĢ tradycyjnie w jħzyku angielskim.
Połączenie z bazą danych
By rozpoczĢę pracħ z bazĢ danych, naleŇy siħ najpierw z niĢ poþĢczyę.
Jakby to wyglĢdaþo w bazie MySQL?
<?php
$db = mysql_connect(ÓlocalhostÓ, ÓuzytkownikÓ,
Æ
ÓhasloÓ);
mysql_select_db(ÓbazaÓ, $db);
?>
Podajemy podstawowe dane, wybieramy bazħ danych, þĢczymy siħ
z MySQL. Teraz dokþadnie to samo, stosujĢc juŇ ADOdb:
<?php
include(Ó/adodb/adodb.inc.phpÓ);
$db = &NewADOConnection(ÓmysqlÓ);
$db->Connect(ÓlocalhostÓ, ÓuzytkownikÓ, ÓhasloÓ,
Æ
ÓbazaÓ);
?>
Tabela 1:
wybrane bazy danych obsþugiwane przez ADOdb
Skrót ADOdb Baza Danych
Wymagany sterownik System operacyjny
access
Microsoft Access/Jet
ODBC
Windows
ado
ADO, bez wskazania
ADO lub OLEDB
Windows
na konkretną bazę
db2
DB2
interfejs DB2 CLI/ODBC
Unix/Windows
vfp
Microsoft Visual FoxPro
ODBC
Windows
ibase
Interbase 6 lub wcześniejszy
klient Interbase
Unix/Windows
firebird
Firebird
klient Interbase
Unix/Windows
ldap
sterownik LDAP
rozszerzenie LDAP
Unix/Windows
mssql
Microsoft SQL Server 7 i starszy klient Mssql
Unix/Windows
mysql
MySQL bez obsługi transakcji
klient MySQL
Unix/Windows
Instalacja
AktualnĢ wersjħ ADOdb moŇna pobraę z oficjalnej strony biblioteki. Instala-
cja wymaga od nas posiadania dystrybucji PHP w wersji 4.0.4 lub starszej. Na
doþĢczonej pþycie CD zamieĻciliĻmy aktualnĢ wersjħ (4.2.2) biblioteki
ADOdb. Choę trudno tu mwię o instalacji, poniewaŇ ADOdb to zbir pli-
kw PHP, naleŇy zastosowaę siħ do kilku uwag. Po rozpakowaniu archiwum
katalog adodb naleŇy wgraę na serwer w miejsce niedostħpne (ze wzglħdw
bezpieczeıstwa katalog z adodb powinien znaleŅę siħ w niewidzialnej z ze-
wnĢtrz strukturze serwera) poprzez wpisanie adresu URL. Dla wiħkszoĻci ser-
werw za katalog bezpieczny uwaŇa siħ katalog rwnorzħdny z public_html.
Obok katalogu public_html powinien znaleŅę siħ wiħc katalog adodb.
Ponadto naleŇy stworzyę w tym samym miejscu nowy katalog, do ktre-
go bħdĢ trafiaþy zapytania buforowane. MoŇe on mieę co prawda dowolnĢ
nazwħ, lecz my nazwiemy ten katalog: adodbcache. Nowo utworzony kata-
log powinien posiadaę prawa dostħpu rwnieŇ i do zapisu (najlepiej chmod
777). Tak przygotowana instalacja pozwala w peþni korzystaę z ADOdb.
JeŇeli zaleŇy nam na maþych rozmiarach instalacji, do poprawnego urucho-
mienia ADOdb w wersji minimalnej potrzebne sĢ nastħpujĢce pliki:
u
adodb.inc.php
u
adodb-lib.inc.php
u
adodb-time.inc.php
u
adodb-php4.inc.php
u
adodb-iterator.inc.php
Z katalogu drivers (sterowniki) naleŇy teŇ wybraę systemy bazodano-
we, z ktrych mamy zamiar korzystaę. ZnajdujĢ siħ tu sterowniki do
wszystkich baz danych obsþugiwanych przez ADOdb. Gdy zdecydujemy
siħ tylko na MySQL, powinniĻmy usunĢę wszystkie pliki poza adodb-my-
sql.inc.php (do dyspozycji mamy jeszcze parħ sterownikw pobocznych
do obsþugi MySQL Î o tym w dokumentacji). Przy zmianie bazy danych,
np. na SQLite, do tego katalogu powinniĻmy takŇe wrzucię odpowiedni
tej bazie sterownik, czyli adodb-sqlite.inc.php.
W dystrybucji ADOdb w katalogu docs znajdziemy peþnĢ dokumenta-
cjħ opisujĢcĢ poszczeglne funkcje i sposb ich uŇycia. Na stronie interne-
towej projektu oraz na doþĢczonej pþycie CD znajduje siħ dokumentacja
mysqlt
MySQL z obsługą transakcji.
klient MySQL
lub
maxsql
oci8
Oracle 8/9
klient Oracle
Unix/Windows
odbc
Standardowy ODBC bez wskazania ODBC
Unix/Windows
na konkretną bazę
odbc_mssql
MSSQL (używa ODBC by połączyć) ODBC
Unix/Windows
odbc_oracle
Oracle (używa ODBC by połączyć) ODBC
Unix/Windows
oracle
Oracle 7 (interfejs oci8 lepszy
klient Oracle
?
– większa wydajność)
postgres
PostgreSQL (obecnie identyczny klient PostgreSQL
Unix/Windows
ze sterownikiem postgres7)
postgres64
PostgreSQL 6.4 i wcześniejsze,
klient PostgreSQL
Unix/Windows
nieobsługujące LIMIT
postgres7
PostgreSQL z obsługą LIMIT
klient PostgreSQL
Unix/Windows
i zachowaną funkcjonalnością
wersji 7
sapdb
SAP DB
klient SAP ODBC
?
sqlanywhere
Sybase SQL Anywhere
klient SQL Anywhere ODBC Unix/Windows
sqlite
SQLite
SQLite (nie dot. PHP5)
Unix/Windows
sybase
Sybase
Sybase client
Unix/Windows
W pierwszej linii stosujĢc ĻcieŇkħ bezwzglħdnĢ doþĢczamy bibliotekħ
ADOdb, ktra znajduje siħ w katalogu adodb, patrzĢc od gþwnego katalogu
konta. Nastħpnie tworzymy instancjħ $db klasy NewADOConnection, jako pa-
rametr podajĢc typ bazy, skrt odpowiadajĢcy sterownikowi do konkretnej ba-
zy danych (patrz tabela 1). Kolejno, korzystajĢc z metody Connect, wprowa-
dzamy wszystkie dane (host, uŇytkownika, hasþo oraz podajemy nazwħ bazy).
W efekcie otrzymujemy zwrotny identyfikator poþĢczenia ($db). Gdy bħdzie-
my chcieli zmienię aktualnie obsþugiwanĢ bazħ danych na caþej stronie, zmia-
nie podlegajĢ tylko 2 ostatnie linijki powyŇszego kodu. Wszystkie pozostaþe
elementy i funkcje sĢ uniwersalne dla kaŇdej obsþugiwanej bazy danych. Gdy-
byĻmy zatem chcieli przejĻę na bazħ danych SQLite, powinniĻmy zrobię to tak:
<?php
include(Ó/adodb/adodb.inc.phpÓÓ);
$db = &NewADOConnection(ÓsqliteÓ);
$db->Connect(Ó/bazy/baza.sqliteÓ);
?>
Tu tkwi najwiħksza zaleta ADOdb. Wystarczy modyfikacja dwch
linii kodu, by zmienię bazħ danych, na ktrej czħsto pracuje caþa strona
internetowa!
INTERNET.sierpieı.2004
85
C
M
Y
K
NA CD
NEWSY
Z OKýADKI
FIRMA
MAGAZYN
PROGRAMY
WARSZTAT
8
technologie
Instalacja ADOdb jako rozszerzenia PHP
Asocjacyjna czy numeryczna
W powyŇszym przykþadzie (wykonanym na bazie MySQL) tablica
wynikowa zawieraþa elementy tablicy asocjacyjnej (gdzie indeksami
byþy nazwy pl tabeli) i numerycznej (gdzie indeksami tablicy byþy
kolejne liczby, odzwierciedlajĢce kolejne pola tablicy poczĢwszy od
zera). W ADOdb wyboru tablicy wynikowej dokonujemy w nastħpujĢ-
cy sposb:
echo Ó<pre>Ó;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs = $db->GetRow(ÓSELECT * FROM premiery WHERE id=1Ó);
print_r($rs);
echo Ó</pre>Ó;
Istnieje możliwość zainstalowania ADOdb również jako modułu rozszerza−
jącego PHP. To rozwiązanie jest dużo wydajniejsze od wersji ADOdb pracują−
cej pod kontrolą PHP. Kod modułu napisany jest (zresztą jak całe PHP) w języ−
ku C++. Korzystanie z ADOdb jako modułu PHP jest nieco wygodniejsze (nie
trzeba np. każdorazowo dołączać pliku biblioteki). Pojawia się jednak problem
z przenośnością. O ile pliki ADOdb w formie skryptów PHP przenieść łatwo, to
może się okazać, że na innym serwerze nie ma możliwości zainstalowania tego
modułu rozszerzającego. Moduł jest również w fazie eksperymentalnej. Można
go pobrać z oficjalnej strony ADOdb. Zamieściliśmy go także na dołączonej
płycie. Aktualna wersja ADOdb 3.3.2ext znajduje się w pliku o nazwie adodb−
−ext−332.zip. Po rozpakowaniu archiwum, w katalogu php−win−4.3 znajdziemy
żądaną bibliotekę dll. By zainstalować rozszerzenie w Windows, bibliotekę
php_adodb.dll należy przenieść do katalogu extensions, który mieści się
w podkatalogu instalacji PHP. Następnie należy otworzyć plik php.ini, który
kryje w sobie całą lokalną konfigurację PHP. Tam znajduje się sekcja nazwana
„Dynamic Extensions”. Na końcu tej listy rozszerzeń należy dodać linijkę:
extension=php_adodb.dll
Wystarczy już tylko uruchomić ponownie serwer, aby ADOdb był standar−
dowo dostępny z poziomu PHP. Informacje na temat instalacji w systemach
uniksowych są dostępne w pliku readme.txt.
n
Tablica wynikowa GetRow() jako tablica asocjacyjna
Tabela 2:
tabela áPremieryÑ, na ktrej bħdziemy operowaę
WyrŇniamy trzy wartoĻci zmiennej $ADODB_FETCH_MODE:
id
tytul_pl
tytul
data_premiery
1
Dirty Dancing 2
Dirty Dancing:
2004−06−04
u
ADODB_FETCH_BOTH (zarwno asocjacyjna,
jak i numeryczna; niektre bazy nie obsþugujĢ tego trybu),
u
ADODB_FETCH_ASSOC (tablica asocjacyjna),
u
ADODB_FETCH_NUM (tablica numeryczna).
Havana Nights
2
Zgromadzenie
The Gathering
2004−06−04
3
Świt żywych trupów
Dawn of the Dead
2004−06−11
4
Efekt motyla
The Butterfly Effect
2004−06−11
5
The Punisher
The Punisher
2004−06−18
6
Ladykillers
The Ladykillers
2004−06−18
Istnieje takŇe elegantsza konstrukcja obiektowa:
$db->SetFetchMode(ADODB_FETCH_NUM);
Przyjrzyjmy siħ danym w tabeli 2. Jest to tabela o nazwie ápremieryÑ z da-
nymi na temat kilku filmw. Zawiera szeĻę rekordw i cztery kolumny. Ma-
my identyfikator liczbowy wiersza (zwiħkszajĢcy siħ o jeden wraz z kolejnym
wierszem), polski tytuþ filmu (ciĢg znakw, VARCHAR), tytuþ oryginalny
(rwnieŇ VARCHAR) oraz datħ premiery (pole typu DATE). Bħdziemy ko-
rzystaę z tej tabeli, wykonujĢc na niej wszystkie przykþady. Ze wzglħdu na
oszczħdnoĻę miejsca w wielu przykþadach zostanĢ pominiħte trzy pierwsze
linie skryptu. DoþĢczamy w nich bibliotekħ ADOdb, tworzymy instancjħ klasy
oraz þĢczymy siħ z bazĢ danych (patrz: poþĢczenie z bazĢ danych).
Buforowanie zapytań
Podczas instalacji ADOdb utworzyliĻmy folder adodbcache, ktry po-
sþuŇy nam teraz do przechowywania danych z zapytaı. Gdy wykona-
my zapytanie buforowane, wynik tej operacji zostanie zapisany w po-
staci pliku do katalogu adodbcache. Gdy powtrnie wykonamy to sa-
mo zapytanie, zapytanie zamiast trafię powtrnie do bazy danych, zo-
stanie odnalezione w katalogu z plikami buforu. ADOdb pobierze
wyniki operacji wprost z pliku, pomijajĢc caþkowicie bazħ danych.
Dziħki temu nasze aplikacje bħdĢ pracowaþy ze zwielokrotnionĢ prħd-
koĻciĢ. Systemu cachingu uŇywa siħ tam, gdzie kieruje siħ do bazy
bardzo duŇo identycznych zapytaı. Buforowanie ma sens, gdzie dane
pobierane z buforu nie ulegajĢ zbyt czħstej aktualizacji (lub wpþyw
tych aktualizacji nie jest waŇny). Stworzymy wiħc przykþadowe zapy-
tanie buforowane:
echo Ó<pre>Ó;
$ADODB_CACHE_DIR = Ó/adodbcacheÓ;
$rs = $db->CacheGetRow(ÓSELECT * FROM premiery
Æ
WHERE id=1Ó);
print_r($rs);
echo Ó</pre>Ó;
W powyŇszym kodzie pojawiþa siħ nowa zmienna. $ADODB_CA-
CHE_DIR informuje bibliotekħ o tym, gdzie znajduje siħ katalog z pli-
kami buforu. Dodatkowo zmianie ulegþa nazwa metody GetRow().
Przybyþ jej przyrostek Cache, ostatecznie mamy wiħc metodħ Cache-
GetRow(). Podobnie bħdzie z innymi funkcjami. Gdy pierwszy raz zo-
stanie wykonane to zapytanie, w katalogu adodbcache powstanie plik
z wynikami tej operacji. Gdy powtrnie uruchomimy program, dane
powħdrujĢ juŇ prosto z pliku. Pliki w buforze przedawniajĢ siħ jednak
po pewnym czasie Î standardowo po 3600 sekundach. Wtedy ADOdb
powtrnie pobiera dane z bazy, by utworzyę nowy, ĻwieŇy cache.
Standardowy czas Ňycia pliku bufora moŇna zmienię, dodajĢc do me-
Pobieranie jednego wiersza
Za wykonanie zapytania i pobranie do tablicy danych z jednego wiersza
odpowiada w ADOdb metoda GetRow(). Jej dziaþanie jest analogiczne
do funkcji mysql_fetch_row() i zbliŇone do pg_fetch_row(). PoniŇszy
przykþad pobiera z tabeli ápremieryÑ wiersz o id rwnym 1, zapisujĢc go
do tablicy $rs. Nastħpnie za pomocĢ funkcji PHP print_r() zostaje gra-
ficznie wyĻwietlony wynik dziaþania skryptu Î tablica z danymi.
echo Ó<pre>Ó;
$rs = $db->GetRow(ÓSELECT * FROM premiery WHERE id=1Ó);
print_r($rs);
echo Ó</pre>Ó;
Wynik dziaþania metody GetRow()
86
INTERNET.sierpieı.2004
C
M
Y
K
7
WARSZTAT
PROGRAMY
MAGAZYN
FIRMA
Z OKýADKI
NEWSY
NA CD
technologie
tody CacheGetRow() dodatkowy parametr. Jest to wartoĻę liczbowa
wyraŇana w sekundach. JeŇeli wiħc chcemy odĻwieŇyę cache po
15 minutach, powinniĻmy wpisaę jako pierwszy parametr wartoĻę 900:
$rs = $db->CacheGetRow(Ó900Ó, ÓSELECT * FROM
Æ
premiery WHERE id=1Ó);
JeŇeli chcemy, by powyŇszy przykþad dziaþaþ na zasadzie zapytania
buforowanego (czyli byþ wydajniejszy), naleŇy zmienię nazwħ metody
Execute() na CacheExecute():
$rs = $db->CacheExecute(ÓSELECT * FROM premieryÓ);
Wprowadzanie danych
By wprowadzię dane do bazy danych, najpierw naleŇy zanegowaę
kþopotliwe znaki. I tak wszystkie kþopotliwe znaki zostanĢ poprze-
dzone odpowiednim dla konkretnej bazy danych symbolem. W My-
SQL korzystaliĻmy z mysql_escape_string() czy addslashes().
W SQLite uŇywaliĻmy sqlite_escape_string(), a uŇycie addslashes()
groziþo bþħdami. W ADOdb mamy jednĢ funkcjħ, ktra odpowiada
za przygotowanie ciĢgu znakw do uŇycia z metodĢ Execute(). Me-
tody qstr() naleŇy uŇywaę zawsze wtedy, gdy chcemy do bazy
danych wprowadzię ciĢg znakw. Ta funkcja jest o tyle nietypowa,
Ňe dodatkowo na koıcu i na poczĢtku ciĢgu znakw dodaje znak po-
jedynczego cudzysþowu Ó. To zaleta, ktra nieco skraca zapytanie
kierowane do bazy. Zaprezentowany poniŇej przykþad dodaje do ta-
beli ápremieryÑ nowy wiersz:
// dane do dodania
$tytul_pl = ÓShrek 2Ó;
$tytul = ÓShrek 2Ó;
$data_premiery = Ó2004-07-02Ó;
$query = ÓINSERT INTO premiery (tytul_pl, tytul,
Æ
data_premiery) VALUES (Ó.$db->qstr($tytul_pl).Ó,
Æ
Ó.$db->qstr($tytul).Ó, Ó.$db->DBDate($data_premiery).Ó)Ó;
$rs = $db->Execute($query);
if($rs)
echo Ódodano poprawie!Ó;
else
echo $db->ErrorMsg();
echo $db->Insert_ID(); // zwrci: 7
echo $db->Affected_Rows(); // zwrci: 1
Jak widzimy, konstrukcja zapytania niczym specjalnym siħ nie
wyrŇnia. Do zmiennej $query wħdruje zapytanie typu INSERT,
ktre nastħpnie wykonujemy przy uŇyciu metody Execute(). JeŇeli
operacja siħ powiedzie, wyĻwietlany jest komunikat o sukcesie, je-
Ňeli operacja siħ nie powiedzie, skrypt informuje o napotkanym bþħ-
dzie. Oprcz sposobu zastosowania metody qstr(), naleŇy rwnieŇ
zwrcię uwagħ na nowĢ metodħ, a mianowicie na DBDate(). Auto-
rzy ADOdb musieli w jakiĻ sposb rozwiĢzaę problem wynikajĢcy
z tego, Ňe kaŇda baza danych zapisuje datħ w nieco innym formacie.
Tak powstaþa metoda DBDate(), ktrej jako parametr moŇemy po-
daę datħ w dwch formatach. MoŇe to byę (tak jak w przykþadzie)
data w standardzie ISO: YYYY-MM-DD lub data w formie unikso-
wego wskaŅnika czasu (timestamp). Data wprowadzona przy uŇyciu
tej funkcji nie powinna rodzię konfliktw i problemw, gdy zmieni-
my system bazodanowy.
Pobieranie wielu wierszy
Gdy z tabeli chcieliĻmy pobraę pojedynczy wiersz, korzystaliĻmy
z funkcji GetRow(). Zajmijmy siħ teraz sytuacjĢ, gdy z tabeli chcemy
pobraę wiħcej niŇ jeden wiersz. Kolejny przykþad bħdzie wykorzysty-
waþ metodħ Execute(). Jest ona odzwierciedleniem mysql_query() czy
pg_query() Î wykonuje dowolne zapytanie na bazie danych. Gdy ope-
racja siħ powiedzie, zwraca prawdħ, gdy coĻ siħ nie powiedzie Î faþsz.
Zapytanie wykonane poprawnie naleŇy nastħpnie wyĻwietlię. Skorzy-
stamy w tym celu z dwch pħtli. Pierwsza zajmie siħ kolejnymi wier-
szami (rekordami), druga kolejnymi komrkami. Skorzystamy takŇe
z metody MoveNext(), ktra przenosi wewnħtrzny wskaŅnik wynikw
o jeden wiersz do przodu. Spjrzmy zatem na przykþad:
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs = $db->Execute(ÓSELECT * FROM premieryÓ);
if (!$rs)
echo $db->ErrorMsg();
else
while (!$rs->EOF) {
foreach($rs->fields as $d){
echo $d.Ó ; Ó;
}
$rs->MoveNext();
echo Ó<br>Ó;
}
echo Ó<br>rekordw: Ó.$rs->RecordCount(); // zwraca: 6
echo Ó<br>kolumn: Ó.$rs->FieldCount(); // zwraca: 4
W pierwszej linii deklarujemy wynikowĢ tablicħ asocjacyjnĢ.
W nastħpnej linii wykonujemy zwykþe zapytanie na bazie, przypisujĢc
wynik do zmiennej $rs. Sprawdzamy, czy zapytanie przebiegþo po-
prawnie. JeŇeli nie, metoda ErrorMsg() wyĻwietli informacjħ tekstowĢ
na jakie problemy napotkano. JeŇeli zapytanie zostanie wykonane po-
prawnie, wykonywana jest pħtla while. Instrukcje w niej zawarte wy-
konywane sĢ dotĢd, aŇ wyraŇenie !rs->EOF nie zwrci faþszu. Sygnali-
zator EOF (podobnie jak w operacjach na plikach tekstowych) zwraca
prawdħ, gdy pobrane zostanĢ wszystkie wyniki. Pħtla while w naszym
przypadku wykona siħ szeĻę razy, dla kaŇdego rekordu w tabeli. Pħtla
foreach operuje juŇ na konkretnym wierszu tabeli, na tablicy
$rs->fields[]. W kaŇdym wierszu znajdujĢ siħ cztery komrki, stĢd ma-
my cztery elementy w tablicy asocjacyjnej $rs->fields[]. WyĻwietlamy
wiħc po kolei wszystkie komrki, a ich zawartoĻę tkwi w zmiennej $d.
WychodzĢc z pħtli foreach widzimy jeszcze metodħ MoveNext().
Pominiħcie jej spowoduje, Ňe pħtla while nigdy siħ nie zatrzyma. Pħtla
ta odpowiada bowiem za przesuniħcie tablicy wynikw do nastħpnego
wiersza.
Na koıcu listingu widoczne sĢ jeszcze dwie metody. Pierwsza
z nich, RecordCount() wyĻwietla liczbħ zwrconych wierszy w wyni-
ku. Metoda FieldCount() zwraca liczbħ kolumn wynikowych.
Typy danych
Czasami potrzebna jest moŇliwoĻę pobrania informacji o danym polu
w tabeli. Chcemy np. wiedzieę jakiego typu dane tam powinny trafiaę
(jakiego typu danych), czy teŇ chcemy znaę maksymalnĢ liczbħ zna-
kw jakĢ moŇna wprowadzię do konkretnego pola. W ADOdb do po-
bierania informacji na temat kolumn w tabeli sþuŇy metoda Fetch-
Field(). PrzejdŅmy do przykþadu:
$rs = $db->Execute(ÓSELECT * FROM premieryÓ);
echo Ó<pre>Ó;
print_r($rs->FetchField(1));
echo Ó</pre>Ó;
W pierwszej linii wykonujemy zapytanie na bazie danych. Pobiera-
my informacje na temat wszystkich pl w tabeli (á*Ñ). Nastħpnie ko-
rzystamy z metody FetchField, jako parametr podajĢc numer kolumny
Pobieranie wielu wierszy z tabeli
INTERNET.sierpieı.2004
87
C
M
Y
K
NA CD
NEWSY
Z OKýADKI
FIRMA
MAGAZYN
PROGRAMY
WARSZTAT
8
technologie
(poczĢwszy od zera). WyĻwietlamy informacje na temat 1 kolumny ta-
beli, czyli nie na temat kolumny ID, a na temat kolumny tytul_pl.
Funkcja print_r() wyĻwietli graficznie zawartoĻę wynikowego obiektu.
SĢ tu informacje na temat nazwy pola, jego maksymalnej dþugoĻci, ty-
pu obsþugiwanych danych itp.
Podobnie jak z datami, takŇe z typami danych sĢ problemy co do
zgodnoĻci pomiħdzy poszczeglnymi bazami danych. W jednej ba-
zie spotkamy siħ z zapisem typu danych áintÑ, w drugiej áintegerÑ.
By w programie mieę pewnoĻę o jaki konkretnie typ chodzi, mamy
do dyspozycji specjalnĢ funkcjħ. MetaType() na podstawie wprowa-
dzonych parametrw: typu danych (np. timestamp, timedate) i mak-
symalnej dþugoĻci pola (np. 127, 65535) decyduje o jaki typ danych
chodzi. Metoda zwraca jednĢ z dziewiħciu wartoĻci Î liter, ktre
symbolizujĢ konkretne typy danych (patrz tabela 3). Spjrzmy na
przykþad:
$rs = $db->Execute(ÓSELECT * FROM premieryÓ);
$inf = $rs->FetchField(1);
echo $rs->MetaType($inf->type, $inf->max_length);
Wykonujemy operacje analogiczne z przedstawionymi w poprzed-
nim przykþadzie. Przybywa jedna linia, czyli sposb uŇycia metody Me-
taType(). W zmiennej $inf znajdujĢ siħ dane na temat pola tytul_pl. Aby
otrzymaę informacje na temat typu danych, wprowadzamy jako parame-
try $inf->type (w tym przykþadzie jest to string), $inf->max_length (tu
60 znakw). W efekcie otrzymujemy wynik: C. PrzyglĢdajĢc siħ tabeli
stwierdzamy, Ňe pole to musi byę typu char lub varchar. Zgadza siħ. Po-
dobnie moŇna postĢpię z pozostaþymi kolumnami tabeli.
echo rs2csv($rs, false);
Parametr faþszu w przypadku obu funkcji spowoduje, Ňe wynikowe
dane nie bħdĢ zawieraþy nazw kolumn tabeli. Nie zobaczymy wiħc pierw-
szego wiersza, gdzie wymienione zostaþy kolejno: id, tytul_pl, tytul, da-
ta_premiery.
Eksportowanie danych do pliku
Zapiszemy teraz wynik dziaþania funkcji rs2csv() do pliku. Nastħpnie po-
staramy siħ wydobyę dane z zapisanego uprzednio pliku csv, by wprowa-
dzię je do bazy danych. W tej sposb najpierw wyeksportujemy dane,
a nastħpnie zaimportujemy je do bazy (co doĻę czħsto siħ przydaje).
<?php
include(Óadodb/adodb.inc.phpÓ);
include(Óadodb/toexport.inc.phpÓ);
$db = &NewADOConnection(ÓmysqlÓ);
$db->Connect(ÓlocalhostÓ, ÓuzytkownikÓ, ÓhasloÓ,
Æ
ÓbazaÓ);
$rs = $db->Execute(ÓSELECT * FROM premieryÓ);
$f_loc = Ópremiery.csvÓ;
$file = fopen($f_loc, ÑwÑ);
if ($file AND $rs) {
rs2csvfile($rs, $file, false);
fclose($file);
}
?>
Podobnie jak w poprzednim przykþadzie doþĢczamy potrzebne bibliote-
ki, þĢczymy siħ z bazĢ i wykonujemy zapytanie pobierajĢce do zmiennej
$db zawartoĻę tabeli ápremieryÑ. Otwieramy do zapisu plik o nazwie za-
wartej w zmiennej $f_loc (prermiery.csv). W przypadku gdy plik nie istnie-
je, skrypt utworzy nowy. JeŇeli wszystko przebiegþo poprawnie (plik zostaþ
otworzony do zapisu i zapytanie zostaþo wykonane poprawnie), funkcja
rs2csvfile() zaþaduje dane do pliku, a nastħpnie plik zostanie zamkniħty.
Funkcja rs2csvfile() to odmiana funkcji rs2csv() przygotowana specjalnie
do wgrywania danych do plikw. Takim sposobem zostaþ utworzony plik
premiery.csv, ktry moŇna bez problemu otworzyę np. w Excelu.
Tabela 3:
ustandaryzowane typy danych ADOdb
Litera
Typ danych
Komentarz
C
char lub varchar
krótkie pola tekstowe; do 255 znaków
X
clob lub text
duże i bardzo duże pola tekstowe
D
date
data lub czas
T
timestamp
uniksowy wskaźnik czasu
L
boolean lub bitowe
wartości 0 (fałsz) lub 1 (prawda)
N
decimal, numeric, float, real
liczby zmiennoprzecinkowe
I
integer
liczba naturalna
R
autoincrement lub inny licznik
pole musi być numeryczne
B
blob lub inne obiekty binarne
np. obrazy
Eksportowanie danych
Standardowo w ADOdb wbudowane sĢ dwie funkcje sþuŇĢce do ekspor-
towania danych pochodzĢcych z wynikw zapytaı. MoŇemy przenieĻę
nasze dane do dwch formatw: CSV (gdzie kolejne komrki oddzielone
sĢ przecinkami) oraz formatu tabularycznego (gdzie kolejne komrki od-
dzielone sĢ znakiem tabulatora). Spjrzmy wiħc na przykþad:
<?php
include(Óadodb/adodb.inc.phpÓ);
include(Óadodb/toexport.inc.phpÓ);
$db = &NewADOConnection(ÓmysqlÓ);
$db->Connect(ÓlocalhostÓ, ÓuzytkownikÓ, ÓhasloÓ,
Æ
ÓbazaÓ);
$rs = $db->Execute(ÓSELECT * FROM premieryÓ);
echo Ó<pre>Ó;
echo rs2tab($rs);
echo Ó<pre>Ó;
?>
W powyŇszym przykþadzie naleŇy zwrcię uwagħ na to, Ňe þadu-
jemy dodatkowĢ bibliotekħ. Biblioteka toexport.inc.php zawiera
dwie funkcje: rs2tab() oraz rs2csv(). Kolejno wykonujemy zapyta-
nie pobierajĢce wszystkie dane z tabeli ápremieryÑ, a nastħpnie ko-
rzystamy z funkcji rs2tab(), ktra zwraca nam dane w ustalonym
formacie.
Teraz przyjrzymy siħ funkcji rs2csv(). Dziaþa ona dokþadnie na ta-
kiej samej zasadzie, jak ta w powyŇszym przykþadzie. Zarwno dla
rs2csv(), jak i rs2tab() istnieje jeszcze drugi, opcjonalny parametr:
Plik premiery.csv moŇna otworzyę m.in. w Excelu
Importowanie danych z pliku
By zaþadowaę dane z pliku, musimy go najpierw otworzyę, potem
przeanalizowaę, by wreszcie wrzucię dane do bazy za pomocĢ zapytaı
typu INSERT. Zobaczmy przykþad:
<?php
include(Óadodb/adodb.inc.phpÓ);
$db = &NewADOConnection(ÓmysqlÓ);
$db->Connect(ÓlocalhostÓ, ÓuzytkownikÓ, ÓhasloÓ,
Æ
ÓbazaÓ);
$query = ÓINSERT INTO premiery (id, tytul_pl,
Æ
tytul, data_premiery) VALUES (?, ?, ?, ?)Ó;
88
INTERNET.sierpieı.2004
[ Pobierz całość w formacie PDF ]