Jump to content

i must be missing something...


Go to solution Solved by gizmola,

Recommended Posts

hey guys i'm using the session_set_save_handler() function but when trying to write to a session i no longer have a connection to my database...

	public function initialize_session_handler()
	{
	    $registry = new Registry;
	    $db       = $registry->db;
		
	    $session_handler = new Session_DB_Handler;
	    $session_handler->set_db_adapter($db);
	    $session_handler->set_lifetime(1);
	    
            print_r($session_handler); // property $_db stats mysqli connection

	    session_set_save_handler(
            array($session_handler, 'open'),
    	    array($session_handler, 'close'),
    	    array($session_handler, 'read'),
    	    array($session_handler, 'write'),
    	    array($session_handler, 'destroy'),
    	    array($session_handler, 'clean')
	    );  
}

when print_r($session_handler) it shows the class property $_db has a mysqli connection:

Session\Session_DB_Handler Object
(
[_db:protected] => DB\Driver\MySQLi Object
(
[_identifier:protected] => mysqli Object
(
[affected_rows] => 0
[client_info] => mysqlnd 5.0.11-dev - ********* - $Id: *********** $
[client_version] => 50011
[connect_errno] => 0
[connect_error] =>
[errno] => 0
[error] =>
[error_list] => Array
(
)

[field_count] => 0
[host_info] => Localhost via UNIX socket
[info] =>
[insert_id] => 0
[server_info] => 5.5.5-10.0.20-MariaDB
[server_version] => 50505
[stat] => Uptime: 120613 Threads: 1 Questions: 73251 Slow queries: 0 Opens: 1606 Flush tables: 1 Open tables: 400 Queries per second avg: 0.607
[sqlstate] => 00000
[protocol_version] => 10
[thread_id] => 3215
[warning_count] => 0
)

[_config:protected] => Array
(
[host] => localhost
[username] => user
[password] => pass
)

[_table:protected] =>
[_result:protected] =>
[_statements:protected] => Array
(
)

[_database:protected] =>
)

[_lifetime:protected] => 86400
)

but if i try to write to a session after initializing the session handler  $_db property is null in my session handler class...i've also tried to use $_db as a static property...i just can't understand why it's null when I'm trying to write

 

does anyone have any ideas as to why please?

 

thank you

 

Link to comment
https://forums.phpfreaks.com/topic/297784-i-must-be-missing-something/
Share on other sites

here's the session handler:

 

the connection to the database is done before everything on my site and closes last...ensuring there is only one connection

<?php

namespace Session;

class Session_DB_Handler
{   
    protected $_db;
    protected $_lifetime;

    public function __construct($config = array())
    {
        ini_set('session.cookie_lifetime', 0);
        ini_set('session.gc_maxlifetime', 3600);
        ini_set('session.gc_probability', 1);
        ini_set('session.gc_divisor', 1000);
        session_set_cookie_params(0, '/', $_SERVER['HTTP_HOST'], false, true);
        session_name('SESSION_ID');
    }
        
    public function open($session_path, $session_name)
    {
        return true;
    }
    
    public function read($session_id)
    {
        $parameters = array(
            'session_id' => $session_id
        );
        
        $query = "SELECT data FROM sessions WHERE session_id = :session_id 
                  AND UTC_TIMESTAMP() < DATE_ADD(modified, INTERVAL lifetime SECOND)";
        
        $db = $this->_db;
        $db->bisi;
        $result    = $db->execute($parameters, $query);
        $row       = $result->fetch_row();
        $row_count = $result->count();
        $result->free();
        
        if ($row_count === 1)
        {
            return $row['data'];
        }
        
        return null;
    }
    
    public function write($session_id, $data)
    {        
        $parameters = array(
            'session_id' => $session_id,
            'data'       => $data,
            'lifetime'   => $this->get_lifetime()
        );
        
        $query = "INSERT INTO sessions (session_id, data, lifetime)
                  VALUES (:session_id, :data, :lifetime)
                  ON DUPLICATE KEY
                  UPDATE data = :data, lifetime = :lifetime";
        
        $db = $this->_db;
        $db->bisi;
        $db->execute($parameters, $query);
    }
    
