Oracle i PHP

Ewa Palarczyk
na podstawie zasobów Internetu i dokumentacji PHP

Wygląda na to, że doczekaliśmy się kolejnego ukłonu
Oracle w kierunku środowiska open source. Tradycyjnie aplikacje
oracle’owe kojarzone były, jak do tej pory, z językiem Java. PHP
traktowano po macoszemu. Jednak od momentu zmiany polityki Oracle w zakresie
systemów operacyjnych i intensywnej akcji marketingowej nastawionej na promocję
Linuksa, otwarcie się na PHP – język programowania ściśle związany ze środowiskiem
linuksowym – było jedynie kwestią czasu. Wśród programistów linuksowych PHP
cieszy się zwykle większą sympatią niż Java. Dlaczego tak się dzieje?
Opinii na ten temat jest wiele i nie ma tu miejsca, by je wszystkie tutaj
przytaczać; powiem tylko, że jednym z koronnych argumentów jest twierdzenie,
iż PHP wykonuje kod szybciej i przy mniejszym zaangażowaniu zasobów
systemowych, mniej obciążając bazę danych. Dlatego też związek
przyczynowo-skutkowy jest prosty – skoro Oracle intensywnie promuje
Linuksa z jego najlepszym serwerem WWW Apache (55% rynku serwerów webowych), a
na 38% serwerów Apache mamy PHP – producent musiał zmienić swoją
sympatię do Javy i niechęć do PHP. Owa niechęć objawiała się tym, iż
administrator mógł (oczywiście na własną rękę) dołożyć moduł PHP do
serwera Apache, na którym bazował Oracle HTTP Server (podstawowy komponent
Oracle iAS lub Oracle Database Server), jednak oznaczało to, iż tracił w tym
samym momencie wsparcie Oracle. Działo się tak dlatego, że firma Oracle nie
wspierała, jak do tej pory, konfiguracji wykorzystujących moduły, które nie
są rozpowszechniane przez Oracle. W tej chwili sytuacja ta uległa zmianie.
Oracle zaczął promować wykorzystywanie skryptów pisanych w PHP, dostrzegając
po czasie funkcjonalność tego języka aplikacji internetowych.

Mówiąc w skrócie, PHP jest językiem skryptowym,
rozpowszechnianym na zasadach open source. Skrypty PHP – podobne do innych
języków, nazwijmy to, uniksowych/linuksowych, jak Perl czy Python, zagnieżdżane
są w stronach HTML. Podejście to oznacza, iż HTML funkcjonuje jako statyczne
ramy danej strony, podczas gdy PHP generuje dynamicznie treść i dane z bazy
Oracle. Kompatybilność PHP z Oracle nie jest niczym nowym, mimo iż była to
sympatia jednostronna. Oracle był jedną z pierwszych baz danych, obok MySQL, z
którymi można się było łączyć z poziomu PHP. Zmiana podejścia Oracle w
tym zakresie polega na tym, że obecnie firma Oracle wspiera programistów PHP
za pomocą stosownej dokumentacji znajdującej się na OTN, czy Metalinku,
wspierając instalację mod_php do Oracle Application Server, zachęca również
do korzystania z tego rozszerzenia. W kolejnym wydaniu Application Server 10g,
Oracle planuje jeszcze bardziej zwiększyć wsparcie dla PHP, dołączając PHP
do wydawanych płyt CD oraz mocniej integrując PHP z produktami Oracle.

O możliwościach i procesie instalacji PHP jako modułu
serwera (statycznie lub dynamicznie) lub jako procesora CGI, pisałam w numerze
26 (Oracle’owe PLOUG’tki), do którego odsyłam w tym
zakresie. Tutaj możemy zatem założyć, iż PHP został już
zainstalowany i działa poprawnie, co sprawdziliśmy za pomocą pliku test.php o
następującej zawartości:

<?phpinfo()?>

Wywołanie tego pliku w przeglądarce spowodowało zwrócenie
przez serwer Apache strony domowej PHP.

