摘要:廢話不多說,直接看代碼:$dbo = new PDO('mysql:host=localhost;dbname=test',...
廢話不多說,直接看代碼:
$dbo = new PDO('mysql:host=localhost;dbname=test', 'root', '123456'); $query = 'INSERT INTO `users` (`username`, `password`) VALUES (:username, :password)'; $statement = $dbo->prepare($query); $bind_params = array('username' => 'admin', 'password' => '123456'); foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); } $statement->execute();
請問, 最終執行的SQL語句是什么, 上面的代碼是否有什么問題?
ok, 我想大部分同學會認為, 最終執行的SQL是:
INSERT INTO `users` (`username`, `password`) VALUES ('admin', '123456');
但是, 可惜的是, 你錯了, 最終執行的SQL是:
INSERT INTO `users` (`username`, `password`) VALUES ('123456', '123456');
究其原因, 也就是bindParam和bindValue的不同之處, bindParam要求第二個參數是一個引用變量(reference).
讓我們把上面的代碼的foreach拆開, 也就是這個foreach:
<?php foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); }
相當于:
<?php //第一次循環 $value = $bind_params[":username"]; $statement->bindParam(":username", &$value); //此時, :username是對$value變量的引用 //第二次循環 $value = $bind_params[":password"]; //oops! $value被覆蓋成了:password的值 $statement->bindParam(":password", &$value);
所以, 在使用bindParam的時候, 尤其要注意和foreach聯合使用的這個陷阱. 那么正確的作法呢?
1. 不要使用foreach, 而是手動賦值
<?php $statement->bindParam(":username", $bind_params[":username"]); //$value是引用變量了 $statement->bindParam(":password", $bind_params[":password"]);
2. 使用bindValue代替bindParam, 或者直接在execute中傳遞整個參數數組.
$statement = $dbo->prepare($query); $statement->execute(array('username' => 'admin', 'password' => '123456'));
最后, 展開了說, 對于要求參數是引用, 并且有滯后處理的函數, 都要在使用foreach的時候, 謹慎!
網友評論:
aaaa
2016-10-17 19:25:49 回復
網友評論:
2016-10-17 19:25:02 回復