如何在 PDO 中使用/编写 mysql_real_escape_string? [复制]
Posted
技术标签:
【中文标题】如何在 PDO 中使用/编写 mysql_real_escape_string? [复制]【英文标题】:How to use/write mysql_real_escape_string in PDO? [duplicate] 【发布时间】:2013-03-16 21:46:11 【问题描述】:在我的代码中,我试图将 mysql_real_escape_string 转换为 PDO 语句。有人有关于如何在 PDO 中编写 mysql_real_escape_string 的提示吗?
我在两行中使用 mysql_real_escape_string: $userName = mysql_real_escape_string($_POST['username']); $password = sha1(mysql_real_escape_string($_POST['password']));
<?php
ob_start();
session_start();
include("../database/db.php");
$userName = mysql_real_escape_string($_POST['username']);
$password = sha1(mysql_real_escape_string($_POST['password']));
echo "<br>user: " . $userName;
echo "<br> pw: " . $password;
$query = "select * from tbladmin where admin_usr_name='$userName' and admin_pwd='$password'";
$res = mysql_query($query);
// $rows = $res->fetch(PDO::FETCH_ASSOC);
$rows = mysql_fetch_assoc($res);
echo "<br>numrows" . mysql_num_rows($res) . "<br>";
// $find = $query->prepare("select * from tbladmin where admin_usr_name='$userName' and admin_pwd='$password'");
// $find->execute();
// if ($find->fetchColumn() > 0)
//
// echo 'You made it, welcome';
// $_SESSION['userName'] = $rows['admin_usr_name'];
// $_SESSION['admin_id'] = $rows['admin_id'];
// header("location: ../pages/content.php");
//
// else
//
// echo 'Username and password dont match <br/> Try again';
// header("location: ../index.php?loginerror=yes");
//
if(mysql_num_rows($res)>0)
$_SESSION['userName'] = $rows['admin_usr_name'];
$_SESSION['admin_id'] = $rows['admin_id'];
header("location: ../pages/content.php");
else
echo 'Username and password dont match <br/> Try again';
header("location: ../index.php?loginerror=yes");
?>
这就是我试图用 PDO 做的事情
$host = "localhost";
$user = "root";
$password = "root";
$db = "blog";
$dsn = "mysql:host=$host;dbname=$db;charset=utf8";
$opt = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$pdo = new PDO($dsn,$user,$password, $opt);
$username = $_POST['username'];
$password = $_POST['password'];
$query = "select * from tbladmin where admin_usr_name=:userName and admin_pwd=:passWord";
try
$databas = new PDO($dsn, $user, $password);
catch (PDOException $e)
echo 'Connection failed: ' . $e->getMessage();
$statement = $databas->prepare($query);
$statement->execute(array(':userName'=>$username, ':passWord'=> $password));
$row = $statement->fetch();
我总是收到这个错误: 在非对象上调用成员函数 prepare()
【问题讨论】:
你不需要。无需使用准备好的语句进行转义。 在使用准备好的语句时不要使用转义函数。您绑定参数。请参阅文档:php.net/manual/en/pdostatement.bindparam.php @an1zhegorodov 谢谢,我去看看... @MichaelRushton 谢谢,不错的链接... 有时需要,例如,在 PDO 准备语句中,表名不能是动态的。 【参考方案1】:关键是通过使用带有参数化查询和绑定值的准备好的语句,您不需要诸如mysql_real_escape_string
之类的东西。
查看PDO documentation,了解如何使用绑定值和参数化查询/准备语句。
关键是你会这样写一个 SQL 查询:
$query = $pdo->prepare("SELECT * FROM users WHERE username = ? and password = ?");
然后您将传入绑定值来代替 ?符号,因此查询只能按字面意思运行:
$query->bindParam(1, $username);
$query->bindParam(2, $password);
上述变量中的任何类型的 SQL 注入尝试(例如 1'; DROP users --
)都将不再起作用,因为它会按字面意思进行调用。
【讨论】:
谢谢,很好的回答。我要看看 PDO 文档。 一旦你使用 PDO 运行你的数据库查询,你会觉得你正在做的事情更加安全。如果您需要任何帮助,请随时告诉我! 谢谢,非常感谢您的帮助...【参考方案2】:您不需要在 PDO 中。至少,您很少需要这样做。
使用parameterized SQL。 Bind your parameters. PDO::QUOTE 自动转义其字符串。【讨论】:
谢谢,不错的链接... 你什么时候真正需要 PDO::QUOTE? @bestprogrammerintheworld 有时会出现缺少正确字符串格式的文本。 @cygorx,是的,但是在使用准备好的语句时你不必这样做,强烈建议不要使用 PDO::QUOTE... @cygorx - 我明白了。我的观点是,它甚至不应该是一个选择:-)【参考方案3】:如前所述,您不必使用转义...因为这可以通过将值与 ? 绑定来更安全地处理。或者在sql语句中用冒号命名
我会这样做:
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$query = "select * from tbladmin where admin_usr_name=:userName and admin_pwd=:passWord";
try
$db = new PDO($dsn, $un, $pw);
catch (PDOException $e)
echo 'Connection failed: ' . $e->getMessage();
$statement = $db->prepare($query);
//:userName and :passWord is set when actually executing the query
$statement->execute(array(':userName'=>$username, ':passWord'=> $password));
$row = $statement->fetch();
?>
注意 fetch() 只会返回一行(结果集中的下一行)。如果你想访问整个记录集,你可以通过 2 种方式做到这一点:
-
使用
while()
循环遍历结果集OR
使用$rows = $statement->fetchAll();
并循环遍历数组$rows
将选项 1 与更大的结果集一起使用。
对较小的结果集使用选项 2(你知道它不会增长这么多)
考虑是否应该设置 PDO::ATTR_EMULATE_PREPARES 的属性。更多关于这里的信息:PDO MySQL: Use PDO::ATTR_EMULATE_PREPARES or not?
【讨论】:
@bestprogrammerintheword 谢谢,我要试试你的代码。 不客气。随意询问您是否遇到困难。 当我运行您的代码时,我收到此错误消息:致命错误:调用非对象上的成员函数 prepare()。我想知道你的代码中的 $db 是什么? $db 未在我的代码中分配。我添加了一些行来说明。 $db 是 PDO 对象。 $dsn 是主机和 dbname,$un 是连接数据库的用户名,$pw 是连接数据库的密码。查看php.net/manual/en/pdo.construct.php 了解有关创建 PDO 对象的更多信息。 @estprogrammerintheworld 谢谢,但我仍然收到此错误:调用非对象上的成员函数 prepare()以上是关于如何在 PDO 中使用/编写 mysql_real_escape_string? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PHP 中使用带有 PDO 的 MySQL 用户函数?
在 bindParam 中使用 LIKE 进行 MySQL PDO 查询