Tech Support Guy banner
Status
Not open for further replies.
1 - 10 of 10 Posts

·
Registered
Joined
·
48 Posts
Discussion Starter · #1 ·
Recently, I have been having a problem with my sessions, and corresponding session variables. I have all of the code written below. The problem, is that, when I POST sessions1.php, the session variable seems to work, and gets carried over into sessions2.php. But, when the link to go to sessions3.php is clicked, the session variable doesn't seem to be set. Thus, returning code from the "else" conditional.

Something similar seems to be happening when I use either a database, or /tmp file, for storing data. In the database example, the session is written to the sessions table. However, when I click the link, from sessions2.php, which takes me to sessions3.php, the session variable doesn't seem to be set. And, when I click the "logout" button, in sessions3.php, the link takes me back to sessions1.php, which is correct. However, when I check the database (or at least refresh the sessions table), the session is not removed, or destroyed.

Furthermore, When I submit the code on sessions1.php, and am taken to sessions2.php, the right session row is created in the sessions table. However, when I click on the link that takes me to sessions3.php, another row is created, within the sessions table, this time without any data, in the data column.

Without a database, whilst resorting to using the filesystem instead: after submitting sessions1.php, the file appears in the /tmp folder. However, the file remains empty.

Any possible solutions?.

I am using PHP7, Apache, and MySQL 5.6.27. And, I am wondering whether my config settings (php.ini, and/or httpd) may have anything to do with the problem.

THE CODE:
--------------------------------------------------------------------------------------------------------------------------
sessions1.php(below)
--------------------------------------------------------------------------------------------------------------------------
<!doctype html>

Session Test

Enter your first name:

--------------------------------------------------------------------------------------------------------------------------
session2.php (below)
--------------------------------------------------------------------------------------------------------------------------

<?php

use SomeNamespace\Sessions\SessionHandler;

require_once('/databases/dbConnect.php');

require_once('/classes/Sessions/SessionHandler.php');

$handler = new SessionHandler($db);
session_set_save_handler($handler);

session_start();

if (isset($_POST['name'])) {
if (!empty($_POST['name'])) {
$_SESSION['name'] = htmlentities($_POST['name']);
} else {
$_SESSION['name'] = 'Nobody Here!';
}
}

?>
<!doctype html>

Session Test

Hello, <?php
if (isset($_SESSION['name'])) {
echo $_SESSION['name'];
} else {
echo 'stranger';
}
?>.

Go to page 3

--------------------------------------------------------------------------------------------------------------------------
session3.php (below)
--------------------------------------------------------------------------------------------------------------------------

<?php

use SomeNamespace\Sessions\SessionHandler;

require_once('/databases/dbConnect.php');

require_once('/classes/Sessions/SessionHandler.php');

$handler = new SessionHandler($db);
session_set_save_handler($handler);

session_start();

if (isset($_POST['logout'])) {
$_SESSION = [];
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 86400, $params['path'],
$params['domain'], $params['secure'], $params['httponly']);
session_destroy();
header('Location: sessions1.php');
exit;
}

?>
<!doctype html>

Session Test

Hello<?php
if (isset($_SESSION['name'])) {
echo ' again, ' . $_SESSION['name'];
} else {
echo ', Nobody!';
}
?>.

">

--------------------------------------------------------------------------------------------------------------------------
SessionHandler.php (below) The session handler class.
--------------------------------------------------------------------------------------------------------------------------

namespace SomeNamespace\Sessions;

