ADOdb Home   Download
Thanks to MaKARON (makaron#hoga.pl) for the translation to Polish.


ADOdb Tutorial

        You say eether and I say eyether, 
        You say neether and I say nyther; 
        Eether, eyether, neether, nyther - 
        Let's call the whole thing off ! 

You like potato and I like po-tah-to, You like tomato and I like to-mah-to; Potato, po-tah-to, tomato, to-mah-to - Let's call the whole thing off !

Uwielbiam tą piosenkę, zwłaszcza w wykonaniu duetu Louisa Armstronga i Ella. Opowiada ona o tym jak ciężko być zgodnym dwojgu zakochanych ludzi - o kompromisie i znajdowaniu wspólnego języka. O tym jest ten artykuł. PHP ma służyć tworzeniu dynamicznych stron bez zbędnego zamieszania i z przyjemnością. Żeby tworzyć te strony potrzebujesz bazy danych - do przechowywania informacji o użytkownikach, żeby parsować newsy i przechowywać wiadomości forum. Można powiedzieć że używamy do tego MySQLa. Ale twoja strona stała się bardziej popularna niż mógłbyś oczekiwać w najśmileszych snach. Dochodzisz do wniosku, że MySQL nie obsłuży takiego obciążenia - czas zmienić bazę danych.

Niestety w PHP każda baza danych ma swój zestaw funkcji i obsługa ich odrobinę się różni. Żeby połączyć się z MySQLem używasz mysql_conncect() jeżeli będziesz chciał zmienić system na Oracl lub Microsoft SQL Server będziesz musiał użyć odpowiednio ocilogon() lub mssql_connect(). A co gorsze funkcje te pobierają różne parametry. Jeden system mówi po-tato a inny pota-to.

NIE nazywajmy wszystkiego po imieniu

Biblioteki takie jak ADODB pomagają w sytuacji kiedy potrzebuje przenośności kodu. Dostarczają standardu API do komunikacji z każdym obsługiawanym systemem bazodanowym.

Skrót ADODB oznacza Active Data Objects DataBase (Obiektowa Baza Danych). W tym momencie obsługuje MySQL, PostgreSQL, Oracle, Interbase, Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. Możesz ją ściągnąć z http://php.weblogs.com/adodb

PHP jest najczęściej używany z MySQL, myślę więc, że rozumiesz poniższy kod. Naiązuję w nim połączenie z localhostem wybierając bazę mydb. Później wykonuje zapytanie wyciągające wiersze z tabeli. Wynikowe wiersze są wypisywane w kolejnych liniach.

$db = mysql_connect("localhost", "root", "password");
mysql_select_db("mydb",$db);
$result = mysql_query("SELECT * FROM employees",$db);
if ($result === false) die("failed"); 
while ($fields = mysql_fetch_row($result)) {
 for ($i=0, $max=sizeof($fields); $i < $max; $i++) {
        print $fields[$i].' ';
 }
 print "<br>n";
} 

Powyższy kod został pokolorowany w celu odróżnienia sekcji. Pierwsza część to połącznie. Druga to wykonanie zapytania SQL, a ostatnia wyświetla wyniki. Pętla while przeskakuje po wierszach wyników, natomiast for po zwróconych kolumnach.

Oto odpowiednik w ADODB

 include("adodb.inc.php");
 $db = NewADOConnection('mysql');
 $db->Connect("localhost", "root", "password", "mydb");
 $result = $db->Execute("SELECT * FROM employees");
 if ($result === false) die("failed");  
 while (!$result->EOF) {
    for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
           print $result->fields[$i].' ';
    $result->MoveNext();
    print "<br>n";
 } 

A teraz zmieńmy kod tak, żeby korzystał z Oracl'a zmieniając drugą linię na NewADOConnection('oracle'). I spójrzmy jeszcze raz na kod.

Łączenie z bazą danych

include("adodb.inc.php");
$db = NewADOConnection('mysql');
$db->Connect("localhost", "root", "password", "mydb");

Kod połączenia jest trochę bardziej skomplikowany niż w MySQL'u ponieważ nasze wymagania są bardziej wyrafinowane. W ADODB używamy obiektów do obsługi różnic pomiędzy systemami bazodanowymi. Jeżeli nie jesteś zaznajomiony z programowaniem orietowanym obiektowo nie przejmuj się -- cała ta złożoność jest ukryta w funkcji NewADOConnection().

Żeby oszczędzić trochę pamięć ładujemy tylko kod potrzebny dla określonego systemu bazodanowego - tego z którym się łączymy. Robimy to wywołując funkcję NewADOConnection(typbazy). Dostępne typbazy to: mysql, mssql, oracle, oci8, postgres, sybase, vfp, access, ibase i wiele innych.

Następnie tworzymy nowy obiekt klasy wywołując NewADOConnection(). W końcu łączymy się z bazą używając $db->Connect().

Wykonywanie poleceń SQL

$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed")
;

Wysyłanie zapytań jest proste. Execute() zwraca obiekt wynikowy jeżeli zapytanie się powiedzie. Powinieneś sprawdzać $result w sposób taki jak wyżej.

To co zastanawia początkujących, to fakt, że mamy dwa typy obiektów w ADODB - obiekt połączenia i obiekt wyników. Kiedy używać którego?

Obiekt połączenia ($db) odpowiada za połączenie z systemem bazodanowym, formatowanie zapytań SQL i wykonywaniem ich na serwerze. Obiekt wyników ($result) jest odpowiedzialny za odbieranie wyników i formatowanie ich jako tekstów lub tablic.

Muszę jeszcze dodać, że ADODB posiada kilka funkcji ułatwiających obsługę poleceń INSERT i UPDATE. Ich opis znajduje się w części Zaawansowane.

Odbieranie danych i wyświetlanie wyników

while (!$result->EOF) {
   for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
       print $result->fields[$i].' ';
   $result->MoveNext();
   print "<br>n";
}

Odbieranie danych jest jak czytaniem z pliku. Dla każdej lini, najpierw sprawdzamy czy nie przeczytaliśmy już wszystkiego (EOF). Jeżeli nie, pętla przechodzi po każdej kolumnie w wierszu. Wtedy przechodzimy do następnego (MoveNext) i powtarzamy.

Tablica $result->fields[] jest generowana przez odpowiednie rozszerzenie PHP. Niektóre rozszerzenia nie generują tablicy indeksowanej nazwami kolumn. Żeby to wymusić użyj zmiennej globalnej $ADODB_FETCH_MODE.

	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
	$rs1 = $db->Execute('select * from table');
	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
	$rs2 = $db->Execute('select * from table');
	print_r($rs1->fields); // shows array([0]=>'v0',[1] =>'v1')
	print_r($rs2->fields); // shows array(['col1']=>'v0',['col2'] =>'v1')

Jak możesz zauważyć z powyższych przykładów oba wyniki przechowywane są w różnych formatach - zależnie od ustawienia $ADODB_FETCH_MODE w momencie wydawania polecenia Execute().

ADOConnection

Obiekt który wykonuje połączenie z bazą, wykonuje zapytania SQL i posiada funkcje pomocne przy tworzeniu zapytań SQL jak łączenie czy formatowanie daty.

Inne pomocne funkcje

$recordset->Move($pos) przewija wyniki do określonego wiersza. ADODB obsługuje przesuwanie w przód dla wszystkich obsługiwanych baz danych. Nie wszystkie bazy pozwalają na przesuwanie wstecz. Oczywiście to nie jest wielki problem, możesz cache'ować dane i symulować przewijanie wstecz.

$recordset->RecordCount() zwraca liczbę wierszy objętych ostanim zapytaniem SQL. Niektóre bazy danych zwracają -1, gdyż funkcja ta dla nich nie jest dostępna.

$recordset->GetArray() zwraca wynik jako tablicę.

rs2html($recordset) jest funkcją, która generuje tabelkę w HTMLu w oparciu o rekordy $recordset przesłane do niej. Przykład poniżej (ważne części są pogrubione):

   include('adodb.inc.php'); 
   include('tohtml.inc.php'); /* includes the rs2html function */
   $conn = &ADONewConnection('mysql'); 
   $conn->PConnect('localhost','userid','password','database');
   $rs = $conn->Execute('select * from table');
   rs2html($rs); /* recordset to html table */ 

Jest wiele pomocniczych funkcji, dokładny spis i opis znajduje się w dokumentacji dostępnej tutaj http://php.weblogs.com/adodb_manual.

Dla zaawansowanych

Insert i Update

Załóżmy że chcemy wprowadzić takie dane do bazy:

ID = 3
TheDate=mktime(0,0,0,8,31,2001) /* 31 sierpnia 2001 */
Note= sugar why don't we call it off

Kiedy używasz różnych baz danych, twoje zapytanie może nie funkcjonować prawidłowo.

Pierwszym problemem jest to, że każda baza ma inny domyślny format daty. MySQL oczekuje daty w formacie RRRR-MM-DD, a inne bazy mają inne domyślne ustawienia. ADODB ma funkcję DBDate() która rozwiązuje ten problem konwertując date do odpowiedniego formatu.

Następnym problemem jest to, że don't w Note musi być ujęte w cudzysłów. W Mysql używamy don't ale w innych bazach (Sybase, Access, Microsoft SQL Server) używamy don''t. Funkcja qstr() rozwiązuje ten problem.

Więc jak używamy tych funkcji? Właśnie tak:

$sql = "INSERT INTO table (id, thedate,note) values (" 
   . $ID . ','
   . $db->DBDate($TheDate) .','
   . $db->qstr($Note).")";
$db->Execute($sql);

ADODB posiada również funkcję $connection->Affected_Rows() (zwracającą ilość wierszy zmienionych/skasowanych przez ostatnie zapytanie update lub delete) i $recordset->Insert_ID() (zwracające ostatni numer wygenerowany przez insert dla kolumn auto_increment). Ale bądź ostrożny, gdyż nie wszystkie systemy bazodanowe posiadają te funkcje.

Możesz uzyskać więcej informacji o każdym polu (używam tych słów zamiennie: pola i kolumny) które jest w zwróconych rekordach przez wywołanie metody FetchField($fieldoffset) obiektu wyników. Zwróci ono obiekt z trzema polami: name (nazwa), type (typ) i max_length (maksymalna dopuszczalna długość).

Dla przykładu:
$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);

