Wed

26

Dec

2012

PHP Pear HTTP_Session2

When programming web apps, you have to recognize the same user whe he loads a new page or revisists after weeks. PHP can take care of that with sessions. On the client side, you can store a cookie with a session id or transparently embed the id in the get-request. On the server side, you need a to save the id in a file, the memcache or in a database table.

The pear package HTTP_Session2 is supposed to take care of that. Like many pear packages, it is in beta for years und poorly documented. After fiddling with it for hours, I would like to share this with the world:

My main goal was to have a really long session. Visitors of my shop should find the shopping cart still full after weeks. Many examples focus rather on making a session that times out after minutes or hours, so that logged in users log out automatically.

The examples to the package tell you how to set the session's expiration and idle timouts and to set the timeout of the cookie. But that is not enough, if you want a long session. 

After a while, php startet a new sessionfor no apperent reason. HTTP_Session2::isNew() was true, but isExpired() or isIdle() were false() and the cookie was still valid.

Your php.ini has a setting like this.

 

called session.gc_maxlifetime = 1440 

 

It means that the garbage collector will kill your session after 1440 seconds. No matter, what timeout or idle or cookie timeout-times you set.

Fortunately, you can overrule that setting, even if you do not have access to your php.ini

 

ini_set('session.gc_maxlifetime', 6000);

So this is my working example:

 

 

 

require_once 'PEAR.php';
require_once('HTTP/Session2.php');

// Öffnet die Session, in der Produkte und Warenkorb zugeordnet sind
function startSession() {
  global $mdb2;
  $SessionLifetime = 8*7*24*60*60; // 8 Wochen

  session_set_cookie_params(
                            $SessionLifetime, // Verfällt in 8 Wochen
                            '/',          // path
                            '',           // domain
                            false,        // "secure only"
                            true);        // only over http

  ini_set('session.gc_maxlifetime', $SessionLifetime);

  HTTP_Session2::setContainer('MDB2',
                      array('dsn' = --> &$mdb2, 'table' => 'sessiondata'));

  HTTP_Session2::useTransSID(false);
  HTTP_Session2::useCookies(true);

  HTTP_Session2::start();

  HTTP_Session2::setExpire( time() + $SessionLifetime);
  HTTP_Session2::setIdle( $SessionLifetime );
  
  if (HTTP_Session2::isExpired()) {
    echo "Session ist abgelaufen.";
    HTTP_Session2::destroy();
  }
  
  if (HTTP_Session2::isIdle()) {
    // idle
    echo "You've been idle for too long!";
    HTTP_Session2::destroy();
  } else {
    HTTP_Session2::updateIdle();
  } 

  if (HTTP_Session2::isNew()) {
    HTTP_Session2::regenerateId();
  }

  //debug_Session();
}

function debug_Session() {
  if (HTTP_Session2::isNew()) {
    echo 'new session was created with the current request';
  } else {
    HTTP_Session2::set('visits', HTTP_Session2::get('visits',0)+1 );
  }

  echo("Session name: '" . HTTP_Session2::name() . "'
\n"); echo("Session id: '" . HTTP_Session2::id() . "'
\n"); echo("Is new session: '" . (HTTP_Session2::isNew() ? "yes" : "no") . "'
\n"); echo("Is expired: '" . (HTTP_Session2::isExpired() ? "yes" : "no") . "'
\n"); echo("Is idle: '" . (HTTP_Session2::isIdle() ? "yes" : "no") . "'
\n"); echo ("cartid: '" . HTTP_Session2::get('cartid') . "'
\n"); date_default_timezone_set('UTC'); echo("Session valid thru: '" . date('Y-m-d H:i:s', ( HTTP_Session2::sessionValidThru() )) . "'
\n"); }

Write a comment

Comments: 0