Jump to content

module avec requete bdd distante


Recommended Posts

bonjour,
voila je developpe un module qui a besoin de requeter une base de données externe.

j'ai donc creer un objet MySQLCore en passant en paramètres le host, login, password, et dbname. ca marche bien.

cependant je souhaite ensuite faire une requete sur la base prestashop, j'utilise donc Db::getinstance->Execute(requête)

mais cela ne fonctionne plus et sans erreur. si je saute l'etape de la db externe, le meme script fonctioone bien.

on dirait que la connexion externe fait sauter la connexion prestashop.

une idée ?

merci

Link to comment
Share on other sites

bonjour,
voila je developpe un module qui a besoin de requeter une base de données externe.

j'ai donc creer un objet MySQLCore en passant en paramètres le host, login, password, et dbname. ca marche bien.

cependant je souhaite ensuite faire une requete sur la base prestashop, j'utilise donc Db::getinstance->Execute(requête)

mais cela ne fonctionne plus et sans erreur. si je saute l'etape de la db externe, le meme script fonctioone bien.

on dirait que la connexion externe fait sauter la connexion prestashop.

une idée ?

merci


Salut,
Oui il y a de grandes chances. j'ai connu le même problème à une époque en développant une passerelle entre deux cms différents. j'avais trouvé la soluce... je devrais bien pouvoir la retrouver, si toutefois tu n'es pas plus rapide que moi.
Link to comment
Share on other sites

haaa tu me serais d'une grande aide.

J'ai passé la journée dessus sans grand succès, j'en suis arrivé au point de reinstancier la classe DB avec les valeurs du setting.inc.php.

Pas tout à fait fini donc je ne sais pas encore si cela sera la solution "miracle", bien que je trouve ça du coup un peu du bricolage

Merci de ta réponse en tout cas, j'attends de voir ce que tu as à me proposer

Link to comment
Share on other sites

J'ai retrouvé mon code.

Il apparait que systématiquement, l'ouverture d'une connexion ferme l'autre
Ce que j'avais dans mon code est donc relativement simple :
1) je mémorise la liaison de la base distante lors de son initialisation
2) je fais ce que j'ai à faire
3) je ferme cette connexion en spécifiant l'id de liaison ($link=...)
4) j'ouvre à nouveau la connexion locale (ça c'est fait automatiquement dans presta, mais tout dépend de l'endroit ou tu appelle la liaison externe)

Pas de miracle donc à l'horizon en regard de ce que tu as déja fais

Link to comment
Share on other sites

C'est également ce que j'en avais déduis, qu'une connexion ferme l'autre

Mais peux tu me donner un code rapide qui correspond à ces étapes ?

Je pense que j'abroche du but de mon coté mais le debugging avec prestashop c'est pas la joie.

Merci beaucoup de ton aide

Link to comment
Share on other sites

juste pour info , j'avais codé ça pour une liaison entre oscommerce et un joomla, je crois me souvenir que la première ligne avait son importance :

$db_link='joomlink'; /* celle ci, il semble que si l'on ne force pas le nom de la liaison , on casse l'autre */
tep_db_connect(JOOM_DB_SERVER, JOOM_DB_USERNAME, JOOM_DB_PASSWORD,JOOM_DB_DATABASE,$db_link);

......

/* J'ai fini avec la base externe */
//close joomla db
tep_db_close($db_link);
//switch back to osc 
tep_db_connect(); /* à voir mais de mémoire la connexion n'était pas coupée, il s'agissait juste de réinitialiser */

Link to comment
Share on other sites

Merci de ton aide mais je n'arrive pas à trouver l'équivalent prestashop de ton "tep_db_connect".

Prestashop avec sa classe abstraite empêche le lancement du traitement Db::connect(); meme le __construct(); d'ailleurs.

En attendant en créant un autre objet héritant de db, et en l'instanciant avec les données de settings.inc.php, cela fonctionne.

Prestashop semble ensuite de lui meme réactiver la connexion Db::getInstance plus tard après le chargement de mon module, mais à savoir comment ........

Je vais quand meme creuser encore un peu car cette solution ne me plait guère

Link to comment
Share on other sites

