Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Empecher la reutilisation d'une connexion mysql

9 réponses
Avatar
Christophe HENRY
Bonjour au groupe,

Existe-il un moyen pour ouvrir une connexion mysql, en mémoriser
l'identifiant et empêcher qu'il ne soit utilisé par les instructions php
ne mentionnant pas l'identifiant ?

Exemple :
mysql_query("CREATE TABLE bla (id INT)", $conn);

// Mise en commentaire oubliée !
// mysql_connect("localhost", "autre", "passe");

mysql_query("DROP TABLE bla"); // DEVRAIT ÉCHOUER
mysql_query("ALTER TABLE bla ....", $conn); // OK
le deuxième mysql_query fait mention à la dernière connexion établie. Du
coup, la deuxième requête utilise la première connexion. Cela fait un bug
difficile à débusquer.
Je voudrais que le deuxième mysql_query tombe en erreur parce que le
premier mysql_connect n'aurait pas été retenu comme lien par défaut.

D'avance, merci.

--
Christophe HENRY
http://www.sbgodin.fr - Site perso

9 réponses

Avatar
Xavier Nayrac
Christophe HENRY a écrit :
Bonjour au groupe,

Existe-il un moyen pour ouvrir une connexion mysql, en mémoriser
l'identifiant et empêcher qu'il ne soit utilisé par les instructions php
ne mentionnant pas l'identifiant ?

Exemple :
mysql_query("CREATE TABLE bla (id INT)", $conn);

// Mise en commentaire oubliée !
// mysql_connect("localhost", "autre", "passe");

mysql_query("DROP TABLE bla"); // DEVRAIT ÉCHOUER
mysql_query("ALTER TABLE bla ....", $conn); // OK
le deuxième mysql_query fait mention à la dernière connexion établie. Du
coup, la deuxième requête utilise la première connexion. Cela fait un bug
difficile à débusquer.
Je voudrais que le deuxième mysql_query tombe en erreur parce que le
premier mysql_connect n'aurait pas été retenu comme lien par défaut.

D'avance, merci.




Si j'ai bien compris, tu veux utiliser une et une seule connexion pour
toutes tes requêtes ? Si c'est ça, regardes du coté du pattern singleton.

--
Xavier Nayrac
http://personalbugtracker.free.fr
Avatar
Mickaël Wolff
Christophe HENRY wrote:

Je voudrais que le deuxième mysql_query tombe en erreur parce que le
premier mysql_connect n'aurait pas été retenu comme lien par défaut.



Ce n'est pas possible avec la version procédurale du module MySQL
pour PHP. Si tu veux utiliser plusieurs connexion sans conflits, il faut
utiliser la version objet du module.

Par exemple :

$db = array() ;
$db[] = new mysql($host, $user, $password, $space) ;
$db[] = new mysql($host, $user, $password) ;
$db[0]->query('show tables') ;
$db[1]->query('show databases') ;

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
CrazyCat
Xavier Nayrac wrote:
Si j'ai bien compris, tu veux utiliser une et une seule connexion pour
toutes tes requêtes ? Si c'est ça, regardes du coté du pattern singleton.



Ca ne marche qu'en PHP5, et c'est justement l'exemple que je donne à
<http://www.g33k-zone.org/post/2009/08/29/Utilisation-des-singletons-en-PHP5>


--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces : http://www.g33k-zone.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
Avatar
Mickaël Wolff
CrazyCat wrote:
Ca ne marche qu'en PHP5, et c'est justement l'exemple que je donne à
<http://www.g33k-zone.org/post/2009/08/29/Utilisation-des-singletons-en-PHP5>



La mise en place d'un singleton en utilisant les fonctions
procédurale est erronée. En dehors de la classe qui est censé gérer la
connexion MySQL peut etre perturbé par des appels aux fonctions
procédurales du module MySQL.
La raison en est que, par défaut, les fonctions procédurales
utilisent la ressource utilisée précédemment.

Donc la mise en place du singleton n'est pas pertinente ici,
puisqu'il ne permet pas de sécuriser l'usage de l'API procédurale.

