OVH Cloud OVH Cloud

Question de philosophie

39 réponses
Avatar
Alexandre
Bonjour,

je fais appel au grands experts du PHP.

Vous vous souvenez quand le register_global faisait des siennes. Pour un
grand nombre de developpeurs il a fallu reprendre le code notamment pour les
formulaire et changer:
$toto (issu du champs de formulaire ... name="toto">)
en
$_POST['toto'].

Pour ma part, je me suis dit qu'il etait hors de question de reprendre des
pages et des pages de codes faites par des predecesseurs ou moi meme.
J'ai donc cree ca:
if(isset($_POST)) {
foreach($_POST as $key=>$val) {
//echo $key.'=>'.$val.'<p>';
$$key = $val;
}
}

Que je mettais en haut de toutes mes pages. Et ca donctionne tres bien.

Puis je me suis dit que je pouvais faire la meme chose pour une requete
SELECT. Imaginons qu'une table contienne 70 champs et que vous souhaitez
tout afficher (les 70 champs).
J'ai donc fait ceci:

$requete = "SELECT * FROM gest_parc";
$resultat = mysql_query($requete);

while($row = mysql_fetch_array($resultat,MYSQL_ASSOC)){

foreach($row as $key=>$val) {
echo $key.'=>'.$val.'<p>';
$$key = $val;
}
}

Ce qui m'evite de faire:
while ($row=mysql_fetch_object($resultat)){
$id = $row->id;
$nom = $row->nom;
.
.
.
.
}

ou un fetch_array ou encoe un mysql_result...

Tout ceci fonctionne a merveille. MAintenant la question que je me pose
c'est que je n'ai jamais vu ce genre de code sur le net ni meme dans les
applis qu'on trouve en open-source.

Je me demandais alors si j'adoptais une bonne methode, si je n'allais pas a
l'encontre de l'efficacite ou d'un certain "bon procede".

Merci d'avance

Alex

10 réponses

1 2 3 4
Avatar
Nadine St-Amand
Alexandre wrote:

Tout ceci fonctionne a merveille. MAintenant la question que je me pose
c'est que je n'ai jamais vu ce genre de code sur le net ni meme dans les
applis qu'on trouve en open-source.

Je me demandais alors si j'adoptais une bonne methode, si je n'allais pas a
l'encontre de l'efficacite ou d'un certain "bon procede".

Merci d'avance

Alex


Apres avoir vu tout le monde critiquer ta mesure en fonction des
politiques/modes actuelles des utilisations de $_GET et $_POST

Moi je pense que tu t'es demande si tu ne pouvais pas automatiser
certaines etapes redondantes de ton developpement. Tu as voulu commencer
a automatiser ton code, en fait tu as fait un premier pas vers la
generation de code.

--
Nadine St-Amand
Code generation sql2php http://www.phpbackend.com/

Avatar
Nadine St-Amand
Je me demandais alors si j'adoptais une bonne methode, si je n'allais pas a
l'encontre de l'efficacite ou d'un certain "bon procede".


Pour les paranoiaque:
une autre facon de faire est d'utiliser une liste de variable
predefinie, et de boucler dans ce tableau plutot que de boucler
directement dans $_POST et $_GET.

Pour si on boucle directement dans $_POST et $_GET,

moi je vois deux cas de figure: les variables attendues et les variables
non-attendues.

- Pour les variables attendues: comme tu les attends et qu'elles
contiennent des donnees, potentiellement bonnes, potentiellement
mauvaises, bien les recevoir dans $variable ou dans $_POST[variable]
revient au meme, il y a les memes dangers (injection sql, chaines trop
longues)

- Pour les variables non-attendues, le danger serait de recevoir en GET
ou en POST une valeur pour une variable interne du code. Ce danger
n'est un danger que si le programmeur l'utilise sans la setter. le cas
de figure le plus courant peut etre une concatenation qui a lieu en
boucle sans initialiser la variable a chaine nulle au debut.
Dans le cas ou le code d'une application est connue, que le nom de la
variable soit publiquement connue et qu'il soit egalement connu que la
variable n'est pas initialise fermement avant utilisation, il y a danger.

Moi je pense que si tu sais que tu ne fais _jamais_ ce genre de chose,
tu peux faire la boucle foreach en haut.

