【问题标题】:destroying session if not set using php pdo如果未使用 php pdo 设置,则销毁会话
【发布时间】:2015-12-19 20:49:10
【问题描述】:

我有这个旧代码,查看会话是否未注册以销毁它并返回登录页面:

<?php
session_start();
$host="localhost"; // Host name 
$username="root"; // Mysql username 
$password=""; // Mysql password 
$db_name=""; // Database name 
//if(!session_is_registered(myusername)){
//header("location:index.html");
if(isset($_SESSION['username'])) {
  echo "Page seen by " . $_SESSION['username']."<br>";
  $con=mysqli_connect($host,$username,$password,$db_name);
  mysqli_set_charset($con, 'utf8mb4');
}
else{
    session_destroy();
    header("location: index.php");
}
?>

我正在尝试将此代码转换为 pdo,但我不知道如何在此方法中销毁会话。写完这些话我就停下来了:

<?php

session_start();

$DB_host = "localhost";
$DB_user = "root";
$DB_pass = "";
$DB_name = "";

try
{
     $conn = new PDO("mysql:host={$DB_host};dbname={$DB_name}",$DB_user,$DB_pass);
     $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     $conn->exec("SET CHARACTER SET utf8mb4");
}
catch(PDOException $e)
{
     echo $e->getMessage();
}
?>

另外,在下面的代码中,当我点击登录时,即使用户名和密码不正确,它也会将我带到下一页:

<?php
$DB_host = "localhost";
$DB_user = "root";
$DB_pass = "";
$DB_name = "";

$conn = new PDO("mysql:host={$DB_host};dbname={$DB_name}",$DB_user,$DB_pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("SET CHARACTER SET utf8mb4");

if(isset($_POST['login'])){
    $username = $_POST['username'];
    $password = $_POST['password'];
        if($username != '' && $password!=''){

        try{
            session_start();
            $sql = "SELECT * FROM login WHERE username = :u AND password = :p LIMIT 1";
            $stmt = $conn->prepare($sql);
            $stmt->bindValue(":u", $username);
            $stmt->bindValue(":p", $password);
            $exec = $stmt->execute();
            $count = $stmt->fetch(PDO::FETCH_ASSOC);
            if((count($count)==1)){//&& password_verify($password, $count['password']
                $_SESSION['username'] = $username;
                header("Location: ./pages/home.php");       
            } 
            else {
                header("Location: index.php");
            }
        }
        catch(PDOException $e) {
            $sql_fail = "INSERT INTO login_attempts(username, password, date_now, time_now) 
                             VALUES (:uf, :pf, :date, now())";
                $stmt_fail = $conn->prepare($sql_fail);
                $stmt_fail->bindValue(":uf", $username);
                $stmt_fail->bindValue(":pf", $password);
                $stmt_fail->bindValue(":date", date("y-m-d"));
                $exec_fail = $stmt_fail->execute();
                header("Location: index.php");
            echo $e->getMessage();
        }
    }
}
?>

【问题讨论】:

  • 我不认为您的trycatch 对您的实施方式有效。
  • 你能修复代码或者至少更具体吗?
  • 是的,给我一分钟时间来回顾一下。我不想给你一半的东西-@$$
  • 好吧,我不会像其他人那样为你重写整个应用程序,但我觉得你的问题在这里:if((count($count)==1)) 尝试使用像这样的内置 PDO 函数if($stmt-&gt;rowCount() &gt; 0)
  • @Pamblam 确实,您可能会检查执行是否成功和行的返回以确保真正确定。无论如何,我很感激你的支持,我对你的一个答案表示赞同。干杯!

标签: php mysql session pdo


【解决方案1】:

我认为登录的关键是您需要一些独立的小应用程序(功能)来分解简单的任务。看看这是否效果更好:

/classes/class.PDOConn.php

<?php
class PDOConn
    {
        // Create a singleton variable to store persistent connection
        private static  $singleton;
        // Set your database credentials here
        public  static function connect($DB_host = "localhost",$DB_user = "root",$DB_pass = "",$DB_name = "")
            {
                // first check if the connection has been already set
                if(empty(self::$singleton)) {
                    try {
                            $conn = new PDO("mysql:host={$DB_host};dbname={$DB_name}",$DB_user,$DB_pass);
                            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                            $conn->exec("SET CHARACTER SET utf8mb4");
                            self::$singleton    =   $conn;
                            return self::$singleton;
                        }
                    catch (PDOException $e) {
                            die("connection failed");
                        }
                }
                // Return the current connection
                return self::$singleton;
            }
    }

/functions/function.query.php

<?php
// This function will make automatic queries to your database
// It accepts a bind array as a second parameter
function query($sql = false,$bind = false)
    {
        // Create connection
        $conn   =   PDOConn::connect();
        // Two ways to query, with and without a bind array
        if(!empty($bind) && is_array($bind)) {
            $query  =   $conn->prepare($sql);
            $query->execute($bind);
        }
        else {
            $query  =   $conn->query($sql);
        }
        // Loop through returned values
        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $result[]   =   $row;
        }
        // Send back array OR send back 0 (for zero results)
        return (!empty($result))? $result : 0;
    }

