首页 > 解决方案 > 如何将 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.

标签: phpmysqlipdoprepared-statement

解决方案


我没有对你投反对票。

但是,我假设您的登录脚本运行良好。

首先,您不需要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 方法。有关详细信息,请参阅手册。

一切顺利。


推荐阅读