如何将 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_stringpdo 准备好的语句。

其次,您应该更改与 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 方法。有关详细信息,请参阅手册。

祝一切顺利。