我正在修改使用mysql_*
到PDO
的代码。在我的代码中,我有mysql_real_escape_string()
。在PDO中这相当于什么?
答案 0 :(得分:63)
嗯不,没有!
从技术上讲,有PDO::quote()
,但很少使用它,并不等同于mysql_real_escape_string()
这是对的!如果您已经使用prepared statements记录的正确方式使用PDO,那么它将保护您免受MySQL注入。
Example:
以下是使用预准备语句(pdo)的安全数据库查询的示例
try {
// first connect to database with the PDO object.
$db = new \PDO("mysql:host=localhost;dbname=xx;charset=utf8", "xx", "xx", [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
} catch(\PDOException $e){
// if connection fails, show PDO error.
echo "Error connecting to mysql: " . $e->getMessage();
}
而且,现在假设已建立连接,您可以像这样执行查询。
if($_POST && isset($_POST['color'])){
// preparing a statement
$stmt = $db->prepare("SELECT id, name, color FROM Cars WHERE color = ?");
// execute/run the statement.
$stmt->execute(array($_POST['color']));
// fetch the result.
$cars = $stmt->fetchAll(\PDO::FETCH_ASSOC);
var_dump($cars);
}
现在,正如您可能已经知道的那样,我没有使用任何东西来逃避/消毒$_POST["color"]
的价值。由于PDO和预处理语句的强大功能,此代码对于myql注入是安全的。
值得注意的是,出于安全原因,您应该在charset=utf8
中传递DSN
属性,并始终启用
PDO以异常的形式显示错误。
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
因此,数据库查询中的错误不会泄露敏感数据,如目录结构,数据库用户名等。
最后但并非最不重要的是,有些时候你不应该信任PDO 100%,并且必然要采取一些额外的措施来防止sql注入,其中一种情况是,如果你使用的是过时版本的mysql { {1}} described in this answer
但是,使用上面显示的预准备语句总是比使用以[ mysql =< 5.3.6 ]
好读
答案 1 :(得分:26)
没有*! PDO的目标是你不必逃避任何事情;你只需将其作为数据发送。例如:
$query = $link->prepare('SELECT * FROM users WHERE username = :name LIMIT 1;');
$query->execute([':name' => $username]); # No need to escape it!
相反:
$safe_username = mysql_real_escape_string($username);
mysql_query("SELECT * FROM users WHERE username = '$safe_username' LIMIT 1;");
*好吧,有一个,正如Michael Berkowski所说的那样!但还有更好的方法。
答案 2 :(得分:5)
$v = '"'.mysql_real_escape_string($v).'"';
相当于$v = $this->db->quote($v);
确保您在$this->db
中有一个PDO实例,因此您可以调用pdo方法quote()
答案 3 :(得分:1)
在PDO中不需要 mysql_real_escape_string 。
PDO本身会调整mysql查询中的特殊字符,您只需要传递匿名参数并绑定它的运行时间即可。 假设您有一个带有属性名称,电子邮件和密码的用户表,并且您必须像这样插入使用准备语句 您可以将名称传递为=> $ name =“ Rajes'h”;
它应该执行,不需要等效的 mysql_real_escape_string
$stmt="INSERT into user(name,email,password) VALUES(:name,:email,:password)";
try{
$pstmt=$dbh->prepare($stmt);//$dbh database handler for executing mysql query
$pstmt->bindParam(':name',$name,PDO::PARAM_STR);
$pstmt->bindParam(':email',$email,PDO::PARAM_STR);
$pstmt->bindParam(':password',$password,PDO::PARAM_STR);
$status=$pstmt->execute();
if($status){
//next line of code
}
}catch(PDOException $pdo){
echo $pdo->getMessage();
}
答案 4 :(得分:-2)
如果要回答原始问题,那么这是mysql_real_escape_string
的等效PDO:
function my_real_escape_string($value, $connection) {
/*
// this fails on: value="hello'";
return trim ($connection->quote($value), "'");
*/
return substr($connection->quote($value), 1, -1);
}
顺便说一下,mysqli的等价物是:
function my_real_escape_string($value, $connection) {
return mysqli_real_escape_string($connection, $value);
}
答案 5 :(得分:-2)
为了回应很多人对此的评论,但我还不能直接发表评论(未达到50分),实际上在使用PDO时甚至需要使用$dbh->quote($value)
,而且完全可以辩解原因...
$dbh->quote($value)
列表中的每个值!所以,是的,使用PDO时需要$dbh->quote($value)
,并且可能为什么该命令首先可用。
PS,您仍然不需要在命令两边加上引号,$dbh->quote($value)
命令也可以为您完成。
出去。