Tworząc rozbudowane aplikacje internetowe, wykorzystanie
bazy danych do przechowywania wartości zmiennych jest koniecznością. W jaki
sposób uzyskujemy dostęp z poziomu PHP do baz danych? PHP udostępnia funkcje
obsługujące wiele różnych baz danych, posługując się przy tym ich
rodzimymi interfejsami programistycznymi (API). W zasadzie obsługę baz danych
możemy podzielić na trzy kategorie: poprzez osobny zbiór funkcji, interfejs
ODBC oraz rozszerzenie dbx.

Połączenie z bazą danych za pomocą PHP wygląda w ten
sposób, iż podajemy nazwę użytkownika, hasło i szczegóły połączenia.
Przykładowo: załóżmy utworzenie tablicy o nazwie „emp”, zawierające
dane na temat pracowników w bardzo uproszczonej postaci, czyli jedynie ich
nazwisko i imię, w dwóch kolumnach. Musimy pamiętać, aby ustawić
ORACLE_HOME i ORACLE_SID na Apache user. Teraz możemy przystąpić do
utworzenia pliku obsługującego połączenie z naszą bazą i tablicą „emp”.
Plik, nazwijmy go połączenie.htm, będzie miał następującą postać:

<HTML>
<HEAD>
<TITLE>Polaczenie z baza </TITLE>
</HEAD>
<BODY>

<?php
$tns = 'emp';

$user = "scott@$tns";
$pass = 'tiger';
$q1 = 'SELECT * FROM example';
$conn = ora_logon($user, $pass);

$mycursor ora_open ($conn);
ora_parse ($mycursor, $q1, 0);
ora_exec ($mycursor);

while (ora_fetch($mycursor)) {
echo "Wynik: ora_getcolumn ($mycursor, 0), ora_getcolumn ($mycursor, 1)
<br>";
}
ora_close($mycursor);
?>

</BODY>
</HTML>