class SessionHandler implements \SessionHandlerInterface
{

protected $db;

protected $useTransactions;

protected $expiry;

protected $table_sess = 'sessions';

protected $col_sid = 'sessionID';

protected $col_expiry = 'expiry';

protected $col_data = 'data';

protected $unlockStatements = [];

protected $collectGarbage = false;

public function __construct(\PDO $db, $useTransactions = true)
{
$this->db = $db;
if ($this->db->getAttribute(\PDO::ATTR_ERRMODE) !== \PDO::ERRMODE_EXCEPTION) {
$this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
$this->useTransactions = $useTransactions;
$this->expiry = time() + (int) ini_get('session.gc_maxlifetime');
}

public function open($save_path, $name)
{
return true;
}

public function read($session_id)
{
try {
if ($this->useTransactions) {

$this->db->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
$this->db->beginTransaction();
} else {
$this->unlockStatements[] = $this->getLock($session_id);
}
$sql = "SELECT $this->col_expiry, $this->col_data
FROM $this->table_sess WHERE $this->col_sid = :sessionID";

if ($this->useTransactions) {
$sql .= ' FOR UPDATE';
}
$selectStmt = $this->db->prepare($sql);
$selectStmt->bindParam(':sessionID', $session_id);
$selectStmt->execute();
$results = $selectStmt->fetch(\PDO::FETCH_ASSOC);
if ($results) {
if ($results[$this->col_expiry] < time()) {

return '';
}
return $results[$this->col_data];
}

if ($this->useTransactions) {
$this->initializeRecord($selectStmt);
}

return '';
} catch (\PDOException $e) {
if ($this->db->inTransaction()) {
$this->db->rollBack();
}
throw $e;
}
}

public function write($session_id, $data)
{
try {
$sql = "INSERT INTO $this->table_sess ($this->col_sid,
$this->col_expiry, $this->col_data)
VALUES :)sessionID, :expiry, :data)
ON DUPLICATE KEY UPDATE
$this->col_expiry = :expiry,
$this->col_data = :data";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':expiry', $this->expiry, \PDO::pARAM_INT);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':sessionID', $session_id);
$stmt->execute();
return true;
} catch (\PDOException $e) {
if ($this->db->inTransaction()) {
$this->db->rollback();
}
throw $e;
}
}

public function close()
{
if ($this->db->inTransaction()) {
$this->db->commit();
} elseif ($this->unlockStatements) {
while ($unlockStmt = array_shift($this->unlockStatements)) {
$unlockStmt->execute();
}
}
if ($this->collectGarbage) {
$sql = "DELETE FROM $this->table_sess WHERE $this->col_expiry < :time";
$stmt = $this->db->prepare($sql);
$stmt->bindValue(':time', time(), \PDO::pARAM_INT);
$stmt->execute();
$this->collectGarbage = false;
}
return true;
}

public function destroy($session_id)
{
$sql = "DELETE FROM $this->table_sess WHERE $this->col_sid = :sessionID";
try {
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':sessionID', $session_id);
$stmt->execute();
} catch (\PDOException $e) {
if ($this->db->inTransaction()) {
$this->db->rollBack();
}
throw $e;
}
return true;
}

public function gc($maxlifetime)
{
$this->collectGarbage = true;

return true;
}

protected function getLock($session_id)
{
$stmt = $this->db->prepare('SELECT GET_LOCK:)key, 50)');
$stmt->bindValue(':key', $session_id);
$stmt->execute();

$releaseStmt = $this->db->prepare('DO RELEASE_LOCK:)key)');
$releaseStmt->bindValue(':key', $session_id);

return $releaseStmt;
}

protected function initializeRecord(\PDOStatement $selectStmt)
{
try {
$sql = "INSERT INTO $this->table_sess ($this->col_sid, $this->col_expiry, $this->col_data)
VALUES :)sessionID, :expiry, :data)";
$insertStmt = $this->db->prepare($sql);
$insertStmt->bindParam(':sessionID', $session_id);
$insertStmt->bindParam(':expiry', $this->expiry, \PDO::pARAM_INT);
$insertStmt->bindValue(':data', '');
$insertStmt->execute();
return '';
} catch (\PDOException $e) {

if (0 === strpos($e->getCode(), '23')) {

$selectStmt->execute();
$results = $selectStmt->fetch(\PDO::FETCH_ASSOC);
if ($results) {
return $results[$this->col_data];
}
return '';
}

if ($this->db->inTransaction()) {
$this->db->rollback();
}
throw $e;
}
}

}
 

