PDO::PARAM_INT is important in bindParam?

Add PDO::PARAM_INT or PDO::PARAM_STR have any meaning in Mysql query?

$sql  = 'SELECT TagId FROM tagthread WHERE ThreadId = :ThreadId';

$stmt = $this->db->prepare($sql);
$stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT);

$stmt->execute();
Asked By: Jarek Kowol
||

Answer #1:

Yes, use it.

I did a few tests (with PDO::ATTR_EMULATE_PREPARES false) and I found out that the quotes around the values will be different.

When you bind an integer value with PARAM_INT there will be no quotes in the query (A string value with PARAM_INT has quotes). If you bind an integer value with PDO::PARAM_STR there will be quotes and mysql has to cast to integer.

Examples:

$stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT);
$threadid = 123;
// SELECT TagId FROM tagthread WHERE ThreadId = 123
$threadid = '123test';
// SELECT TagId FROM tagthread WHERE ThreadId = '123test'
// mysql will cast 123test to 123

EDIT:

I further tested and read on that topic. Conclusion: Implicit casting is dangerous and can lead to unexpected results. Read more on that here. Another disadvantage to always use PDO::PARAM_STR is the performance. Read more on performance Disadvantages of quoting integers in a Mysql query?

So if your column is of type [TINY|SMALL|MEDIUM|BIG]INT than use PARAM_INT. And in case it is a LIMIT clause than cast to integer if the variable type in PHP is not integer.

Answered By: bitWorking

Answer #2:

Edit: Depends! See Your Common Sense comment below.

If the value is a integer it should be treated as an integer. Apply this with as many datatypes as possible.

If you don't set the Attribute of PDO::ATTR_EMULATE_PREPARES to false, you will get a nasty error.

Solid example:

$stmt = $dbh->prepare("SELECT * FROM table123 WHERE raw_field = :field LIMIT 1 OFFSET :offset;");
$stmt->bindParam(':field',  $field);
$stmt->bindParam(':offset', $offset);

if ($map_stmt->execute())
{
    $data = stmt->fetch(PDO::FETCH_ASSOC);
}
else
{
    echo 'Error :';
    echo '<pre>';
    print_r($map_stmt->errorInfo());
    print_r($map_stmt->debugDumpParams());
    echo '</pre>';
}

Will return back a nasty error containing:

Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0'' at line 1

Query: SELECT * FROM table123 WHERE raw_field = 'home' LIMIT 1 OFFSET '0'

Useless you treat it as an integer, and it will remove the string (e.g.: ' ').

$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);

In a nutshell:

You choose! Strict data or not..

Answered By: tfont

Answer #3:

I cannot tell for all the drivers supported by PDO, but for mysql it's ok not to use PDO::PARAM_INT most of time.

Therefore, it makes no sense to bloat your code with numerous bindParam calls. As a rule, just send your variables directly into execute():

$sql  = 'SELECT TagId FROM tagthread WHERE ThreadId = ?';
$stmt = $this->db->prepare($sql);
$stmt->execute([$threadid]);

Here your $threadid variable will be silently bound as a string, but it will make not a single problem for mysql to compare it with integer value stored in database. In reality, everyone does it this way and never has any problem.

The problem with string type bindnig in LIMIT clause can be easily solved by switfhing the emulation mode OFF.

Note that PDO::PARAM_INT doesn't cast your value. Means if you're trying to bind a string type value using this mode, it will be bound as a string nevertheless, even if you explicitly set type to PDO::PARAM_INT. This mode will be actually applied only for integer values.

There are few edge cases where you may want to bind an integer explicitly though:

  • peculiar column types, like BIGINT or BOOLEAN that require an operand of exact type to be bound (note that in order to bind a BIGINT value with PDO::PARAM_INT you need a mysqlnd-based installation).
  • some DBAs claim that complex queries with non-trivial query plan can be affected by a wrong operand type. though noone provided a verifiable example yet

All other issues are common for the loose typing and neither mysql nor PDO binding has any special effect in them.

Also, to avoid possible problems you should choose right column types for your data. Say, for big integers you should use BIGINT, while for any price-like data it have to be DECIMAL. And there will be not a single issue with comparison.

Answered By: Your Common Sense
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .



# More Articles