Rozwiązanie programistów PHP, aby do każdej bazy stosować
osobny zestaw funkcji, nieco komplikuje nam życie. Tym bardziej, iż w
przypadku baz Oracle mamy do czynienia z dwoma interfejsami: standardowym (oracle)
i bardziej elastycznym, oferującym więcej możliwości (OCI8). Wśród
pierwszej grupy predefiniowanych funkcji obsługi baz danych Oracle 7.x i Oracle
8.x, warto zwrócić uwagę na:

  • resource ora_logon (string user, string password)
    – otwiera połączenie z bazą Oracle dla użytkownika o danym haśle. Połączenia
    mogą być tworzone przy użyciu SQL*Net z nazwą TNS dla użytkownika:

    $conn = Ora_Logon("user@TNSNAME", "pass");

    Jeżeli w naszych nazwach występują inne znaki niż ASCII,
    powinniśmy mieć w naszym środowisku zdefiniowaną zmienną NLS_LANG. W
    przypadku modułów serwera, zmienna ta powinna być określona w środowisku
    serwera, jeszcze przed jego uruchomieniem.

  • resource ora_plogon (string user, string password)
    – otwiera trwałe połączenie z bazą Oracle dla użytkownika o określonym
    haśle.
  • bool ora_logoff (resource connection) –
    wylogowuje użytkownika i zamyka połączenie z bazą Oracle.
  • resource ora_open (resource connection) –
    otwiera kursor bazy danych Oracle;
  • bool ora_close (resource cursor) – zamyka
    kursor Oracle otwarty przez ora_open.
  • bool ora_commit (resource conn) – zatwierdza
    transakcję Oracle. Transakcja jest definiowana jako wszystkie zmiany w trakcie
    danego połączenia od wyłączenia ostatniego commit/rollback, autocommit lub
    od momentu, kiedy nawiązano połączenie.
  • bool ora_commiton (resource conn) – włącza
    automatyczne zatwierdzanie transakcji po każdym ora_exec() w trakcie danego połączenia.
  • bool ora_commitoff (resource conn) – funkcja
    wyłącza automatyczne zatwierdzanie transakcji po każdym ora_exec().
  • bool ora_rollback (resource connection) –
    wycofuje transakcję.
  • resource ora_do (resource conn, string query)
    – analizuje i wykonuje polecenie oraz pobiera pierwszy wiersz zwróconego
    zbioru wyników. Funkcja ta jest uproszczoną wersją ora_parse(), ora_exec() i
    ora_fetch().
  • bool ora_parse (resource cursor, string
    sql_statement, int defer) – parsuje polecenie SQL lub blok PL/SQL i
    kojarzy je z danym kursorem.
  • bool ora_bind (resource cursor, string
    PHP_variable_name, string SQL_parameter_name, int length [, int type]) –
    kojarzy zmienną PHP z parametrem Oracle. Funkcja ora_bind musi być wywoływana
    po ora_parse(), a przed ora_exec().

    <?php
    ora_parse($curs, „declare tmp INTEGER; begin tmp := :in; :out := tmp;
    😡 := 7.77; end;”);
    ora_bind($curs, „wynik”, „:x”, $len, 2);
    ora_bind($curs, „input”, „:in”, 5, 1);
    ora_bind($curs, „output”, „:out”, 5, 2);
    $input = 765;
    ora_exec($curs);
    echo „Wynik: $result<BR>Out: $output<BR>In: $input”;
    ?>

  • bool ora_exec (resource cursor) – wykonuje
    przetworzone polecenie.
  • bool ora_fetch (resource cursor) – zwraca
    wiersz danych ze wskazanego kursora.
  • int ora_fetch_into (resource cursor, array result [,
    int flags]) – zwraca wiersz danych ze wskazanego kursora i zapisuje go w
    podanej tablicy. Flaga może przyjmować dwie wartości: ora_fetchinto_nulls, do
    tablicy zapisywane są wtedy kolumny o wartościach null, ora_fetchinto_assoc
    – powoduje utworzenie tablicy asocjacyjnej.

    <?php
    $results = array();
    ora_fetch_into($cursor, $results);
    echo $results[0];
    echo $results[1];
    $results = array();
    ora_fetch_into($cursor, $results, ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC);
    echo $results[‚MyColumn’];
    ?>

  • string ora_error (resource cursor_or_connection)
    – zwraca komunikat błędu w formacie: xxx-nnnn, gdzie xxx
    jest źródłem pochodzenia błędu, a nnnn pokazuje nam treść błędu.
  • int ora_errorcode (resource cursor_or_connection)
    – zwraca numer błędu.
  • string ora_columnname (resource cursor, int column)
    – zwraca nazwę określonej kolumny zbioru wyników. Zwraca nazwę pola /
    kolumny column, kursora cursor. Zwracana nazwa pisana jest dużymi
    literami. Pierwsza kolumna ma numer 0.
  • int ora_columnsize (resource cursor, int column)
    – zwraca wielkość określonej kolumny zbioru wyników.
  • string ora_columntype (resource cursor, int column)
    – zwraca typ określonej kolumny zbioru wyników. Dopuszczalne typy to
    varchar2, varchar, char, number, long, long raw, rowid, date, cursor.

  • mixed ora_getcolumn (resource cursor, int column)
    – zwraca wartość z konkretnej kolumny.
  • int ora_numcols (resource cursor) – zwraca ilość
    kolumn znajdujących się w zbiorze wyników. Zwraca jedynie wartości wyniku
    sekwencji funkcji parse / exec / fetch.
  • int ora_numrows (resource cursor) – zwraca ilość
    wierszy znajdujących się w zbiorze wyników.

Osobną grupą są funkcje obsługi bazy danych Oracle8. Jeżeli
PHP zostanie połączone z bibliotekami klienckimi Oracle8, to poniższe funkcje
będziemy mogli wykorzystywać do obsługi baz Oracle w wersji 7 i 8.
Wykorzystują one Oracle8 Call-Interface (OCI8). Rozszerzenie to oceniane jest
jako bardziej elastyczne niż standardowe rozszerzenie Oracle, które opisałam
powyżej. OCI8 wspiera łączenie globalnych i lokalnych zmiennych PHP z polami
zastępczymi Oracle, posiada pełne wsparcie dla LOB, FILE i ROWID i pozwala nam
na samodzielne definiowanie zmiennych. Aby móc korzystać z tego rozszerzenia,
musimy mieć poprawnie ustawione następujące zmienne: ORACLE_HOME, ORACLE_SID,
LD_PRELOAD, LD_LIBRARY_PATH, NLS_LANG i ORA_NLS33. Następnie musimy dodać użytkownika
sieciowego (nobody, www) do grupy oracle; z kolei Apache musi być powiązany z
biblioteką pthread. Na niektórych systemach uniksowych w miejscu biblioteki
libpthread występuje libthread. PHP i Apache muszą być skonfigurowane z opcją
EXTRA_LIBS=-lthread. Poza tym nasz PHP musi być skompilowany z opcją
-with-oci8=[DIR], gdzie DIR wskazuje naszą zmienną ORACLE_HOME.

