blueshoes php application framework and cms            core_net
[ class tree: core_net ] [ index: core_net ] [ all elements ]

Class: Bs_SimpleSession

Source Location: /core/net/http/session/Bs_SimpleSession.class.php

Class Overview

Bs_Object
   |
   --Bs_SimpleSession

Simple-Session extends PHP's standard session handling making it more usable.


Author(s):

Version:

  • 4.4.$Revision: 1.14 $ $Date: 2003/11/17 00:18:05 $

Copyright:

  • blueshoes.org

Methods


Inherited Variables

Inherited Methods

Class: Bs_Object

Bs_Object::Bs_Object()
Bs_Object::getErrors()
Basic error handling: Get *all* errors as string array from the global Bs_Error-error stack.
Bs_Object::getLastError()
Basic error handling: Get last error string from the global Bs_Error-error stack.
Bs_Object::getLastErrors()
Basic error handling: Get last errors string array from the global Bs_Error-error stack sinc last call of getLastErrors().
Bs_Object::persist()
Persists this object by serializing it and saving it to a file with unique name.
Bs_Object::setError()
Basic error handling: Push an error string on the global Bs_Error-error stack.
Bs_Object::toHtml()
Dumps the content of this object to a string using PHP's var_dump().
Bs_Object::toString()
Dumps the content of this object to a string using PHP's var_dump().
Bs_Object::unpersist()
Fetches an object that was persisted with persist()

Class Details

[line 196]
Simple-Session extends PHP's standard session handling making it more usable.

From the PHP-manuel:
"The session support allows you to register arbitrary numbers of variables to be preserved across requests.When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through start() or implicitly through register()) whether a specific session id (SID) has been sent with the request. If this is the case, the prior saved environment is recreated."

Features :

  • Object vars can be passed directly and do not have to be copied to a global var.
  • Is only based on PHP's built in sessions handling, no additional SID is used. So we benefit from all features that PHP sessions handling uses to pass the SID (like url_rewriter.tags )
  • Automatically stores session data to disk on PHP exits.
  • Auto-change detection. If session-data is left unchanged, then no data is written to disk.
  • Supports garbage collecting.
  • Supports 'maxLifeTime' and 'maxStandbyTime'
  • 2do Protection against Session hijacking
  • You may have Parallel Sessions. the short answer is: "To have multiple session (from the same user) using *one* SID".
What are Parallel Sessions? The short answer is: "To have multiple session (from the same user) using *one* SID". Let me give you some examples in where you would like to have parallel sessions:
  1. You have 2 (or more) independent login pages on the same site and want to keep a session for each. Also you must guarantee that the same session vars are not overwritten by accident.
  2. You would like to have a different timeout for some session-vars. E.g. Some pages in a portal could be very conservative and would like to drop data while others would like to keep it until the browser is closed.
  3. You have to store a high volume of session data, but most of the data is NOT needed in every session. Using a normal PHP-session would load *all* session-vars collected so far (if used or not). If the session data is complex (like serialized objects) this will result in a high overhead.
Typical Use Cases:
  • You are programming object oriented and also think it's very 'dirty' to have to define the session variables *global*. (See below "Reason for Writing this Class")
  • It's possible to have more than one session at a time from the same user using only *one* session ID (we call this Parallel Sessions).
  • Only the session vars are loaded that are used. (See "Features".)
USAGE Samples (also check the 3 example scripts in the examples folder.)

1 ################################################################################
2 # Sample 1
3 # --------
4 # Simple Counter.
5 include_once($APP['path']['core'] . 'net/http/session/Bs_SimpleSession.class.php');
6 $session =& $GLOBALS['Bs_SimpleSession']; // Use the per ref operator '=&' <-- !!
7
8 $aVariable=0;
9 $ok = $session->register('my_var', $aVariable);
10 if (!$ok) echo $session->getErrors();
11 echo "<hr>Sample 1 - Simple Counter: <B>" . $aVariable++ . "</B><br>";
12
13 ################################################################################
14 # Sample 2
15 # --------
16 # TIP: If you have a lot of session data that is not needed during every request, then
17 # you may want to use following technique (called parallel sessions)
18 # In this manner the $bigDataRec will only be loaded when needed and not on every request.
19 include_once($APP['path']['core'] . 'net/http/Bs_SimpleSession.class.php');
20 $session =& $GLOBALS['Bs_SimpleSession']; // Use the per ref operator '=&' <-- !!
21
22 $smallDataRec = NULL; // Data used in ever session
23 $bigDataRec = NULL; // Data not used in ever session
24 $session->register('my_sessionData', $smallDataRec);
25 if ($needThatBigData) {
26 $session->register('my_bigData', $bigDataRec, 'myBigDataSession');
27 // do something with the $bigDataRec
28 }
29

