php - 如何将 msqli 查询中的登录系统修改为 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
.
解决方案
我没有对你投反对票。
但是,我假设您的登录脚本运行良好。
首先,您不需要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 方法。有关详细信息,请参阅手册。
一切顺利。
推荐阅读
- ssl - dotnet core 3.0 SSL 在调试模式下工作,但不适用于 `dotnet run`
- bash - 使用 jq 从 json 中获取数组
- php - 从 xlxs 文件插入 10000 行时,浏览器抛出错误“糟糕,出了点问题” - laravel
- r - 识别分组数据上的重叠日期间隔
- ruby-on-rails - 检查父或关联中是否存在值并在Rails中获取父对象
- c# - HealthCheckUI 不显示 CosmosDB 等依赖项的状态
- r - 如何计算一代中不同姓氏缺失值的自回归?
- javascript - 将参数分配给函数内部的新值,好的还是坏的做法?
- c# - How to create a json with mixed type matrix in c#
- java - 如何将自定义视图与其他 UI 组件一起使用?