我已经将与数据库的连接从mysqli重写为PDO。我的连接适用于准备好的语句。我的班级PDO看起来像这样:
<?php
define('DB_HOST', 'xxx');
define('DB_NAME', 'xxx');
define('DB_USER', 'xxx');
define('DB_PASS', 'xxx');
define('DB_CHAR', 'xxx');
class DBController
{
protected static $instance;
protected $pdo;
public function __construct() {
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_EMULATE_PREPARES => FALSE,
);
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
$this->pdo = new PDO($dsn, DB_USER, DB_PASS, $opt);
}
// a classical static method to make it universally available
public static function instance()
{
if (self::$instance === null)
{
self::$instance = new self;
}
return self::$instance;
}
// a proxy to native PDO methods
public function __call($method, $args)
{
return call_user_func_array(array($this->pdo, $method), $args);
}
// a helper function to run prepared statements smoothly
public function run($sql, $args = [])
{
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->pdo->prepare($sql);
$stmt->execute($args);
return $stmt;
}
function insert($query) {
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->pdo->prepare($sql);
$stmt->execute($args);
return $stmt;
}
function update($query) {
if (!$args)
{
return $this->query($sql);
}
$stmt = $this->pdo->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
使用新的PDO类与数据库的连接很明显。但是,当我想以用户身份登录时,我得到了“无效登录名”。但是,登录名和密码正确。
我的班级Auth看起来像这样:
<?php
require "DBController.class.php";
class Auth {
protected $db;
protected $data;
public function __construct()
{
$this->db = DBController::instance();
}
function getMemberByUsername($username)
{
$this->data = $this->db->run("Select * from `members` where `member_name` = ?", array($username))->fetchAll(0);
}
function getTokenByUsername($username,$expired)
{
$this->data = $this->db->run("Select * from `tbl_token_auth` where `username` = ? and `is_expired` = ?", [$username, $expired])->fetchAll();
}
function markAsExpired($tokenId)
{
$expired = 1;
$this->data = $this->db->run("UPDATE `tbl_token_auth` SET `is_expired` = ? WHERE id = ?", [$expired, $tokenId])->fetchAll();
}
function insertToken($username, $random_password_hash, $random_selector_hash, $expiry_date)
{
$this->data = $this->db->run("INSERT INTO `tbl_token_auth` (username, password_hash, selector_hash, expiry_date) values (?, ?, ?,?)", [$username, $random_password_hash, $random_selector_hash, $expiry_date])->fetchAll();
}
}
下面的代码,与功能getMemberByUsername一起使用
if (! empty($_POST["login"])) {
$isAuthenticated = false;
$username = $_POST["member_name"];
$password = $_POST["member_password"];
$user = $auth->getMemberByUsername($username);
if (password_verify($password, $user[0]->member_password)) {
$isAuthenticated = true;
}
if ($isAuthenticated) {
$_SESSION["member_id"] = $user[0]["member_id"];
// Set Auth Cookies if 'Remember Me' checked
if (! empty($_POST["remember"])) {
setcookie("member_login", $username, $cookie_expiration_time);
$random_password = $util->getToken(16);
setcookie("random_password", $random_password, $cookie_expiration_time);
$random_selector = $util->getToken(32);
setcookie("random_selector", $random_selector, $cookie_expiration_time);
$random_password_hash = password_hash($random_password, PASSWORD_DEFAULT);
$random_selector_hash = password_hash($random_selector, PASSWORD_DEFAULT);
$expiry_date = date("Y-m-d H:i:s", $cookie_expiration_time);
// mark existing token as expired
$userToken = $auth->getTokenByUsername($username, 0);
if (! empty($userToken[0]["id"])) {
$auth->markAsExpired($userToken[0]["id"]);
}
// Insert new token
$auth->insertToken($username, $random_password_hash, $random_selector_hash, $expiry_date);
} else {
$util->clearAuthCookie();
}
$util->redirect("dashboard.php");
} else {
$message = "Invalid Login";
}
}
我做错了什么?
您正在使用O::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
,因此fetchAll()
返回一个对象数组,而不是数组。因此,您需要使用$user[0]->member_password
从结果中获取密码。
if (password_verify($password, $user[0]->member_password)) {
$isAuthenticated = true;
}