If i do this:
$qry->execute(array($usuario,$pass));
instead of this:
$qry->bindParam(1, $usuario);
$qry->bindParam(2, $pass);
$qry->execute();
does this give a security problem?
Nope, they are semantically identical
And it's specified in the documentation
Execute the prepared statement. If the prepared statement included parameter markers, you must either:
call PDOStatement::bindParam() to bind PHP variables to the parameter markers: bound variables pass their value as input and receive the output value, if any, of their associated parameter markers
or pass an array of input-only parameter values
No, it will not. It will work fine.
Related
I often see code using bindParam or bindValue with PDO. Is simply passing arguments to execute frowned upon for any reason?
I understand that bindParam actually binds to the variables and that you can set the type of parameter being bound with both bind methods, but what if you are only inserting strings?
$query = "SELECT col1 FROM t1 WHERE col2 = :col2 AND col3 = :col3 AND col4 = :col4";
$pdo->bindValue(':col2', 'col2');
$pdo->bindValue(':col3', 'col3');
$pdo->bindValue(':col4', 'col4');
I often see the above, but personally I prefer:
$pdo->execute(array(':col2' => 'col2', ':col3' => 'col3', ':col4' => 'col4'));
It is not as verbose and visually it makes more sense to me to have the inputs "going in" to the query together. However, I hardly ever see it used.
Is there a reason to prefer the bind methods over passing parameters to execute when you don't have to take advantage of the special behaviors of the former?
You might find bindParam used when you just want to bind a variable reference to a parameter in the query, but perhaps still need to do some manipulations on it and only want the value of the variable calculated at time of query execution. It also allows you to do more complex things like bind a parameter to a stored procedure call and have the returned value updated into the bound variable.
For more, see the bindParam documentation, bindValue documentation and execute documentation.
For example
$col1 = 'some_value';
$pdo->bindParam(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_other_value' for ':col1' parameter
bindValue and passing an array to execute behave in much the same way as the parameter value is fixed at that point and SQL executed accordingly.
Following the same example above, but using bindValue
$col1 = 'some_value';
$pdo->bindValue(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_value' for ':col1' parameter
When passing values directly in execute all values are treated as strings (even if integer value is provided). So if you need to enforce data types, you should always use bindValue or bindParam.
I think you might see bind* used more than execute(array) as many consider it to be better coding practice to explicitly define data types in parameter declarations.
By passing the parameters along with the $pdo->execute() method, all values in the array with be passed, as PDO::PARAM_STR to the statement with the $pdo->bindParam() function.
The main difference that I can see now, is that with the $pdo->bindParam() function, you can define the data type passed along, using the PDO::PARAM_* constants as described in the PHP.net manual
Simple,
the value of bindParam may change but the value of bindValue can not change.
Example:
$someVal=10;
$someVal2=20;
/* In bindParam, the value argument is not bound and
will be changed if we change its value before execute.
*/
$ref->bindParam(':someCol',$someVal);
$someVal=$someVal2;
$ref->execute();
//someCol=20
/* In bindValue, the value argument is bound and
never changed if we change its value before execute.
*/
$ref->bindValue(':someCol',$someVal);
// here assignment is referral (&$someVal)
$someVal=$someVal2;
$ref->execute();
//someCol=10
I am getting the error:
Cannot pass parameter 2 by reference in.....
in this line...
$stmt1->bindParam(':value', $_SESSION['quantity'.$i] * $_SESSION['price'.$i], PDO::PARAM_STR);
What is wrong with code above ??
I'd say it's the typical confusion between PDO:bindParam() and what you probably intended to use: PDO:bindValue().
PDOStatement::bindParam
Binds a PHP variable to a corresponding named or question mark
placeholder in the SQL statement that was used to prepare the
statement. Unlike PDOStatement::bindValue(), the variable is bound
as a reference and will only be evaluated at the time that
PDOStatement::execute() is called.
PDOStatement::bindValue
Binds a value to a corresponding named or question mark placeholder in
the SQL statement that was used to prepare the statement.
It expects the second paramter to be a variable which can be passed by reference. Assuming $stmt1is a PDO statement then, as the docs for bindparam say
Unlike PDOStatement::bindValue(), the variable is bound as a reference
and will only be evaluated at the time that PDOStatement::execute() is
called.
Your second param is an expression ($_SESSION['quantity'.$i] * $_SESSION['price'.$i]) not a variable. Since you appear to want to evaluate the exptression now, I guess you should used bindValue() instead.
I want to know if the use of bindParam is mandatory to prevent SQL injection using PDO and MYSQL.
Example:
$username=$_POST['username'];
$password=$_POST['password'];
$cryptpass=hashFunction($password);
$sth=$dbh->prepare("INSERT INTO users(username,password) VALUES(?,?)");
$sth->execute(array($username,$cryptpass));
Is it a safe and proper way to write this code? Omitting bindParam makes shorter code.
This is still binding the values to a prepared statement. You are doing the same thing as if you were using the bindParam function. So the answer is yes it is just as safe. bindParam just allows for more functionality than simply binding with the execute function for example:
$sth=$dbh->prepare("Select * from users where status=:v1");
$sth->bindParam(':v1',1,PDO::PARAM_INT);
$sth->execute();
This allows you to specify the data_type by default with execute everything is sent as a string. Also you can look at the answer to this similar question: PDO bindParam vs. execute
All that matters is that you use parameters rather than substituting directly into the query string. It doesn't matter whether you bind the parameters with bindParam or with an array argument to execute, they're equivalent.
I often see code using bindParam or bindValue with PDO. Is simply passing arguments to execute frowned upon for any reason?
I understand that bindParam actually binds to the variables and that you can set the type of parameter being bound with both bind methods, but what if you are only inserting strings?
$query = "SELECT col1 FROM t1 WHERE col2 = :col2 AND col3 = :col3 AND col4 = :col4";
$pdo->bindValue(':col2', 'col2');
$pdo->bindValue(':col3', 'col3');
$pdo->bindValue(':col4', 'col4');
I often see the above, but personally I prefer:
$pdo->execute(array(':col2' => 'col2', ':col3' => 'col3', ':col4' => 'col4'));
It is not as verbose and visually it makes more sense to me to have the inputs "going in" to the query together. However, I hardly ever see it used.
Is there a reason to prefer the bind methods over passing parameters to execute when you don't have to take advantage of the special behaviors of the former?
You might find bindParam used when you just want to bind a variable reference to a parameter in the query, but perhaps still need to do some manipulations on it and only want the value of the variable calculated at time of query execution. It also allows you to do more complex things like bind a parameter to a stored procedure call and have the returned value updated into the bound variable.
For more, see the bindParam documentation, bindValue documentation and execute documentation.
For example
$col1 = 'some_value';
$pdo->bindParam(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_other_value' for ':col1' parameter
bindValue and passing an array to execute behave in much the same way as the parameter value is fixed at that point and SQL executed accordingly.
Following the same example above, but using bindValue
$col1 = 'some_value';
$pdo->bindValue(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_value' for ':col1' parameter
When passing values directly in execute all values are treated as strings (even if integer value is provided). So if you need to enforce data types, you should always use bindValue or bindParam.
I think you might see bind* used more than execute(array) as many consider it to be better coding practice to explicitly define data types in parameter declarations.
By passing the parameters along with the $pdo->execute() method, all values in the array with be passed, as PDO::PARAM_STR to the statement with the $pdo->bindParam() function.
The main difference that I can see now, is that with the $pdo->bindParam() function, you can define the data type passed along, using the PDO::PARAM_* constants as described in the PHP.net manual
Simple,
the value of bindParam may change but the value of bindValue can not change.
Example:
$someVal=10;
$someVal2=20;
/* In bindParam, the value argument is not bound and
will be changed if we change its value before execute.
*/
$ref->bindParam(':someCol',$someVal);
$someVal=$someVal2;
$ref->execute();
//someCol=20
/* In bindValue, the value argument is bound and
never changed if we change its value before execute.
*/
$ref->bindValue(':someCol',$someVal);
// here assignment is referral (&$someVal)
$someVal=$someVal2;
$ref->execute();
//someCol=10
How can I pass a constant to the bind_param in mysqli prepared statements. The following works fine by passing variable:
$stmt->bind_param("i", $id);
But if i try to pass constant, it does not work.
For example:
$stmt->bind_param("i", ID);
Gives following error:
Fatal error: Cannot pass parameter 2 by reference in...
Thanks
In MySQLi, the arguments following the type strings are passed by reference, not by value. The only thing you can pass by reference is a variable. The reason for using variables is that you can assign the variables, execute the statement, assign the variables again, execute the statement again, etc. So try this:
$id = ID;
$stmt->bind_param("i", $id);
Or try using PDO's MySQL driver instead of MySQLi. PDO allows you to choose to bind a value instead of a variable to a query parameter. This is useful if you plan to execute a prepared statement only once.