2012-02-09 97 views
1

我已經在這裏建議了幾次,以開始將我的代碼更改爲PDO,並且我終於開始這樣做了。我的問題是,我在轉換現有的登錄腳本時遇到了難以置信的困難。對於下面的代碼的最後幾行(行$result = $query->fetchAll();後),我一直沒能找到任何資源網上,可以幫助我重新寫它:將MySQL轉換爲PDO

$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

你爲什麼用這句話? ''「'' – dynamic 2012-02-09 14:40:10

+0

你期望結果集有多少條記錄?即所有三個表中的$ username都只有0或1條記錄?爲什麼有三個不同但結構相同的表格用於同一目的? – VolkerK 2012-02-09 14:52:19

+0

對不起,實際上只有兩張表,那是我的錯誤,我現在已經更新了。查詢返回一個將在JB_Jobseeker或JB_Employer表中的用戶。 – David 2012-02-09 14:56:52

回答

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"); 
     } 
    } 
} 
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()

+0

謝謝,我來試試看:) – David 2012-02-09 15:13:34

+0

@kai,呵呵看看我提供的例子嗎?它給出了關於PDO如何工作的更多信息:-)(不是說drrcknlsn是錯誤的) – 2012-02-11 17:27:13