Rozszerzenie OCI8 posiada pewne predefiniowane stałe, z których
możemy korzystać jedynie wtedy, gdy zostało ono wkompilowane w PHP lub
dynamicznie załadowane w trakcie pracy. Stałe te są następujące:

  • OCI_DEFAULT (integer),
  • OCI_DESCRIBE_ONLY (integer),
  • OCI_COMMIT_ON_SUCCESS (integer),
  • OCI_EXACT_FETCH (integer),
  • SQLT_BFILEE (integer),
  • SQLT_CFILEE (integer),
  • SQLT_CLOB (integer),
  • SQLT_BLOB (integer),
  • SQLT_RDD (integer),
  • OCI_B_SQLT_NTY (integer),
  • OCI_SYSDATE (integer),
  • OCI_B_BFILE (integer),
  • OCI_B_CFILEE (integer),
  • OCI_B_CLOB (integer),
  • OCI_B_BLOB (integer),
  • OCI_B_ROWID (integer),
  • OCI_B_CURSOR (integer),
  • OCI_B_BIN (integer),
  • OCI_FETCHSTATEMENT_BY_COLUMN (integer),
  • OCI_FETCHSTATEMENT_BY_ROW (integer),
  • OCI_ASSOC (integer),
  • OCI_NUM (integer),
  • OCI_BOTH (integer),
  • OCI_RETURN_NULLS (integer),
  • OCI_RETURN_LOBS (integer),
  • OCI_DTYPE_FILE (integer),
  • OCI_DTYPE_LOB (integer),
  • OCI_DTYPE_ROWID (integer),
  • OCI_D_FILE (integer),
  • OCI_D_LOB (integer) i OCI_D_ROWID (integer).

Abyśmy mogli sprawdzić, czy rozszerzenie OCI8 działa
poprawnie, możemy wykorzystać poniższy skrypt:

<?php

$db_conn = ocilogon( "scott", "tiger" );

$cmdstr = "select ename, sal from emp";

$parsed = ociparse($db_conn, $cmdstr);
ociexecute($parsed);

$nrows = ocifetchstatement($parsed, $results);

echo "<html><head><title>Test OCI8</title></head><body>";
echo "<center><h2>Test Oracle i PHP</h2><br>";
echo "<table border=1 cellspacing=’0' width='50%'>n<tr>n";
echo"<td><b>Nazwisko</b></td>n<td><b>Wynagrodzenie</b></td>n</tr>n";

for ($i = 0; $i < $nrows; $i++ )
{
echo "<tr>n";
echo "<td>" . $results["ENAME"][$i] .
"</td>";
echo "<td>$ " . number_format($results["SAL"][$i],
2). "</td>";
echo "</tr>n";

}

echo "<tr><td colspan='2'> Liczba wierszy: $nrows</td></tr></table>";
echo "<br><em>Test przeprowadzony poprawnie!</em><br></center></body></html>n";

?>

