JeuWeb - Crée ton jeu par navigateur
[POO] Classe InterfaceSQL : Conseillez moi - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [POO] Classe InterfaceSQL : Conseillez moi (/showthread.php?tid=1129)

Pages : 1 2


[POO] Classe InterfaceSQL : Conseillez moi - Plume - 28-04-2007

Bonsoir à tous.

J'initialise un nouveau topic dans plusieurs buts :
~ Faire plaisir à ceux qui voulaient voir ma façon de coder
~ Avoir des avis, des conseils, des critiques [...] sur le code que je vais poster à la suite

Je maitrise relativement les fondements de l'approche objet, mais n'ayant jamais mit en pratique avec PHP, il s'agit là de ma première expérience.
Comme toute première fois , cela fait mal, alors je compte sur vous pour tout de même faire passer le morceau avec douceur Smile

Code PHP :
<?php
class InterfaceSQL
{
// Déclaration des variables //
private $c_hebergeur; // adresse/nom de l'hébergeur
private $c_utilisateur; // nom de l'utilisateur
private $c_motDePasse; // mot de passe de l'utilisateur
private $c_baseDeDonnees; // nom de la base de données
private $e_identifiantConnexion; // identifiant de la connexion
private $b_connexionEnCours; // Connexion en cours ?

private $c_requete;
private
$r_resultat;

// Constructeur
function InterfaceSQL()
{
$this->c_hebergeur = '';
$this->c_utilisateur = '';
$this->c_motDePasse = '';
$this->c_baseDeDonnees = '';
$this->e_identifiantConnexion = NULL;
$this->b_connexionEnCours = FALSE;
}

// Connexion au serveur MySQL
function e_connexion()
{
if(
$this->b_connexionEnCours == FALSE)
{
$this->e_identifiantConnexion = @mysql_connect($this->c_getHebergeur(), $this->c_getUtilisateur(), $this->c_getMotDePasse());
if(
$this->e_identifiantConnexion == false)
{
$this->erreurConnexionSQL();
$this->b_connexionEnCours = FALSE;
return
0;
}

$c_baseDeDonnees = @mysql_select_db($this->c_getBaseDeDonnees($this->e_identifiantConnexion));
if(
$c_baseDeDonnees == false)
{
$this->erreurSQL('Impossible de sélectionner la base de données : <b>'.$this->c_getBaseDeDonnees().'</b>');
$this->b_connexionEnCours = FALSE;
return
0;
}
}

$this->b_connexionEnCours = TRUE;

return
$this->e_identifiantConnexion;
}

// selectionInformations
function selectionInformations($nomTable, $nomIdentifiant = '', $identifiant = '')
{
if(
$nomIdentifiant !== '' AND $identifiant !== '')
{
$this->c_requete = 'SELECT * FROM '.$nomTable.' WHERE '.$nomIdentifiant.' = "'.$identifiant.'"';
}
else
{
$this->c_requete = 'SELECT * FROM '.$nomTable;
}

return
$this->c_requete;
}

// executionRequete
function executionRequete()
{
$this->r_resultat = @mysql_query($this->c_requete);
if(
$this->r_resultat == FALSE)
{
$this->c_erreurSQL('V&eacute;rifiez la requ&ecirc;te : '.$this->c_requete.'<br />');
return
0;
}

return
$this->r_resultat;
}

// deconnexion
function deconnexion()
{
if(
$this->b_connexionEnCours == TRUE)
{
@
mysql_close($this->e_identifiantConnexion);
}

$this->b_connexionEnCours = FALSE;
}

// Erreur de connexion au serveur MySQL
function erreurConnexionSQL()
{
$c_texte = '<font style="font-family : arial, helvetica; font-size : 12px; color : red">';
$c_texte .= 'Connexion impossible vers le serveur : <b>'.$this->c_getHebergeur().'</b><br />';
$c_texte .= '</font>';

$this->toString($c_texte);
}

// Erreur SQL
function erreurSQL($c_message)
{
$c_texte = '<font style="font-family:arial, helvetica; font-size:12px; color:red">';
$c_texte .= $message;
$c_texte .= '<hr>';
$c_texte .= 'Erreur SQL : '.@mysql_error($this->e_identifiantConnexion).'<br />';
$c_texte .= 'Num&eacute;ro de l\'erreur : '.@mysql_errno($this->e_identifiantConnexion).'<br />';
$c_texte .= '</font>';

$this->toString($c_texte);
}

// Fonctions d'initialisation
function setHebergeur($c_hebergeur = '')
{
if(empty(
$c_hebergeur))
{
$this->c_hebergeur = 'localhost';
}
else
{
$this->c_hebergeur = $c_hebergeur;
}
}

function
setUtilisateur($c_utilisateur = '')
{
if(empty(
$c_utilisateur))
{
$this->c_utilisateur = 'root';
}
else
{
$this->c_utilisateur = $c_utilisateur;
}
}

function
setMotDePasse($c_motDePasse = '')
{
if(empty(
$c_motDePasse))
{
$this->c_motDePasse = '';
}
else
{
$this->c_motDePasse = $c_motDePasse;
}
}

function
setBaseDeDonnees($c_baseDeDonnees)
{
if(empty(
$c_baseDeDonnees))
{
$this->c_baseDeDonnees = 'mysql';
}
else
{
$this->c_baseDeDonnees = $c_baseDeDonnees;
}
}

// Fonctions GET
function c_getHebergeur()
{
return
$this->c_hebergeur;
}

function
c_getUtilisateur()
{
return
$this->c_utilisateur;
}

function
c_getMotDePasse()
{
return
$this->c_motDePasse;
}

function
c_getBaseDeDonnees()
{
return
$this->c_baseDeDonnees;
}

// Fonction toString()
function toString($c_message = '')
{
if(empty(
$c_message))
{
$c_texte = 'H&eacute;bergeur : <b>'.$this->c_getHebergeur().'</b<<br />';
$c_texte .= 'Utilisateur : <b>'.$this->c_getUtilisateur().'</b><br />';
$c_texte .= 'Mot de passe : <b>'.$this->c_getMotDePasse().'</b><br />';
$c_texte .= 'Base de donn&eacute;es : <b>'.$this->c_getBaseDeDonnees().'</b><br />';
}
else
{
$c_texte = $c_message;
}

print(
$c_texte);
}
}
?>

