Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 刷新后登录会话被破坏_Php_Mysql_Authentication_Login_Mysqli - Fatal编程技术网

Php 刷新后登录会话被破坏

Php 刷新后登录会话被破坏,php,mysql,authentication,login,mysqli,Php,Mysql,Authentication,Login,Mysqli,我用一些谷歌帮助做了一个登录脚本,但问题是每次我刷新页面时,它就会退出并重定向到登录页面。因此,基本上我希望用户在输入详细信息后登录,而不是在一次刷新后注销。我的代码是: <?php if(!isset($_SESSION)){ session_start(); } $username = mysqli_real_escape_string($con, $_POST['username']); $password = mysqli_real_escape_string($con, $_

我用一些谷歌帮助做了一个登录脚本,但问题是每次我刷新页面时,它就会退出并重定向到登录页面。因此,基本上我希望用户在输入详细信息后登录,而不是在一次刷新后注销。我的代码是:

<?php

if(!isset($_SESSION)){
session_start();
}

$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);

if ($username && $password)

{


$result = mysqli_query($con, "SELECT * FROM admin WHERE username='$username' ");

$numrows = mysqli_num_rows($result);

if($numrows !=0)
{
    while($row = mysqli_fetch_assoc($result))
    {
        $dbusername = $row["username"];
        $dbpassword = $row["password"]; 

    }
        if($username==$dbusername && $password==$dbpassword)
        {

            $_SESSION['username'] = $dbusername;
        }
        else
            echo "Incorrect Password";
}       
else
    header("location: login.php"); 


}
else    
header("location: login.php"); 
?>
mysqli_real_escape_字符串要求您与数据库建立活动/已建立的连接。由于您在连接之前正在进行m_r_e_s调用,因此您只需返回布尔值FALSE即可表示失败。所以你在贬低你引用的价值

插入到字符串中的布尔假值只会被转换为空字符串,所以您的查询看起来像

SELECT ... WHERE username=''
                           ^---see the boolean false in there?
您的代码序列应该是:

session_start();
connect_to_db();
prepare_variables();
do_query();
既然您使用的是mysqli,为什么还要手动转义变量呢?您可以使用一个准备好的语句+占位符,完全绕过这个问题。

学习点1:会话

以下是一些与课程相关的学习要点,以及如何高效地使用它们。请注意,您的代码的问题是,您询问在调用会话开始之前是否设置了会话,因此superglobal$\u会话不可用,因此您的逻辑语句总是返回false,但在登录中调用会话开始时除外,您无论如何都不应调用会话开始。在配置文件中调用会话开始1次确保在所有视图/页面中都包含此文件,然后可以检查会话是否设置为正常。仔细阅读这段代码,并尝试理解它所做的一切,这样您就可以利用php会话提供的强大功能

添加到login.php

添加到config.php或所有页面中包含的任何文件

现在在您的文件中测试用户是否登录

现在,如果需要从函数内部调用此对象,有两种方法

其他考虑

考虑向loggedInUser对象添加站点范围的机密属性,并检查是否存在此机密以标识有效会话。 如果用户未通过传递格式错误的get请求登录,则可以创建名为$loggedInUser的变量。 不过,攻击者很可能无法猜到您的站点机密。 第一个示例中显示了此站点范围机密的示例

学习点2:面向对象Mysqli速成班

创建连接对象

设置字符集

运行查询

准备好的语句:手动转义值的替代方法


对不起,我没听懂你的意思,如果你直接指出问题出在哪里会更有帮助?@user3694543你能更懒一点吗?我想我的前两句话非常清楚问题出在哪里。如果你不能理解这一点,那么你就不应该编程…@user3694543,他确实指出了你的一些问题所在,在你定义$con之前,你在mysqli\u real\u escape\u字符串中使用$con。先解决这个问题,然后再解决其他问题。我以前有过这段代码,其中我定义了$con,无论会话是否设置,您都需要调用会话\u start。注意:会话已经启动-忽略会话\u start我使用的是会话\u start;看看我的答案。您只需要在包含在所有脚本中的配置文件中调用会话启动一次。在登录过程中不要调用它。
//upon successful validation of login.
//create an object to store basic user information in. 