Si tu as peur de le faire, bien fait plutot une boucle avec une liste de
variables attendues. J'utilise deja cette procedure pour valider mes
variables (verifier que tous les champs sont remplis) dans mes
formulaires en plusieurs etapes.

Dites-moi si je me trompe dans mon analyse.

--
Nadine St-Amand
Code generator sql2php http://www.phpbackend.com/

Avatar
Nadine St-Amand
ftc wrote:
[SNIP]

J'ai donc cree ca:
if(isset($_POST)) {
foreach($_POST as $key=>$val) {
//echo $key.'=>'.$val.'<p>';
$$key = $val;
}
}



if ( isset( $_POST ) ) extract( $_POST, EXTR_SKIP );
me semble plus concis et plus facile à lire et évide d'écraser des
variables déjà définies.



S'il ajoutait dans son code
if(!isset($$key))
avant de fixer la variable cela reviendrait au meme non ?

Mais comme ce code est place au debut du code et qu'il n'y a encore
aucune variable de definie, bien cela est identique en resultat non ?

La reponse facile toute faite que 'register global on' est mauvais se
propage tel un dogme :)

Le danger ne vient-il pas des variables utilisees en milieu de script
lesquelles devraient commencer des accumulations a null ?

J'aime bien clarifier d'ou vient exactement le danger
et ce qu'offre exactement la mesure preconisee...

Si ce n'est pas qu'une mesure d'architecture..

Car le probleme vient tout d'abord d'un probleme de programmation et
d'architecture, et la mesure ne vise qu'a imposer une solution pre-faite
aux concepteurs qui seraient nous dit-on incapables d'ecrire du code
secure sans register global.

Je pense que le concepteur doit etre libre de
concevoir son architecture et de choisir ses mesures de securites
en fonction du probleme reel.

Sinon, tout code pourrait etre ecris par des machines.

--
Nadine St-Amand
Code generator sql2php http://www.phpbackend.com/


Avatar
ftc
ftc wrote:

[SNIP]

J'ai donc cree ca:
if(isset($_POST)) {
foreach($_POST as $key=>$val) {
//echo $key.'=>'.$val.'<p>';
$$key = $val;
}
}




if ( isset( $_POST ) ) extract( $_POST, EXTR_SKIP );
me semble plus concis et plus facile à lire et évide d'écraser des
variables déjà définies.



S'il ajoutait dans son code
if(!isset($$key))
avant de fixer la variable cela reviendrait au meme non ?

Mais comme ce code est place au debut du code et qu'il n'y a encore
aucune variable de definie, bien cela est identique en resultat non ?


Enfin, ça ne rajoute toujours pas à la lisibilité du code.


La reponse facile toute faite que 'register global on' est mauvais se
propage tel un dogme :)


Ca évite quand même un bon nombre de trous de sécurité puisque tout un
tas de développeurs se bornent à ne pas vouloir initialiser leurs variables.

[SNIP]

Car le probleme vient tout d'abord d'un probleme de programmation et
d'architecture, et la mesure ne vise qu'a imposer une solution pre-faite


Une solution plus que logique. Il n'y a aucune raison pour que les
arguments du script soient des variables globales.
La solution pré-faite est d'intégrer les arguments en variables
globales, a ma connaissance, PHP est le seul langage a intégrer les
arguments saisis par l'utilisateur en variables globales.



Avatar
Nadine St-Amand
Une solution plus que logique. Il n'y a aucune raison pour que les
arguments du script soient des variables globales.
La solution pré-faite est d'intégrer les arguments en variables


Cela depend de l'utilisation faite de php.

Le programmeur d'une page php qui passe deux ou trois arguments a la
suivante, qui elle, utilise ces variables pour faire une requete et
c'est tout, ce qui est le cas le plus frequent, n'as pas beoin de cette
separation de namespace.

Par contre, la web application complexe avec des tonnes de modules et
d'include et de dependances entre les scripts pourraient y voir un
avantage dependant de la facon de proceder du prorammeur.

Moi j'utilise des noms de variables si systematiques que le namespace
est deja fait sans l'utilisation des tableaux $_GET et $_POST

De plus, il arrive dans mes architecture
qu'un script ne sache pas a l'avance si la variable
sera recue en post ou en get.
Dans ce cas, le namespace devient un obstacle qui demande d'ajouter du
code tres peu elegant...

L'ideal serait de pouvoir choisir au niveau du script, et non pas au
niveau du serveur, quel est le comportement desire.

