[PHP-MySQL]: Una classe per gestire al meglio il database: SQLManager


Era tanto che non creavo una classe per facilitare il compito dei programmatori con qualche “chicca” per i programmatori più pigri…

Quella che vi presento oggi, è una versione migliorata della mia classe “ManageDB“, con più funzioni e una migliore organizzazione dei comandi.

Iniziamo a copiare il seguente codice nel file SQLManager.class.php



/**
 * @name SQLManager
 * @description Classe per Gestire il Database
 * @author StefanoV
 * @copyright 2010
 */

class SQLManager
{
	var $risorsa; // risorsa del db
	var $dieerror = true; // esce con il mysql error
	var $mailerror = ""; // invia una mail con l'errore della query.
	var $logfile = ""; // percorso dove salvare il log delle query
	var $logall = false; // decide se mostrare anche le query che hanno avuto successo

	function SQLManager($dieerror = true, $mailerror = "", $logfile = "", $logall = false)
	{
		$this->dieerror = $dieerror;
		$this->mailerror = $mailerror;
		$this->logfile = $logfile;
		$this->logall = $logall;
	}
	/*********************************** Funzioni Base ****************************************/

	/**
	 * Permette di usare una risorsa già aperta
	 *
	 * Param: $res (resource) - risorsa da utilizzare
	 */
	function usaRisorsa($res)
	{
		// se $res è settata, non vuota, ed è una risorsa
		if(isset($res) && !empty($res) && is_resource($res))
		{
			// applicala come risorsa globale
			$this->risorsa = $res;
		}
	}

	/**
	 * Connette lo script al Database MySQL
	 *
	 * Param: $host (string) - server del database
	 * Param: $user (string) - username del database
	 * Param: $pass (string) - password del database
	 * Param: $db (string) - nome del database
	 */
	function Open($host, $user, $pass, $db)
	{
		// se i campi sono inseriti
		if(empty($host) || empty($user) || empty($db))
			exit();

		// connetto al' host
		$ris = mysql_connect($host, $user, $pass) or $this->getErr("Errore di connessione all'host!");

		// seleziono il db
		mysql_select_db($db, $ris) or $this->getErr("Errore di selezione del database!");

		// setto la risorsa come globale della classe
		$this->risorsa = $ris;
	}