$user = (object) ['username'=>$username,'hash_password'=>$password,'group'=>$usergroup,'site_secret'=>$secret];//your user object

$_SESSION['user'] = $user;//store the object in the users session.
GLOBAL const static $secret = (string)'someUltraSecretStringThatIsDifficultToGuess';//your site wide secret.(you should probably add this to your config file instead of the login.
session_start(); 

//you have to call session start or you don't have access to $_SESSION superglobal, 
//regardless of a user being logged in or logged out they have a session.
//as a programmer it is your job to figure out how to store data in the session

if(isset($_SESSION['user']) && is_object($_SESSION['user']) && $_SESSION['user']->site_secret == $secret)
{
    $loggedInUser = $_SESSION['user'];//if an authenticaed user session is set and is an object and contains our site secret, we assign the $loggedInUser variable to it. so we can call this variable instead of calling the session ad nauseum in our code.
}
if($loggedInUser !== null && is_object($loggedInUser) && $loggedInUser->site_secret = $secret)
{
    //user is logged in. no reason to even call the database at this point, unless there is extra information you need.
    //if said information is going to be accessed on multiple pages, its probably wise to include it in the object when you create it during the login process. don't store overly sensitive
    //information in the object in any circumstance. things like credit card numbers, plain text passwords, security questions are big no nos.
}
//pass by reference

function foo($loggedInUser) 
{
    //your object is available here because you passed by reference! 
    //you can check if a user is loggedIn from within functions now without a single call to the database!
}

//pass with global language feature.
function bar()
{
    global $loggedInUser; //object is available here through usage of global directive. nifty eh?
}
$mysqli = new mysqli("db-host","db-username","db-password","db-name");
//since your object is already created, you can now set a property on the object

$mysqli->set_charset("utf8");//set it to whatever the collation of your database is.

//side note: you should user utf_unicode_ci in your database and utf8 in php.
$query = $mysqli->query("SELECT column1,column2,column3 FROM table1 WHERE 1 LIMIT 30");

//getting number of rows
$num_rows = $query->num_rows;//your mysqli object has morphed into $query at this point.

//working with the result set
if($num_rows > 0)
{
    while($row = $query->fetch_assoc())
    {
    echo '<li>'.$row["column1"].' | '.$row["column2"].' | '.$row["column3"].'</li>';
    }
    $query->close();//optionally close the query object NOTE: the $mysqli object is still open
    $query->free();//optionally free the result set
}
//when you are done with your $mysqli object close the connection
$mysqli->close();
$stmt = $mysqli->prepare("SELECT column1,column2,column3 FROM table1 WHERE column4 = ? column5 = ? and column6 = ?");//prepare our query.

//now we need to assign our variables to the question marks in the statement above in the correct order.
// s represents string, d represents double and i represents an integer.
$stmt->bind_param('sdi',$column4,$column5,$column6);//for illustrative purposes i name the variables the same as the column they correspond to so you can understand.

//now that we have bound our parameters to our statement wehave to execute it. if it doens't execute there is an error in our query or binding parameters

if($stmt->execute())
{
    //now we have two ways we can work with this result set. i am only going to show you what i consider the best way, `bind_result().
    $stmt->bind_result($column1,$column2,$column3);//binds in the same order of our columns.
    if($stmt->num_rows > 0) {
        //great, our query returned a result! lets work with this data now
        while($stmt->fetch())
        {
            echo '<li>'.$column1.' | '.$column2.' | '.$column3.'</li>';//we prent each row of our result. easy peasy
        }
        $stmt->close();//no need to free the result, as it is not stored by default.
    }
    //if there were no results, no need to close stmt as it was automatically closed by default.    
}