Dynamically Start Session? [Solved]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
flying_circus
Forum Regular
Posts: 732
Joined: Wed Mar 05, 2008 10:23 pm
Location: Sunriver, OR

Dynamically Start Session? [Solved]

Post by flying_circus »

Rather than calling session_start() on each page, or setting the .ini file to auto start sessions, I want to start a session only when needed. I have a custom session handler and the constructor calls session_start().

The session handler is loaded into a registry, so I can start the session handler (which starts the session) by doing something like:

$registry->session_handler();

The problem is, this is no different than calling session_start(), and I don't need a session for every page of my site...

To get around this, I want to mimic the old session_register() function that is now deprecated, which implicitly calls session_start(). In short, I'd like to do something like:

$registry->session_handler()->set_var(); or $registry->session_handler()->get_var();

This is where I've painted myself into a corner... It's very easy to manage data in the $_SESSION super global array, but $_SESSION doesn't exist until session_start() is called. I also havent found a way to easily manage session data using the set/get functions. I was planning to use a path structure and build nested array keys based on the path (ex: $_SESSION['foo']['bar']['baz']).

This is what I've been working on, but I feel like it has a smell about it. I could use some guidance and/or thoughts. (please) :)

Code: Select all

<?php declare(encoding = 'UTF-8');
  class session_handler
  {
    /* ... */
    function set_var($path, $value = '')
    {
      if(is_string($path) && !is_null($value)) {
        $path = explode('/', dirname($path . '/.'));
        
        foreach($path as $key => $piece) {
          if(empty($piece) || !preg_match('/^[a-z][a-z0-9]*$/ui', $piece))
            unset($path[$key]);
        }
        
        print_r($path);
        /* Output:
          Array
          (
              [1] => asd
              [6] => authorized
              [12] => asds
          )
        */
      }
    }
  }

  $registry->session_handler()->set_var('/asd///../../authorized//////asds//.', 'test');
?>

Edit: Made a little progress with get_var()

Code: Select all

    function get_var($path)
    {
      if(is_string($path)) {
        $path = explode(DS, dirname($path . DS . '.'));
        
        foreach($path as $key => $piece) {
          if(empty($piece) || !preg_match('/^[a-z][a-z0-9_]*$/ui', $piece))
            unset($path[$key]);
        }
        
        $path = array_values($path);
        
        $input = array(&$_SESSION);
        
        while(list($k, $v) = each($input)) {
          foreach($v as $key => $val) {
            if($key == $path[0]) {
              if(!next($path))
                return $input[$k][$key];
              else
                array_shift($path);
                
              $input = array(&$input[$k][$key]);
            }
          }
        }
        
      # Throw Notice:
        trigger_error("Undefined index: {$path[0]}", E_USER_NOTICE);
      }
    }

    # Pulls value from $_SESSION['authentication']['last_impress']
    $registry::session_handler()->get_var('/authentication/last_impress/'); // 1309845395
Last edited by flying_circus on Tue Jul 05, 2011 11:05 pm, edited 1 time in total.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: Dynamically Start Session?

Post by McInfo »

See how Zend Framework does it.

Here is a quick hit counter example.

Code: Select all

<?php
require_once 'Zend/Session.php';
$ns = new Zend_Session_Namespace('PageViews');
if (isset($ns->counter)) {
    ++$ns->counter;
} else {
    $ns->counter = 1;
}
echo $ns->counter;
User avatar
flying_circus
Forum Regular
Posts: 732
Joined: Wed Mar 05, 2008 10:23 pm
Location: Sunriver, OR

Re: Dynamically Start Session?

Post by flying_circus »

Hi McInfo,

Thanks for the thought, I'll take a peek through their code and see if I can figure out what they are doing.

On a side note, I did a little execution time comparison:

Parse Time: 0.137s - Default ZF install, generated a blank quickstart project and executed it.
Parse Time: 0.022s - Default myFramework (skeleton) install and executed it (no session calls).
Parse Time: 0.117s - Default myFramework (skeleton) install and call session_handler->get_var() 1000 times.

*Parse times are +/- 0.003s, I tried to pull a middle of the range benchmark


I realize it's not exactly apples to apples, but it calms my fears about my frameworks efficiency. Looks like I still have a little elbow room before it's par for the course. Maybe that will change as the session var array grows, but only time will tell.
User avatar
flying_circus
Forum Regular
Posts: 732
Joined: Wed Mar 05, 2008 10:23 pm
Location: Sunriver, OR

Re: Dynamically Start Session?

Post by flying_circus »

Ok, I can't believe I didnt think of it sooner, but if anyone was wondering (or cares), the simple solution was in front of my face and REALLY simple.

Code: Select all

<?php declare(encoding = 'UTF-8');
  class session_handler
  {
    public $session_vars;
    
    function __construct()
    {
    # Start Session
      session_start();
      
    # Assign $_SESSION reference to public var
      $this->session_vars =& $_SESSION;
    }
  }
  
  # Get/Set Session Vars
    $registry->session()->session_vars['Hello'] = 'World';
?>
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: Dynamically Start Session? [Solved]

Post by McInfo »

If you create more than one instance of session_handler, you get:
Notice: A session had already been started - ignoring session_start()
Because there is only one session, consider making a singleton.
Post Reply