fire.gif

PHP3 E I DATABASE
Le funzioni per l'accesso ai database relazionali sono il vero punto di forza di php3. Nel linguaggio se ne possono trovare davvero molte. In pratica vengono soddisfatte tutte le esigenze di interfacciamento con le basi di dati più diffuse
Se vi ricordate già nel primo articolo avevamo presentato la numerosa lista dei database supportati da php3. Si trattava di un elenco veramente completo. Accanto a marchi prestigiosi quali Oracle e Sybase c'erano nomi ben più conosciuti al popolo dei linuxiani come mSQL, MySQL e PostgreSQL. Non poteva poi mancare la sigla ODBC la cui presenza faceva subito intuire che con php saremmo stati in grado di usare gli archivi attraverso una fonte di dati odbc. Effettivamente il programmatore può avere problemi di scelta di fronte al numero di drivers offerti da php. Per non rimanere intrappolati dallo stesso problema concentriamoci sulle funzioni per l'accesso ai database più usati nei server Linux. Attenzione che per testare con successo gli esempi presentati in questo articolo si dovranno "passare" i seguenti parametri al comando "configure" eseguito all'inizio della fase di compilazione del pacchetto php

--with-mysql=DIR --whit-pgsql=DIR --whit-msql=DIR

Occhio, inoltre, ala parola DIR, da sostituire con il path della directory di installazione del db.
linea.gif
PHP3 E GDBM
Il modo più semplice per archiviare dati in una macchina Linux consiste nel creare e riempire un database dbm. In realtà il termine dbm non indica il formato dell'archivio ma bensì una libreria di funzioni per scrivere, cancellare, ricercare o sostituire coppie di dati (chiave/valore) in un file. Si tratta inoltre di una libreria standard degli ambienti Unix e può essere facilmente inclusa nei programmi durante la fase di linking. Ovviamente anche Linux possiede una libreria simile. Il suo nome è gdbm, in virtù della filosofia GNU (GNU is Not Unix) che sta alla base di ogni progetto per Linux. E' quindi un software freeware, infatti viene distribuito rispettando i principi della licenza GPL (General Public License), ma anche totalmente compatibile con la classica dbm. E' bene precisare che esistono alcune varianti alla libreria dbm. Le più note sono Berkeley-DB e ndbm entrambe supportate da php3. Un argomento interessante su cui bisogna fare attenzione, quando si lavora con files ed archivi, è il criterio di locking usato da php per bloccare in modo esclusivo l'accesso in scrittura ai database dbm. In realtà è la libreria stessa che si incarica del blocco dell'archivio. Php non fa altro che effettuare un lock secondario, tra l'altro sempre eseguito automaticamente quando si scrive su un file, senza interferire con il blocco primario. Dopo questa breve introduzione teorica passiamo alla pratica scoprendo il modo in cui si accede ad un archivio in stile dbm usando la libreria gdbm. La funzione principale, usata per leggere o creare l'archivio, è

int dbmopen(string filename, int flags);

Il primo parametro, "filename", è il nome del file dell'archivio, eventualmente completo di path. Il secondo, invece, è il modo in cui si accede al file. L'argomento "flags", quindi, può avere i seguenti valori

'r'Apre l'archivio in sola lettura
'n'Apre l'archivio in lettura e scrittura e tronca il file se esiste già
'w'Apre l'archivio in lettura e scrittura

Dopo la chiamata a dbmopen(), che restituisce una sorta di puntatore al file del db, saremo in grado di compire le operazioni di inserimento, ricerca, sostituzione o cancellazione delle coppie di dati utilizzando nell'ordine le seguenti funzioni.

int dbminsert(int dbm_identifier, string key, string value);
string dbmfetch(int dbm_identifier, string key);
bool dbmreplace(int dbm_identifier, string key, string value);
bool dbmdelete(int dbm_identifier, string key);

Vediamo un'applicazione pratica proponendo un esempio per gestire un semplice archivio di login e password cifrate. Iniziamo dal form html


