11
votes

Connexion à deux bases de données différentes avec Zend Cadre

J'ai ici un site intranet de taille moyenne qui est entièrement écrit à Zend FW. La base de données pour l'intranet est située sur un autre serveur. Maintenant, j'ai besoin d'étendre l'intranet avec de nouvelles fonctionnalités. Pour ce faire, je dois vous connecter à une autre base de données sur le même serveur (et même SGBD).

La question est maintenant: quelle est la meilleure façon de faire cela? Devrais-je créer un nouvel objet Zend_Config et un nouveau zend_db_adapter? Ou devrais-je utiliser l'existant et essayer avec le "Utiliser un autre nom"; " déclaration à connecter dans la même session à la nouvelle base de données?

ou y a-t-il un moyen encore meilleur de le faire?


0 commentaires

5 Réponses :


11
votes

Une option consiste à enregistrer 2 poignées de base de données de votre bootstrap.php code>, une pour chaque connexion. E.G.:

public function init()
{
     $this->db = Zend_Registry::get('db');
     $this->db2 = Zend_Registry::get('db2');
}

public function fooAction()
{
    $data = $this->db2->fetchAll('select foo from blah');
    ...
}
RESTOIR VOS CONTROILLANTEURS (E.G.): P>
$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db', $db);

$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db2', $db);


8 commentaires

Ce serait une solution. Mais alors je n'utiliserais pas zend_db_table. Je devrais pouvoir choisir le zend_db_adapter dans zend_db_table. Mais votre réponse a déjà aidé.


@Raffael Luthiger - Je n'ai fait aucune mention de zend_db_table, je ne vois pas où cela convient à ma réponse :)


@ Karim79: Je pense qu'il parle de l'adaptateur de base de données par défaut pour zend_db_table. S'il utilise deux adaptateurs différents, il devra associer ses classes de table avec l'adaptateur DB correct, respectivement. C'est pourquoi j'ai proposé d'utiliser la syntaxe de noms de table pleinement qualifiée.


@Stefan Gehrig - Ah, je l'obtiens maintenant. Je ne connais pas Zend_Db_table, ce commentaire m'a un peu confondu. Merci pour la clarification.


@Stefan. Correct. Merci de clarifier. Vous n'auriez pas pu l'avoir écrit mieux moi-même.


J'ai pris votre réponse maintenant. Merci! De cette façon, vous n'avez pas à utiliser zend_registry :: get ('dbadapter2');


@ karim79 Je sais que c'est un ancien poste, mais j'essaie réellement ZF pour la première fois et je dois également faire des connexions à plusieurs bases de données. Si j'utilise cette solution, cela signifie-t-il que plusieurs connexions DB ont ouvert tout le temps ou seulement lorsque j'appelle zend_registry :: get ('db') par exemple. Cela vient d'un point de vue de la performance. Merci


$ DB-> GetConnection () chez Bootstrap pourrait être considéré comme coûteux si vous n'utilisez pas les deux bases de données dans chaque demande.



3
votes

Je pense que cela dépend de la fréquence à laquelle vous devez changer de bases de données. L'utilisation de deux adaptateurs différents se différenciera entre les deux bases de données plus proprement et seraient ma préférence.

Lorsque vous changez de bases de données sur votre adaptateur unique, vous avez sûrement du mal à suivre quelle base de données est actuellement active - gardez à l'esprit que votre connexion de base de données est probablement un singleton qui est passé sur les modules, leurs contrôleurs et leurs modèles respectifs.

La troisième option serait d'utiliser des noms de table explicites dans votre application. MySQL, par exemple, fournit le db_name.table_name -Syntax dans les tables d'adresses dans différentes bases de données sur le même serveur. La base de données par défaut n'a pas d'importance de cette façon et zend_db_table et zend_db_select prend en charge cette syntaxe hors de la zone.

EDIT:

Je dois ajouter que l'option 2 et 3 ne fonctionnera que si votre utilisateur de base de données dispose des droits d'accès appropriés sur toutes les bases de données, tables et colonnes que vous souhaitez utiliser. L'option 1 sera la seule option à gauche, si votre base de données nécessite un utilisateur différent de chacune de vos bases de données.


3 commentaires

