3. Gestore del Database

Ci accingiamo ora a creare l'ultimo oggetto di questo Tutorial : "dbHandler".

Quando creerete un'applicazione che utilizzerà questo oggetto, sarà buona norma crearne uno solo per ogni database, passandolo sempre per riferimento a metodi e costruttori, in questo modo :

// --- Funzione di esempio
function aggiornaTabella($dati, &$db)
{
	// --- Codice e query
}

// --- Creazione istanza
$db = new $dbHandler($nome_utente, $pass_utente, $nome_server, $nome_database);
$db->openConnection();

aggiornaTabella("dati", $db);

Vi consiglio di mettere la & commerciale nella dichiarazione della funzione, metodo o costruttore, così da non doverla ripetere ogni volta che la richiamate.

Includiamo le librerie create all'inizio del tutorial ...

<?php

	require_once("MySQLTable.php");
	require_once("MySQLErrors.php");

Ho usato require_once() piuttosto che require() o include(), per due motivi :

  • Se il file non viene trovato, viene sollevato un errore fatale e lo script viene bloccato, in quanto diciamo al compilatore che il file è vitale per la nostra applicazione
  • Se durante l'esecuzione dello script, il codice del file è già stato incluso, non sarà incluso nuovamente

Cominciamo con la scrittura dell'oggetto.
Stavolta gli attributi della classe saranno 6. Cinque privati ed uno pubblico.

// --- Dichiarazione della classe
class dbHandler
{
	private $nome_utente; // Nome utente per accedere al database
	private $pass_utente; // Password per accedere al database
	private $nome_server; // Host o indirizzo IP del server
	private $nome_database; // Nome del database interessato

	public $isConnected; // Flag per controllare se l'oggetto è connesso al database
	private $connessione_db; // Connessione al database

Procediamo con la scrittura del costruttore, che prenderà 5 parametri :

// --- Costruttore dbHandler
	function dbHandler($user, $pass, $host, $db, $connect = false)
	{
		$this->isConnected = false;
		$this->connessione_db = null;

		if (isset($user) && eregi("^[a-z0-9] $", $user))
			$this->nome_utente = $user;
		else
			throw new Exception("Nome utente non valido");

		if (isset($pass) && eregi("^[_a-z0-9-] $", $pass))
			$this->pass_utente = $pass;
		else
			throw new Exception("Password non valida");

		if (isset($host) && eregi("^[0-9\.a-z-] $", $host))
			$this->nome_server = $host;
		else
			throw new Exception("Nome host non valido");

		if (isset($db) && eregi("^[_a-z0-9-] $", $db))
			$this->nome_database = $db;
		else
			throw new Exception("Nome database non valido");

		if ($connect) $this->openConnection();
	}

Il costruttore non fa altro che controllare la validità dei dati con dei semplici controlli, mediante le espressioni regolari.

Se il quinto parametro (opzionale) viene specificato come true, l'oggetto stabilirà una connessione al database non appena verrà creata una sua istanza, grazie al metodo "openConnection()" che definiremo assieme nella prossima pagina.

Iniziamo subito con la scrittura di un importante metodo : "openConnection()".
Questo metodo non avrà un antagonista "closeConnection()", dal momento che la connessione creata con il database sarà persistente.

Ho scelto di creare una connessione persistente per due motivi :

  • Se viene trovata una connessione (anch'essa persistente) già aperta, che punta allo stesso host e con gli stessi nome utente e password, verrà usata quella invece di aprirne una nuova
  • Quando l'esecuzione del nostro script terminerà, la connessione persistente non sarà chiusa, ma rimarrà in attesa di essere riutilizzata per usi futuri, per un certo periodo di tempo impostato dal vostro Web Server.
    Questo incrementa notevolmente le prestazioni di applicazioni in PHP e AJAX.

Di seguito il metodo "openConnection()" sopra citato :

// --- Dichiarazione e definizione
	public function openConnection()
	{
		if ($this->isConnected) return true;

		$this->connessione_db = @mysql_pconnect($this->nome_server, $this->nome_utente, $this->pass_utente);
		$check = @mysql_select_db($this->nome_database, $this->connessione_db);

		if (!$check || !$this->connessione_db)
			throw new Exception("openConnection: " . getMySQLError(mysql_errno()));
		else
		{
			$this->isConnected = true;
			return true;
		}
	}

Ho usato la @ prima dei metodi di PHP "mysql_pconnect()" e "mysql_select_db()" per sopprimere gli errori standard sollevati da MySQL, utilizzando invece quelli tradotti in "MySQLErrors.php".

Nella "if" che segue, controllo se la connessione è andata a buon fine, e in caso contrario mi servo di "mysql_errno()" per richiamare la stringa tradotta corrispondente all'ultimo errore rilevato.

Nella prossima pagina andremo a definire l'ultimo metodo della nostra classe.

Il prossimo ed ultimo metodo servirà ad eseguire e controllare le nostre query.
Questa funzione risulta particolarmente utile per due motivi :

  • Esegue un controllo sul tipo di query effettuata e ritorna di conseguenza il valore adeguato
  • Nel caso in cui la query è una SELECT automaticamente viene inizializzata e restituita una "MySQLTable"
// --- Dichiarazione e definizione
	public function query($query, $html = false)
	{
		if ($this->connessione_db == null) $this->openConnection();
		if (!$html) $query = htmlspecialchars($query);

		$result = @mysql_query($query, $this->connessione_db);

		if ($result == null)
			throw new Exception(getMySQLError(mysql_errno()));

		if (eregi("^(select) ", $query))
		{
			$myTable = new MySQLTable($result);
			return $myTable;
		}
		else if (eregi("^(update) ", $query) || eregi("^(delete) ", $query) || eregi("^(insert) ", $query))
			return (boolean) $result;
		else
			throw new Exception("Tipo query non valida o non autorizzata.");
	}
}

?>

Il primo parametro ovviamente è la query vera e propria in MySQL.
Il secondo parametro dice alla funzione se nella nostra query è presente del contenuto in HTML.

Nel caso in cui la query è una SELECT viene restituita una "MySQLTable", nel caso in cui sia una UPDATE, DELETE o una INSERT viene restituito un valore booleano, true o false, per indicare se la query di aggiornamento, cancellazione o inserimento, è avvenuta con successo.

La scrittura della nostra nuova libreria si conclude qui.
Vedremo nella prossima ed ultima pagina un semplice esempio di utilizzo.