    public function destroy($session_id = null)
    {
        $parameters = array(
            'id' => $session_id,
        );
        
        $query = "DELETE FROM session WHERE session_id = :session_id";
                
        $db = $this->_db;
        $db->bisi;
        $db->execute($parameters, $query);
    }
    
    public function close()
    {
        return true;
    }
    
    public function clean()
    {      
        $query = "DELETE FROM sessions WHERE UTC_TIMESTAMP() > DATE_ADD(modified, INTERVAL lifetime SECOND)";
        
        $db = $this->_db;
        $db->bisi;
        $db->execute($query);
    }

    public function get_lifetime()
    {
        return $this->_lifetime;
    }
    
    public function set_lifetime($lifetime, $period = "Days")
    {
        switch (strtolower($period))
        {
            default:
            case 'seconds':
            break;
            
            default:
            case 'minutes':
                $lifetime = $lifetime * 60;
            break;
            
            default:
            case 'hours':
                $lifetime = $lifetime * 60 * 60;
            break;
            
            default:
            case 'days':
                $lifetime = $lifetime * 60 * 60 * 24;
            break;
            
            default:
            case 'weeks':
                $lifetime = $lifetime * 60 * 60 * 24 * 7;
            break;
            
            default:
            case 'months':
                $lifetime = $lifetime * 60 * 60 * 24 * 30.4368;
            break;
            
            default:
            case 'years': 
                $lifetime = $lifetime * 60 * 60 * 365.242;
            break;
        }
        
        $this->_lifetime = $lifetime;
        
        return $this;
    }
    
    public function set_db_adapter($db_adapter)
    {
        $this->_db = $db_adapter;
    }
}

thank you for your help

ok i've almost solved the problem...although its all still a bit confusing here is the code i used to call the session_handler which is in my bootstrap

	public function initialize_session_handler()
	{
	    echo "here";
	    
	    $registry = new Registry;
		$db       = $registry->db;
		
	    $session_handler = new Session_DB_Handler;
	    $session_handler->set_db_adapter($db);
	    $session_handler->set_lifetime(1);
	    
	    session_set_save_handler(
            array($session_handler, 'open'),
    	    array($session_handler, 'close'),
    	    array($session_handler, 'read'),
    	    array($session_handler, 'write'),
    	    array($session_handler, 'destroy'),
    	    array($session_handler, 'clean')
	    );
	    
	    $session = new session;
	    $session->start();
	    $session->wtf = "now";
	    
	    echo "here";
	}

index.php where bootstap is called and initializes my methhods

<?php

define('DS', DIRECTORY_SEPARATOR);
define('PARENT_DIRECTORY_PATH', dirname(dirname(__FILE__)));
define('PUBLIC_DIRECTORY', PARENT_DIRECTORY_PATH . DS . 'public' . DS);
define('PRIVATE_DIRECTORY', PARENT_DIRECTORY_PATH .DS . 'private' . DS );

use Config\Bootstrap as Bootstrap;

require_once PRIVATE_DIRECTORY . 'library' . DS . 'utility' . DS . 'autoloader.class.php';
new Autoloader;

$bootstrap = new Bootstrap;
$bootstrap->config;
$bootstrap->database->connect();
$bootstrap->headers;
$bootstrap->timezone;
$bootstrap->error_reporting;
$bootstrap->error_handler;
$bootstrap->session_handler;    // session handler is loaded here
$bootstrap->geoip;
$bootstrap->authentication;
//$bootstrap->statistics;
$bootstrap->routes;
$bootstrap->view_helpers;
$bootstrap->framework;
// $bootstrap->database->close();

ok well i commented out the closure of the database and now sessions are added to the database as the suppose to do....if i execute the closure of the database then i have no connection on the session handler write (wtf!)

 

only thing i can think of is that the session write happens at the end of php like a destructor?

 

but this is how my html page looks when print_r($db_adpater)

hello 

