Page 1 sur 2

PDO et syntaxe

Posté : 04 mars 2015, 18:03
par sam01
Bonjour,
pouvez-vous me dire si cette syntaxe est correcte ?

Code : Tout sélectionner

$sqla = $db->prepare("SELECT cont_".$lang." FROM flatforswap_continent ORDER BY cont_".$lang." ASC"); $sqla->execute(array());
Merci d'avance pour votre aide.

Re: PDO et syntaxe

Posté : 04 mars 2015, 18:57
par sirakawa
$sqla = $db->prepare("SELECT cont_".$lang." FROM flatforswap_continent ORDER BY cont_".$lang." ASC");
serait plus simple ainsi:
$cont_lang = "cont"_".$lang;
//on peut vérifier la variable et on s'épargne des concaténations dans la requête
$sqla = $db->prepare("SELECT $cont_lang FROM flatforswap_continent ORDER BY $cont_lang ASC"); /

Re: PDO et syntaxe

Posté : 04 mars 2015, 20:20
par AB
Si tu ne lie (bind) aucune variable alors pas la peine de faire une requête préparée...

Tu as intérêt de vérifier la valeur de $lang avant de l'employer dans ta requête sinon tu auras une erreur.

Re: PDO et syntaxe

Posté : 05 mars 2015, 15:40
par sam01
Bonjour,

mais alors à quoi sert le

Code : Tout sélectionner

$sqla->execute(array());
?

Dans la requête suivante, par exemple, j'utilise le ->execute(array())

Code : Tout sélectionner

$sql = $db->prepare("select * from fcadsd_adh where mail=? and mdp=? and valide !=?"); $sql->execute(array($mail, $mdp, '0'));

Re: PDO et syntaxe

Posté : 05 mars 2015, 15:43
par tof73
le execute sert à exécuter ta requête, étape indispensable.
selon que tu as des paramètres à lier, tu passes un tableau avec du contenu, un tableau vide, ou rien.

Re: PDO et syntaxe

Posté : 05 mars 2015, 16:05
par xTG
Non... Si tu ne passes rien tu ne fais pas de requête préparée du tout.
Sinon c'est comme utiliser une pelleteuse 40t pour retourner ton parterre de fleur de 2m², cela ne sert à rien... :P

Voici quelques exemples d'utilisation (et encore qui pourraient se discuter).
Requête préparée car utilisée plusieurs fois :
foreach($liste as $champs3)
{
   $sql = $db->prepare("SELECT champs1, champs2 FROM maTable WHERE champs3 = ? AND date > NOW()");
   $sql->execute(array($champs3));
   // traitement ....
}
Un cas de requête unique qui ne requiert donc pas de requête préparée :
$sql = $db->query("SELECT champs1, champs2 FROM maTable WHERE champs3 = " . $db->quote($champs3));
La fonction quote est là pour protéger la requête contre les injections.
Note : dans le cas d'une requête préparée c'est directement géré par la fonction execute.

Re: PDO et syntaxe

Posté : 05 mars 2015, 16:18
par AB
Normalement on utilise une requête préparée pour lier des variables dans une requête.
Donc on fait un prepare(), on bind les variables individuellement et on utilise execute() sans paramètre,
ou,
on fait un prepare() et on bind les variables globalement en passant un tableau comme paramètre dans le execute($array).

Quand il n'y a pas de variable à lier dans la requête, l'étape du prepare() n'est pas justifiée.
Dans ce cas on utilise juste query() pour les sélections et exec() pour les autres (update, insert, delete)

Re: PDO et syntaxe

Posté : 05 mars 2015, 16:45
par AB
J'avais pas vu le message d'xTG...

Voici donc quelques explications concernant nos "différentes versions" :

Il faut savoir qu'à l'origine les requêtes préparées sont prévues pour accélérer le processus d'exécution des requêtes multiples, typiquement dans une boucle.