	/**
	 * Libera le risorse della risorsa risultante dalla query
	 *
	 * Param: $query (resource link) - la risorsa ottenuta dalla funzione doQuery
	 */
	function Free($query)
	{
		if(mysql_free_result($query))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * Restituisce l'ID generato dall' ultima query INSERT
	 */
	function lastID()
	{
		return @mysql_insert_id();
	}

	/**
	 * Restituisce le righe contate nella query
	 *
	 * Param: $query (resource link) - la risorsa ottenuta dalla funzione doQuery
	 */
	function Count($query)
	{
		return @mysql_num_rows($query);
	}

	/**
	 * Restituisce true se trova almeno un record
	 *
	 * Param: $query (resource link) - la risorsa ottenuta dalla funzione doQuery
	 */
	function Found($query)
	{
		if($this->Count($query) != 0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * Mostra l'errore o manda la mail con l'errore
	 *
	 * Param: $errore (string) - stringa di errore restituita da MySQL
	 * Param: $mErr (string) - stringa di errore da mostrare scelta da noi
	 */
	private function getErr($errore = "")
	{

		if(empty($errore)) $errore = mysql_error();

		// se bisogna mandare la mail
		if(!empty($this->mailerror))
		{
			// testo mail
			$testo = "Si è verificato un errore: ".$errore." \r\n \r\n Indirizzo del file chiamato: ".$_SERVER['REQUEST_URI'];

			// destinatario
			$to = $this->mailerror;

			// soggetto
			$subject = "SQLManager: Errore query.";

			// headers
			$headers = "From: $to\r\n";
			$headers .= "Reply-To: $to\r\n";
			$headers .= "Return-Path: $to\r\n";

			// manda la mail
			if (!mail($to, $subject, $testo, $headers))
			{
				// se non va a buon fine, mostra l'errore
			   die("Errore durante l'invio della Segnalazione!");
			}

		}

		if(!empty($this->logfile))
		{
			$fp = @fopen($this->logfile, "a");
			@fwrite($fp, $tipo . date("d/m/Y H:i:s")." - Si è verificato un errore: $errore\r\n");
			@fclose($fp);
		}

		if($this->dieerror)
		{
			// mostra errore personale
			die($errore);
		}
	}

	/**
	 * Esegue la query al database
	 *
	 * Param: $query (string) - la query da eseguire al database
	 * Param: $manualError (string) - errore personalizzato in caso di fallimento della query
	 */
	function Query($query, $manualError = "")
	{
		$query = stripslashes($query);
		$query = addslashes($query);

		// eseguo la query
		$rs = mysql_query($query) or $this->getErr($manualError);

		// se è andata bene
		if($rs)
		{
			if(!empty($this->logfile) && $this->logall)
			{
				$fp = @fopen($this->logfile, "a");
				@fwrite($fp, $tipo . date("d/m/Y H:i:s")." - Query eseguita correttamente: $query\r\n");
				@fclose($fp);
			}
			// restituisco il link di risorsa
			return $rs;
		}
	}

	/**
	 * Ottiene i dati come oggetti (da usare come mysql_fetch_object)
	 *
	 * Param: $query (resource link) - la risorsa ottenuta dalla funzione doQuery
	 */
	function getObject($query)
	{
		// ottiene le righe come oggetto
		$rig = @mysql_fetch_object($query);

		// restituisce il tutto
		return $rig;
	}

	/**
	 * Chiude la connessione al Database
	 */
	function Close()
	{
		mysql_close($this->risorsa);
	}

	/*********************************** Funzioni Utili ****************************************/

	/**
	 * Ottiene i dati ottenuti da una query SELECT in un array
	 *
	 * Param: $query (resource link) - la risorsa ottenuta dalla funzione doQuery
	 * Param: $associativo (boolean) - determina se creare un sotto-array associativo per ogni riga, oppure no
	 */
	function getArray($query, $associativo = true)
	{
		// dichiaro e svuoto l'array
		$arrayCampi = array();

		// ciclo i nomi dei campi nella SELECT e li metto in array
		for($i = 0; $i < @mysql_num_fields($query); $i++)
		{
			$arrayCampi[] = @mysql_fetch_field($query)->name;
		}

		// dichiarazione e svuotamento array $dati
		$dati = array();

		// ciclo per ottenere i valori associativi in $linea
		while($linea = @mysql_fetch_array($query, MYSQL_ASSOC))
		{

			// dichiaro e svuoto l'array $par
			$par = array();

			// ciclo i nomi passati nell'array $arrayCampi
			foreach($arrayCampi as $nomi)
			{
				// se è impostato l'associativo
				if($associativo)
				{
					// mette in $par i valori come array associativo
					$par[$nomi] = $linea[$nomi];
				}
				else // ... altrimenti ...
				{
					// mette in $par i valori come array numerato
					$par[] = $linea[$nomi];
				}

			}

			// aggiunge all'array $dati, l'array $par
			$dati[] = $par;
		}

		// restituisce i dati
		return $dati;
	}

	/**
	 * Muove il puntatore interno ad una riga
	 *
	 * Param: $query (resource) - la risorsa della query
	 * Param: $riga (int) - la riga da cui iniziare - Default: 0
	 */
	function dataSeek($query, $riga = 0)
	{
		return @mysql_data_seek($query, $riga);
	}

	/**
	 * Inserisce un array (chiave => valore) nel database
	 *
	 * Param: $table (string) - la tabella del database
	 * Param: $array (array) - l'array da cui prendere i valori
	 */
	function insertArray($table, $array)
	{
		$keys = array_keys($array);

		$values = array_values($array);

		$sql = 'INSERT INTO ' . $table . '(' . implode(', ', $keys) . ') VALUES ("' . implode('", "', $values) . '")';

		return($this->Query($sql));
	}

	/**
	 * Resetta l'ultimo ID autoincrement
	 *
	 * Param: $table (string) - la tabella del database
	 */
	function resetIncrement($table)
	{
		$get = $this->Query("SELECT MAX(id) as mxid FROM $table");

		if($this->Found($get))
		{
			$max = $this->getObject($get);

			$mxid = (int)$max->mxid;

			$mxid++;

			$this->Query("ALTER TABLE $table AUTO_INCREMENT = $mxid");
		}
	}

	/**
	 * Ottiene un campo specifico
	 *
	 * Param: $campo (string) - il campo da restituire
	 * Param: $table (string) - la tabella da cui estrarre il campo
	 * Param: $where (string) - la clausula where
	 */
	function getField($campo, $table, $where)
	{
		$query = $this->Query("SELECT $campo FROM $table WHERE $where LIMIT 1");

		$risultato = $this->getObject($query);

		return $risultato->$campo;
	}
}

Ora vediamo come usare la classe, qui di seguito il codice di esempio commentato che poi andremo ad analizzare riga per riga:


/**
 * @description Example File of SQLManager class
 * @author StefanoV
 * @copyright 2010
 */

// richiede la libreria
require_once("libs/SQLManager.class.php");

// valorizza la variabile con la classe applicando i parametri:
// 1. Visualizza errori con die() - (bool) - Default: true
// 2. Invia errore via email - (string) - Default:
// 3. Salva un log degli errore - (string) - Default:
// 4. Includi le query andate a buon fine nel log - (bool) - Default: false
$db = new SQLManager(true, "", "log.txt", true);

	// utilizza una connessione gia stabilita in precedenza
	//$db->usaRisorsa($connessione);

// connette al db (host, user, pass, db)
$db->Open("localhost", "root", "test", "cmsv");

// esegue la query settando un errore personale in caso di fallimento
$ri = $db->Query("SELECT * FROM cmsv_sezioni", "Errore Query Clienti!!");

		// ottiene i dati della SELECT da ciclare restituendoli come oggetti
		//while($riga = $db->getObject($ri))
		//{
		//	echo $riga->campo;
		//}

	// se trova almeno un valore
	if($db->Found($ri))
	{
			// stampa i valori a partire dal terzo
			//$db->dataSeek($ri, 3);

		// ottiene un array di valori, e impostando l'array interno come associativo (true)
		$array_val = $db->getArray($ri, true);

		// conta i record restituiti
		$righe = $db->Count($ri);

				// ottiene l'ultimo ID inserito dopo una query INSERT
				//$numID = $db->lastID();

		// libera la memoria
		$db->Free($ri);

		// Visualizza i Dati Ottenuti
		echo "<pre>";

		echo "N° Records: " . $righe;

		echo "<br /> <br />";

		print_r($array_val);

		echo "</pre>";
	}

	/********************* altre funzioni ************************/

		// inserisce un array in una tabella
		// $dati = array();
		// $dati["campo"] = "valore";
		// $dati["campo2"] = "valore2";
		// $db->insertArray("tabella", $dati);

		// resetta l'autoincrement della tabella portandolo al primo id disponibile
		// $db->resetIncrement("tabella");

		// effettua una select e restituisce un campo
		// echo $db->getField("campo", "tabella", "id = 1");

	/*************************** fine funzioni ********************/

	// chiude la connessione al database
	$db->Close();

Veniamo ora alla documentazione della classe:

$db = new SQLManager(true, “”, “log.txt”, true);
Serve a valorizzare la variabile con la classe, i parametri sono:
1. Decide se stampare l’errore con un die() – (bool) – Default: true
2. Invia gli errori via email – (string) – Default: “”
3. Salva un log degli errori – (string) – Default: “”
4. Includi le query andate a buon fine nel log – (bool) – Default: false
Non vi consiglio di usare la fuzione email, altrimenti in caso di molti errori intaserete la vostra casella email

function usaRisorsa($risorsa)
Serve a far usare alla classe un’altra connessione
$risorsa – La risorsa di connessione al database

function Open($host, $user, $pass, $db)
Serve ad aprire la connessione al database, i parametri sono:
$host – L’host del database
$user – Il nome utente del database
$pass – La password del database
$db – Il nome del database

function Free($query)
Libera la memoria occupata dalla risorsa
$query – il link di risorsa restituito dalla query

function lastID()
Ottiene l’ultimo id dopo una query INSERT

function Count($query)
Conta le righe dopo una query SELECT
$query – il link di risorsa restituito dalla query

function Found($query)
Restituisce TRUE se trova almeno una riga in una query SELECT
$query – il link di risorsa restituito dalla query

function Query($query, $manualError = “”)
Invia una query al database
$query (string) – La query da inviare al database
$manualError (string/optional) – Se settato verrà stampato/registrato un errore personalizzato anzichè quello restituito da mysql_error()

function getObject($query)
Restituisce un oggetto con i risultati di una query SELECT
$query – il link di risorsa restituito dalla query

function Close()
Chiude la connessione al database

In più ci sono alcune funzioni utili quali:

function getArray($query, $associativo = true)
Restituisce un array con tutti i risultati
$query – il link di risorsa restituito dalla query
$associativo (bool) – Indica se l’array restituito dovrà essere associativo

function dataSeek($query, $riga = 0)
Imposta il puntatore interno della risorsa restituita dalla query
$query – il link di risorsa restituito dalla query
$riga (int/optional) – Indica da quale riga partire

function insertArray($table, $array)

Inserisce un array di valori nel database
$table (string) – Tabella in cui inserire i dati
$array (array) – Array da inserire (key => value)

function resetIncrement($table)
Resetta l’id di autoincrement all’ultimo valore disponibile
$table (string) – Tabella da resettare

function getField($campo, $table, $where)
Restituisce il valore di un campo del database
$campo (string) – Il campo da ottenere
$table (string) – La tabella in cui cercare
$where (string) – La clausula where

Per scaricare l’esempio completo clicca qui: Classe SQLManager



8 Commenti

  1. stefanov89 ha detto:

    Ciao,
    puoi provare a rendere globale la variabile istanziata con la classe e vedere se da dentro la classe risulta raggiungibile (non ho il tempo di provare ma in teoria dovrebbe andare).
    Altrimenti può fare come hai detto tu, istanziare la classe all'interno della classe o provare ad estendere la classe…

  2. Andrea Dell'Orco ha detto:

    Ciao, grazie per la classe.
    Ho però una domanda, come faccio a usare questa classe per effettuare query in altre classi.

    Per esempio, in testa alla pagina istanzio la classe del db ed effettuo la connessione con il database.
    Poi vado a creare altri oggetti diversi, ma a loro volta devono farmi query all'interno delle loro classi(magari in construct). Mi converrebbe istanziare nuovi oggetti db all'interno di queste classi ? estendere la classe del db? cosa?

    grazie

  3. stefanov89 ha detto:

    Ciao,
    scusa il ritardo nella risposta ma nel cambio della gestione dei commenti mi ha saltato qualche notifica.

    Riguardo il file della classe è tutto scritto in alto nel post, metti il file della classe con il codice all'interno, e poi dal file in cui ti serve utilizzare la classe la richiami con i codici riportati sopra.

  4. Mario ha detto:

    per metterla meglio devo volevo capire come devo usare questo file class per connettermi ad un DB ed effettuare le operazioni….
    sono un neofita, so che la domanda ti sembra assurda….
    Grazie in anticipo

  5. Mario ha detto:

    Ciao mi sto avvicinando alla programmazione in PHP da auto didatta, volevo sapere dove si vanno a posizionere le classi???..
    Grazie

  6. StefanoV ha detto:

    Si restituisce un array multidimensionare con tutti i record

    • Dolce ha detto:

      I think that what you posted was very loaigcl. But, think about this, what if you were to create a killer post title? I mean, I don’t wish to tell you how to run your blog, but suppose you added a title that grabbed folk’s attention? I mean Make Archives.php Include Custom Post Types is a little boring. You should peek at Yahoo’s home page and watch how they create post headlines to get viewers interested. You might try adding a video or a related pic or two to get people excited about everything’ve got to say. Just my opinion, it would make your posts a little livelier.

  7. Valerio ha detto:

    Ma in pratica il metodo getArray() restituisce un array bidimensionale?

Lascia un commento

%d blogger hanno fatto clic su Mi Piace per questo: