Singleton de connexion et fermeture de connexion

Eléphanteau du PHP | 27 Messages

11 mai 2012, 16:36

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

ViPHP
xTG
ViPHP | 7331 Messages

11 mai 2012, 19:50

Montres nous le code de déconnexion. :)

Eléphanteau du PHP | 27 Messages

14 mai 2012, 09:27

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...

ViPHP
xTG
ViPHP | 7331 Messages

14 mai 2012, 09:39

Remets $_id à NULL dans la fonction de déconnexion après le mysql_close(). :)

Eléphanteau du PHP | 27 Messages

14 mai 2012, 09:50

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 !

Eléphanteau du PHP | 27 Messages

14 mai 2012, 10:26

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...

Eléphanteau du PHP | 27 Messages

14 mai 2012, 10:31

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)

Eléphanteau du PHP | 27 Messages

14 mai 2012, 11:01

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...

ViPHP
xTG
ViPHP | 7331 Messages

14 mai 2012, 12:39

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;

Eléphanteau du PHP | 27 Messages

14 mai 2012, 14:04

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 ! :?

ViPHP
xTG
ViPHP | 7331 Messages

14 mai 2012, 14:50

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.

Eléphanteau du PHP | 27 Messages

14 mai 2012, 15:01

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...

ViPHP
xTG
ViPHP | 7331 Messages

14 mai 2012, 19:16

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. ;)

Eléphanteau du PHP | 27 Messages

14 mai 2012, 19:31

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 !