OVH Cloud OVH Cloud

Executer des requetes SQL sures en PHP

7 réponses
Avatar
Christophe CLEMENT
Bonjour,

Je programme habituellement en perl, et pour éviter les requètes du
genre :

$requete = "select * from nom_table where id=$id";

car si $id=";delete * from nom_table "; y a un problème...

J'utilise donc une fonction prepare, en gros ça donne :

$sel=$dbi->prepare('"select * from nom_table where id=?"');
$sel->execute(";delete * from nom_table "); # ce truc là sera
correctement placé dans des guillemets


Y a-t-il une fonction prédéfinie et équivalente en PHP ?


Christophe
--
Le site de toutes les piscines de Paris : http://www.nageurs.com/

7 réponses

Avatar
Pierre Goiffon
Patrick Mevzek wrote:
En toute généralité (le problème n'étant ni spécifique à PHP ni à
MySQL), les requêtes préparées (avec placeholders) n'ont que des
avantages:



Qu'est-ce qu'un placeholder ?

Quant aux fonctions, mon autre conseil, mais orthogonal avec les
problèmes d'injection SQL, c'est de ne *pas* utiliser les fonctions
natives, mais de passer par une bibliothèque d'abstraction



Je ne suis pas sûr que celà soit toujours un excellent conseil : cela
alourdit considérablement les applications, rend dépendant à une
implémentation dont les méthodes ne seront pas applicables à tous les
SGBD... Sur le papier, c'est bien beau, en pratique, souvent ça empire
encore les choses. Je pense en particulier à plusieurs expériences
douloureuses avec ADO...

Mais bon, comme d'habitude avec les choix de solutions, des généralités
n'ont que peu de sens, il faut voir au cas par cas.
Avatar
Patrick Mevzek
Le Mon, 07 Nov 2005 10:06:27 +0100, Pierre Goiffon a écrit :
En toute généralité (le problème n'étant ni spécifique à PHP ni à
MySQL), les requêtes préparées (avec placeholders) n'ont que des
avantages:



Qu'est-ce qu'un placeholder ?



Je ne sais pas, fainéantise de chercher, quelle est la bonne traduction
française.

Cela revient à envoyer la requête SQL en deux bouts au SGBDR: d'abord la
partie fixe, avec dedans des indications, les placeholders, du style juste
? ou :nom, et dans un deuxième temps les différentes valeurs qui doivent
remplacer les placeholders.

En faisant ainsi on préserve les contextes, et on se prémunit donc des
injections SQL qui ont comme racine justement la fusion des contextes.

Quant aux fonctions, mon autre conseil, mais orthogonal avec les
problèmes d'injection SQL, c'est de ne *pas* utiliser les fonctions
natives, mais de passer par une bibliothèque d'abstraction



Je ne suis pas sûr que celà soit toujours un excellent conseil : cela
alourdit considérablement les applications,



A quel niveau ? Code ? Performances ?
Au niveau du code, non (écrire connect au lieu de mysql_connect ca ne
change pas grand chose). Au niveau performances, pas suffisamment avec une
bibliothèque correcte, en tout cas par rapport au gain obtenu (code qui
fonctionnera correctement avec plusieurs SGBDRs et obligation -symbolique
certes- faites au développeur de penser à ses requêtes SQL sans penser
à un SGBDR particulier).

Il faudrait bien sûr coupler avec une factorisation des accès au SGBDR
dans son propre code, en allant jusqu'à un mécanisme de mappage avec des
objects intraséques au langage, ou non, mais au moins des
fonctions/classes à part.

rend dépendant à une
implémentation dont les méthodes ne seront pas applicables à tous les
SGBD...



C'est justement le but d'une telle bibliothèque que de s'affranchir des
détails de chaque SGBDR. Certaines sont même capables de re-écrire les
ordres SQL.

Toutes les bibliothèques d'abstraction dignes de ce nom doivent être
capables de s'interfacer avec les SGBDR classiques (MySQL, PostgreSQL,
DB2, Orable, etc...)

Sur le papier, c'est bien beau, en pratique, souvent ça empire
encore les choses.