--
Nadine St-Amand
Generation de code sql2php http://www.phpbackend.com/

Avatar
Nadine St-Amand
Enfin, ça ne rajoute toujours pas à la lisibilité du code.


La syntaxe est extremement alourdie avec les $_POST et les $_GET
obligatoires, du fait que les acces dans les tableaux ne se
dereferencent pas dans les chaines comme les variables simples.

Un exemple naif pour illustrer :

$sql = "insert into matable(var1, var2) values('$test1','$test2')";

est beaucoup plus lisible donc maintenable que

$sql = 'insert into matable(var1, var2) values(''.
$_POST[test1].'',''.$_POST[test2].'')';

Il y a deja quelqu'un qui a dit : simple is beautiful.

--
Nadine St-Amand
Generateur de code sql2php http://www.phpbackend.com/

Avatar
loufoque
Nadine St-Amand a dit le 20/06/2005 à 12:36:

De plus, il arrive dans mes architecture
qu'un script ne sache pas a l'avance si la variable
sera recue en post ou en get.
Dans ce cas, le namespace devient un obstacle qui demande d'ajouter du
code tres peu elegant...


$_REQUEST c'est peu élégant ?

Avatar
ftc
[SNIP]

De plus, il arrive dans mes architecture
qu'un script ne sache pas a l'avance si la variable
sera recue en post ou en get.
Dans ce cas, le namespace devient un obstacle qui demande d'ajouter du
code tres peu elegant...


$_REQUEST['mavariable'] ne m parrait pas si inélégant

Avatar
P'tit Marcel
Nadine St-Amand wrote:
Il y a deja quelqu'un qui a dit : simple is beautiful.


là t'as bon

$sql = 'insert into matable(var1, var2) values(''.
$_POST[test1].'',''.$_POST[test2].'')';


là t'as pas bon :
http://fr.php.net/manual/en/language.types.array.php#language.types.array.donts


Comme disait quelqu'un "voler c'est voler, reprendre c'est reprendre"

--
P'tit Marcel
(non pas Gotlib, c'est de Michel Gérard Joseph :-)

Avatar
loufoque
Nadine St-Amand a dit le 20/06/2005 à 12:36:

Un exemple naif pour illustrer :

$sql = "insert into matable(var1, var2) values('$test1','$test2')";

est beaucoup plus lisible donc maintenable que

$sql = 'insert into matable(var1, var2) values(''.
$_POST[test1].'',''.$_POST[test2].'')';


1) ton code produit un notice, les constantes test1 et test2 n'existent pas

2) le premier exemple était une déclaration de chaîne avec des
guillemets doubles et interprétation des variables et le second et une
déclaration de chaîne avec guillemets simples et concaténation.
Ce sont deux techniques totalement différentes, et il est tout à fait
possible d'utiliser les deux techniques sur des tableaux.

$sql = "INSERT INTO matable(var1, var2) VALUES ('$_POST[test1]',
$_POST[test2]')";
Ceci fonctionne mais produit toujours les deux notices.
$sql = "INSERT INTO matable(var1, var2) VALUES ('{$_POST['test1']}',
'{$_POST['test2']}')";
Il est nécessaire d'utiliser les accolades dans ce cas pour pouvoir
délimiter quelle est réellement la variable.

3) De toutes façons, on intègre pas directement une variable dans une
requête SQL, surtout si elle est issue de GET, POST ou autre.
Il faut mapper le type PHP vers le type SQL, ce qui se traduit, pour les
chaînes de caractères, à entourer la chaîne de deux ' et réaliser un
échappemment avec mysql_escape_string().
Simplement entourer la chaîne de deux ' n'est pas suffisant.
Personnellement, je pense qu'il vaut mieux utiliser une fonction
"magique" qui génerera la requête.
Du genre maFonctionMagique('INSERT INTO matable(var1, var2) VALUES (?,
?)', $_POST['test1'], $_POST['test2']);

Bien sûr il y a magic_quotes_gpc qui réalisera automatiquement un
addslashes sur GET/POST/Cookie, addslashes qui équivaut à
mysql_escape_string.
Mais ce n'est pas portable avec d'autres SGBDs et de toutes façons c'est
du non-sens. Une variable est censée contenir son contenu, et non pas un
contenu altéré en vue d'un traitement spécifique.

1 2 3 4