将MySQL转换为PDO

时间:2012-02-09 14:36:50

标签: php mysql pdo

我已经在这里多次建议开始将我的代码更改为PDO,并且我终于完成了这项工作。我的问题是我在转换现有的登录脚本时遇到了难以置信的困难。对于下面代码的最后几行(在$result = $query->fetchAll();行之后),我无法在线找到任何可以帮助我重新编写代码的资源:

$username = $_POST['username'];
$password = $_POST['password'];

$db=getConnection();

$username = mysql_real_escape_string($username);

$query = $db->prepare( "SELECT password, salt, 'employer' as user_type
FROM JB_Employer
WHERE Username = '$username'

UNION
SELECT password, salt, 'jobseeker' as user_type
FROM JB_Jobseeker
WHERE User_Name = '$username'");

$result = $query->fetchAll();

$qData = mysql_fetch_array($result, MYSQL_ASSOC);
$hash = hash('sha256', $qData['salt'] . hash('sha256', $password) );

if ($result -> rowcount() <1 ;) { print “Fail, No such user”;}

if ($hash != $qData['password']) { header('Location: register.php?loginStatus=fail');  exit;}

else {$_SESSION['user'] = $username;
$_SESSION['permission'] = $qData['user_type'];}

任何人都可以建议我如何实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

看看这个,请重新调整您的代码,特别是关于XSS漏洞!此外,为了一个好的开发人员的缘故,重构/重写您的数据库。这是最好的,但是要走的路。

此外,代码未经测试。

<?php

$db = getConnection(); //assuming you are returning a PDO object here!

$username = getUsername(); //assuming you are NOT escaping the username!
$password = getPassword(); //assuming your hashed password here!

$query = "SELECT password, salt, 'emplyer' as user_type
FROM  JB_Employer
WHERE Username = :username

UNION

SELECT password, salt, 'jobseeker' as user_type
FROM JB_Jobseeker
WHERE User_Name = :username";

//$statement == PDOStatement
$statement = $db->prepare($query);

//bind the $username param to :username, this is the real power of PDO,
//no more SQL Injections. Don't use mysql_real_escape-esque things!
//they are not nececary with PDO
$statement->bindParam(":username", $username);

//execute the statement
if($statement->execute()){
    $result = $statement->fetchAll();

    $rowCount = count($result);

    if($rowCount < 1){
        // redirect?
        die("No Such user");
    }else{
        // more than one user can be possible, this is not the correct way, but it appears to be your way so let's continue
        $firstRow = $result[0];

        if( isPasswordEqual($firstRow['salt'], $password) ){
            $_SESSION['user'] = $username; //security risk here. Vulnerable for XXS
            $_SESSION['permission'] = $firstRow['user_type'];
        }else{
            //Don't tell them this! It will give them knowledge of which accounts do exist.
            //Just say some general message like "login failed"
            die("wrong information");
        }
    }
}

答案 1 :(得分:0)

您应该考虑重命名变量以使其更有意义。特别是,$db->prepare()会返回语句,而不是查询。您传递一个查询,它准备该查询并返回一个语句。如果你遵循这个命名惯例,它将为你节省麻烦。

那就是说,你应该改变这段代码:

$result = $query->fetchAll();

$qData = mysql_fetch_array($result, MYSQL_ASSOC);

进入这个:

$qData = $query->fetch(\PDO::FETCH_ASSOC);

其余的应该排成一行。 PDOStatement::fetch(\PDO::FETCH_ASSOC)会返回一个关联数组,就像mysql_fetch_array(..., MYSQL_ASSOC)mysql_fetch_assoc()一样。

修改:此外,您需要将$result->rowCount()更改为$query->rowCount()

相关问题