mauvais résultat retourné par ma faction

bug lors du retour des resultats

a marqué ce sujet comme résolu.

Bonjour en ce moment je développe un espace membre l’inscription fonctionne bien toutes les données sont bien enregistrer. mais seulement lors de la connexion il me retourne un mauvais résultat mais alors très mauvais

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
function getMember($fildName="m.id", $fildValue) {
    global $bdd;
    $req=$bdd->prepare('SELECT *
                FROM member m 
                INNER JOIN membergroup g ON g.id=m.memberGroupId
                INNER JOIN memberstatus s ON s.id=m.memberStatusId
                WHERE '.$fildName.'=:fildValue');
    $req->bindParam(':fildValue', $fildValue, PDO::PARAM_STR|PDO::PARAM_INT);
    $req->execute();
    $member=$req->fetch();
    $req->closeCursor();
    return $member;
}

l'id retourner n'est jamais le bon il est toujours 1 ou 2 et si je supprime les deux jointures le résultat ce corrige or je ne pense pas avoir fait d'erreur dans la requête sql lorsque je de-bug avec un var_dump il me donne ceci

1
2
3
array (size=54)
  'id' => string '1' (length=1)
  0 => string '4' (length=1)

normalement ce membre a pour id 4 en BDD

1
2
3
array (size=54)
  'id' => string '2' (length=1)
  0 => string '1' (length=1)

de même ici en BDD ce membre a pour id 1. je pense que l'erreur ce trouve dans la requête mais j'arrive pas a trouver une solution

EDIT Artragis: juste l'ajout de <?php pour la coloration.

+1 -0

Salut, et t'as essayé d'afficher $fildValue ?

A priori, y a une erreur dans ta requete, dans les données fournies ou dans le schema de la base. As tu essayé ta requete dans phpmyadmin par exemple ?

Tu n'as pas mis de mode pour ton fetch, est ce voulu ? (PDO::FETCH_ASSOC par exemple ?) Comment teste tu que l'id renvoyé ? Dans ton exemple, on voit que la colonne 0 a l'id 4, et tu dis que c'est l'id que tu es censé avoir, donc le var dump est correct ?

PDO::PARAM_STR|PDO::PARAM_INT

C'est l'un ou l'autre mais pas un masque des deux.

Pour revenir au résultat, t'es sûr de considérer le bon "id" ? Parce que vu le SELECT *, la requête renvoie 3 champs nommés id : les tables aliasées par m, s et g ont toutes une colonne id si on en croit ce que tu nous mets. C'est potentiellement ce que montre le var_dump : tu dois être en PDO::FETCH_BOTH (le mode par défaut) où on voit que la clé id a un résultat différent de l'index 0, qui doit réellement correspondre à m.id, parce que PHP écrase la valeur des précédentes colonnes nommées id par celle qu'il trouve en dernier (celle de m.id est écrasée par la valeur de g.id puis par celle s.id logiquement).

PDO prévoit d'ailleurs le mode PDO::FETCH_NAMED pour créer un sous-tableau en cas de conflit sur le nom de la colonne au lieu d'écraser bêtement la valeur des autres. Sinon il faut aliaser les colonnes m.id/s.id et g.id pour lever le conflit ou carrément renommer les colonnes.

+0 -0
1
PDO::PARAM_STR|PDO::PARAM_INT

ça peut etre l'un ou l'autre si je veux un membre dont le pseudo est blabla ou si je veux un membre dont l’émail est blabla@waff.fr ou encore si je veux un membre dont l'id est 10 le résultat est là c'est juste pour élargir les possibilité et dans la doc si ne me trompe bindParam peut accepter plusieurs types

Regardes comment PHP le gère en interne : ce sont des comparaisons (== et case) et non des tests sur les bits (&).

De toute façon, avec MySQL, tu peux binder un entier comme une chaîne, il fera la cast. Si tu veux vraiment le faire correctement, ça devrait être à toi de le gérer (genre : $req->bindParam(':fildValue', $fildValue, is_int($fildValue) ? PDO::PARAM_INT : PDO::PARAM_STR);).

EDIT : en plus, vu que :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
enum pdo_param_type {
        PDO_PARAM_NULL,

        /* int as in long (the php native int type).
         * If you mark a column as an int, PDO expects get_col to return
         * a pointer to a long */
        PDO_PARAM_INT,

        /* get_col ptr should point to start of the string buffer */
        PDO_PARAM_STR,

        /* get_col: when len is 0 ptr should point to a php_stream *,
         * otherwise it should behave like a string. Indicate a NULL field
         * value by setting the ptr to NULL */
        PDO_PARAM_LOB,

        /* get_col: will expect the ptr to point to a new PDOStatement object handle,
         * but this isn't wired up yet */
        PDO_PARAM_STMT, /* hierarchical result set */

        /* get_col ptr should point to a zend_bool */
        PDO_PARAM_BOOL,

        /* get_col ptr should point to a zval*
           and the driver is responsible for adding correct type information to get_column_meta()
         */
        PDO_PARAM_ZVAL,

        /* magic flag to denote a parameter as being input/output */
        PDO_PARAM_INPUT_OUTPUT = 0x80000000
};

Tu dois les binder comme du PDO::PARAM_LOB (var_dump(PDO::PARAM_LOB === (PDO::PARAM_INT|PDO::PARAM_STR)); # => true) donc ça finit réellement en PDO::PARAM_STR parce que $fildValue n'est pas une resource type descripteur de fichier/stream (résultat d'un fopen comprenant la lecture notamment).

De toute façon, si tu fournis un masque de deux types, qui et comment ce serait choisi sachant qu'ils ne doivent pas être gérés de la même façon (rien qu'au niveau de l'API cliente du SGBD) ? C'est à toi de lui fournir cette information.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte