47

我正在修改我的代码,从使用mysql_*to PDO。在我的代码中,我有mysql_real_escape_string(). 在 PDO 中这个等价物是什么?

4

6 回答 6

72

嗯,不,没有!

从技术上讲有,PDO::quote()但很少使用,也不等同于mysql_real_escape_string()

这是正确的!如果您已经按照使用准备好的语句记录的正确方式使用 PDO ,那么它将保护您免受 MySQL 注入。


#Example:

下面是使用准备好的语句 (pdo) 进行安全数据库查询的示例

  try {
     // first connect to database with the PDO object. 
     $db = new \PDO("mysql:host=localhost;dbname=xxx;charset=utf8", "xxx", "xxx", [
       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-injection 的影响。


值得注意的是,出于安全原因,您应该charset=utf8在如上所示的那样传递 as 属性,DSN并始终启用 PDO 以异常形式显示错误。

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION

因此,来自您的数据库查询的错误不会泄露敏感数据,例如您的目录结构、数据库用户名等。

最后但并非最不重要的一点是,有时您不应该 100% 信任 PDO,并且必然会采取一些额外的措施来防止 sql 注入,其中一种情况是,如果您使用的是过时版本的 mysql [ mysql =< 5.3.6 ],如本文所述回答

但是,使用如上所示的准备好的语句总是比使用任何以mysql_

好读

MySQL 开发人员的 PDO 教程

于 2012-12-23T16:38:23.733 回答
28

空无一人*!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;");

* 好吧,正如迈克尔·伯科夫斯基所说,有一个!但是还有更好的方法。

于 2012-12-23T16:34:19.240 回答
6
$v = '"'.mysql_real_escape_string($v).'"'; 

相当于$v = $this->db->quote($v); 确保您有一个 PDO 实例,$this->db因此您可以调用 pdo 方法quote()

于 2014-12-14T13:39:33.283 回答
4

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();
}
于 2018-07-25T13:08:03.383 回答
-1

针对这里很多人的评论,但我还不能直接评论(未达到50分),$dbh->quote($value)使用PDO时实际上需要使用EVEN,它们是完全正当的理由......

  1. 如果您正在循环构建“BULK INSERT”命令的许多记录,(我通常在 1000 条记录上重新启动)由于利用 MySQL/Maria Db 中的 InnoDb 表。使用准备好的语句创建单独的插入命令很简洁,但在执行批量任务时效率非常低!
  2. PDO 还不能处理动态 IN(...) 结构,因此当您从用户变量列表构建 IN 字符串列表时,您将需要$dbh->quote($value)列表中的每个值!

所以是的,$dbh->quote($value)在使用 PDO 时需要,这可能是该命令首先可用的原因。

PS,您仍然不需要在命令周围加上引号,该$dbh->quote($value)命令也会为您执行此操作。

出去。

于 2019-09-04T09:58:38.107 回答
-3

如果要回答原始问题,那么这是 PDO 等效项mysql_real_escape_string

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);
}
于 2015-12-05T10:02:12.863 回答