Page 1 sur 1

Singleton de connexion et fermeture de connexion

Posté : 11 mai 2012, 16:36
par JulieDev
Bonjour,
après avoir mis en place un singleton de connexion dans un projet existant,
je rencontre des problèmes avec la connexion et déconnexion à la base.

J'ai fait quelques tests qui semblent indiquer que le problème vient de la 2e connexion qui ne se fait pas.
Sans doute à cause de mon singleton..

Exemple du résultat obtenu:
1re connexion à la base, affichage du var-dump de la connexion :
resource(6) of type (mysql link)

après 1re fermeture avec mysql_close, affichage du var-dump de la connexion :
resource(6) of type (Unknown)

2e connexion à la base, affichage du var-dump de la connexion :
resource(6) of type (Unknown)

2e fermeture avec mysql_close, affichage du var-dump de la connexion :
Warning: mysql_close(): 6 is not a valid MySQL-Link resource in C:\wamp\www\\Main\www\source\singletonConnexionBD.php on line 142

Est-ce qu'avec un singleton on ne peut pas fermer la connexion et la ré-ouvrir comme on veut ?
Merci par avance,
Julie

Re: Singleton de connexion et fermeture de connexion

Posté : 11 mai 2012, 19:50
par xTG
Montres nous le code de déconnexion. :)

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 09:27
par JulieDev
Bonjour,
eh bien voici ma classe singleton avec ma fonction close :
class singletonConnexionBD {

// Connexion definie par:
// identifiant connexion
    public static $_id;
//serveur
    private $_hostname;
// Login
    private $_username;
// Password
    private $_userpwd;
// Nom BD
    private $_dbname;
//
    private $_createBase;
//
    private $_configDir;
// Instance static de Connexion
    private static $_instanceConnexion;

// Setter
    private function setId($id) {
        if (!isset($id)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_id = $id;
        }
    }

    private function setHostname($hostname) {
        if (!isset($hostname)) { // test si la variable est initialisée
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_hostname = $hostname;
        }
    }

    private function setUsername($username) {
        if (!isset($username)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_username = $username;
        }
    }

    private function setUserpwd($userpwd) {
        if (!isset($userpwd)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_userpwd = $userpwd;
        }
    }

    private function setDbname($dbname) {
        if (!isset($dbname)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_dbname = $dbname;
        }
    }

    private function setCreateBase($createBase) {
        if (!isset($createBase)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_createBase = $createBase;
        }
    }

    private function setConfigdir($configDir) {
        if (!isset($configDir)) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        } else {
            $this->_configDir = $configDir;
        }
    }

// Ouverture de la connexion et sélection de la base
    private function connectToDB($hostname, $username, $userpwd, $dbname, $createBase = FALSE, $configDir="") {
// Open a connection to a MySQL server.
        $connection = mysql_connect($hostname, $username, $userpwd);
//echo'connexion ok';
        if ($connection == FALSE) {
            displayErrorAndExit('Impossible de se connecter au serveur MySQL : ' . mysql_error());
        }
// Select the MySQL database.
        $db = mysql_select_db($dbname, $connection);
        if ($db == FALSE AND $createBase == TRUE) {
// create the database if needed when asked
            $query = 'CREATE DATABASE ' . $dbname;
            if (mysql_query($query, $connection) == FALSE) {
                displayErrorAndExit('Impossible de cr�er la base de donn�e : ' . mysql_error());
            } else {
// create all database tables
                createDbTables($configDir);
                $db = mysql_select_db($dbname, $connection);
            }
        } elseif ($db == FALSE and $createBase == FALSE) {
// return an error when the database does not exist if it's not asked to create it
            displayErrorAndExit('Impossible de s�lectionner la base de donn�es : ' . mysql_error());
        }
        return $connection;
    }

// Constructeur de la classe Connexion
    private function __construct($hostname, $username, $userpwd, $dbname, $createBase = FALSE, $configDir="") {
//Methodes permettant l'acces en ecriture des variables
        $this->setHostname($hostname);
        $this->setUsername($username);
        $this->setUserpwd($userpwd);
        $this->setDbname($dbname);
        $this->setCreateBase($createBase);
        $this->setConfigdir($configDir);
//Tentative de connexion à la base
        try {
            self::$_id = $this->connectToDB($this->_hostname, $this->_username, $this->_userpwd, $this->_dbname, $this->_createBase, $this->_configDir);
        } catch (Exception $e) {
            $e->getMessage();
        }
    }