C'est tout sauf mon expérience.
J'ai même passé 3 ans, en pure perte, à devoir essayer de re-écrire un
code de 10000 lignes sans bibliothèques d'abstraction ni factorisation
pour passer de MySQL à PostgreSQL. Tout re-écrire de zéro fut plus
simple. Difficile de ne pas voir ca comme un gachis qui plaide pour les
bibliothèques d'abstraction.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>
Avatar
Pierre Goiffon
Patrick Mevzek wrote:
Qu'est-ce qu'un placeholder ?



Je ne sais pas, fainéantise de chercher, quelle est la bonne traduction
française.

Cela revient à envoyer la requête SQL en deux bouts au SGBDR


(...)

C'est une bonne explication, j'ai compris, merci !

Quant aux fonctions, mon autre conseil, mais orthogonal avec les
problèmes d'injection SQL, c'est de ne *pas* utiliser les fonctions
natives, mais de passer par une bibliothèque d'abstraction



Je ne suis pas sûr que celà soit toujours un excellent conseil : cela
alourdit considérablement les applications,



A quel niveau ? Code ? Performances ?



Code !
Pour ajouter un enregistrement, créer 2, 3, voir 4 objets. Les maintenir
entres les différents blocs (portées des variables). Jongler entre les
méthodes : .Add, . Refresh, ...

Pour les performances, avec les machines d'aujourd'hui et considérant la
nature des applications Web, ce n'est pas ce qui me venait à l'esprit.

Il faudrait bien sûr coupler avec une factorisation des accès au SGBDR
dans son propre code



Un pooling de connections sur le SGBD ? C'est plutôt à la couche ODBC ou
assimilé, voir au serveur de composants de le gérer à mon sens.

rend dépendant à une
implémentation dont les méthodes ne seront pas applicables à tous les
SGBD...



C'est justement le but d'une telle bibliothèque que de s'affranchir des
détails de chaque SGBDR



Oui.
Mais on se retrouve, à chaque fois, à vérifier ce que tel ou tel
provider permet d'utiliser comme objets, propriétés et méthodes. Pour se
rendre compte que le provider machin chose version trucmuche ne gère pas
ce que l'on a utilisé partout, et devoir modifier son application, et...
(...)

Sur le papier, c'est bien beau, en pratique, souvent ça empire
encore les choses.



C'est tout sauf mon expérience.
J'ai même passé 3 ans, en pure perte, à devoir essayer de re-écrire un
code de 10000 lignes sans bibliothèques d'abstraction ni factorisation
pour passer de MySQL à PostgreSQL. Tout re-écrire de zéro fut plus
simple. Difficile de ne pas voir ca comme un gachis qui plaide pour les
bibliothèques d'abstraction.



J'ai du ré-écrire des portions entières de code ASP qui s'appuyait sur
les objets ADO lors du passage de Access à SQL Server d'un gros CMS...

Loin de moi l'idée de généraliser, mais j'ai au moins vécu quelques
contre exemples. Comme dis avant, bien valider une solution avant de
s'investir à l'utiliser. Et vu l'était du marché actuellement, ce
sentiment qu'il n'y a pas de réponse permettant de s'affranchir
totalement des différences entre SGBD reste persistant.
Avatar
Patrick Mevzek
Le Mon, 07 Nov 2005 16:09:45 +0100, Pierre Goiffon a écrit :
Je ne suis pas sûr que celà soit toujours un excellent conseil : cela
alourdit considérablement les applications,



A quel niveau ? Code ? Performances ?



Code !
Pour ajouter un enregistrement, créer 2, 3, voir 4 objets. Les maintenir
entres les différents blocs (portées des variables). Jongler entre les
méthodes : .Add, . Refresh, ...



On ne doit pas parler de la même chose/se comprendre.

En schématisant, depuis PHP pour se connecter à Mysql en natif:
mysql_connect
mysql_query
mysql_fetch_*
mysql_close

Avec une bibliothéque d'interconnexion comme PearDB (mais ca serait
identique avec une autre)
DB::connect
query
fetchRow
disconnect

Je ne vois donc pas en quoi la deuxième variante est plus lourde. Il y a
autant de lignes.

