Я нашел решение указанной ниже проблемы, которая может помочь людям, использующим PHP PDO. Я проверил это, и это работает, но я не уверен, что это самый чистый код или лучший. Любые улучшения приветствуются.
Вот оригинальная задача для справки:
Я хочу хэшировать пароли, которые уже есть в базе данных MySQL. Я уже могу хэшировать новые пароли с помощью API хэширования php 5.5, но я хочу знать, есть ли способ взять все старые пароли в виде простого текста и преобразовать их в хеши bcrypt. Сейчас я думаю о том, чтобы скопировать пароли в новую строку с именем ‘hash’ и, после проверки правильности их копирования, преобразовать их в хэши. Я не уверен, как скопировать строку пароля и переименовать ее в той же таблице, или как наиболее эффективно хэшировать все это.
Любое понимание будет оценено.
Вот решение:
<?
// IMPORTANT: only call this script one time or you will double hash and the passwords input by your users won't work anymore
// Get Configuration file
require("configsecuresavedgames.php");
// Connect to your server
$dbh = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8" , $user, $pass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);///////////////////////////////////////////////////////
// Upload new score
///////////////////////////////////////////////////////
// set variable $x to 1 to start at ID 1 and then update each row in a loop, adding 1 to the $x variable once done
$x = 1;
// Note: Change the statement below so that the number is larger to match the number of users in your database
while($x <= 100) {
// select hash for each row...
$stmt = $dbh->prepare("SELECT hash FROM $tname WHERE id = $x");
$stmt->execute();
// set the resulting array to associative
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
// set $hash variable to hash (from database) for the respective row
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['hash'];
$hash = $row ['hash'];
}
// update hash row with new hash data (note: prior to running the script make sure that you've copied all plain text passwords to the hash row in the database.$newhash = password_hash($hash, PASSWORD_DEFAULT);
$sql = "UPDATE securesavegames SET hash = '$newhash' WHERE id = $x";// Prepare statement
$stm = $dbh->prepare($sql);
// execute the query
$stm->execute();
// echo a message to say the UPDATE succeeded
echo $stm->rowCount() . " records UPDATED successfully";
// add to $x so that the hash for the next 'id' will be updated, then the loop will continue.
$x++;
}
$dbh = null;
?>
Если ваши пароли в виде простого текста, просто передайте их через хеш, и все будет готово.
Нет простого способа сделать запрос одним обновлением, потому что password_hash
это функция PHP Вам нужно будет получить значения, а затем перебрать их. Подготовленные заявления очень помогают в этом.
$sql = 'SELECT record_id, password FROM table';
$res = $mysqli->query($sql);
$sql = 'UPDATE table SET password = ? WHERE record_id = ?';
$prep = $mysqli->prepare($sql);
$prep->bind_param('si', $pass, $record);
while($row = $res->fetch_assoc()) {
$pass = password_hash($row['password']);
$record = $row['record_id'];
$prep->execute();
}
Других решений пока нет …