Je compte améliorer ça en développant des méthodes de configuration qui me permettraient de récupérer des informations dans des fichiers textes.

J'aurais pour cela une question : Classe ou pas ?

A ceux qui auront eu la patience, la force & le courage nécessaire pour tout lire : Merci ! ^^


RE: [POO] Classe InterfaceSQL : Conseillez moi - denisc - 29-04-2007

Pour les assesseurs, je n'utilise pas de typage... Je fait simplement des getMonAttribut et des setMonAttribut... Pour le reste, c'est de l'objet et de laccès aux données!


RE: [POO] Classe InterfaceSQL : Conseillez moi - Nessper - 29-04-2007

Ben ton code est bien propre donc facile à lire, c'est cool. Si j'ai compris ta question c'est est-ce que tu trouves utile de mettre tes fonctions dans une classe, c'est ça? Si c'est le cas moi je dis oui car tu pourra dans ce cas là utiliser tes variables en interne dans ta classe. L'appel de tes fonctions les une entre les autres sera également simplifié. Donc pour un confort d'utilisation, oui, garde ta classe.


RE: [POO] Classe InterfaceSQL : Conseillez moi - Plume - 29-04-2007

Ma question concernait mon envie de coder la configuration à partir de fichiers textes. Devrais-je développer une classe `Fichiers` (pour l'exemple) ou bien seulement développer des méthodes dans ma classe SQL ?

Et évidemment, Denisc, je n'ai pas la prétention de développer quelque chose d'extraordinaire. Chez moi, tout est simple ^^


RE: [POO] Classe InterfaceSQL : Conseillez moi - denisc - 29-04-2007

Loin de moi l'idée de parler d'extra-ordinaire, mais c'est une façon de coder.
En C#, comme en Java (et aussi en PHP Wink) on utilise couramment la notation get et set pour accéder aux variables que l'on met, par ailleurs en private (ou éventuellement en protected) dans les classes, c'est tout...
Et c'est d'ailleurs la seule remarque négative quant à ton code...

Par contre, OUI!!! fait une classe à part pour gérer tes fichiers de configuration, car elle pourra être utilisée par d'autres classes que la SQL Smile


RE: [POO] Classe InterfaceSQL : Conseillez moi - Plume - 30-04-2007

denisc a écrit :on utilise couramment la notation get et set pour accéder aux variables
Je m'en doutais ! Big Grin J'y ai pensé pendant que je codais. Mais moi & ma manie de ne vouloir utiliser que du français ^^ J'vais changer ça alors Sad

denisc a écrit :fait une classe à part pour gérer tes fichiers de configuration, car elle pourra être utilisée par d'autres classes que la SQL
C'est un fait ^^ C'est ce que je me suis dit aussi. Tant mieux pour moi si tu confirmes Big Grin En plus ma question était idiote puisqu'il est prévu d'utiliser des fichiers textes pour d'autre configuration <_<
Au temps pour moi Tongue


RE: [POO] Classe InterfaceSQL : Conseillez moi - Plume - 30-04-2007

Et voilà, p'ti up. J'ai fait les mini modif' ^^

Prochaine étape : class Configuration !
Puis adaptation de la classe SQL Smile


RE: [POO] Classe InterfaceSQL : Conseillez moi - Plume - 03-05-2007

Bonsoir ^^

Je voudrais vous demander si vous n'avez pas quelques conseils d'ajouts utiles niveau méthodes, vérifications ... Peut être même des choses à modifier, ou à enlever qui sait ? Peut être même des apports en optimisation Smile

Merci Smile

@ tchaOo°


RE: [POO] Classe InterfaceSQL : Conseillez moi - Plume - 14-11-2007

Tiens, j'viens de ressortir du tiroir quelques trucs intéressants & donc voilà le dernier visage de cette dernière Smile
Code PHP :
<?php

include_once( 'configuration.classe.php' );

interface
iDatabase
{
public function
ping();
public function
get_TempsExecutionRequete( $requete );
public function
enregistrements_affectes();

public function
executer_requete( $requete );
public function
selectionner( $table, $select, array $params = array() );
public function
ajouter( $table, $set );
public function
mettreajour( $table, $set, $where );
public function
detruire( $table, $where );
public function
vider( $table );
public function
prepare( $nomRequete, $requete );
public function
set( $nomVariable, $valeur );
public function
execute( $nomRequete, $using );
}

interface
iResultat
{
public function
__construct( $query );
public function
fetch_row();
public function
fetch_array();
public function
fetch_assoc();
public function
fetch_object( $classname=NULL, $args=NULL );
public function
nbre_enregistrements();
public function
free();
}

abstract class
Database
{
protected static
$instance; //instance de la classe ( il ne peut n'y en avoir qu'une )

public $nbreRequetes; //nombre de requetes effectuées par cette classe
public $connexionOuverte = false; //indique si la connexion est ouverte
public $connexion = false; //connexion en cours
protected $erreurs = array();
protected
$tempsExecution = 0.0;

public
$debug = false;
public
$executerRequetes = true;

protected
$serveur;
protected
$utilisateur;
protected
$motdepasse;
protected
$bdd;
protected
$SGBD;

protected
$fichierConfiguration;


abstract protected function
ouvrir_connexion();
abstract protected function
fermer_connexion();
abstract protected function
parse_params( array $params );

protected function
__construct( $fichierConfiguration )
{
$this->fichierConfiguration = $fichierConfiguration;
$configuration = Configuration::chargement_ini( $fichierConfiguration );
$this->serveur = $configuration['serveur'];
$this->utilisateur = $configuration['utilisateur'];
$this->motdepasse = $configuration['motdepasse'];
$this->bdd = $configuration['bdd'];
$this->SGBD = $configuration['sgbd'];

$this->ouvrir_connexion();
}

public function
__destruct()
{
$this->fermer_connexion();
}

public function
__toString()
{
$texte = '<p class=\'debugSQL\'><em>Affichage des informations concernant l\'instance de la classe SQL correspondant &agrave; la connexion :</em> <strong>'.$this->connexion.'</strong><br />'."\n";

$texte .= 'Serveur : <strong>'.$this->serveur.'</strong><br />'."\n";
$texte .= 'Base de donn&eacute;es : <strong>'.$this->bdd.'</strong><br />'."\n";
$texte .= 'Type de base de donn&eacute;es : <strong>'.$this->SGBD.'</strong><br />'."\n";

$texte .= 'Mode debug : <strong>';
if(
$this->debug )
$texte .= 'on';
else
$texte .= 'off';
$texte .= '</strong><br />'."\n";

$texte .= 'Connexion ouverte : <strong>';
if(
$this->connexionOuverte )
$texte .= 'oui';
else
$texte .= 'non';
$texte .= '</strong><br />'."\n";

$texte .= 'Nombre de requ&ecirc;tes effectu&eacute;es avec cette instance : <strong>'.$this->nbreRequetes.'</strong><br />'."\n";
$texte .= 'Nombre d\'erreurs qui se sont produites avec cette instance : <strong>'.sizeof( $this->erreurs ).'</strong><br />'."\n";
$texte .= 'Temps d\'ex&eacute;cution totale des requ&ecirc;tes de cette instance : <strong>'.$this->tempsExecution.'</strong><br /><br />'."\n";

if(
$this->debug )
$texte .= $this->debug();

$texte .= '</p>'."\n";

return
$texte;
}

public function
__sleep()
{
$this->fermer_connexion();
}

public function
__wakeup()
{
$this->ouvrir_connexion();
}

protected function
erreurSQL( $message )
{
$texte_erreur = '<span class=\'erreurSQL\'>'."\n";
$texte_erreur .= $message."\n";
$texte_erreur .= '</span>'."\n";

$this->erreurs[] = $texte_erreur;
}

public function
debug()
{
$texte_debug = '<em>Debugage de la classe SQL correspondant à la connexion :</em> <strong>'.$this->connexion.'</strong><br />'."\n";

if(
count( $this->erreurs ) > 0 )
{
foreach(
$this->erreurs as $erreur )
{
$texte_debug .= $erreur.'<br />'."\n";
}
}
else
$texte_debug .= 'Aucune erreur ne s\'est produite durant cette instance.<br />'."\n";

$texte_debug .= 'Fin du debugage de la classe SQL.<br />'."\n";

return
$texte_debug;
}

public function
active_debug()
{
$this->debug = true;
}

public static function
getInstance( $fichierConfiguration = './configuration/bdd.ini', $SGBD = 'MySQL' )
{
if(
self::$instance === null )
{
switch(
$SGBD )
{
case
'MySQL':
self::$instance = new MySQLDatabase( $fichierConfiguration );
break;
default:
throw new
Exception( 'Ce type de SGBD n\'est pas valable !' );
break;
}
}
return
self::$instance;
}

}


abstract class
DatabaseResultat
{
protected
$query;
public
$resultat;
}


class
MySQLDatabase extends Database implements iDatabase
{

protected function
ouvrir_connexion()
{
$this->connexion = @mysql_connect($this->serveur, $this->utilisateur, $this->motdepasse) or die( mysql_error() );
@
mysql_select_db($this->bdd, $this->connexion) or die( mysql_error() );
$this->connexionOuverte = true;
}

public function
fermer_connexion()
{
if(
$this->connexionOuverte )
@
mysql_close( $this->connexion );
$this->connexionOuverte = false;
}



public function
executer_requete( $requete )
{
$debut = microtime(true);
$query = @mysql_query( $requete );
$this->tempsExecution +=microtime(true) - $debut;

$this->nbreRequetes++;

if(
$query === FALSE )
{
$texte_requete = 'V&eacute;rifiez la requ&ecirc;te : <strong>'.$requete.'</strong><br />'."\n";
$texte_requete .= 'Erreur SQL : <strong>'.mysql_error().'</strong><br />'."\n";
$texte_requete .= 'Num&eacute;ro de l\'erreur : <strong>'.mysql_errno().'</strong><br />'."\n";
$this->erreurSQL( $texte_requete );

return
false;
}

if (
strtolower(substr($requete, 0, 6)) === 'select' )
return new
MySQLResultat( $query );
else
return
$this->enregistrements_affectes();
}

public function
selectionner( $table, $select, array $params = array() )
{
$requete = "SELECT ".$select." FROM ".$table;
$requete .= $this->parse_params( $params );
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
ajouter( $table, $set )
{
$requete = "INSERT INTO ".$table." SET ".$set;
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
mettreajour( $table, $set, $where )
{
$requete = "UPDATE ".$table." SET ".$set." WHERE ".$where;
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
detruire( $table, $where )
{
$requete = "DELETE FROM ".$table." WHERE ".$where;
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
vider( $table )
{
$requete = "TRUNCATE TABLE ".$table;
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
prepare( $nomRequete, $requete )
{
$requete = "PREPARE ".$nomRequete." FROM '".$requete."'";
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
set( $nomVariable, $valeur )
{
$requete = "SET @".$nomVariable."='".$valeur."'";
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}

public function
execute( $nomRequete, $using )
{
$requete = "EXECUTE ".$nomRequete." USING ".$using;
return
$this->executerRequetes ? $this->executer_requete( $requete ) : $requete;
}


public function
enregistrements_affectes()
{
return
mysql_affected_rows( $this->connexion );
}

public function
get_TempsExecutionRequete( $requete )
{
$debut = microtime(true);
@
mysql_query( $requete );
return
microtime(true) - $debut;
}

public function
ping()
{
return
mysql_ping( $this->connexion );
}

protected function
parse_params( array $params )
{
$retour = '';

if(
array_key_exists('where', $params))
$retour .= ' WHERE '.$params['where'];

if(
array_key_exists('leftJoin', $params))
{
if(
is_array( $params['leftJoin'] ) )
{
$i = 0;
$taille = count( $params['leftJoin'] );
while(
$i < $taille )
{
$retour .= ' LEFT JOIN '.$params['leftJoin'][$i];
$i++;
}
}
else
$retour .= ' LEFT JOIN '.$params['leftJoin'];
}

if(
array_key_exists('order', $params))
$retour .= ' ORDER BY '.$params['order'];

if(
array_key_exists('limit', $params))
$retour .= ' LIMIT '.$params['limit'];

return
$retour;
}

}


class
MySQLResultat extends DatabaseResultat implements iResultat
{
public function
__construct( $query )
{
$this->query = $query;
}

public function
fetch_row()
{
return
$this->resultat = mysql_fetch_row( $this->query );
}

public function
fetch_array()
{
return
$this->resultat = mysql_fetch_array( $this->query );
}

public function
fetch_assoc()
{
return
$this->resultat = mysql_fetch_assoc( $this->query );
}

public function
fetch_object( $nomClasse=NULL, $args=NULL )
{
return
$this->resultat = mysql_fetch_object( $this->query, $nomClasse, $args );
}

public function
nbre_enregistrements()
{
return
$this->resultat = mysql_num_rows( $this->query );
}

public function
free()
{
if( !
mysql_free_result( $this->query ) )
throw new
Exception( 'Impossible de libérer la mémoire !' );
unset(
$this );
}
}

?>

C'autre chose, non ?

~L~


RE: [POO] Classe InterfaceSQL : Conseillez moi - Zamentur - 14-11-2007

Ouai elle est cool.
Moi sur ma classe sql que j'avais fait pour ragol, j'avais mis quelques methode d'extration de resultat simplifié

Donc dans ce qui correspond(enfin pas exactement) à ta classe MySQLResultat

J'ai mis une methode extract_one($sql,$extract='fetch_array') qui renvoie directement la ligne de la requete sql
En gros le mysql_query et le mysql_fetch_array(ou assoc) sont fait à la suite ce qui est pratique si il n'y a qu'une ligne à extraire...

Dans la meme idée j'avais extract_ladata($sql) qui renvoyais la premiere donnée de la premiere ligne

Alors çà peut paraitre bete mais ces 2 methodes m'ont clarifié le code à mort, car à chaque fois çà fait 3 lignes qui en deviennent plus qu'une.

Le hic c'est que là çà serais difficile à mettre en place, puisque la classe Resultat est differente de la classe d'execution!

J'espere que t'as compris ce que je voulais dire j'aurrais peut etre due mettre un peu de code...

Edit: tu devrais rajouter une methode insert_id dans la classe Resultat, enfin bon de toute façon c'est le genre de trucs qui va super vite