PHP PDOStatement: Analysis of data insertion errors in bindParam
- 2020-11-26 18:43:57
- OfStack
Without further ado, just look at the code:
What is the final SQL statement executed and is there anything wrong with the above code?
Okey, I think most of the students will think that the final SQL is:
INSERT INTO `user` (`username`, `password`) VALUES ("laruence", "weibo");
Unfortunately, you are wrong. SQL is:
INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");
Is it a big hole?
This question comes from today's 1 Bug report: #63281
The reason is the difference between bindParam and bindValue. bindParam requires the second parameter to be a reference variable (reference).
Let's break down foreach in the above code, which is this foreach:
Is equivalent to:
Therefore, when using bindParam, pay particular attention to the trap used in conjunction with foreach. So what's the right approach?
1. Do not use foreach, but manually assign values
2. Use bindValue instead of bindParam, or pass the entire parameter array directly in execute.
3. Use foreach and reference(not recommended)
Finally, it is expanded that foreach should be used with caution when using functions that require a reference and have a lag processing.
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', "test");
$query = <<<QUERY
INSERT INTO `user` (`username`, `password`) VALUES (:username, :password);
QUERY;
$statement = $dbh->prepare($query);
$bind_params = array(':username' => "laruence", ':password' => "weibo");
foreach( $bind_params as $key => $value ){
$statement->bindParam($key, $value);
}
$statement->execute();
What is the final SQL statement executed and is there anything wrong with the above code?
Okey, I think most of the students will think that the final SQL is:
INSERT INTO `user` (`username`, `password`) VALUES ("laruence", "weibo");
Unfortunately, you are wrong. SQL is:
INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");
Is it a big hole?
This question comes from today's 1 Bug report: #63281
The reason is the difference between bindParam and bindValue. bindParam requires the second parameter to be a reference variable (reference).
Let's break down foreach in the above code, which is this foreach:
<?php
foreach( $bind_params as $key => $value ){
$statement->bindParam($key, $value);
}
Is equivalent to:
<?php
// The first 1 loops
$value = $bind_params[":username"];
$statement->bindParam(":username", &$value); // At this time , :username Is the $value Reference to a variable
// The first 2 loops
$value = $bind_params[":password"]; //oops! $value Covered with :password The value of the
$statement->bindParam(":password", &$value);
Therefore, when using bindParam, pay particular attention to the trap used in conjunction with foreach. So what's the right approach?
1. Do not use foreach, but manually assign values
<?php
$statement->bindParam(":username", $bind_params[":username"]); //$value It's a reference variable
$statement->bindParam(":password", $bind_params[":password"]);
2. Use bindValue instead of bindParam, or pass the entire parameter array directly in execute.
3. Use foreach and reference(not recommended)
<?php
foreach( $bind_params as $key => &$value ) { // Note that there
$statement->bindParam($key, $value);
}
Finally, it is expanded that foreach should be used with caution when using functions that require a reference and have a lag processing.