Reason for Writing this Class:
In PHP you can only register variables that are global with PHP's session handling :-(. This is very unsatisfying when programming OO. So if I have a var $this->foo in an object that you would like to register with 'session_register()', you'd have to somehow globalise it. *Yack!* This Class makes it much easier with a method like $session->register($key, $value).

This class is called simple-session because:

  1. One main feature is the practical approach when working with PHP-objects. Session vars don't have to be global (read below for more).
  2. Based on PHP's Session handling functions. This means that all the session features from PHP are inherited like the use of cookies (See below or PHP manual).
Because this object is based on the built-in session handling of PHP, all PHP session properties set in php.ini also have an influence on this object (Note: the default settings are usually OK). The most important settings are:

  • session.auto_start : Initialize session on request startup.
  • session.use_cookies : specifies whether the module will use cookies to store the session id on the client side. Defaults to 1 (enabled).
  • session.use_only_cookies: specifies whether the module will only use cookies to store the session id on the client side.
  • session.cookie_lifetime : (default 0 == "until restart of browser"). If a time >0 is given, all session data will be lost after that time is over. You can shorten this time in this class but NOT longer it.
  • session.gc_maxlifetime : (default 1440 == 24min) defines how long after the last access the PHP-session should be considered as garbage. You can shorten this time in this class but NOT longer it.
  • variables order : (default "EGPCS") Describes the order in which PHP registers GET, POST and Cookie vars and therefore the order how PHP looks for the SID.
NOTE: Check PHP-bug report: http://bugs.php.net/?id=14798 (PHP V4.1.0) Sessions lifetime will not work with Win and FAT32!

For more info on PHP-session handling see http://www.zend.com/zend/tut/session.php and the PHP manuel.

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

Implementation details:
Quite easy: We start a normal PHP sessions and only register one global variable called: $bs_sessInfoList. $bs_sessInfoList is a hash and is brought into the Bs_SimpleSession object as $this->_sessInfoList. Every entry in $this->_sessInfoList represents a 'running' session. The session-entry is made of the property- and state-data.

Session Info List ($this->_sessInfoList) :

  $_sessInfoList[] = array (
      'prop' => array (  // NOTE: Final values are given in constructor.
            'version'        => 0,    // <- Session version, to detect outdated session data if PHP sources change.
            'path'           => "",   // <- Path to where to store the session files.
            'maxStandbyTime' => 180,  // <- How long should the session stay valid (in min) since last access. 0 means until browser end.
            'maxLifeTime'    => 0,    // <- Independent of use, invalidate after this time (in min).  0 means until browser end.
           ),
       'state' => array (
            'SID'         => $sid,    // <- The unique SID for this session.
            'filePrefix'  => $prefix, // <- The filename prefix (without path)
            'fileName'    => $prefix . $sid,
            'createTime'  => time(),  // <- Time of creation    (used with  'maxLifeTime')
            'accessTime'  => time(),  // <- Time of last access (used with  'maxStandbyTime')
            'md5'         => '',      // <- To autodetect changes.
            'forceWrite'  => FALSE    // <- To force a write to file (ignor autodetect)
       )
    );
  

During a session the $this->_sessInfoList is saved and read by PHP-session handling. And *no* other data is been imported (for the moment). We are now aware of the state and property of all 'parallel' sessions and the source of it's data registered so far. Every session has a name that is the key in the _sessInfoList. All public function of Bs_SimpleSession have a last optional parameter called $sessName (default value = 'default'). The moment you use one of these functions the data of $sessName is read. Or if it's a new session name a new _sessInfoList-entry is created. The data will automatically store at end of script.

RECOMMENDATION: Please don't make use of the ini setting 'session.referer_check'. From the manual:
contains the substring you want to check each HTTP Referer for. If the Referer was sent by the client and the substring was not found, the embedded session id will be marked as invalid. Defaults to the empty string.
Reason: 1. The referer can be cheated or change randomly (some privacy protectors do that). 2. Now you're clever and add 'yourdomain.com'. Someone is on your site, opens another webbrowser, clicks on a link to 'anotherdomain.com', which has a link back to yourdomain.com. now what? right, session is lost, new one is created. and we don't want that, right?