·
Registered
Joined
·
3,421 Posts
I have a feeling that by setting and saving the session handler again in session3.php you are losing any session data previously updated by 'moving to the next row'. There is no indication of this in the manual, but if true it would explain your dilemma.
Try taking
PHP:
$handler = new SessionHandler($db);
session_set_save_handler($handler);
out of session3.php and see what transpires ...
 

·
Registered
Joined
·
48 Posts
Discussion Starter · #3 ·
I have a feeling that by setting and saving the session handler again in session3.php you are losing any session data previously updated by 'moving to the next row'. There is no indication of this in the manual, but if true it would explain your dilemma.
Try taking
PHP:
$handler = new SessionHandler($db);
session_set_save_handler($handler);
out of session3.php and see what transpires ...
Hi.

Tried it. But, no luck.

To simplify things, I stripped the files down and executed the following:

I have the following three pages:

--------------------------------------------------------------------------------------------------------------------

(sessions_01.php)

--------------------------------------------------------------------------------------------------------------------

<!doctype html>

Session Test

Enter your first name:

--------------------------------------------------------------------------------------------------------------------

(sessions_02.php)

--------------------------------------------------------------------------------------------------------------------

<?php
// initialize session
session_start();

print_r($_POST['first_name']);

print '';
var_dump($_POST['first_name']);
print '';

// create session variable if form has been submitted
if (isset($_POST['first_name'])) {
if (!empty($_POST['first_name'])) {
$_SESSION['first_name'] = htmlentities($_POST['first_name']);
} else {
$_SESSION['first_name'] = 'Bashful';
}
}
?>
<!doctype html>

Session Test

Hello, <?php
if (isset($_SESSION["first_name"])) {
echo $_SESSION["first_name"];
} else {
echo 'stranger';
}
?>.

Go to page 3

--------------------------------------------------------------------------------------------------------------------

(sessions_03)

--------------------------------------------------------------------------------------------------------------------

<?php
// initialize session
session_start();

print_r($_POST['first_name']);

print '';
var_dump($_POST['first_name']);
print '';

?>
<!doctype html>

Session Test

Hello<?php
if (isset($_SESSION['first_name'])) {
echo ' again, ' . $_SESSION['first_name'];
} else {
echo ', stranger';
}
?>.

Go to page 1

--------------------------------------------------------------------------------------------------------------------

On running the above code (you can see that I have "print_r" and "var_dump" added), I get the following responses:

--------------------------------------------------------------------------------------------------------------------
(After clicking the "submit" button in sessions_01.php):

John Doe

string(8) "John Doe"

array(0) {
}

Hello, John Doe.

Go to page 3

----------------------------------------------------------------------

(After clicking the "Go to page 3" link in sessions_02.php):

----------------------------------------------------------------------

Notice: Undefined index: first_name in H:\www\www.czzaaac.com\session_03.php on line 6

Notice: Undefined index: first_name in H:\www\www.czzaaac.com\session_03.php on line 9

NULL

array(0) {
}

Hello, stranger.

Go to page 1

----------------------------------------------------------------------------------------------------------------

When I check the /temp folder (which is where session files are written to) there are 2 file entries, one with data (obviously made when I click the "submit" button), and another one without data (must be created when I click the "Go to page 3" link).

I don't see where there is a problem in the code, so, I am assuming that my configuration settings (Apache 2.4 , or PHP7 settings are to blame). Although, I may be wrong.
 

·
Registered
Joined
·
3,421 Posts
No posting is done to session3.php (i.e. $_POST is empty), hence the errors on lines 6 and 9.
I know that session_start(); in a called php script will simply 'pick up' the current session, but please humour me and try replacing line 3 (session_start();) with ...
PHP:
    if(!isset($_SESSION))
    {
        session_start();
    }
and see what happens ...
 

·
Registered
Joined
·
48 Posts
Discussion Starter · #5 ·
Yep.

have done that. And the response is similar.

Notice: Undefined index: first_name inH:\www\www.czzaaac.com\session_03.phpon line6

