PHP $ _SESSION变量不跨页面保存

I've been having some big problems with this all day.

I'm trying to save a SESSION variable and then print it onto another PHP file however the variable isn't saving across pages. I'm essentailly making a login system using SQL to then be able to view the users details using the username as the SESSION variable.

I've done a lot of research and it seems that my redirect URL is causing the issue. It needs to be a realtive URL used not a HTTP one as this doesn't carry over SESSION variables.

I've tested that the variable is stored by printing it straight away in the source PHP file and that works fine. It just doesn't get transfered across, it comes back with a blank array.

I'm calling my method from an API routes PHP file. I don't think this causes an issue?

Here is my setup:

API PHP file:

app->post('/api/customer/login/{Username}/{PassW}', function(Request $request, Response $response){
    $Username = $request->getParam('Username');
    $PassW = $request->getParam('PassW');

    $PassW = md5($PassW);//FIND NEW WAY OF HASHING AS MD5 IS DEPRECIATED
    $sql = "SELECT * FROM login WHERE Username= '$Username' AND PassW='$PassW' LIMIT 1";

    try{
        $db = new db();
        $db = $db->connect();

        $stmt = $db->query($sql);
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

        if(count($result) == 1){
        session_start();      
        $_SESSION['Username'] = $Username;


       echo "<script type='text/javascript'>alert('Correct!');
       window.location.href='http://localhost/testing/yourprofile.php';
       </script>";
        exit();

Test SESSION variable has been set PHP file:

<?php

session_start();
print_r($_SESSION); 
?>

I'm very new to all this so my apologies if it's something very simple for you guys.

Big Love.

I did what I could to fix and clean up your code. I don't know if it will fix the session issues, but you should be calling session_start much sooner then you are.

app->post('/api/customer/login/{Username}/{PassW}', function(Request $request, Response $response){
    session_start(); //<-- put this here or (just put in index.php)
    $Username = $request->getParam('Username');
    $PassW = $request->getParam('PassW');

    $sql = "SELECT * FROM login WHERE Username = :username";

    try{
        $db = new db();
        $db = $db->connect();
         ///prepare the query
        $stmt = $db->prepare($sql); 
         /// execute the query 
        $stmt->execute([':username'=>$Username]);   
        ///get the result, our usernames are unique in the DB
        //so there is no need to limit them or count
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        //result is an array or boolean false.
        if(!$result){
            //check the password
            if(password_verify($PassW, $result['PassW'])){ 
                $_SESSION['Username'] = $Username;
                //redirect, do not output ANYTHING before doing this
                header('Location: http://localhost/testing/yourprofile.php');
                exit();

            }

Notes/Updates

  • Use password_hash to hash passwords (it's pretty much the standard these days)

  • Use prepared statements, thankfully your using PDO (which is what I have used the last 4 years). I used to use Mysqli, but I found PDO much easier, and with better overall functionality. So you will see where I used :username as a named placeholder, instead of the value and then the value goes in an array with the same key(I think the : in the data array is optional with certain settings turned on, but I always just put it in), and then you execute it and that's it.

  • The Username field in the Database should be a Unique Index. This way it's impossible to put duplicate usernames in, the database wont let you. This simplifies what we need to do in PHP because we can rely on that and don't need to check as much stuff.

  • When checking passwords you can use password_verify. The first argument is the incoming password from the user. It doesn't need to be encrypted or anything. One of the reasons it's designed that way is you shouldn't really be searching with the password as part of the condition. Because then you are relying on the case-insensitive search of the database for verifying the hash, which it was not built to do. There are various other reasons for using password_verify besides that, but one could write a whole post on just the intricacy of cryptological hashing and comparison.

But I think that is enough for now.

I have finally sorted it!

I needed to get the session ID first.

Hopefully this will help anyone in the future with this issue

Please see solution below:

PHP Page One:

session_start();  
        $_SESSION['Username'] = $Username;
        header("Location: http://localhost/testing/yourprofile.php?PHPSESSID=".session_id());
        exit();

PHP Page Two (Test):

<?php
session_id($_GET['PHPSESSID']);
session_start();
print_r($_SESSION);
?>

Thanks to Phoenix for sorting my other issues! :)