// Création d'une instance de connexion
    public static function getInstanceConnexion($hostname, $username, $userpwd, $dbname, $createBase = FALSE, $configDir="") {
        if (!isset(self::$_instanceConnexion)) {
            $c = __CLASS__;
            self::$_instanceConnexion = new $c($hostname, $username, $userpwd, $dbname, $createBase, $configDir);
        }
        return self::$_instanceConnexion;
    }

    public function getConnexionDatabase() {
        return self::$_id;
    }

//Destruction de l'instance de connexion
//    public function __destruct() {
//        if (isset(self::$_id) && !empty(self::$_id)) {
//            mysql_close(self::$_id);
//        }
//    }

  public static function close($id) {
        if (isset($id) && !empty($id)) {
            mysql_close(self::$_id);
        }
    }

    public function __clone() {
        trigger_error('Le clônage n\'est pas autorisé.', E_USER_ERROR);
    }
}
La fonction close est appelée dans un fichier fonctions générales :
function disconnectToDB($dataBase)
{
    include_once 'singletonConnexionBD.php';
    singletonConnexionBD::close($dataBase);
}


J'avais aussi préparé une fonction __destruct mais elle fait planter le script...
J'avais beaucoup d'appels à la fonction close et apparemment ça pose problème.
J'espère que je finirai par y arriver ;-)
Merci beaucoup en tout cas si vous pouvez m'éclairer sur ce qui ne va pas...

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 09:39
par xTG
Remets $_id à NULL dans la fonction de déconnexion après le mysql_close(). :)

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 09:50
par JulieDev
Ahh merci beaucoup, depuis vendredi je vous dois une fière chandelle !
J'ai un petit souci maintenant avec la fonction mysql_query qui n'accepte pas null en paramètre mais ça avance !
Encore merci !

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 10:26
par JulieDev
Je suis désolée mais je m'enfonce... :oops:
J'ai bien ajouté le null
  public static function close($id) {
        if (isset($id) && !empty($id)) {
            mysql_close(self::$_id);
            is_null(self::$_id);
   }}
mais j'ai deux messages d'erreur :
le premier pointe sur cette fonction :
Warning: mysql_close(): 6 is not a valid MySQL-Link resource

et le deuxième sur le mysql_query qui vient après un 2e appel au singleton qui ne me permet pas de faire ma connexion :
comme le var_dump de cette connexion indique null, le mysql_query ne récupère pas un paramètre valide :
Warning: mysql_query(): 6 is not a valid MySQL-Link resource
J'ai pourtant vérifié tous les paramètres de connexion avec un var_dump. Ils sont bien définis...

Je ne comprends pas pourquoi la connexion ne se fait pas alors qu'elle a été fermée précédemment...

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 10:31
par JulieDev
J'ai aussi testé l'appel à ma fonction close, avant fermeture et après fermeture et le résultat est bon :
connexion avant fermeture : resource(6) of type (mysql link)
connexion fermée : resource(6) of type (Unknown)

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 11:01
par JulieDev
Désolée pour ce dernier message, ne cherchez pas car je pense que le problème est ailleurs...
La connexion se ferme et s'ouvre apparemment...

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 12:39
par xTG
La fonction is_null comme son nom l'indique teste si la variable est NULL.
Elle ne fait rien d'autre.
Pour passer une variable à NULL :
$maVar = NULL;

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 14:04
par JulieDev
Merci !
C'est ce que j'avais mis au début mais ma connexion devenait extrêmement lente...
Par contre ça me permet de régler certains autres problèmes.
Pas facile cette vie de débutant ! :?

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 14:50
par xTG
Ce qui devrait être lent surtout c'est d'ouvrir et fermer la DB plusieurs fois dans un script.
Cela n'a aucun intérêt, encore plus quand on met en place un singleton.

Le principe c'est justement de ne l'ouvrir qu'une fois et de l'utiliser dans plusieurs codes.

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 15:01
par JulieDev
D'accord, effectivement comme je travaille sur un projet existant j'ai laissé les "close" où ils étaient mais j'ai tout intérêt à les enlever en fait... Je n'osais pas trop tout chambouler...

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 19:16
par xTG
A noter aussi que le mysql_close() est fait automatiquement lorsque le script est terminé pour peu que la connexion ouverte ne soit pas persistante. ;)

Re: Singleton de connexion et fermeture de connexion

Posté : 14 mai 2012, 19:31
par JulieDev
Eh bien je prends toutes les notes j'en ai besoin !
Un grand merci jusqu'au prochain bug qui me fera arracher les cheveux de la tête !