0

I run app on google cloud platform using php in standard mode. I use session_set_save_handler to store session in mysql database.

.php file

...
$mysqli = new mysqli($config->host, $config->user, $config->password, $config->db, $port, $socket);

// test connection, works fine.
$mysqli->query("INSERT INTO `sessions` (`ID`, `SessionID`, `Data`, `DateTouched`) VALUES (NULL, 'aaa1', 'aa1', '21')");

$CurrentTime = time();

function sess_open($sess_path, $sess_name) {

    echo "session open - sess_path: " . $sess_path . "session_name " . $sess_name . "<br />";
    return true;
}

function sess_close() {
    echo "session close" . "<br />";
    return true;
}
    ...
    function sess_write($sess_id, $data) {
        GLOBAL $mysqli;
    
        echo 'session write';// never called
    
        $CurrentTime = time();
        $mysqli->query("UPDATE sessions SET Data = '$data', DateTouched = $CurrentTime WHERE SessionID = '$sess_id';");
        return true;
    }
    ...

    session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
    session_start();
    
    $_SESSION['foo'] = "bar";
    $_SESSION['baz'] = "wombat";
    
    $s_w_c = session_write_close();
    var_export($s_w_c); // false on gcloud

It works fine on my local system(MAMP), but the write function is not called on google. Other functions works fine. Any idea?

Thanks.

Simon
  • 22,637
  • 36
  • 92
  • 121
  • 1
    your code is **vulnerable** to **sql injection** so use **prepared statements with parameters** see https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – nbk Jun 02 '21 at 15:22
  • @nbk Thanks, I will fix that. – Simon Jun 05 '21 at 15:27
  • mysqli connection is ok ? any errors (https://github.com/php/php-src/blob/master/php.ini-production#L97) in logs ? – cetver Jun 05 '21 at 15:40
  • Yes, it's ok, writing data into database(I've updated question, test query works fine). – Simon Jun 05 '21 at 15:45
  • I doubt if `$_SESSION` can be trusted on a cloud platform -- it is tied to a single instance of a web server on a single server. – Rick James Jun 05 '21 at 17:47

2 Answers2

0

I have no clue why it would work on your local machine. Perhaps an older version of PHP or no debug text?

What happens to a session on startup is:

session_start() -> open() -> read() -> all_green? true : false;

You're using echo in the open function, since session_start() needs to be called before any output, it fails and closes the session. The internal check is placed right after read function. Here is a simple code for testing:

class Session implements SessionHandlerInterface {

    public function __construct(&$mysql) { }

    function open($path, $name) {
        //echo "session open" . PHP_EOL;
        return true;
    }

    function close() {
        echo "session close" . PHP_EOL;
        return true;
    }

    function write($id, $data) {
        echo 'session write' . PHP_EOL;
        return true;
    }

    function read($id) { 
        //echo "session read" . PHP_EOL;
        return ""; 
    }

    function destroy($id) {
        echo "session Destroy" . PHP_EOL;
        return true;
    }

    function gc($lifetime) {
        echo "session gc" . PHP_EOL;
        return true;
    }
}
    $dummy_connection = true;
    session_set_save_handler(new Session($dummy_connection), true);
    session_start();
    
    $_SESSION['foo'] = "bar";
    $_SESSION['baz'] = "wombat";
    
    $s_w_c = session_write_close();
    var_export($s_w_c);

The commented echos will cause the startup to fail.

Sleepwalker
  • 101
  • 6
0

If the data is written correctly into the database the reason why it is not able to see the output of the echo in the write handler is that as it is stated in the documentation this handler is not executed until after the output stream is closed, so the output from debugging statements will never be seen in the browser.

If you need to debug the output, it is suggested as a better practice that the debug output is written to a file.

SSoulMiles
  • 88
  • 9