Tags:

example:  example
example:  example
example:  example
pattern:  singleton (pseudostatic, rtfm)
access:  public
author:  Sam Blum <at blueshoes dot org>, Andrej Arn <andrej at blueshoes dot org>
copyright:  blueshoes.org
version:  4.4.$Revision: 1.14 $ $Date: 2003/11/17 00:18:05 $
todo:  Prevent SID hijacking. If we reuse a previously created session by getting the sid from the querystring (and not from a cookie), we have a possible hole. Someone might send his url (with sid included) to someone else, and this person pastes it into the browser. See the problem. So what we do is check the class c network of the ip address (proxies might switch ip's). This still leaves room for ppl trading url's in the same company/using the same isp, but what can we do? Check browser string? hmm maybe. Well this is internal anyway and you shouldn't care.


[ Top ]


Class Methods


constructor Bs_SimpleSession [line 247]

Bs_SimpleSession &Bs_SimpleSession( )

Constructor.

There is no need to use this contructor. Please use the instance as follows $session =& $GLOBALS['Bs_SimpleSession']; (instead of $session =& new Bs_SimpleSession() )




Tags:

pattern:  singleton (rtfm)


[ Top ]

method destroy [line 441]

bool destroy( [string $sessName = 'default'])

Destroys all data of a session by removing the data.



Tags:

return:  always TRUE.
see:  Bs_SimpleSession::reset()
access:  public


Parameters:

string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method destroySID [line 465]

bool destroySID( mixed $sid, [mixed $destroySessName = NULL], string $sid., string $sessName)

Destroys all data of a session that matches the passed SID.

NOTE: Will destroy all data with that SID (incl. all parallel sessions) if second parameter is not passed




Tags:

return:  TRUE if found, FALSE oterwise.
see:  Bs_SimpleSession::reset()
access:  public


Parameters:

string   $sid.  
string   $sessName   (Optional, default is NULL). See NOTE above.

[ Top ]

method gc [line 623]

bool gc( )

Garbage collection

Old session files often have to be deleted. These orphan files are left overs of useres that for example just close their browser. From time to time these orphans have to be deleted. We parse all dir's we find in the _sessInfoList for files with the $this->_sessPrefix and read the modtime. If the age is greater then the $this->_runProperties['garbage_lifetime'] (set start()) the file is deleted.

NOTE: This function is called randomly on every new session start. The %-chance to fire a gc is given by $this->_runProperties['gc'] (see start()).




Tags:

return:  TRUE on success, FALSE otherwise
access:  public


[ Top ]

method getSid [line 550]

void getSid( )

Returns the session id for the current session.



[ Top ]

method getVar [line 422]

mixed &getVar( string $key, [string $sessName = 'default'])

Returns the value of a registered var.

NOTE: You will normaly not be using this function. Instead you'll be using register().

Examples: To get the data by value, do $val = getVar('someVar'); // Gives you a copy To get the data by reference, do $ref = &getVar('someVar');




Tags:

throws:  NULL if not found of failer.


Parameters:

string   $key   (to identify the value)
string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method isRegistered [line 400]

bool isRegistered( string $key, [string $sessName = 'default'])

Tells if the var is registered.

The session-data with name == $sessName is loaded (if not loaded already) and checks if passed $key has a session value. TIP: Call only when you plan to use and/or modify a session var. This will improve the performance by omitting the file load.




Parameters:

string   $key   (to identify the value)
string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method register [line 356]

bool register( string $key, string &$value, [string $sessName = 'default'])

Register a var to the session by passing a unique key, the var and an optional session name.

Behaver of this function:

  • If the passed key is *not* registered, the passed value is taken as default.
  • If the passed key is registered, the session value will overwrite the passed value (this is possible because it's passed by reference)
  • From the moment you call register, that value is 'watched' (by holding a pointer to it). That means that any change to that value will be stored at the request end and available at the next request.
Sample I "Simple Counter": include_once($APP['path']['core'] . 'net/http/Bs_SimpleSession.class.php'); $session =& $GLOBALS['Bs_SimpleSession']; // Use the per ref operator '=&' <-- !! $counter=0; if (!$session->register('my_counter', $counter)) echo $session->getErrors(); echo $counter++ . "
";

Sample II "Parallel Session":

  • TIP: If you have a lot of session data that is not needed on every request, then
  • you may want to use following technique (called parallel sessions)
  • In this manner the $bigDataRec will only be loaded when needed and not on every include_once($APP['path']['core'] . 'net/http/Bs_SimpleSession.class.php'); $session =& $GLOBALS['Bs_SimpleSession']; // Use the per ref operator '=&' <-- !! $smallDataRec = NULL; // Data used in ever session $bigDataRec = NULL; // Data not used in ever session $session->register('my_sessionData', $smallDataRec); if ($needThatBigData) { $session->register('my_bigData', $bigDataRec, 'myBigDataSession'); // do something with the $bigDataRec } // do something with the $smallData

WARNING: Never add session values that reference themselfs in a cyclic way. PHP 4.x cycles 7 time and then ends. This will lead to unwanted results. E.g. $a = array(); $a[0] = &$a; Will become array(array(array(array(array(array(array())))))) Array of array, depth 7




Tags:

return:  TRUE on success, FLASE on error (use getLastError())


Parameters:

string   $key   (to identify the value)
string   &$value   (*by reference*)
string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method reset [line 495]

bool reset( [string $sessName = 'default'])

Reset the session data. All data is lost but session properties remain



Tags:

return:  always TRUE.
see:  Bs_SimpleSession::destroy()


Parameters:

string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method setProperty [line 533]

array setProperty( array $prop, [string $sessName = 'default'])

Set a new property for a session.

You may pass a property hash with following parameters. All are optional and if omitet the default will be taken. $prop = array ( 'path' => "", // <- Path to where to store the session files. 'maxStandbyTime' => 30, // <- How long should the session stay valid (in min) if *not* used. 0 means until browser end. 'maxLifeTime' => 300, // <- Independent of use, invalidat after this time (im min). 0 means until browser end. );

 NOTE 1 :
   The properties will only have an effect, if the session wasn't started alread.
   Thus this function must be called *before* you do any register(), unRegister(), getVar(), a.s.o.,
   so before any function call involving session data.
 NOTE 2 :
   'maxLifeTime' is limited by PHP's 'session.cookie_lifetime' that we can not exceed if
   cookies are used.
   PHP writes: "session.cookie_lifetime specifies the lifetime of the cookie in seconds which is
                sent to the browser. The value 0 means "until the browser is closed." Default is 0."
   So session.cookie_lifetime == 0 is OK.
 




Tags:

return:  of used properties on success, FALSE otherwise


Parameters:

array   $prop   see above
string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method start [line 286]

bool start( [hash $runProperties = array()])

Starts up session.

There is no need to call this function as Bs_SimpleSession is started the moment it's included. (Unless you want to chage the default run-properties)

A array of parameters may be passed to change the run-properties

  $runProperties = array (
       'gc'               => 1,        // - garbage collection. Chace of gc to start 1 - 100%. 0 means never.
       'garbage_lifetime' => 60*24*30, // - The age (in min) that a session file may have befor it's assumed garbage and is deleted. 0 means never.
     );
 




Tags:

return:  TRUE if succes, FALSE otherwise.


Parameters:

hash   $runProperties   (see text)

[ Top ]

method unRegister [line 378]

bool unRegister( string $key, [string $sessName = 'default'])

Remove a var from the session register list



Tags:

return:  TRUE on success, FLASE on error (use getLastError())


Parameters:

string   $key   (to identify the value)
string   $sessName   (Optional, default is 'default'). Only used for parallel sessions.

[ Top ]

method write_close [line 567]

TRUE write_close( )

'Manually' store all session data to file.

Session data is automatically stored after your script terminated without the need to call write_close(), but because we write the session-data with exclusive locks to prevent concurrent writes on the same file this leads to a new behaver when using framesets together with sessions. You will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done by calling write_close().




Tags:

return:  on seccess, FALSE otherwise.
access:  public


[ Top ]

method _htmlBar [line 680]

void _htmlBar( mixed $delta, mixed $h, [mixed $color = 'green'])

Make a litte html-bar for the toHtml output



[ Top ]


Documentation generated on Mon, 29 Dec 2003 21:12:41 +0100 by phpDocumentor 1.2.3