--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.
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.
TABELLA PRODOTTI | |
Campo | Descrizione |
cprod | codice del prodotto |
cat | categoria del prodotto |
descp | descrizione del prodotto |
prezzo | prezzo unitario |
qres | quantità residua |
TABELLA CLIENTI | |
Campo | Descrizione |
ccli | codice del cliente |
descc | descrizione del cliente |
ind | indirizzo |
piva | partita iva |
tel | telefono |
fax | fax |
indirizzo email |
TABELLA ORDINI | |
Campo | Descrizione |
cord | codice dell'ordine |
ccli | codice del cliente |
cprod | codice del prodotto |
qord | quantità ordinata |
data | data 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>
<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>
<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.
Data creazione HTML: Gennaio 2000
Autore: Francesco Munaretto
E-mail: NoSpam@thank.you