如何将 msqli 查询中的登录系统修改为 PDO?
How to modify a Login System in msqli query to PDO?
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM users WHERE email='$email'");
if( $result->num_rows == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
$user = $result->fetch_assoc();
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
我需要将上面这段代码修改为PDO。我试着做了一些改变:
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', null);
define('DB_CHARSET', 'utf8');
define('DB_DATABASE', 'publicacoes');
$conn = new PDO('mysql:host=' . DB_HOSTNAME . ';dbname=' . DB_DATABASE . ';charset=' . DB_CHARSET . ';', DB_USERNAME, DB_PASSWORD);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = $conn->prepare("SELECT * FROM users WHERE email = :email"); ###
$result->execute([':email' => $_POST['email']]); ###
if( $result->num_rows == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
$user = $result->fetch_assoc();
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
但它不起作用,我收到错误:
1 - Undefined variable: result
。
2 - Fatal error: Uncaught Error: Call to a member function execute() on null
.
如果我将 &result 更改为 $email,它会得到同样的错误。
代码有什么问题?我不熟悉 MYSQLi
。我在想也许我需要更改此登录系统上的所有代码。我需要修改为PDO
.
您的代码可以使用我的 PDO 包装器 class 称为 GrumpyPDO.
来编写
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//select row of results where email is posted email
//$db must be set prior to this
$user = $db->row("SELECT * FROM users WHERE email=?", [$_POST['email']]);
if(!empty($user)) { //user exists if $result is not empty
//everything from here on is the same
if(password_verify($_POST['password'], $user['password'])) {
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
// This is how we'll know the user is logged in
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
} else {
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
}
}
我没有给你投反对票。
但是,我认为您的登录脚本运行良好。
首先,您不需要 escape_string
和 pdo
准备好的语句。
其次,您应该更改与 pdo
兼容的数据库连接以及 pdo
属性 PDO::ATTR_ERRMODE
& PDO::ERRMODE_EXCEPTION
这样您至少可以捕获 pdo 错误和例外。您也可以在连接语句中添加其他错误处理属性。有关详细信息,请参阅 http://php.net/manual/en/pdo.error-handling.php。
$DATABASESERVER = "YOUR_DATABASE_SERVER_NAME";
$DATABASENAME = "YOUR_DATABASE_NAME";
$DATABASEUSERNAMNE = "YOUR_DATABASE_USERNAME";
$DATABASEPASSWORD = "YOUR_DATABASE_PASSWORD";
try {
$DatabaseCon = new PDO("mysql:host=$DATABASESERVER; dbname=$DATABASENAME", $DATABASEUSERNAMNE, $DATABASEPASSWORD);
$DatabaseCon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo "$DatabaseCon-> failed: " . $e->getMessage();
}
最后您可以将您的代码替换为:
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = trim($_POST['email']);
try{
$Query = "SELECT * FROM users WHERE email=:email";
$statement = $DatabaseCon->prepare($Query);
$statement->bindValue(':email', $email);
$statement->execute();
$user = $statement->fetch(PDO::FETCH_ASSOC);
$RowCount = $statement->rowCount();
}
catch (PDOerrorInfo $e){
die('QuerySCD Error '.$e->getMessage());
}
if( $RowCount == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
//close database connection
$DatabaseCon-> = NULL;
但是,您也可以在 pdo 语法中使用位置占位符和 bindParam 方法。有关详细信息,请参阅手册。
祝一切顺利。
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM users WHERE email='$email'");
if( $result->num_rows == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
$user = $result->fetch_assoc();
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
我需要将上面这段代码修改为PDO。我试着做了一些改变:
define('DB_HOSTNAME', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', null);
define('DB_CHARSET', 'utf8');
define('DB_DATABASE', 'publicacoes');
$conn = new PDO('mysql:host=' . DB_HOSTNAME . ';dbname=' . DB_DATABASE . ';charset=' . DB_CHARSET . ';', DB_USERNAME, DB_PASSWORD);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = $conn->prepare("SELECT * FROM users WHERE email = :email"); ###
$result->execute([':email' => $_POST['email']]); ###
if( $result->num_rows == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
$user = $result->fetch_assoc();
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
但它不起作用,我收到错误:
1 - Undefined variable: result
。
2 - Fatal error: Uncaught Error: Call to a member function execute() on null
.
如果我将 &result 更改为 $email,它会得到同样的错误。
代码有什么问题?我不熟悉 MYSQLi
。我在想也许我需要更改此登录系统上的所有代码。我需要修改为PDO
.
您的代码可以使用我的 PDO 包装器 class 称为 GrumpyPDO.
来编写session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//select row of results where email is posted email
//$db must be set prior to this
$user = $db->row("SELECT * FROM users WHERE email=?", [$_POST['email']]);
if(!empty($user)) { //user exists if $result is not empty
//everything from here on is the same
if(password_verify($_POST['password'], $user['password'])) {
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
// This is how we'll know the user is logged in
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
} else {
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
}
}
我没有给你投反对票。
但是,我认为您的登录脚本运行良好。
首先,您不需要 escape_string
和 pdo
准备好的语句。
其次,您应该更改与 pdo
兼容的数据库连接以及 pdo
属性 PDO::ATTR_ERRMODE
& PDO::ERRMODE_EXCEPTION
这样您至少可以捕获 pdo 错误和例外。您也可以在连接语句中添加其他错误处理属性。有关详细信息,请参阅 http://php.net/manual/en/pdo.error-handling.php。
$DATABASESERVER = "YOUR_DATABASE_SERVER_NAME";
$DATABASENAME = "YOUR_DATABASE_NAME";
$DATABASEUSERNAMNE = "YOUR_DATABASE_USERNAME";
$DATABASEPASSWORD = "YOUR_DATABASE_PASSWORD";
try {
$DatabaseCon = new PDO("mysql:host=$DATABASESERVER; dbname=$DATABASENAME", $DATABASEUSERNAMNE, $DATABASEPASSWORD);
$DatabaseCon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo "$DatabaseCon-> failed: " . $e->getMessage();
}
最后您可以将您的代码替换为:
session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$email = trim($_POST['email']);
try{
$Query = "SELECT * FROM users WHERE email=:email";
$statement = $DatabaseCon->prepare($Query);
$statement->bindValue(':email', $email);
$statement->execute();
$user = $statement->fetch(PDO::FETCH_ASSOC);
$RowCount = $statement->rowCount();
}
catch (PDOerrorInfo $e){
die('QuerySCD Error '.$e->getMessage());
}
if( $RowCount == 0 ){
// User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error-login.php");
} else{ // User exists
if( password_verify($_POST['password'], $user['password'])){
$_SESSION['email'] = $user['email'];
$_SESSION['first_name'] = $user['first_name'];
$_SESSION['last_name'] = $user['last_name'];
$_SESSION['active'] = $user['active'];
$_SESSION['logged_in'] = true;
header("location: riscar.php");
} else {
$_SESSION['message'] = "You have entered wrong password, try again!";
header("location: error-login.php");
}
}
}
//close database connection
$DatabaseCon-> = NULL;
但是,您也可以在 pdo 语法中使用位置占位符和 bindParam 方法。有关详细信息,请参阅手册。
祝一切顺利。