Bijour bijour :)
Bon, alors je reviens avec une énième version de wrapper MySQL... mais cette fois ci, j'ai fais plus large. J'ai utilisé comme modèle MySQLi en utilisant les fonctions MySQL de base.
Tout est découpé en 3 :
Le wrapper à proprement parlé, une classe de préparation de requète SQL et une classe de résultats.
J'ai ajouté autant de classes abstraites que possible (histoire que si vous utilisez autre chose, il vous suffit d'utiliser le modèle déja présent) et 3 interfaces pour un futur developpement organisé.
Voici ce que cela donne :
Source / Exemple :
<?php
/**
- Interface de liaison avec le SGBD
*
interface iFab {
public function Query($sql);
public function AffectedRows();
public function Close();
public function Ping();
public function Prepare($sql);
public function ConnectTo();
}
/**
- Interface de préparation des commandes SQL
*
interface iStatement {
public function __construct($sql, $link);
public function BindResult($format);
public function Execute();
}
/**
- Interface de dialogue des resultats SQL
*
interface iResult {
public function __construct($query, $sql);
public function FetchAll();
public function FetchRow();
public function FetchArray();
public function FetchAssoc();
public function FetchObject($classname=NULL, $args=NULL);
public function NumRows();
public function Seek($offset);
public function Free();
}
/**
- Classe d'abstraction des résultats SQL
*
abstract class DatabaseResult {
/**
- Contient la ressource de la requète
*
protected $query;
/**
*
protected $sql;
}
/**
- Classe d'abstraction de la préparation des requètes SQL
*
abstract class DatabaseStatement {
/**
*
protected $sql;
/**
- Lien de communication avec le SGBD
*
protected $link;
}
/**
- Classe d'abstraction de toutes les bases de données.
*
abstract class DatabaseFactory {
/**
*
protected $host;
/**
*
protected $user;
/**
*
protected $passwd;
/**
*
protected $dbname;
/**
- Identifiant de connection unique
*
protected $link;
/**
- Instancie une classe utilisant une connection avec un SGBD
*
- @param string $host
- @param string $user
- @param string $passwd
- @param string $dbname
- /
public function __construct($host, $user, $passwd, $dbname) {
$this->host = $host;
$this->user = $user;
$this->passwd = $passwd;
$this->dbname = $dbname;
}
/**
- Méthode de connection au serveur de SGBD
*
abstract protected function ConnectTo();
}
/**
- Classe d'abstraction pour le SGBD MySQL
*
abstract class MySQLFab extends DatabaseFactory implements iFab {
/**
- Récupère l'encodage du serveur
*
public $encoding;
/**
- Récupère les infos du client
*
public $client_info;
/**
- Récupère les infos de l'hôte
*
public $host_info;
/**
- Récupère les infos du protocole utilisé
*
public $proto_info;
/**
- Récupère les infos du serveur
*
public $server_info;
/**
- Récupère le numéro d'ID du thread
*
public $thread_id;
/**
- Méthode de connection au SGBD MySQL
*
protected function ConnectTo() {
$this->link = mysql_connect($this->host, $this->user, $this->passwd);
if ( $this->link === FALSE )
throw new MySQLException(1, $this->host, $this->user);
if ( !mysql_select_db($this->dbname, $this->link) )
throw new MySQLException(mysql_error(), $this->dbname);
$this->encoding = mysql_client_encoding($this->link);
$this->client_info = mysql_get_client_info();
$this->host_info = mysql_get_host_info($this->link);
$this->proto_info = mysql_get_proto_info($this->link);
$this->server_info = mysql_get_server_info($this->link);
$this->thread_id = mysql_thread_id($this->link);
}
/**
- Méthode pour envoyer une requète MySQL
*
- @param string $sql
- @return MySQLResult Object / int
- /
public function Query($sql) {
try {
if ( ! isset($this->link) ) $this->ConnectTo();
$query = @mysql_query($sql, $this->link);
if ( $query === FALSE )
throw new MySQLException(10, $sql);
} catch ( MySQLException $e ) {
die ( $e->GetMessage() );
}
if ( strtolower(substr($sql, 0, 6)) === 'select' )
return new MySQLResult($query, $sql);
else
return $this->AffectedRows();
}
/**
- Retourne le nombre de champs modifiés ou insérés
*
public function AffectedRows() {
return mysql_affected_rows($this->link);
}
/**
- Ferme la connection avec le SGBD MySQL
*
public function Close() {
try {
if ( !mysql_close($this->link) )
throw new MySQLException(3, $this->host, $this->user);
unset($this->link);
} catch ( MySQLException $e ) {
die( $e->GetMessage() );
}
}
/**
- Effectue un ping sur le SGBD
*
public function Ping() {
return mysql_ping($this->link);
}
/**
- Renvoit un objet pour la préparation des requètes SQL
*
- @param string $sql
- @return MySQLStatement Object
- /
public function Prepare($sql) {
return new MySQLStatement($sql, $this->link);
}
}
/**
- Classe de gestion MySQL en type Singleton
*
class MySQLSingle extends MySQLFab {
/**
- Gestion de la connection unique
*
static protected $_link;
/**
- Instancie la classe et vérifie si une connection existe déja
*
- @param string $host
- @param string $user
- @param string $passwd
- @param string $dbname
- /
public function __construct($host='localhost', $user='root', $passwd='', $dbname='blog') {
parent::__construct($host, $user, $passwd, $dbname);
if ( isset(self::$_link) ) $this->link = self::$_link;
}
/**
- Overloading de la connection à la base de donnée
*
protected function ConnectTo() {
parent::ConnectTo();
self::$_link = $this->link;
}
}
/**
- Classe de gestion MySQL en type Multiton
*
class MySQLMulti extends MySQLFab {
/**
- Défini les liens de connections existantes
*
static protected $_links = array();
/**
*
- @param string $host
- @param string $user
- @param string $passwd
- @param string $dbname
- /
public function __construct($host='localhost', $user='root', $passwd='', $dbname='blog') {
parent::__construct($host, $user, $passwd, $dbname);
if ( isset(self::$_links[$host.$user]) )
$this->link = self::$_links[$host.$user];
}
/**
- Overloading de la connection MySQL
*
protected function ConnectTo() {
parent::ConnectTo();
self::$_links[$this->host.$this->user] = $this->link;
}
}
/**
*
class MySQLResult extends DatabaseResult implements iResult {
public function __construct($query, $sql) {
$this->query = $query;
$this->sql = $sql;
}
public function FetchAll() {
$a = array();
while ( $data = mysql_fetch_array($this->query) )
$a[] = $data;
return $a;
}
public function FetchRow() {
return mysql_fetch_row($this->query);
}
public function FetchArray() {
return mysql_fetch_array($this->query);
}
public function FetchAssoc() {
return mysql_fetch_assoc($this->query);
}
public function FetchObject($classname=NULL, $args=NULL) {
return mysql_fetch_object($this->link, $classname, $args);
}
public function NumRows() {
return mysql_num_rows($this->query);
}
public function Seek($offset) {
try {
if ( !mysql_data_seek($this->query, (int) $offset) )
throw new MySQLException(11, $this->sql);
} catch ( MySQLException $e ) {
die ( $e->GetMessage() );
}
}
public function Free() {
try {
if ( !mysql_free_result($this->query) )
throw new MySQLException(12, $this->sql);
unset($this);
} catch ( MySQLException $e ) {
die ( $e->GetMessage() );
}
}
}
/**
- Classe de traitement pour MySQL
*
class MySQLStatement extends DatabaseStatement implements iStatement {
public function __construct($sql, $link) {
$this->sql = $sql;
$this->link = $link;
}
public function BindResult($format) {
for ($i=1, $n=strlen($format); $i<=$n; $i++) {
switch (strtolower($format[$i-1])) {
case 'i':
$a = func_get_arg($i);
$this->sql = str_replace('{'.$i.'}', (int) $a, $this->sql);
break;
case 's':
$a = func_get_arg($i);
$this->sql = str_replace('{'.$i.'}', mysql_real_escape_string($a, $this->link), $this->sql);
break;
}
}
}
public function Execute() {
try {
if ( ! isset($this->link) ) $this->ConnectTo();
$query = @mysql_query($this->sql, $this->link);
if ( $query === FALSE )
throw new MySQLException(10, $this->sql);
} catch ( MySQLException $e ) {
die ( $e->GetMessage() );
}
if ( strtolower(substr($this->sql, 0, 6)) === 'select' )
return new MySQLResult($query, $this->sql);
else
return $this->AffectedRows();
}
}
class MySQLException extends Exception {
static $xmlfile;
static $lang = 'fr';
public function __construct($errno) {
// if ( !isset(self::$xmlfile) ) self::$xmlfile = simplexml_load_file('./xml/db/'.self::$lang.'.php');
// Manque le parsing !
parent::__construct($errno);
}
}
?>
<?php
// En utilisation, cela donne :
$db = new MySQLSingle('host', 'user', 'passwd', 'dbname');
$query = $db->query('SELECT montruc FROM machin WHERE x = 1);
$data = $query->FetchArray();
$query->Free();
echo $data['montruc'];
// Bref, ca marche comme avant :p
// Autre facon de faire :
$sql = $db->prepare('SELECT machin, chose FROM truc WHERE untruc = {1} AND autretruc = "{2}"');
$sql->BindResult('is', $une_variable, $une_autre_variable);
$query = $sql->Execute();
$data = $query->FetchRow();
echo $data[0];
// Ca marche aussi :)
?>
Conclusion :
Il faut savoir que MySQLStatement::BindResult() fait un cast automatique des variables... enfin que pour INT pour le moment. Je fais aussi un mysql_real_escape_string() sur les types chaines !
Bref, un gros truc .. j'ai zappé la partie Exception (pas eu le temps, suis malade en ce moment :s) mais si y'a de la modif à faire... c'est avec plaisir :)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.