PHP PDO:: bindParam () types de données.. comment ça fonctionne?

je me demande ce que la déclaration du type de données dans bindParam() (ou bindValue()) est utilisé pour...

je veux dire, j'ai pensé que si je définis un argument entier (PDO::PARAM_INT), l'argument doit être converti en entier, quelque chose comme

$delete->bindParam(1, $kill, PDO::PARAM_INT);
// should work like
$delete->bindParam(1, (int)$kill);

ou au moins de lever une erreur si l'argument n'est pas du type déclaré. Mais ce n'est pas le cas.

Googler autour, j'ai trouvé que les php.net archive:

Salut à tous,

je travaille actuellement sur PDO. Exactement sur la fonction bindParam (). Troisième paramètre data_type semble être ici pour forcer le type de la valeur ? Mais quand j'ai essayer :

$sql = "INSERT INTO produit (idproduit, nom, marque) VALUES (NULL, :nom, :marque)";
$stmt = $dbh->prepare($sql);
$nom = 'Testarossa'; $marque = 'Ferrari' ;
$stmt->BindValue(':marque',$marque) ;
$stmt->BindParam(':nom',$nom,PDO::PARAM_INT) ;

$stmt->execute(); $nom = '250 GTO' ;
$stmt->execute(); ?>

Je m'attendais à avoir soit un PHP erreur ou un nombre entier dans ma base de données. Mais dans ma DB j'ai :

22 Testarossa Ferrari 23 250 GTO Ferrari

cela signifie que cela n'a pas changé si je la troisième paramètre ou pas. Ou j'ai peut-être raté quelque chose. Quelqu'un peut-il tole plus de moi ? Ou tout simplement quelqu'un peut dit moi où je peux trouver des informations sujet.

Cordialement,

Cyruss

C'est exactement ma situation. Où sont mes pensées vont mal?

29
demandé sur Shi 2009-05-07 12:42:57

4 réponses

dans d'autres cadres d'abstraction DB dans d'autres langues, il peut être utilisé pour des choses comme s'assurer que vous faites la bonne échappée pour les valeurs in-lining (pour les pilotes qui ne supportent pas les paramètres liés appropriés) et l'amélioration de l'efficacité du réseau en s'assurant que les nombres sont binaires emballés de manière appropriée (prise en charge du protocole donnée). On dirait QU'en AOP, ça ne fait pas grand-chose.

   if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
                if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
                        char *p;
                        int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter));
                        ZVAL_STRINGL(param->parameter, p, len, 0);
                } else {
                        convert_to_string(param->parameter);
                }
        } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
                convert_to_long(param->parameter);
        } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) {
                convert_to_boolean(param->parameter);
        }

Donc, si vous dites que c'est un STR (ou si vous ne dites rien du tout car c'est la valeur par défaut) et votre le type interne de données est un double puis il le transformera en une chaîne en utilisant une méthode, si ce n'est pas un double alors il le convertira en une chaîne en utilisant une méthode différente.

si vous dites que c'est un int mais c'est vraiment un bool alors il le convertira en un long.

si vous dites que c'est un bool mais c'est vraiment un nombre alors il le convertira en un vrai booléen.

C'est vraiment tout ce que j'ai vu (rapidement) en regardant la source stmt, j'imagine qu'une fois que vous passez les paramètres dans le pilote qu'ils peuvent faire magiques supplémentaires. Donc, je suppose que tout ce que vous obtenez est un peu de faire le bon et beaucoup de comportement ambiguïté et la divergence entre les conducteurs.

32
répondu Trey 2009-05-14 21:43:19

alors j'ai décidé de plonger dans le code source de PHP et c'est ce que j'ai trouvé.

static int really_register_bound_param ext/aop/pdo_stmt.c à la ligne 329 de la version 5.2.9

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
    if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
        char *p;
        int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter));
        ZVAL_STRINGL(param->parameter, p, len, 0);
    } else {
        convert_to_string(param->parameter);
    }
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
    convert_to_long(param->parameter);
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) {
    convert_to_boolean(param->parameter);
}

ce sont les conversions Que fait AOP lors de la liaison.

  • PDO::PARAM_STR convertit tout ce que vous lui donnez en chaîne sauf null.
  • PDO::PARAM_INT convertit bools en longs
  • PDO::PARAM_BOOL convertit longs en bool

c'est tout. Rien d'autre est converti. AOP utilise les drapeaux PARAM pour formater SQL et non pas pour lancer des types de données.

20
répondu gradbot 2014-01-26 17:28:14
INSERT requêtes: les valeurs booléennes sont converties en 0 ou 1. Comme dans

$i = true;
$stmt->bindParam(':i', $v, PDO::PARAM_INT);

pdo_stmt.c:

else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
        convert_to_long(param->parameter);
}
6
répondu VolkerK 2009-05-07 10:49:17

j'ai essayé la même chose avec BindValue et a obtenu le même résultat, donc le comportement que vous voyez n'est pas limité à bindParam.

$stmt->BindValue(':marque', $marque) ;
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ;

$stmt->execute();
$nom = '250 GTO';
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ;
$stmt->execute(); 
3
répondu gradbot 2009-05-14 20:38:57