phptypespdoprepared-statement

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


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?


Solution

  • It can be used for things like making sure PDO is 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 base PDO, it doesn't do much.

    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && !Z_ISNULL_P(parameter)) {
        if (!try_convert_to_string(parameter)) {
            return 0;
        }
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE)) {
        convert_to_long(parameter);
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(parameter) == IS_LONG) {
        convert_to_boolean(parameter);
    }
    

    So, if you say it is a string (or if you say nothing at all as that is the default) and your data's type is something other than a NULL then it will convert it into a string.

    If you say it's an int but you bind a bool then it will convert it to an integer.

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

    When emulation mode is turned on, the type hint is used to determine how to inject it into the SQL string.

    Additionally, PDO provides this information to the database drivers, which can then be used to bind the data most optimally or correctly, depending on the particular DB's requirements.