tu as regardé la classe Db de plus près ? on parle bien de la 1.4 ? (tu cites MysqlCore)

    protected static $_servers = array(    
   array('server' => _DB_SERVER_, 'user' => _DB_USER_, 'password' => _DB_PASSWD_, 'database' => _DB_NAME_), /* MySQL Master server */
   /* Add here your slave(s) server(s)*/
   /*array('server' => '192.168.0.15', 'user' => 'rep', 'password' => '123456', 'database' => 'rep'),
   array('server' => '192.168.0.3', 'user' => 'myuser', 'password' => 'mypassword', 'database' => 'mydatabase'),
   */



Dans la 1.4 il semble bien que tu puisses utiliser Db::getInstance en spécifiant le server, sans doute dans l'instance de MySQL ,

Link to comment
Share on other sites

En effet, en passant une variable numérique en paramètre représentant le serveur esclave.

Malheureusement ce n'est pas terrible sachant que je souhaite développer un module sans modifier le coeur de prestashop


Je vois ,
C'est étrange que cette qui devrait être externalisé et ressemble fort à une configuration soit ainsi codée dans la classe elle même. Il serait intéressant que cette variable soit refactorée...

Mais ton module pourrait installer un fichier de surcharge uniquement pour le champ protected static $_servers = array(...)
dans /override/classes :

fichier/override/classes/Db.php dans le genre

Class Db extends DbCore
{
protected static $_servers = array(    
   array('server' => _DB_SERVER_, 'user' => _DB_USER_, 'password' => _DB_PASSWD_, 'database' => _DB_NAME_));
if(Configuration::get('MYMODULE_USE_EXT_DB')){
$extDbHost = Configuration::get('MYMODULE_EXT_DB_HOST');
$extDbUser = Configuration::get('MYMODULE_EXT_DB_USER');
$extDbPwd = Configuration::get('MYMODULE_EXT_DB_PWD');
$extDbName = Configuration::get('MYMODULE_EXT_DB_NAME');
$_servers[] = arrayarray('server' => $extDbHost, 'user' => $extDbUser, 'password' => $extDbPwd, 'database' => $extDbName));
}

}

Link to comment
Share on other sites

En effet c'est pas bête. ça complique bcp les choses pour une simple requete externe mais si on a pas le choix...

Je vais tenter ça

Merci


Effectivement...ça complique... Ca ne serait pas utile si Db->_servers pouvait prendre en compte une donnée de configuration pour les serveurs supplémentaires, mais bon avec la surcharge , c'est le comportement que tu obtiendras.
Link to comment
Share on other sites

Sinon, rien ne t'empêche de te créer une classe "Db2" à la racine de ton module implémentant le pattern et utilisant une autre base de connexion afin de ne pas perturber la réplication native !


En fait, quoi que tu fasses la connexion initiale saute.
Du coup je me contente de recréer une instance de la classe MySQLCore avec les identifiants de la base prestashop, puis de la refermer, et cela semble fonctionner correctement.
Link to comment
Share on other sites

C'est normal, c'est le but du pattern singleton de la classe DB !

1) Créer une classe Db2Core avec le nom de fichier Db2.php

2) Paramètrer le serveur

protected static $_servers = array(    
   array('server' => 'SERVEUR', 'user' => 'UTILISATEUR', 'password' => 'MOT DE PASSE', 'database' => 'BASE')
);



3) L'utiliser

Db2::getInstance(); ...



4) Tiens Juju au courant :)

Link to comment
Share on other sites

C'est normal, c'est le but du pattern singleton de la classe DB !

1) Créer une classe Db2Core avec le nom de fichier Db2.php

2) Paramètrer le serveur

protected static $_servers = array(    
   array('server' => 'SERVEUR', 'user' => 'UTILISATEUR', 'password' => 'MOT DE PASSE', 'database' => 'BASE')
);



3) L'utiliser

Db2::getInstance(); ...



4) Tiens Juju au courant :)



Ca ça va servir à plus d'un ! ;)

Concernant l'existant, je me demande néanmoins si la définition des serveurs slave dans $_servers ne devrait pas puiser dans une constante définie dans les settings. Cette classe Db est 'miseajourable'. Pour moi ça casse complètement l'intérêt de la gestion multiserveurs d'avoir ça en dur.
Link to comment
Share on other sites

