Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need to specify the parameter type in bindParam()?

I am a bit confuse as to why we need to specify the type of data that we pass in the bindParam() function in PDO in Php. For example this query:

$calories = 150; 
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT); 
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
$sth->execute();

Is there a security risk if I do not specify the 3rd parameter. I mean if I just do in the bindParam():

$sth->bindParam(1, $calories); 
$sth->bindParam(2, $colour);
like image 635
Sameer Zahid Avatar asked Jun 02 '13 08:06

Sameer Zahid


2 Answers

Using bindParam() with types could be considered safer, because it allows for stricter verification, further preventing SQL injections. However, I wouldn't say there is a real security risk involved if you don't do it like that, as it is more the fact that you do a prepared statement that protects from SQL injections than type verification. A simpler way to achieve this is by simply passing an array to the execute() function instead of using bindParam(), like this:

$calories = 150; 
$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories
                      FROM fruit
                      WHERE calories < :calories AND colour = :colour');

$sth->execute(array(
    'calories' => $calories,
    'colour' => $colour
));

You're not obligated to use a dictionary, you can also do it just like you did with questionmarks and then put it in the same order in the array. However, even if this works perfectly, I'd recommend making a habit of using the first one, since this method is a mess once you reach a certain number of parameters. For the sake of being complete, here's what it looks like:

$calories = 150; 
$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories
                      FROM fruit
                      WHERE calories < ? AND colour = ?');

$sth->execute(array($calories, $colour));
like image 50
PLPeeters Avatar answered Oct 05 '22 00:10

PLPeeters


If you do not specify a type, the parameter will be bound as a string by default. You may then end up with a query equivalent to:

SELECT foo FROM bar WHERE baz = '42'

This may or may not be a problem. Just like PHP and other programming languages, databases have types and rules for casting between types. MySQL will typically implicitly cast numeric strings to numbers as needed. Some databases are stricter than others, requiring the right type for certain operations. In most cases, it makes little difference. But if you really need to pass 42 as 42 and not '42', you need to explicitly bind it as an INT.

like image 40
deceze Avatar answered Oct 04 '22 23:10

deceze