Jeśli wszystko działa poprawnie, możemy się przyjrzeć możliwościom,
jakie daje rozszerzenie OCI8. Do ważniejszych funkcji należą tutaj:

  • resource ocilogon (string username, string password
    [, string db]) – nawiązuje połączenie z bazą danych Oracle8 i
    rejestruje się w niej. Funkcja zwraca identyfikator połączenia, który jest
    potrzebny dla większości wywołań OCI. Jako trzeci opcjonalny parametr, możemy
    podać nazwę lokalnej instancji bazy Oracle, lub nazwę wpisu w tnsnames.ora,
    do którego chcemy się połączyć. Jeśli nie sprecyzujemy tego parametru, PHP
    będzie korzystało ze zmiennych środowiskowych ORACLE_SID (instancja Oracle)
    lub TWO_TASKS (tnsnames.ora), aby określić bazę danych połączenia. Połączenia
    są dzielone na poziomie stron, co oznacza, iż polecenia commit i rollback
    stosują się do wszystkich transakcji otwartych w tej stronie, nawet gdy
    utworzyliśmy kilka połączeń.
  • resource ociplogon (string username, string password
    [, string db]) – tworzy trwałe połączenie z bazą Oracle8 i rejestruje
    się w niej.
  • resource ocinlogon (string username, string password
    [, string db]) – nawiązuje połączenie z bazą danych Oracle8 i
    rejestruje się w niej. Trzeci, opcjonalny parametr możemy wykorzystać do określenia
    nazwy lokalnej instancji bazy Oracle lub nazwy wpisu w tnsnames.ora. Jeżeli nie
    wskażemy tego parametru, PHP pobierze zawartość zmiennej środowiskowej
    ORACLE_SID (dla instancji Oracle) lub TWO_TASKS (dla tnsnames.ora), aby określić
    bazę docelową. Ocinlogon() wymusza nowe połączenie, dlatego powinniśmy go używać,
    gdy chcemy wyizolować grupę transakcji. Gdy używamy ocilogon(), domyślnie połączenia
    są współdzielone na poziomie strony. Mając wiele połączeń otwartych przy
    pomocy ocinlogon(), wszystkie zatwierdzenia i wycofania stosują się wyłącznie
    do określonego połączenia.
  • bool ocilogoff (resource connection) – zamyka
    połączenie z bazą danych. Stosowanie tej funkcji zwykle nie jest konieczne,
    ponieważ otwarte nie stałe połączenia są zamykane automatycznie po
    wykonaniu skryptu.
  • bool ocibindbyname (resource stmt, string ph_name,
    mixed &variable [, int maxlength [, int type]]) – kojarzy zmienną PHP
    variable z polem zastępczym Oracle8 o podanej nazwie ph_name.
    Parametr length określa maksymalną długość powiązania. Gdybyśmy
    ustawili length na -1, funkcja ocibindbyname() użyłaby aktualnej
    długości zmiennej variable do ustawienia maksymalnej długości. Jeśli
    natomiast chcielibyśmy powiązać zmienną z abstrakcyjnym typem danych (jak
    LOB, ROWID czy BFILE), będziemy musieli najpierw wykonać funkcję
    ocinewdescriptor(). Dla abstrakcyjnych typów danych nie używamy length
    -1, który powinien być ustawiony na -1. Zmienna type informuje
    Oracle o rodzaju deskryptora, z jakiego chcemy korzystać.
  • object ocinewdescriptor (resource connection [, int
    type]) – inicjalizuje nowy, pusty deskryptor LOB lub FILE (domyślnie
    inicjalizowany jest deskryptor LOB). Poprawne wartości zmiennej type to
    OCI_D_FILE, OCI_D_LOB i OCI_D_ROWID. Dla deskryptorów LOB metody load, save
    i savefile są kojarzone z deskryptorem, natomiast dla BFILE dostępna
    jest jedynie metoda load.

<?php
    /* Wywołanie przechowywanej procedury PL/SQL, która zawiera na
    * wejściu parametry clob (PHP 4 >= 4.0.6).
    * Zapis procedury PL/SQL wygląda następująco:
    * zapisane dane procedury
    * Nazwa argumentu   Typ        
Domyślnie In/Out?
    *-----------------  ----------  -----------------
    * KEY              
NUMBER(38)   IN
    * DATA             
CLOB         IN
    *
    */

    $conn = OCILogon($user, $password);
    $stmt = OCIParse($conn, "zapisuje dane(:key, :data); end;");
    $clob = OCINewDescriptor($conn, OCI_D_LOB);
           