/functions/function.write.php

<?php
// This function is the same as query(), just no return array
function write($sql = false,$bind = false)
    {
        $conn   =   PDOConn::connect();
        if(!empty($bind) && is_array($bind)) {
            $query  =   $conn->prepare($sql);
            $query->execute($bind);
        }
        else {
            $conn->query($sql);
        }
    }

/functions/function.check_user.php

<?php
// This will check the user.
// Do not store plain text passwords
// Instead use password_hash() and password_verify()
function check_user($username,$password)
    {
        $query  =   query("SELECT * FROM `login` WHERE `username` = :u LIMIT 1",array(":u"=>$username));

        if($query == 0)
            return false;

        return ($query[0]['password'] == $password);
    }

/functions/function.AutoloadFunction.php

<?php
// This is just an autoloader for your functions
// I use it to help cut down on bulk loading of functions
function AutoloadFunction($function = false)
    {
        // If input is not array, just stop
        if(!is_array($function))
            return false;
        // Set the load folder as this folder
        // (all functions should be in the same folder)
        $function_dir   =   __DIR__.'/function.';
        // Loop through the array and add the function(s)
        for($i = 0; $i < count($functions); $i++) {
            // Function name
            $addfunction    =   $functions[$i];
            // See if function exists
            if(!function_exists($addfunction)) {
                $dir    =   $function_dir.$addfunction.'.php';
                if(is_file($dir)) {
                    include_once($dir);
                }
            }
        }
    }

login.php

<?php
// Session start regardless
session_start();
// Check if login attempted
if(isset($_POST['login'])){
        $username = $_POST['username'];
        $password = $_POST['password'];
        // If user or pass is empty OR there is already a session, just stop
        // You may want to do a redirect here, not sure....
        if(empty($username) || empty($password) || !empty($_SESSION['username']))
            return false;
        // Include the autoloader function
        include_once(__DIR__.'/functions/function.AutoloadFunction.php');
        // Maybe look into using spl_autoload_register() to autoload classes
        include_once(__DIR__.'/classes/class.PDOConn.php');
        // Autoload functions
        AutoloadFunction(array("check_user","write","query"));
        // Verify with handy-dandy function
        if(check_user($username,$password)) {
            $_SESSION['username'] = $username;
            $location   =   "./pages/home.php";
        }
        // Write the attempt
        else {
            write("INSERT INTO `login_attempts` (`username`, `password`, `date_now`, `time_now`) VALUES (:uf, :pf, :date, NOW())",array(":uf"=>$username,":pf"=>$password,":date"=>date("y-m-d")));
            $location   =   "index.php?errror=invalid";
        }
        // Forward
        header("Location: {$location}");
        exit;
}

【讨论】:

  • 这里发生了什么?
  • 要回答您的问题,正在发生的事情是对脚本中应该发生的事情的分解。可携带的独立部件。例如,在我的场景中,无论我在网站上开发哪个页面,我都可以使用 check_user() 函数检查某人的密码......与上面的答案或您的示例一样,您有一次性使用脚本。除了用于登录的内容外,您不能将其用于其他任何用途。无论如何,我可以解释更多,但我已经做了很多注释,所以每个部分你都知道它在做什么。
  • 另外,我可以在站点的任何位置使用query() 从数据库中返回结果,而无需重复整个bindParam(),execute(),while()...etc。我可以做到$all = query("select * from login");,它会自动将行返回到数组中,而无需进一步编写脚本。
  • @am90 如果您对实施有任何疑问,请告诉我,我可以进一步解释。
  • 谢谢您,先生,您的代码非常结构化和解释。如果我需要其他东西,我会发送消息。
【解决方案2】:

使用this link here中的代码。

你应该使用fetch(PDO::FETCH_NUM),所以你的代码会是这样的:

$result = $conn->prepare("SELECT * FROM users WHERE username= :hjhjhjh AND password= :asas");
$result->bindParam(':hjhjhjh', $user);
$result->bindParam(':asas', $password);
$result->execute();
$rows = $result->fetch(PDO::FETCH_NUM);
if($rows > 0) {
header("location: home.php");
}
else{
    $errmsg_arr[] = 'Username and Password are not found';
    $errflag = true;
}
if($errflag) {
    $_SESSION['ERRMSG_ARR'] = $errmsg_arr;
    session_write_close();
    header("location: index.php");
    exit();
}

【讨论】:

  • 现在可以正常使用了。你能帮我注销代码吗?
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 2013-04-17
  • 2012-05-25
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多