5

在我的代码中,我试图将 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()

4

3 回答 3

7

关键是通过使用带有参数化查询和绑定值的准备好的语句,您不需要诸如mysql_real_escape_string.

查看有关如何使用绑定值和参数化查询/准备语句的PDO 文档。

关键是你会这样写一个 SQL 查询:

$query = $pdo->prepare("SELECT * FROM users WHERE username = ? and password = ?");

然后,您将传入绑定值来代替 ? 符号,因此查询只能按字面意思运行:

$query->bindParam(1, $username);
$query->bindParam(2, $password);

任何类型的 SQL 注入尝试(例如1'; DROP users --在上面的变量中)都将不再起作用,因为它会按字面意思进行调用。

于 2013-03-26T22:04:33.537 回答
4

你不需要在 PDO 中。至少,您很少需要这样做。

于 2013-03-26T22:09:20.183 回答
1

如前所述,您不必使用转义...因为通过将值与 ? 绑定可以更安全地处理它。或在 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 种方式执行此操作:

  1. 使用OR循环遍历结果集while() { }
  2. 使用 $rows = $statement->fetchAll();并循环遍历数组 $rows

将选项 1 与更大的结果集一起使用。

使用带有较小结果集的选项 2(你知道它不会增长这么多)

考虑是否应该设置 PDO::ATTR_EMULATE_PREPARES 的属性。更多关于这里的信息:PDO MySQL: Use PDO::ATTR_EMULATE_PREPARES or not?

于 2013-03-26T22:27:33.090 回答