25
Mar
Gestione della connessione MySQL in PHP: la mia classe
Condivido un pezzo di codice che ritengo fondamentale per una creazione e gestione chiara di siti web dinamici basati su PHP/MySQL.
class Database {
private $conn;
public $queries;
public $time;
private $buffer_values;
function __construct() {
$this->conn = mysql_connect(MYSQL_HOSTNAME, MYSQL_USERNAME, MYSQL_PASSWORD) or die("Connessione non riuscita: " . mysql_error());
mysql_select_db(MYSQL_DATABASE) or die("Connessione non riuscita: " . mysql_error());
$this->queries = 0;
$this->time = 0;
$this->reset_buffer_values();
}
function __destruct() {
mysql_close($this->conn);
}
/*****/
private function reset_buffer_values() {
if (isset($this->buffer_values)) unset($this->buffer_values);
$this->buffer_values = Array();
}
public function escape($s) {
return mysql_real_escape_string($s, $this->conn);
}
/*****/
public function sql($sql) {
$this->time -= microtime('get_as_float');
$res = mysql_query($sql, $this->conn);
$this->time += microtime('get_as_float');
$this->queries++;
return $res;
}
public function rows($res = false) {
// $res deve essere passato solo per query SELECT e SHOW
if ($res === false) return mysql_affected_rows($this->conn);
else return mysql_num_rows($res);
}
public function fetch($res) {
return mysql_fetch_assoc($res);
}
public function insert_id() {
return mysql_insert_id($this->conn);
}
public function get_row($sql) {
$res = $this->sql($sql);
if ($res === false) return false;
return $this->fetch($res);
}
public function get_var($sql) {
$res = $this->sql($sql);
if ($res === false) return false;
$record = mysql_fetch_array($res);
if ($record === false) return false;
return $record[0];
}
public function set_value($name, $value) {
$this->buffer_values[$name] = $value;
}
public function add_row($table) {
$sql = "INSERT INTO $table ";
$sql .= "(".implode(', ', array_keys($this->buffer_values)).") ";
$values = '';
foreach ($this->buffer_values as $value) {
if (strlen($values) > 0) $values .= ', ';
if (gettype($value) == 'string') {
$values .= "'".$this->escape($value)."'";
} else {
$values .= $value;
}
}
$sql .= "VALUES ($values)";
$this->reset_buffer_values();
return $this->sql($sql);
}
}
A monte la definizione delle costanti. Non ho mai avuto la necessità di gestire connessioni a diversi database per cui è la classe a leggere direttamente le costanti. Diversamente basterebbe modificare il costruttore richiedendo i parametri necessari.
define('MYSQL_HOSTNAME', 'localhost');
define('MYSQL_USERNAME', 'root');
define('MYSQL_PASSWORD', 'securepassword');
define('MYSQL_DATABASE', 'miodb');
Tanto per chiarezza, qualche esempio:
Inizializzazione
$db = new Database();
Acquisizione di una variabile singola (un campo di una singola riga)
$sql = "SELECT colonna FROM tabella WHERE chiave LIKE 'chiave univoca'"; echo $db->get_var($sql);
Acquisizione di una riga singola
$sql = "SELECT * FROM tabella WHERE chiave LIKE 'chiave univoca'"; $record = $db->get_row($sql); echo $record['campo1'] . ' ' . $record['campo2'];
Acquisizione di n righe
$sql = "SELECT * FROM tabella WHERE anno < 2009"; $res = $db->sql($sql); while ($record = $db->fetch($res)) { echo $record['chiave'] . '
'; }Ottenere il numero di righe restituite da una
SELECToSHOW$sql = "SELECT * FROM tabella WHERE anno < 2009"; $res = $db->sql($sql); echo $db->rows($res);
Ottenere il numero di righe restituite da una
UPDATE,INSERT,DELETE, ecc...$sql = "DELETE FROM tabella WHERE anno < 2009"; $db->sql($sql); echo $db->rows();
Inserimento di un nuovo record
$db->set_value('chiave', 'xyz'); $db->set_value('anno', 2009); $db->set_value('numero', settype('10', 'float')); $db->add_row('tabella');Ottenere l'id della colonna
AUTO_INCREMENTa seguito di unINSERTecho $db->insert_id();
Statistiche numero e tempo query eseguite nella connessione
echo $db->queries . ' in ' . $db->time . ' secondi';
function get_querystring($qs) {
if (get_magic_quotes_gpc()) {
$qs = stripslashes($qs);
} else {
$qs = $qs;
}
return $qs;
}
$db = new Database();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$db->set_value('nome', get_querystring($_POST['nome']);
$db->set_value('cognome', get_querystring($_POST['cognome']);
$db->add_row('anagrafica');
}
Il magic_quotes non è sempre a on nel php.ini, quindi è bene verificare se rimuovere o meno le slashes (\) dalle variabili $_POST e $_GET prima di passare i valori alla classe Database.
4 Commenti
grazie per la segnalazione, classe utilissima.
mi toccherà usarla :)
la provo questa sera, anche se a occhio mi pare molto valida!
ciao
magari lo implemento.
L'update non l'ho fatto per via delle varie sfumature di complessità che può avere. Più che altro nel WHERE. Per cui preferisco scrivere direttamente la query SQL.
Commenta