OCIBindByName($stmt, ':key', $key);
           
OCIBindByName($stmt, ':data', $clob, -1, OCI_B_CLOB);
            $clob->WriteTemporary($data);
           
OCIExecute($stmt, OCI_DEFAULT);
           
OCICommit($conn);
            $clob->close();
            $clob->free();
           
OCIFreeStatement($stmt);
?>

  • bool ocicancel (resource stmt) – anuluje
    odczyt z kursora.
  • bool ocicloselob (void) – zamyka deskryptor
    lob.
  • bool ocicollappend (string value) – dołącza
    kolejny obiekt.
  • bool ocicollassign (object from) – kojarzy zbiór
    obiektów z istniejącym zbiorem.
  • bool ocicolumnisnull(resource stmt, mixed col)
    – sprawdza czy kolumna ma wartość NULL.
  • string ocicolumnname (resource stmt, int col)
    – zwraca nazwę kolumny odpowiadającą numerowi przetwarzanej kolumny.
  • int ocicolumnsize (resource stmt, mixed column)
    – zwraca rozmiar kolumny wynikowej.

<?php
    $conn = OCILogon("scott", "tiger");
    $stmt = OCIParse($conn,"select * from emp");
    OCIExecute($stmt);
    print "<TABLE BORDER="1">";
    print "<TR>";
    print "<TH>Name</TH>";
    print "<TH>Type</TH>";
    print "<TH>Length</TH>";
    print "</TR>";
    $ncols = OCINumCols($stmt);
    for ( $i = 1; $i <= $ncols; $i++ ) {
            $column_name =
OCIColumnName($stmt,$i);
            $column_type =
OCIColumnType($stmt,$i);
            $column_size =
OCIColumnSize($stmt,$i);
            print "<TR>";
            print "<TD>$column_name</TD>";
            print "<TD>$column_type</TD>";
            print "<TD>$column_size</TD>";
            print "</TR>";
    }
    print "</TABLE>";
    OCIFreeStatement($stmt);
    OCILogoff($conn);
?>

  • mixed ocicolumntype (resource stmt, int col) –
    zwraca typ danych kolumny.

<?php
    $conn = OCILogon("scott", "tiger");
    $stmt = OCIParse($conn,"select * from emp");
    OCIExecute($stmt);
    print "<TABLE BORDER="1">";
    print "<TR>";
    print "<TH>Nazwa</TH>";
    print "<TH>Typ</TH>";
    print "<TH>Długość</TH>";
    print "</TR>";
    $ncols = OCINumCols($stmt);
    for ( $i = 1; $i <= $ncols; $i++ ) {
            $column_name =
OCIColumnName($stmt,$i);
            $column_type =
OCIColumnType($stmt,$i);
            $column_size =
OCIColumnSize($stmt,$i);
            print "<TR>";
            print "<TD>$column_name</TD>";
            print "<TD>$column_type</TD>";
            print "<TD>$column_size</TD>";
            print "</TR>";
    }
    print "</TABLE>n";
    OCIFreeStatement($stmt);
    OCILogoff($conn);
?>

  • bool ocicommit (resource connection) –
    zatwierdza oczekujące transakcje dotyczące aktywnej transakcji.