Pole $f0->name będzie zawierać 'adata', $f0->type będzie ustawione na 'date'. Jeżeli nieznana jest maksymalna długość, to zostanie ustawiona na -1.

Problemem przy obsłudze różnych baz danych jest to, że każda z nich inaczej nazywa te same typy danych. Dla przykładu typ timestamp jest nazywany datetime w jednej bazie, a time w innej. ADODB ma specjalną funkcję MetaType($type,$max_length) która stanadryzuje te typy w taki oto sposób:

C: char i varchar
B: blob i obrazy binarne
D: data
T: timestamp
L: logiczny (boolean
I: integer
N: zmienno przecinkowy (float, double, money)

Dla poprzedniego przykładu

$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
$type = $recordset->MetaType($f0->type, $f0->max_length);
print $type; /* powinno wypisać 'D'
*/

Obsluga "Select limit" i "Top"

ADODB posiada funkcję $connection->SelectLimit($sqk,$nrows,$offset) która pozwala wyciągnąć tylko część rekordów które zwróciłoby zapytanie $sql. Wykorzystuje ono SELECT TOP dla produktów Microsoft i SELECT ... LIMIT dla PostgreSQL i MySQL, a emuluje je na bazach, które nie obsługują tego typu zapytań.

Cache

ADODB pozwala na cache'owanie rekordów w lokalnym systemie plików i wykonywanie zapytań bazy danych po czasie określonym w $connection->CacheExecute($secs2cache,$sql) i $connection->CacheSelectLimit($secs2cache,$sql,$nrrows,$offset).

Obsługa sesji PHP4

ADODB posiada obsługę sesji PHP. Możesz przechowywać zmienne sesji w bazie danych, jeżeli chcesz w pełni korzystać z możliwości ADODB. Aby uzyskać więcej informacji zajzyj do http://php.weblogs.com/adodb-sessions.

Komercyjne wykorzystanie ADODB

Jeśli planujesz pisać komercyjną aplikację w PHP którą zamierzarz sprzedawać, powinieneś wziąć pod uwagę ADODB. Opublikowana jest ona na licencji lesser GPL, co oznacza, że możesz legalnie dołączać ją do komercyjnych produktów, zachowując zamkniętość swojego kodu. Gorąco zachęcamy do użycia ADODB. Między innymi dlatego my z niej korzystamy.