Ensuite il s'avère que les requêtes préparées sont plus sécurisées contre les infections sql car la préparation de la requête fait une abstraction (bind) entre le symbol et la variable et donc la variable ne fait pas partie directement de la chaine de la requête. Comme le coût de la préparation n'est pas très élevé en terme de performance on conseille donc d'utiliser les requêtes préparées pratiquement à chaque fois que l'on traite des variables utilisateurs.
Ensuite pour pas se prendre le choux, on peut aller jusqu'à dire à chaque fois que l'on traite une variable.

Mais si j'ai bien compris vous voulez utiliser des requêtes préparées systématiquement même sans variables. Là vous poussez le bouchon un peu loin. Et puis vous passez à côté des fonctionnalités pratiques des fonctions exec et query que ne possède pas execute.

Re: PDO et syntaxe

Posté : 05 mars 2015, 16:50
par sam01
OK.

j'ai effectivement été attaqué par injection mysql. certaines de mes tables ont complètement été vidées.
J'ai donc décidé de mettre à jour mon site en intégrant du PDO.
Si j'ai bien compris, et en tenant compte de vos remarques, voici ce que donne mon code :

Code : Tout sélectionner

$sqla = $db->query("SELECT cont_".$lang." FROM flatforswap_continent ORDER BY cont_".$lang." ASC"); while($dataa = $sqla->fetch()) { if ($continent == $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'" selected="selected">'.$dataa['cont_'.$lang.''].'</option>'; } if ($continent != $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'">'.$dataa['cont_'.$lang.''].'</option>'; } }
etc-ce que ça vous semble correct ?

Re: PDO et syntaxe

Posté : 05 mars 2015, 16:53
par xTG
Tu t'exposes toujours aux injections.
Regardes mon exemple utilisant query ET SURTOUT l'utilisation de quote. ;)

Re: PDO et syntaxe

Posté : 05 mars 2015, 17:13
par sam01
es-tu sûr que je m'expose aux injections...

Je ne vois pas comment une injection peut rentrer dans ce code...

Re: PDO et syntaxe

Posté : 05 mars 2015, 17:19
par AB
Effectivement c'est typiquement le cas où les requêtes préparées ne servent à rien car les marqueurs ne peuvent se lier qu'aux valeurs des champs et non pas au nom des champs. Ainsi tu faisais une requête préparée qui n'était pas sécurisée. Avec query ou exec il faut utiliser quote pour protéger la chaine de la requête.

Cela dit normalement tu dois bien avoir un tableau de traduction des langues. Et dans le cas il te suffit de faire

Code : Tout sélectionner

if(in_array($lang, $tab_lang)) {//requête}
Pour dire qu'à chaque fois que cela est possible, requête préparée ou pas, on vérifie toujours si la variable fournie fait partie des variables attendues avant de faire une requête.

Re: PDO et syntaxe

Posté : 05 mars 2015, 17:48
par sam01
Au fait la variables $lang est définiie en amont de mon code (elle est donc forcément vérifiée puisque c'est moi qui l'impose)

Code : Tout sélectionner

$domaines_config = array( 'www.example.com' => 'en', 'www.example.fr' => 'fr', 'www.example.es' => 'es' ); // $domaine = ''; $lang = ''; // On vérifie que le domaine if ( isset($domaines_config[$_SERVER['HTTP_HOST']] ) ) { $lang = $domaines_config[$_SERVER['HTTP_HOST']] ; } else { echo 'Domaine non reconnu'; exit(); // throw new Exception("Domaine non reconnu:".$_SERVER['HTTP_HOST']); }

Re: PDO et syntaxe

Posté : 05 mars 2015, 18:08
par AB
Oui donc tu ne risque pas d'injection.
Enfin bon cela ne te dispense pas de faire la requête correctement avec la protection quote sur $lang, comme ça tu sauras le faire (c'est assez souvent qu'on ne peut pas contrôler la variable avant).

Re: PDO et syntaxe

Posté : 05 mars 2015, 18:20
par AB
Je me répond à moi-même :

Cela dit quand on modifie le nom d'un champ avec une variable, il est normalement "toujours" possible de contrôler si le nom du champ est correct avant de faire la requête. Et si par ailleurs on utilise les requêtes préparées dès qu'il s'agit de lier des valeurs aux variables (excepté les noms des champs), cela explique pourquoi je n'utilise quasiment jamais la fonction quote().