<html>
<head>
<title>Esempio GDBM</title>
</head>
<body>
<form method=post action=http://localhost/gdbm.php3>
Login: <input type=text size=8 name=login><p>
Password: <input type=text size=8 name=password><p>
<input type=radio name=azione value=CREA>Crea<br>
<input type=radio name=azione value=CERCA>Cerca<br>
<input type=radio name=azione value=ELIMINA>Elimina<br>
<input type=radio name=azione value=MODIFICA>Modifica<br>
<input type=radio name=azione value=ELENCA>Elenca<p>
<input type=submit value=Ok>
<input type=reset value=Annulla>
</form>
</body>
</html>

e poi terminiamo il lavoro con il programma php

<html>
<head>
<title>Esempio GDBM</title>
</head>
<body>
<?php
  $pwd = crypt($password, "pw");
  $dbm = dbmopen("/www/dati/users.dbm", "w");
  switch($azione) {
  case "CREA" :
    if(dbmexists($dbm, $login)) {
      echo "Attenzione!!!<br>";
      echo "User già presente nell'archivio";
    }
    else {
      dbminsert($dbm, $login, $pwd);
      echo "Dati creati con successo";
    }
    break;
  case "CERCA" :
    $key = dbmfetch($dbm, $login);
    if($key) {
      echo "$login -> $key<br>";
    } 
    else {
      echo "Dato non trovato";
    }    
    break;
  case "ELIMINA" :
    if(! dbmdelete($dbm, $login)) {
      echo "Dato eliminato con successo";
    }
    else {
      echo "Impossibile eliminare lo user $login";
    }
    break;
  case "MODIFICA" :
    if(! dbmreplace($dbm, $login, $pwd)) {
      echo "Dato modificato con successo";
    }
    else {
      echo "Impossibile modificare i dati";
    }
    break;
  case "ELENCA" :
    echo "<table border>";
    echo "<tr><td>Login</td><td>Password</td></tr>";
    // ---
    $key = dbmfirstkey($dbm);
    while($key) {
      echo "<tr>";
      echo "<td>$key</td><td>" . dbmfetch($dbm, $key) . "</td>";
      echo "</tr>";
      $key = dbmnextkey($dbm, $key);
    }
    // ---
    echo "</table>"; 
    break;
  }
  dbmclose($dbm);
?>
</body>
</html>

Forse, per pura pignoleria, l'ultima parte dell'esempio non ci convincerà più di tanto. L'elenco delle coppie login/password, infatti, non è ordinato. Per rimediare potremo creare un array di appoggio ed ordinarlo con la funzione asort(). Vediamo

$key = dbmfirstkey($dbm);
while($key) {
  $users[] =  $key;
  $key = dbmnextkey($dbm, $key);
}
sort($users);
$i = sizeof($users);
for($k=0; $k<=$i; $k++) {
  echo "<tr><td>$users[$k]</td><td>" . dbmfetch($dbm, $users[$k]) . "</td></tr>"; 
}

Dopo aver sostituito le righe di codice racchiuse dai commenti //--- con quest'ultime, dovremo ottenere la lista degli users ordinata per login.
linea.gif
PHP3 E POSTGRESQL
Se però le nostre esigenze di archiviazione dovessero aumentare, e quindi ci fosse bisogno di accedere a basi di dati ben più complesse dei files gdbm, dovremmo usare il linguaggio SQL adottando un vero gestore di database relazionali (RDBMS). Anche in questo caso non ci dovremo preoccupare più di tanto poiché Php3 e Linux ci daranno una grossa mano per risolvere brillantemente ogni nostro problema. Supponiamo quindi di dover gestire un piccolo negozio di componenti hardware per personal computer. Semplificando molto il problema e tralasciando le nozioni teoriche relative alla creazione ed al mantenimento delle basi di dati relazionali, concentreremo la nostra attenzione sulle principali funzioni di php per accedere ad un database di nome "negozio", creato con PostgreSQL, e costituito dalle seguenti tabelle:

TABELLA PRODOTTI
CampoDescrizione
cprodcodice del prodotto
catcategoria del prodotto
descpdescrizione del prodotto
prezzoprezzo unitario
qresquantità residua

TABELLA CLIENTI
CampoDescrizione
cclicodice del cliente
desccdescrizione del cliente
indindirizzo
pivapartita iva
teltelefono
faxfax
emailindirizzo email