tout à fait d'accord.

Cependant, je m'aperçois également que pour une meilleure compatibilité avec les anciennes versions, il est plus simple d'intégrer le tout dans le module à développer.


Oui oui absolument ! La solution de julien est parfaite et rétro-compatible.

Je n'insiste que sur le coté 'non fini' de la classe de la 1.4 ;)
Link to comment
Share on other sites

Ben mince ! Je n'ai pas songé une seconde que le module en question pouvait être voué à la réplication : c'est fort possible en effet...J'imaginais plutôt des fonctionnalités type 'passerelle' ...

Dans les seuls cas de figure que j'ai rencontré nécessitant une réplication, elle se faisait au niveau du moteur mysql , avec une couche d'abstraction pour n'avoir qu'une seule connexion. La réplication à la main dans le logiciel lui même c'est bof...
En effet si tu as eu des demandes de réplication pour du 200 commandes hebdo ... :lol:
Le clustering n'a de sens que dans des cours que je ne fréquente pas ;)

Link to comment
Share on other sites

  • 11 months later...

C'est normal, c'est le but du pattern singleton de la classe DB !

 

1) Créer une classe Db2Core avec le nom de fichier Db2.php

 

2) Paramètrer le serveur

 

protected static $_servers = array(	
array('server' => 'SERVEUR', 'user' => 'UTILISATEUR', 'password' => 'MOT DE PASSE', 'database' => 'BASE')
);

 

3) L'utiliser

 

Db2::getInstance(); ...

 

4) Tiens Juju au courant :)

 

Bonjour,

 

En rapport à ce post, je suis entrain de créer un module avec une connexion sur une autre base de données sur le même serveur, j'ai copié le fichier db.php que j'ai collé dans override en Db2.php mais à chaque fois que je l'utilise dans mon module j'ai un message qui me dit que Fatal error : Class 'Db2' not found. Dois-je faire autre chose de toute façon avec l'autoload il charge bien ma classe ?

 

Merci,

Alexis

Link to comment
Share on other sites

Bonsoir,

 

Voici donc l'ultime réponse pour connecter plusieurs bases de données à PrestaShop en version 1.5.

 

Les codes sont ici : https://gist.github.com/2287568

 

Mettre la classe DbFactory dans le dossier classes.

 

Le fichier test.php vous permet simplement de tester le fonctionnement.

 

Note : La Factory est basée sur le Singleton de façon à conserver son efficacité.

 

Note additionnelle : Si utilisé dans un module, faire un simple "require".

Link to comment
Share on other sites

Salute !

 

Merci Julien j'ai testé sur une version 1.4.x de Prestashop mais ça me coupe toujours l'autre connexion de Prestashop et j'ai aussi du renommer :

 

class DbFactoryCore

{

 

En

 

class DbFactory

{

 

Sinon il comprend pas :P

 

Qu'est-ce que tu en penses ?

 

Merci encore :-)

Link to comment
Share on other sites

Hum mais du coup je dois utiliser DbFactory pour la connexion standard de Prestashop ?

 

*** EDIT : Dans mon module j'utilise des fonctions de Prestashop pour CRUD un produit, et même en déclarant les 2 servers grâce a DbFactory il m'écrase toujours le primary, bref je sais pas trop comment faire !!

Link to comment
Share on other sites

Ok en fait on ne peut vraiment pas avoir plusieurs bdd connectées en même temps, du coup et bien pour le traitement de ma bdd externe je crée un secondary :

$secondary = DbFactory::addServer('secondary', 'localhost', 'root', '', 'monautrebase');

$rs = DbFactory::getInstanceByServer('secondary')->ExecuteS('SELECT * FROM monautretable');

 

Je fais mon traitement et ensuite c'est important de remettre le serveur primaire :

$primary = DbFactory::addServer('primary', 'localhost', 'root', '', 'mabaseprestashop');

$rs = DbFactory::getInstanceByServer('primary');

 

Voili !

ça marche comme ça pour moi (je suis sur une version 1.4.x de Prestashop)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...