Search code examples
phpsqlpdobindvalue

How define the variable type in PDOStatement::bindValue()?


The PDOStatement::bindValue() method offers a way to specify the type of the variable bound:

PDOStatement::bindValue ( $parameter , $value [, $data_type = PDO::PARAM_STR ] )

I'm wondering, what's the purpose of specifying the data type, whereas when leaved as default (PARAM_STR) eventually the database will anyway cast the value to the proper type before using it?

For example, if you have these queries over an INTEGER field:

INSERT INTO table (integerField) VALUES (?) ;
SELECT * FROM table WHERE integerField = ?  ;

And you bind an integer in PHP, PDO will by default bind it as a string, which is equivalent as:

INSERT INTO table (integerField) VALUES ("1") ;
SELECT * FROM table WHERE integerField = "1"  ;

That will work flawlessly, because the SQL database (at least MySQL, I'm not really aware of how that would work on other RDBMS) knows how to convert the string back to an integer before using it.

What are the use cases where it would make a difference to bound typed parameters vs strings?


Solution

  • I'm no PDO-expert, but I can think of a few scenarioes where the data_type parameter is both useful and even needed.

    Output parameters

    When you define output or input/output parameters, you must provide both type and length of the expected output parameter.

    Ref: http://www.php.net/manual/en/pdo.prepared-statements.php

    Example #4

    $stmt = $dbh->prepare("CALL sp_returns_string(?)");
    $stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); 
    

    Example #5

    $stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
    $value = 'hello';
    $stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); 
    

    DBMs without implicit casting

    Explained in another answer to this question...

    When parameter is not bound to castable data

    Even databases with casting abilities will not always be able to cast you variable correctly.

    Ref: Reasons to strongly type parameters in PDO?

    $limit = 1;
    
    $dbh->prepare("SELECT * FROM items LIMIT :limit");
    $dbh->bindParam(":limit", $limit, PDO::PARAM_STR); 
    // Will throw "You have an error in your SQL syntax..."