Je vais avoir le même utilisateur pour les deux bases de données. Alors l'option 2 et 3 fonctionnerait. Je dois dire que j'ai essayé l'option 3 mais cela n'a pas fonctionné. Mais cela aurait pu être un problème avec ma syntaxe.


Quel SGBD? Quelles erreurs obtenez-vous? Lorsque vous utilisez MySQL, vous devrez peut-être citer le nom de la DB ainsi que le nom de la table à l'aide de tiques de retour.


Malheureusement, ce n'est pas mysql. Mon client "a forcé" moi d'utiliser MSSQL. Selon la documentation que je dois utiliser là db.dbo.table. Mais mon problème est probablement avec la citation différente et les espaces des noms de table. La citation est normalement comme celle-ci: [Nom de la table]. [Nom de la colonne] Mais zend_db est modifié par défaut sur "Nom de la table" standard.



3
votes

J'utilise cette config.ini Vous pouvez également l'utiliser:

resources.db2.adapter = "pdo_mysql"
resources.db2.params.host = "localhost"
resources.db2.params.username = "root"
resources.db2.params.password = ""
resources.db2.params.dbname = "world"
resources.db2.isDefaultTableAdapter = true


6 commentaires

Merci pour l'information. Il s'agit de la même chose que Karim79 proposé. Vous le faites avec le fichier de configuration uniquement. Cela aurait été bien que vous auriez copié uniquement le code pertinent .. et le mettre dans les tags de pré Ensuite, cela aurait été mieux surprenant. Mais merci quand même.


Merci de reformater votre réponse. Je vous ai donné un point parce que je vais utiliser votre réponse avec réponse de Karim79.


Merci beaucoup de raffael, je l'apprécie vraiment :)


+1 Merci pour cette configuration utile. Il contient la plupart des solutions pour mes erreurs / problèmes.


Il contient ressources.db.params.dbname ligne deux fois. Un pour 'World' et un pour 'MyProject_testing' à la fin. Cela générera-t-il un problème ou un conflit.


@Awan: Non. Ce n'est pas un problème car ils sont dans différents "environnement". Une fois dans [production] et une fois dans [tests].



3
votes

L'un des meilleurs moyens est la suivante:

Créer une nouvelle table modèle pour n'importe quelle table de base de données: H2>
class Article extends Zend_Db_Table_Abstract  
{    
    protected $_name = 'id';
    public  function __construct()  {
        $adaptor = new Zend_Db_Adapter_Pdo_Mysql(array(
            'host'     => 'localhost',
            'username' => 'username',
            'password' => 'password',
            'dbname'   => 'database'

        ));
        $this->_db = $adaptor;
        parent::__construct();
    }

    // your functions goes here
    public function add($data) {
        // any syntax
    }
}


1 commentaires

Comme ceci, vous avez la configuration codée en dur dans le modèle. Lorsque vous souhaitez que le logiciel soit installé sur trois serveurs différents avec différentes bases de données, vous rencontrez des problèmes lorsque vous créez des mises à jour du logiciel.



2
votes

de ce que j'ai trouvé ici , Afin d'utiliser différentes bases de données dans une application ZEND, vous pouvez suivre l'une de ces deux manières possibles, en fonction de vos besoins:

- avoir le même hôte / utilisateur pour les deux bases de données h2>

Vous pouvez spécifier le Database Vous souhaitez utiliser l'initialisation de la variable € _ Schema Code> dans le modèle, comme suit: p> xxx pré>

- avoir un hôte / utilisateur différent pour les deux bases de données

in application.ini code> Vous devez écrire la configuration pour les deux bases de données comme suit: p> xxx pré>

ajout du _InitdBrigie code> Block to bootstrap ajoutera les bases de données au registre, de sorte que vous pourrez y accéder: p>

class Customer extends Zend_Db_Table_Abstract
{
    protected $_name    = 'customer';
    protected $_schema  = 'db_name_1';
    protected $_adapter = 'db_local'; //Using the local adapter

    ....
}

class Product extends Zend_Db_Table_Abstract
{
    protected $_name    = 'product';
    protected $_schema  = 'db_name_2';
    protected $_adapter = 'db_remote'; //Using the remote adapter

    ....
}


0 commentaires