TABELLA ORDINI
CampoDescrizione
cordcodice dell'ordine
cclicodice del cliente
cprodcodice del prodotto
qordquantità ordinata
datadata dell'ordine

Una delle operazioni che dovremo essere in grado di eseguire con il nostro browser preferito sarà l'inserimento o la modifica dei dati relativi ad un prodotto venduto dal negozio. Prepariamo subito il form html di appoggio


<html>
<head>
<title>Nuovo prodotto</title>
</head>
<body>
<form method=post action=http://localhost/nuovoprodotto.php3>
Codice Prodotto: <input type=text size=4 name=cprod><p>
<select name=cat>
<option value=CPU>CPU
<option value="Schede video">Schede video
<option value="Hard disk">Hard disk
</select><p>
Descrizione: <input type=text size=50 name=descp><p>
Prezzo: <input type=text size=5 name=prezzo><p>
Quantita' residua: <input type=text size=3 name=qres><p>
<input type=submit value=Ok>
<input type=reset value=Annulla>
</form>
</body>
</html>

Poi ci servirà lo script "nuovoprodotto.php3" il quale alimenterà la tabella prodotti con i dati ricevuti dal form, eccolo

<?php
  $db = pg_connect("localhost", "5432", "", "", "negozio");
  if(!$db) {
    echo "<h1>Connessione al database "NEGOZIO" fallita</h1>";
    exit;
  }
  pg_exec($db, "INSERT INTO prodotti VALUES ($cprod, $cat, $descp, $prezzo, $qres)");
  pg_close($db);
?>

Potrebbe servirci anche il listino completo dei prodotti in catalogo. In questo caso dovremo scrivere un codice simile a questo

<table border>
<tr>
<td>Codice prodotto</td>
<td>Categoria</td>
<td>Descrizione</td>
<td>Prezzo</td>
</tr>
<?php>
  $query = pg_exec($db, "SELECT * FROM prodotti ORDER BY cat AND descp");
  $row = 0; 
  while ($data = pg_fetch_object ($query, $row)) {
    echo "<tr><td>" . $data->cprod . "</td></tr>";
    echo "<tr><td>" . $data->cat . "</td></tr>";
    echo "<tr><td>" . $data->descp . "</td></tr>";
    echo "<tr><td>" . $data->prezzo . "</td></tr>";
    $row++;
  }
?>
</table>

linea.gif
PHP3 E MySQL
Immaginiamo adesso di dover eseguire le precedenti operazioni sulla tabella clienti ipotizzando, però, che il database del negozio sia interamente gestito dall'RDBMS MySQL. Quest'ultimo, grazie alle sue doti di velocità e stabilità, rappresenta una validissima alternativa al PostgreSQL. Iniziamo dal modulo per inserire i dati dei clienti

<html>
<head>
<title>Nuovo cliente</title>
</head>
<body>
<form method=post action=http://localhost/nuovocliente.php3>
Codice cliente: <input type=text size=4 name=ccli><p>
Descrizione: <input type=text size=50 name=descc><p>
Indirizzo: <input type=text size=50 name=ind><p>
Partita IVA: <input type=text size=15 name=piva><p>
Telefono: <input type=text size=15 name=tel><p>
Fax: <input type=text size=15 name=fax><p>
E-mail: <input type=text size=20 name=email><p>
<input type=submit value=Ok>
<input type=reset value=Annulla>
</form>
</body>
</html>

e proseguiamo con il frammento di programma php contenente le funzioni di accesso al db MySQL

<?php
  $dblink = mysql_connect("localhost");
  if(!$dbconn) {
    echo "<h1>Connessione al database fallita</h1>";
    exit;
  }
  $db = mysql_select_db("negozio", $dblink);
  if(!$db) {
    echo "<h1>Impossibile aprire il database "NEGOZIO"</h1>";
    exit;
  }
  mysql_query("INSERT INTO clienti VALUES ($ccli, $descc, $ind, $piva, $tel, $fax, $email)");
  mysql_close($db);
?>

Se volessimo ottenere un elenco di tutti i clienti del negozio oppure dovremmo usare questo script

