PHP PDO::bindParam() data types.. how does it work

pdophpprepared-statementtypes

I'm wondering what the declaration of the data type in bindParam() (or bindValue()) is used for…

I mean, I thought that if I define an integer argument (PDO::PARAM_INT), the argument must be converted to an integer, something like

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

or at least throw an error if the argument is not of the declared type. But this is not the case.

Googling around, I found that in the php.net archive:

Hi all,

I am currently working on PDO. Exactly
on the bindParam() function. The third
parameter data_type seems to be here
to force the type of the value ? But
when I try :

$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(); ?>

I was expecting to have either a PHP
error or an interger in my database.
But in my DB I have :

22 Testarossa Ferrari 23 250 GTO
Ferrari

It mean that it didn't change if I
have the third parameter or not. Or
perhaps I miss something. Can someone
tole me more ? Or just can someone
told me where I can find information
about it.

Regards,

Cyruss

That is exactly my situation. Where are my thoughts going wrong?

Best Solution

In other DB abstraction frameworks in other languages it can be used for things like making sure you're doing the proper escaping for in-lining values (for drivers that don't support proper bound parameters) and improving network efficiency by making sure numbers are binary packed appropriately (given protocol support). It looks like in PDO, it doesn't do much.

   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);
        }

So, if you say it is a STR (or if you say nothing at all as that is the default) and your data's internal type is a double then it will turn it into a string using one method, if it's not a double then it will convert it to a string using a different method.

If you say it's an int but it is really a bool then it will convert it to a long.

If you say it's a bool but it's really a number then it will convert it to a true boolean.

This is really all I saw (quickly) looking at the stmt source, I imagine once you pass the parameters into the driver they can do additional magic. So, I'd guess that all you get is a little bit of do the right and a whole lot of behavior ambiguity and variance between drivers.