<?php
    // Logowanie do serwera Oracle
    $conn = OCILogon('scott', 'tiger');

    // Parsuje SQL
    $stmt = OCIParse($conn, "INSERT INTO employees (name, surname) VALUES
('Jan', 'Kowalski')");

    // Wykonuje polecenie
    OCIExecute($stmt);

    // Zatwierdza transakcję
    $committed = OCICommit($conn);

        // Test zatwierdzenia transakcji. W przypadku błędu zwraca
        // komunikat
    if(!$committed) {
        $error = OCIError($conn);
        echo 'Commit failed. Oracle reports: ' .
$error['message'];
    }

    // Zamyka połączenie
    OCILogoff($conn);
?>

  • bool ocidefinebyname (resource stmt, string
    column_name, mixed &variable [, int type]) – definiuje zmienną PHP
    jako kolumnę Oracle8 o podanej nazwie. Powinniśmy uważać, aby wpisać nazwę
    kolumny drukowanymi literami, tak jak pisane są nazwy kolumn w Oracle, chociaż
    w zapytaniach SQL poprawnie odczytywane są również nazwy pisane małymi
    literami. Jeśli zdefiniujemy zmienną, która nie istnieje w poleceniu select,
    nie otrzymamy komunikatu o błędzie.

<?php
$conn = OCILogon("scott","tiger");
$stmt = OCIParse($conn,"select empno, ename from emp");

/* zdefiniowanie jest konieczne przed ociexecute! */

OCIDefineByName($stmt,"EMPNO",$empno);
OCIDefineByName($stmt,"ENAME",$ename);

OCIExecute($stmt);

while (OCIFetch($stmt)) {
    echo "Lp:".$empno."n";
    echo "Dane:".$ename."n";
}

OCIFreeStatement($stmt);
OCILogoff($conn);
?>

  • bool ociexecute (resource stmt [, int mode]) –
    wykonuje wcześniej parsowane wyrażenie. Opcjonalna zmienna mode umożliwia
    nam określenie trybu wykonywania polecenia (domyślnie OCI_COMMIT_ON_SUCCESS).
  • array ocierror ([resource stmt|conn|global])-
    zwraca ostatni błąd polecenia, połączenia lub całej bazy. Jeżeli nie został
    zgłoszony żaden błąd, to zwracana jest wartość FALSE. Funkcja ocierror
    zwraca wynik w postaci tablicy asocjacyjnej. Obejmuje ona kod i treść
    komunikatu błędu.
  • bool ocifetch (resource stmt) – przygotowuje
    nowy wiersz danych do odczytu dla wyrażeń select.
  • int ocifetchinto (resource stmt, array &result
    [, int mode]) – pobiera wiersz ze zbioru wyników i zapisuje go w podanej
    tablicy. Parametr mode pozwala nam na zmianę domyślnego zachowania
    funkcji. Możemy określić więcej niż jedną flagę, po prostu dodając
    kolejne (np. OCI_ASSOC+OCI_RETURN_NULLS). Możliwe są flagi takie, jak poniżej:
  • OCI_ASSOC – zwraca tablicę asocjacyjną.
  • OCI_NUM – zwraca tablicę zaczynającą się od
    0. Opcja domyślna.
  • OCI_RETURN_NULLS – zwraca kolumny NULL.
  • OCI_RETURN_LOBS – zamiast deskryptora, zwraca
    wartość LOB.

<?php
$conn = ocilogon("username","password");

$query = "SELECT apples FROM oranges";

$statement = OCIParse ($conn, $query);
OCIExecute ($statement);

while (OCIFetchInto ($statement, $row, OCI_ASSOC)) {
    print $row['apples'];
}
?>

  • int ocinewcursor (int con) – przydziela i
    zwraca nowy uchwyt polecenia (kursor) dla podanego połączenia z bazą danych.
  • int ocinumcols (resource stmt) – zwraca ilość
    kolumn w zbiorze wyników dla danego polecenia.

<?php
    print "<PRE>n";
    $conn = OCILogon("scott", "tiger");
    $stmt = OCIParse($conn,"select * from emp");
    OCIExecute($stmt);
    while ( OCIFetch($stmt) ) {
        print "n";
        $ncols = OCINumCols($stmt);
        for ( $i = 1; $i <= $ncols; $i++ ) {
            $column_name =
OCIColumnName($stmt,$i);
            $column_value =
OCIResult($stmt,$i);
            print $column_name . ': ' . $column_value . "n";
        }
        print "n";
    }
    OCIFreeStatement($stmt);
    OCILogoff($conn);
    print "</PRE>";
?>

  • resource ociparse (resource conn, string query)
    – parsuje zapytanie i zwraca polecenie Oracle.
  • mixed ociresult (resource statement, mixed col)
    – zwraca dane kolumny w bieżącym wierszu. Funkcja zwraca dowolny łańcuch,
    poza abstrakcyjnymi typami danych (ROWID, LOB i FILE).
  • int ocifetchstatement (resource stmt, array &output
    [, int skip [, int maxrows [, int flags]]]) – pobiera wszystkie wiersze
    zbioru wyników i zapisuje je w podanej tablicy.
  • bool ocifreestatement (resource stmt) –
    zwalnia wszystkie zasoby związane z wyrażeniem stmt.
  • int ocirowcount (resource stmt) – zwraca liczbę
    wierszy wyniku działania polecenia (np. update). Oznacza to, że funkcja nie
    wskaże nam liczby wierszy zwróconych przez select.

<?php
    print "<PRE>";
    $conn = OCILogon("scott","tiger");
    $stmt = OCIParse($conn,"create table emp2 as select * from emp");
    OCIExecute($stmt);
    print OCIRowCount($stmt) . " wierszy wstawiono.<BR>";
    OCIFreeStatement($stmt);
    $stmt = OCIParse($conn,"delete from emp2");
    OCIExecute($stmt);
    print OCIRowCount($stmt) . " wierszy usunieto.<BR>";
    OCICommit($conn);
    OCIFreeStatement($stmt);
    $stmt = OCIParse($conn,"drop table emp2");
    OCIExecute($stmt);
    OCIFreeStatement($stmt);
    OCILogOff($conn);
    print "</PRE>";
?>

  • bool ocirollback (resource connection) –
    wycofuje transakcję.
  • string ociserverversion (resource conn) –
    zwraca łańcuch znaków zawierający informacje o numerze wersji serwera.

<?php
    $conn = OCILogon("scott","tiger");
    print "Wersja serwera: " . OCIServerVersion($conn);
    OCILogOff($conn);
?>

  • string ocistatementtype (resource stmt) –
    zwraca typ zapytania OCI. Przyjmuje jedną z następujących wartości: SELECT,
    UPDATE, DELETE, INSERT, CREATE, DROP, ALTER, BEGIN, DECLARE, UNKNOWN.

<?php
    print "<PRE>";
    $conn = OCILogon("scott","tiger");
    $sql = "delete from emp where deptno = 10";

    $stmt = OCIParse($conn,$sql);
    if ( OCIStatementType($stmt) == "DELETE" ) {
            die "Nie możesz usuwać z tej tablicy <BR>";
    }

    OCILogoff($conn);
    print "</PRE>";
?>

Starałam się opisać najważniejsze funkcje obsługujące
standardowy Oracle i Oracle8 (OCI). Jak możemy sprawdzić w dokumentacji języka,
lista funkcji stale się rozszerza. Wiele z nowych funkcji nie jest jeszcze
udokumentowanych, niektóre nie są dostatecznie sprawdzone.

Na zakończenie, jako alternatywę dla nauki funkcji PHP do
obsługi baz Oracle, chciałabym zwrócić uwagę na ciekawe narzędzie, jakim
jest aplikacja PhpOracleAdmin, które może znacznie ułatwić i przyspieszyć
pracę z Oracle i PHP. Program ten wyda się znajomy tym, którzy pracowali z
PhpMyAdmin – programem do administracji bazą MySQL. PhpOracleAdmin jest
aplikacją internetową, która z poziomu przeglądarki umożliwia zarządzanie
obiektami bazy Oracle. Ma ona bardzo intuicyjny układ – po lewej stronie
mamy przedstawione bazy danych z ich obiektami, a w prawym oknie szczegóły
dotyczące danego obiektu. Mamy tu możliwość skonfigurowania nowego połączenia,
usunięcia połączeń, konfiguracji sesji. Program ten można pobrać ze strony
www.phporacleadmin.org

Zachęcam do śledzenia dalszego rozwoju polityki Oracle względem
PHP. Być może doczekamy się wkrótce również wsparcia dla innych języków
„uniksowych”. Wydaje się to całkiem prawdopodobne, jako kolejny
krok ku pełnej integracji baz i aplikacji Oracle z platformą linuksową, co
jest, jak można sądzić, zamierzeniem firmy. Możliwość korzystania z
„rodzimych” w świecie linuksowym programów, na pewno przysporzy
popularności Oracle w tym środowisku. Póki co, poczekajmy na dalszy rozwój
wypadków.