Notice: Undefined index: first_name in H:\www\www.czzaaac.com\session_03.php on line 9
NULL

array(0) {
}

Hello, stranger.

Go to page 1

-------------------------------------------------------------------------------------------------------------------------

Am also currently checking my config settings and values.
 

·
Registered
Joined
·
48 Posts
Discussion Starter · #6 ·
Just out of interest, added the following code at the top of "session_02.php" and "session_03.php", just before the "session_start() function:

-------------------------------------------------------------------------------

phpinfo();

-------------------------------------------------------------------------------

surprisingly, I get this extra error information:

-------------------------------------------------------------------------------
session_02.php (below)
-------------------------------------------------------------------------------

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at H:\www\www.example.com\session_02.php:3) inH:\www\www.example.com\session_02.phpon line6

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at H:\www\www.example.com\session_02.php:3) inH:\www\www.example.com\session_02.phpon line6
John Doe
string(8) "John Doe"

array(0) {
}

Hello, John Doe.

Go to page 3

------------------------------------------------------------------------------------------------
session_03.php
------------------------------------------------------------------------------------------------

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at H:\www\www.example.com\session_03.php:4) inH:\www\www.example.com\session_03.phpon line6

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at H:\www\www.example.com\session_03.php:4) inH:\www\www.example.com\session_03.phpon line6

Notice: Undefined index: first_name inH:\www\www.example.com\session_03.phpon line8

Notice: Undefined index: first_name in H:\www\www.example.com\session_03.php on line 11
NULL

array(0) {
}

Hello, stranger.

Go to page 1
 

·
Registered
Joined
·
48 Posts
Discussion Starter · #7 ·
Just out of interest, added the following code at the top of "session_02.php" and "session_03.php", just before the "session_start() function:

-------------------------------------------------------------------------------

phpinfo();

-------------------------------------------------------------------------------

surprisingly, I get this extra error information:

-------------------------------------------------------------------------------
session_02.php (below)
-------------------------------------------------------------------------------

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at H:\www\www.example.com\session_02.php:3) inH:\www\www.example.com\session_02.phpon line6

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at H:\www\www.example.com\session_02.php:3) inH:\www\www.example.com\session_02.phpon line6
John Doe
string(8) "John Doe"

array(0) {
}

Hello, John Doe.

Go to page 3

------------------------------------------------------------------------------------------------
session_03.php
------------------------------------------------------------------------------------------------

Warning: session_start(): Cannot send session cookie - headers already sent by (output started at H:\www\www.example.com\session_03.php:4) inH:\www\www.example.com\session_03.phpon line6

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at H:\www\www.example.com\session_03.php:4) inH:\www\www.example.com\session_03.phpon line6

Notice: Undefined index: first_name inH:\www\www.example.com\session_03.phpon line8

Notice: Undefined index: first_name in H:\www\www.example.com\session_03.php on line 11
NULL

array(0) {
}

Hello, stranger.

Go to page 1
-----------------------------------------------------------------------------------------------

However, when I put the phpinfo() after the session_start();, I get the same message returned as before the time I tried the above.

Why then, is it saying that it cannot send "session cache limiter", and "session cookie", when yet, taking away any code from before the "session_start", it then doesn't send the session data?
 

·
Registered
Joined
·
48 Posts
Discussion Starter · #8 ·
Okay.

So, to everyone who might want to find out how I got out of this mess.

I did a simple re-install of Apache and Php. In this case, I installed them as separate components (AMP stacks tend to give (me) more subtle problems down the line).

Although, I did not check to see whether it would have been necessary to re-install Apache, after only re-installing PHP.

In any case, my advice, would be to not mess around too much with the php.ini configuration settings. In this case, especially the sessions settings. Because, I did change quite a few of them originally, before I started working on sessions.
 

·
Registered
Joined
·
3,421 Posts
I came across this tutorial, which explains the process of using session_set_save_handler and also explains why you get those extra warnings about cookies. Hope you will find it informative ...
 
1 - 10 of 10 Posts
Status
Not open for further replies.
Top