Bonjour à tous,
voici quelque heures que je cherche l'origine d'un bug sur une de mes pages qui utilise 2 Bases de données.
En effet pour faciliter certaine opération sur phpmyadmin j'ai divisé la bd original en 2 et modifié tous les objet pour qu'ils puissent retrouvé leur petit.

Mais ce que je n'avais pas pensé, c'est que mon singleton me bloquerait.
Si dans un même programme j'utilise des objets qui ont besoin des deux bd différente, les objets qui ont besoin de la premiére bd instancié fonctionne, et ceux qui ont besoin de la seconde bd crash car la seconde instance de la bd ne se fait pas, le premiére est retourné avec les mauvaise infos. C'est normal c'est le but du singleton.

/**
 * Gestion des accés à la base de données
 */
Class Db_mark5
{
    private $dbase_dns;
    private $dbase_server;
    private $dbase_name;
    private $dbase_user;
    private $dbase_pass;
    private $db_pdo = NULL;
    private static $_instance = NULL;

    private function __construct ($info)
    {
        if ($info === NULL)
        {
            return FALSE;
        }
        $this->dbase_dns = constant (DBASE_ . $info . _DNS);
        $this->dbase_server = constant (DBASE_ . $info . _SERVER);
        $this->dbase_name = constant (DBASE_ . $info . _NAME);
        $this->dbase_user = constant (DBASE_ . $info . _USER);
        $this->dbase_pass = constant (DBASE_ . $info . _PASS);

        $pdo = new PDO($this->dbase_dns, $this->dbase_user, $this->dbase_pass,
                array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        $pdo->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db_pdo = $pdo;
    }

    /**
     * Méthode qui crée l'unique instance de la classe
     * si elle n'existe pas encore puis la retourne.
     */
    public static function getInstance ($info)
    {
        if (is_null (self::$_instance))
        {
            self::$_instance = new Db_mark5($info);
        }

        return self::$_instance;
    }
}

-Existerai t'il une maniére élégante et propre de permettre de crée d'autre instance pour X bd différente si elle ne sont pas déja instancié.
-Dois je crée X objet bd ou X correspond à mon nombre de bd différente.
-l'héritage est elle une solution.

Je ne sais pas quelle est la meilleur piste, le programme complet et encore relativement petit, donc il est envisageable de tout réécrire, mais s'il y avait une méthode miracle qui opererait dans l'objet bd, je serai heureux.

merci d'avance pour votre aide

Flo

6 réponses


Huggy
Réponse acceptée

Bonjour,
Tu pourrais gérer un tableau static d'instances
avec comme clé le nom de la base et comme valeur l'instance qui correspond.
Dans le getInstance, il suffit de regarder si la clé (nom de la base) existe, si oui on retourne l'instance, si non, on la crée

Le pattern factory devrait t'aider ;) En clair, tu crées un objet singleton qui stocke les instances des connexions.

flo3376
Auteur

j'ai regardé le pattern factory, et je suis encore trop jeune pour comprendre :D

j'ai essayé avec l'idée de Huggy, et cela fonctionne nickel, pas de doublons

Class Db_mark5
{
    private $dbase_dns;
    private $dbase_server;
    private $dbase_name;
    private $dbase_user;
    private $dbase_pass;
    private $db_pdo = NULL;
    private static $_instance=array();
    //private static $_instance = NULL;

    private function __construct($info)
    {
        if ($info === NULL) {
            return FALSE;
        }
        $this->dbase_dns = constant(DBASE_ . $info . _DNS);
        $this->dbase_server = constant(DBASE_ . $info . _SERVER);
        $this->dbase_name = constant(DBASE_ . $info . _NAME);
        $this->dbase_user = constant(DBASE_ . $info . _USER);
        $this->dbase_pass = constant(DBASE_ . $info . _PASS);

        $pdo = new PDO($this->dbase_dns, $this->dbase_user, $this->dbase_pass,
                array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db_pdo = $pdo;
    }

    /**
     * Méthode qui crée l'unique instance de la classe
     * si elle n'existe pas encore puis la retourne.
     */
    public static function getInstance($info)
    {
        if (array_key_exists($info,self::$_instance))
        {
            //echo "<br>=====<br>";var_dump(self::$_instance);echo "<br>=====<br>";
        }
        else{
            self::$_instance[$info]=new Db_mark5($info);
        }
        return self::$_instance[$info];
        /*if (is_null(self::$_instance)) {
            self::$_instance = new Db_mark5($info);
        }

        return self::$_instance;*/
    }

merci pour aide

Pour le pattern factory, c'est pas super compliqué:

class ConnectionFactory{
    private static $_instances=[]; 

    public function get($connectionName){
        if (!isset(static::$_instances[$connectionName])
            static::$_instances[$connectionName] = new Connection();
        return static::$_instances[$connectionName];
    }
}

@intelligid oui ça revient à ce qu'il à fait et à ce que j'ai proposé
c'est une "factory"

Pas vraiment, le pattern factory utilise un objet singleton(ou une classe statique) à part de l'objet à produire