Pour les performances, avec les machines d'aujourd'hui et considérant
la nature des applications Web, ce n'est pas ce qui me venait à
l'esprit.



C'est pourtant le seul argument qu'on peut reprocher à ces
bibliothèques.

Il faudrait bien sûr coupler avec une factorisation des accès au
SGBDR dans son propre code



Un pooling de connections sur le SGBD ?



Non, ca c'est encore autre chose. Je parlais d'éviter d'avoir du code SQL
dans *tout* le programme et de préférer le mettre dans quelques
fonctions/classes spécifiques.
C'est peut-être évident pour vous, mais ce ne l'est pas en général.

rend dépendant à une
implémentation dont les méthodes ne seront pas applicables à tous les
SGBD...



C'est justement le but d'une telle bibliothèque que de s'affranchir des
détails de chaque SGBDR



Oui.
Mais on se retrouve, à chaque fois, à vérifier ce que tel ou tel
provider permet d'utiliser comme objets, propriétés et méthodes. Pour se
rendre compte que le provider machin chose version trucmuche ne gère pas
ce que l'on a utilisé partout, et devoir modifier son application, et...
(...)



Je crois qu'on ne parle manifestement pas de la même chose, et je pense
que vous êtes à un plus haut niveau que moi dans la pile de
bibliothèques. Le but d'une bibliothèque est de vous *garantir* la même
API quel que soit le SGBDR, en mettant de côté le contenu SQL en
lui-même (que certaines peuvent réécrire ou non)

Après on peut avoir des choses encore plus haut niveau pour les objets,
etc... mais c'est encore un autre problème.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>
Avatar
Pierre Goiffon
Patrick Mevzek wrote:
On ne doit pas parler de la même chose/se comprendre.


(...)
Avec une bibliothéque d'interconnexion comme PearDB (mais ca serait
identique avec une autre)
DB::connect
query
fetchRow
disconnect



Je ne connais PEAR quasiment que de nom...
Je pensais à une bibliothèque qui per met de s'affranchir totalement du
SQL - c'est le cas avec ADO
En lisant ce nouveau message, j'ai l'impression que tu parle plus d'un
moyen standard d'ouvrir une source ODBC ou équivalente ? Ensuite, on
continue à faire exécuter son SQL ?
Avatar
Patrick Mevzek
Le Mon, 07 Nov 2005 17:42:01 +0100, Pierre Goiffon a écrit :
Je pensais à une bibliothèque qui per met de s'affranchir totalement du
SQL - c'est le cas avec ADO
En lisant ce nouveau message, j'ai l'impression que tu parle plus d'un
moyen standard d'ouvrir une source ODBC ou équivalente ? Ensuite, on
continue à faire exécuter son SQL ?



Tout à fait. Une bibliothèque d'abstraction des SGBDRs, *pas* une
bibliothèque d'abstraction SQL, autrement dit de mapping style
SQL<->object natif dans le langage de programmation utilisé.

Bref, ODBC, ou JDBC en Java, ou DBI en Perl, ou une des multiples
solutions en PHP (AdoDB,Pear, MDB, etc...), langage avec lequel on
voit trop souvent l'usage des fonctions natives de chaque SGBDR, c'était
le sens de mon message initial, mais je suis tombé un peu à côté de la
plaque, désolé.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>
Avatar
Pierre Goiffon
Patrick Mevzek wrote:
Bref, ODBC, ou JDBC en Java, ou DBI en Perl, ou une des multiples
solutions en PHP (AdoDB,Pear, MDB, etc...), langage avec lequel on
voit trop souvent l'usage des fonctions natives de chaque SGBDR, c'était
le sens de mon message initial, mais je suis tombé un peu à côté de la
plaque, désolé.



On peut aussi dire que j'ai répondu un peu vite :D
En tout cas, évidemment tout à fait d'accord. Ensuite, il faut peut être
quand même étudier les performances en charge de la méthode d'accès
universelle vs méthode spécifique... (pour SQL Server, le provider
OLE-DB est largement plus rapide que le provider ODBC... mais ça reste
du relativement générique tout de même)