Je rajouterais que l'emploi systématique du singleton pour gérer la
connexion à la base de données n'est généralement pas une bonne idée
(vous n'importez jamais des données entre deux bases de données ?

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
CrazyCat
Mickaël Wolff wrote:
La mise en place d'un singleton en utilisant les fonctions procédurale
est erronée. En dehors de la classe qui est censé gérer la connexion
MySQL peut etre perturbé par des appels aux fonctions procédurales du
module MySQL.
La raison en est que, par défaut, les fonctions procédurales utilisent
la ressource utilisée précédemment.
Donc la mise en place du singleton n'est pas pertinente ici, puisqu'il
ne permet pas de sécuriser l'usage de l'API procédurale.



Tout à fait d'accord, il s'agit là d'un *simple exemple* facile à
comprendre sur le principe du singleton, c'est le premier qui m'est venu
à l'esprit.

Je rajouterais que l'emploi systématique du singleton pour gérer la
connexion à la base de données n'est généralement pas une bonne idée
(vous n'importez jamais des données entre deux bases de données ?



Je suis entièrement d'accord là aussi, ce n'est (encore une fois) qu'*un
exemple* qui a pour but d'expliquer un principe, en aucun cas je n'ai
dit que c'était ce qu'il fallait faire dans tous les cas. D'ailleurs,
j'ai des systèmes qui demandent justement des connexions différentes et
simultanées sur des bases différentes.

Peut-être mon exemple n'est-il pas le choix le plus judicieux, il me
semblait le plus parlant, mais il reste simplement de la théorie. Les
seules choses qui peuvent être utilisées /sans trop réfléchir/ sur ce
blog sont les classes que je diffuse en .zip


--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces : http://www.g33k-zone.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
Avatar
Christophe HENRY
Le Tue, 15 Sep 2009 15:39:50 +0000, Mickaël Wolff a écrit :

CrazyCat wrote:
Ca ne marche qu'en PHP5, et c'est justement l'exemple que je donne à
<http://www.g33k-zone.org/post/2009/08/29/Utilisation-des-singletons-




en-PHP5>

La mise en place d'un singleton en utilisant les fonctions
procédurale est erronée. En dehors de la classe qui est censé gérer la
connexion MySQL peut etre perturbé par des appels aux fonctions
procédurales du module MySQL.
La raison en est que, par défaut, les fonctions procédurales
utilisent la ressource utilisée précédemment.
(...)



Oui, c'est ce qui me gène. Si on programme proprement, l'utilisation de
classes enveloppantes (Singleton, pool, etc.) est pratique. Ne serait-ce
que pour la gestion des erreurs/exceptions. Cependant, ça n'empêche la
réutilisation de la connexion entre-temps. Sauf à fermer la connexion à
chaque fois, ce que je me suis résigné à faire.


--
Christophe HENRY
http://www.sbgodin.fr - Site perso
Avatar
Christophe HENRY
Le Tue, 15 Sep 2009 07:08:23 +0000, Mickaël Wolff a écrit :

Christophe HENRY wrote:

Je voudrais que le deuxième mysql_query tombe en erreur parce que le
premier mysql_connect n'aurait pas été retenu comme lien par défaut.



Ce n'est pas possible avec la version procédurale du module MySQL
pour PHP. Si tu veux utiliser plusieurs connexion sans conflits, il faut
utiliser la version objet du module.

Par exemple :

$db = array() ;
$db[] = new mysql($host, $user, $password, $space) ; $db[] = new
mysql($host, $user, $password) ; $db[0]->query('show tables') ;
$db[1]->query('show databases') ;



C'est ce qu'il me faudrait, à deux questions près :
- où ça se récupère ? Je n'ai pas trouvé ça dans la doc' officielle;
- est-ce que, juste après le "new mysql" une instruction procédurale a
accès à la connexion crée ?

--
Christophe HENRY
http://www.sbgodin.fr - Site perso
Avatar
Mickaël Wolff
Christophe HENRY wrote:

C'est ce qu'il me faudrait, à deux questions près :
- où ça se récupère ? Je n'ai pas trouvé ça dans la doc' officielle;


<http://fr.php.net/mysqli>

- est-ce que, juste après le "new mysql" une instruction procédurale a
accès à la connexion crée ?


Non, il n'y a pas accès.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Christophe HENRY
Le Mon, 21 Sep 2009 10:09:38 +0000, Mickaël Wolff a écrit :

Christophe HENRY wrote:

C'est ce qu'il me faudrait, à deux questions près : - où ça se récupère
? Je n'ai pas trouvé ça dans la doc' officielle;


<http://fr.php.net/mysqli>



Tellement gros que je n'ai pas pensé à regarder là-dedans. Sûrement la
proximité de Sqlight. C'est en effet tout ce que je cherchais : un moyen
de faire comme mysql en isolant la connexion. En plus, on a le choix
entre style procédural et objet.


- est-ce que, juste après le "new mysql" une instruction procédurale a
accès à la connexion crée ?


Non, il n'y a pas accès.



Je confirme. J'ai testé avec le code ci-dessous. Deux connexions mysqli,
une en procédural, l'autre en objet, ouvrent chacun une connexion valide.
Deux requêtes mysqli testent la validité des connexions. Enfin, le
mysql_query final est destiné à échouer puisqu'il ne devrait pas y avoir
de connexion disponible :

<?php

$bd1 = mysqli_connect("localhost", "root", "root");
$bd2 = new mysqli("localhost", "root", "root");

echo "mysqli ok!n";

$query = "select count(*) from mysql.user";

mysqli_query($bd1, $query); // obligé d'utiliser le link
$bd2->query($query);

// Plante (à supposer que la connexion par défaut sans mdp échoue)
// car la connexion mysql, procédurale ou objet, ne peut être volée.
$truc = mysql_query($query);

?>

Effectivement, le mysql_query ne marche pas. La connexion version objet
est naturellement encapsulée. La connexion procédurale oblige à
réutiliser l'identifiant de connexion, qui n'est pas accessible
autrement. C'est ce que je cherchais.

Une remarque : Mysql_query, lorsqu'il ne trouve pas de connexion, en
ouvre une tout seul ! Il y arrive avec le mysql.default_user du php.ini
ou en ouvrant une connexion locale sans utilisateur et sans mot de passe.

Merci à Mickaël Wolff et aux autres.

--
Christophe HENRY
http://www.sbgodin.fr - Site perso