2012-02-09 2 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

+0

Сколько записей вы ожидаете от набора результатов? То есть может ли быть только 0 или 1 запись для $ username во всех трех таблицах? Почему для одной и той же цели существуют три разные, но структурно идентичные таблицы? – VolkerK

+0

Извините, на самом деле есть только две таблицы, это была моя ошибка, я обновил ее сейчас. Запрос возвращает одного пользователя, который будет находиться в таблице JB_Jobseeker или JB_Employer. – David

ответ

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

+0

@kai, внимательность взяла взгляд на пример, который я предоставил? Он дает больше информации о том, как работает PDO :-) (не говоря о том, что drrcknlsn является неправильным) –

Смежные вопросы