<table border>
<tr>
<td>Codice cliente</td>
<td>Descrizione</td>
<td>Indirizzo</td>
<td>Partita IVA</td>
<td>Telefono</td>
<td>Fax</td>
<td>E-mail</td>
</tr>
<?php 
  $sx_cell = "<tr><td>";
  $dx_cell = "</td></tr>";
  $query = mysql_db_query("db", "SELECT * FROM clienti");
  while($row = mysql_fetch_array($query)) {
    echo $sx_cell . $row["ccli"] . $dx_cell;
    echo $sx_cell . $row["descc"] . $dx_cell;
    echo $sx_cell . $row["ind"] . $dx_cell;
    echo $sx_cell . $row["piva"] . $dx_cell;
    echo $sx_cell . $row["tel"] . $dx_cell;
    echo $sx_cell . $row["fax"] . $dx_cell;
    echo $sx_cell . $row["email"] . $dx_cell;
  }
  mysql_free_result($result);
?>
</table>

linea.gif
PHP3 E mSQL
Concludiamo presentando alcune funzioni per accedere ad un database costruito con mSQL. Anche questo rdbms è molto conosciuto tra gli utilizzatori di Linux. Questa volta useremo la tabella ordini per provare gli esempi. Iniziamo dal consueto form per l'inserimento dei dati

<html>
<head>
<title>Nuovo ordine</title>
</head>
<body>
<form method=post action=http://localhost/nuovoordine.php3>
Codice ordine: <input type=text size=4 name=cord><p>
Codice cliente: <input type=text size=4 name=ccli><p>
Codice prodotto: <input type=text size=4 name=cprod><p>
Data: <input type=text size=10 name=data><p>
Quantita': <input type=text size=2 name=qord><p>
<input type=submit value=Ok>
<input type=reset value=Annulla>
</form>
</body>
</html>

accompagnato dal codice php3

<?php
  $db = msql_connect("");
  if(!$db) {
    echo "<h1>Connessione al database fallita</h1>";
    exit;
  }
  msql_query("INSERT INTO ordini VALUES ($cord, $ccli, $cprod, $data, $qord)");
  msql_close($db);
?>

Per ottenere la stampa di un elenco degli ordini di un particolare cliente, ordinato per data di acquisto, si potrebbe usare la funzione msql_fetch_row() come nell'esempio seguente

<table border>
<tr>
<td>Codice ordine</td>
<td>Codice prodotto</td>
<td>Prodotto</td>
<td>Quantità ordinata</td>
<td>Data dell'ordine</td>
</tr>
<?php 
  $sx_cell = "<tr><td>";
  $dx_cell = "</td></tr>";
  $query = msql_query("SELECT cord.ordini, cprod.prodotti, descp.prodotti, qord.ordini, data.ordini FROM ordini, prodotti, clienti WHERE $ccli=ccli.clienti" ORDER BY data.ordini, $db);
  while($campo = mysql_fetch_row($query)) {
    echo $sx_cell . $campo[0] . $dx_cell;
    echo $sx_cell . $campo[1] . $dx_cell;
    echo $sx_cell . $campo[2] . $dx_cell;
    echo $sx_cell . $campo[3] . $dx_cell;
    echo $sx_cell . $campo[4] . $dx_cell;
  }
?>
</table>

Tutti gli esempi dimostrano come le funzioni per operare con i database più diffusi siano molto simili. Sostanzialmente tutte restituiscono le stesse strutture dati (oggetti, array o variabili scalari) e tutte richiedono gli stessi parametri. Cambia solo una parte del nome della funzione e l'ordine con cui vengono passati gli argomenti. Non ci rimane altro da dire che php3 si conferma ancora una volta un ottimo concorrente alla tecnologia ASP, soprattutto nell'attività attualmente più impegnativa: la gestione delle basi di dati relazionali.
linea.gif
SU INTERNET
Per documentarsi bene sulla libreria Berkeley-DB: http://www.sleepycat.com
Per scaricare la versione corrente di PostgresSQL collegarsi a http://www.postgresql.org
Per chi volesse sapere tutto su MySQL consigliamo di approdare su http://www.mysql.com
Per avere la versione aggiornata di mSQL seguire questo link: http://www.Hughes.com.au

fire.gif

Data creazione HTML: Gennaio 2000
Autore: Francesco Munaretto
E-mail: NoSpam@thank.you
exclaim.gif