[html here]

hello

DB\Driver\MySQLi Object
(
    [_identifier:protected] => mysqli Object
        (
            [affected_rows] => 2
            [client_info] => ****************
            [client_version] => 50011
            [connect_errno] => 0
            [connect_error] => 
            [errno] => 0
            [error] => 
            [error_list] => Array
                (
                )

            [field_count] => 1
            [host_info] => Localhost via UNIX socket
            [info] => 
            [insert_id] => 0
            [server_info] => 5.5.5-10.0.20-MariaDB
            [server_version] => 50505
            [stat] => Uptime: 172349  Threads: 1  Questions: 110793  Slow queries: 10  Opens: 1634  Flush tables: 1  Open tables: 400  Queries per second avg: 0.642
            [sqlstate] => 00000
            [protocol_version] => 10
            [thread_id] => 6093
            [warning_count] => 0
        )

    [_config:protected] => Array
        (
            [host] => localhost
            [username] => ***
            [password] => ***
        )

    [_table:protected] => 
    [_result:protected] => 
    [_statements:protected] => Array
        (

        )

    [_database:protected] => 
) 

surly both echo's of hello and the print_r() executed from the session write should be at the top of my page before the html as it's executed well before the framework...the first echo hello is at the top!

 

honestly this is messed up or i should just give up php now

  • Solution

Did you read this page? http://php.net/manual/en/function.session-set-save-handler.php

 

Session handlers involve a bit of black magic and attempting to trace them can be confusing.

 

With that said, the write handler that is going to write out any changed variables gets executed at the end of script execution.

 

So yes, if you closed the database connection it was going to use, that is not going to work.

 

You should never be issuing html output prior to a session_start().

 

If you really want debugging/logging then you're much better off adding a file logging feature to your framework, and writing debug information there.

i have a more basic question, why are you trying to use database based session data handling? using the default file based session data handling, insuring that you are storing the session data files in a location of your choosing and with permissions set so that only your hosting account can access the files, is adequate in all but a very few cases.

 

you also have a problem with database based session security if you are using the same database connection that your application code is using and ANY of your code allows sql injection, someone can grab all the session data. if the reason you are doing this is for a perceived security problem, to make this as secure as possible, you would need a separate database with a separate connection username that only has access to that database and you would want to encapsulate the database connection into your session handler so that no other code can use possibly it.

  • Like 1

thank you!...would of helped if i read first =/....what i said is what it was...sorry guys.

 

a good idea about integrating my authentication to my framework though :)

 

although this session business leaves me a slight problem still....how do i disconnect from the database?...ideally i want the disconnection to be the last script to be executed...only have one connection to my whole site...before i would connect and disconnect per query =/...i've even tried a destruct in my db class but nahh session handler plays up again.

 

what would be my best approach here please?

i have a more basic question, why are you trying to use database based session data handling? using the default file based session data handling, insuring that you are storing the session data files in a location of your choosing and with permissions set so that only your hosting account can access the files, is adequate in all but a very few cases.

 

you also have a problem with database based session security if you are using the same database connection that your application code is using and ANY of your code allows sql injection, someone can grab all the session data. if the reason you are doing this is for a perceived security problem, to make this as secure as possible, you would need a separate database with a separate connection username that only has access to that database and you would want to encapsulate the database connection into your session handler so that no other code can use possibly it.

 

i hope my code protects me from sql injection and csfr...but you have a good point and i don't really have an answer as to why i chosen to use a database instead of the traditional way...just when i read up about it i thought it was a good idea...i'm currently in the middle of building a web server so i can run everything at home...so putting sessions onto a separate database is something i can consider for extra security....or like you said go back to the having sessions in a directory.

 

really appreciate your help guys.

 

although this answers my question about...i'll set a new database up for the sessions and can connect and close in the methods ;D

Edited by Destramic

Don't concern yourself with closing the database connection, especially when using MySql.

 

When the script is done executing all handles are closed for you.

 

There are very few situations where you need to worry about opening and closing individual database connections within a script.

  • Like 1
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.