Re: cookies and carts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Allen McCabe wrote:
I have a shopping cart type system set up which keeps track of the cart
contents using a SESSION variable, where $_SESSION['cart'][$item_id'] is
equal to the quantity, so the name/value pair is all the information I need.

But sessions are unreliable on the free server I am currently using for this
website (not my choice), so I had start using cookies because users were
being sporadically logged out, sometimes just on a page refresh.

Have access to a database?
If yes, then run your own session management in the database.

This is what I use.
You don't want to use APC on a multiuser system, but this works without APC as well.

<?php
//require_once("sessions_apc.php");
//$sess = new SessionManager($mdb2);
//session_start();

// from :
//  http://www.devshed.com/c/a/PHP/Storing-PHP-Sessions-in-a-Database/
//  Rich Smith - 2007-05-02
//
// Modified by mpeters@xxxxxxx to use mdb2 w/ prepared statements
//  and attempt to use caching

class SessionManager {
   public  $sesstable = 'new_sessions';
   private $life_time;
   private $mdb2;
   // CHANGE THE SALT BEFORE USING
   private $apcSalt = '2d8lyds45a@&0KLybafz';
   private $apcMaxLife = 1500; // delete from cache after that many seconds
                                // even if session still active
   function SessionManager($mdb2) {
      // constructor function
      // Read the maxlifetime setting from PHP
      $this->life_time = get_cfg_var("session.gc_maxlifetime");
      $this->mdb2 = $mdb2;

      // Register this object as the session handler
      session_set_save_handler(
         array( &$this, "open" ),
         array( &$this, "close" ),
         array( &$this, "read" ),
         array( &$this, "write"),
         array( &$this, "destroy"),
         array( &$this, "gc" )
         );
      }

   function open($save_path,$session_name) {
      global $sess_save_path;
      $sess_save_path = $save_path;
      // Don't need to do anything. Just return TRUE.
      return true;
      }

   function close() {
      return true;
      }

   function read($id) {
      // Set empty result
      $data = '';
      $myreturn = $this->wrap_fetch($id);
      if (! $myreturn) {
         // Fetch session data from the selected database
         $time = time();
         $types = Array('text','integer');
$q = 'SELECT session_data FROM ' . $this->sesstable . ' WHERE session_id=? AND expires > ?';
         $sql = $this->mdb2->prepare($q,$types,MDB2_PREPARE_RESULT);
      //   if(PEAR::isError($sql)) {
// die('Failed to make prepared 58: ' . $sql->getMessage() . ', ' . $sql->getDebugInfo());
      //      }
         $args = Array($id,$time);
         $rs = $sql->execute($args);
      //   if(PEAR::isError($rs)) {
// die('Failed to issue query 63: ' . $rs->getMessage() . ', ' . $rs->getDebugInfo());
      //      }
         if ($rs->numRows() > 0) {
            $row = $rs->fetchRow(MDB2_FETCHMODE_OBJECT);
            $myreturn = $row->session_data;
            } else {
            $myreturn = '';
            }
         }
      return $myreturn;
      }

   function write($id,$data) {
      // Build query
      $time = time() + $this->life_time;

      // see if a session exists
      $sessTest = wrap_fetch($id);
      if (! $sessTest) {
         $types = Array('text');
$q = 'SELECT COUNT(session_id) from ' . $this->sesstable . ' WHERE session_id=?';
         $sql = $this->mdb2->prepare($q,$types,MDB2_PREPARE_RESULT);
         //if (PEAR::isError($sql)) {
// die('Failed to make prepared 86: ' . $sql->getMessage() . ', ' . $sql->getDebugInfo());
         //   }
         $args = Array($id);
         $rs = $sql->execute($args);
      //if(PEAR::isError($rs)) {
// die('Failed to issue query 91: ' . $rs->getMessage() . ', ' . $rs->getDebugInfo());
      //   }
         $row = $rs->fetchRow(MDB2_FETCHMODE_ORDERED);
         $count = $row[0];
         } else {
         $count = 1;
         }

         if ($count > 0) {
         // update the session
         $types = Array('text','integer','text');
$q = 'UPDATE ' . $this->sesstable . ' SET session_data=?, expires=? WHERE session_id=?';
         $args = Array($data,$time,$id);
         } else {
         $types = Array('text','text','integer');
$q = 'INSERT INTO ' . $this->sesstable . ' (session_id,session_data,expires) VALUES (?,?,?)';
         $args = Array($id,$data,$time);
         }
      $sql = $this->mdb2->prepare($q,$types,MDB2_PREPARE_MANIP);
      //if(PEAR::isError($sql)) {
// die('Failed to make prepared 111: ' . $sql->getMessage() . ', ' . $sql->getDebugInfo());
      //   }
      $rs = $sql->execute($args);
      //if(PEAR::isError($rs)) {
// die('Failed to issue query 115: ' . $rs->getMessage() . ', ' . $rs->getDebugInfo());
      //   }
      $this->wrap_store($id,$data);
      return TRUE;
      }

   function destroy($id) {
      // Build query
      $this->wrap_delete($id);
      $types = Array('text');
      $args  = Array($id);
      $q = 'DELETE FROM ' . $this->sesstable . ' WHERE session_id=?';
      $sql = $this->mdb2->prepare($q,$types,MDB2_PREPARE_MANIP);
      //if(PEAR::isError($sql)) {
// die('Failed to make prepared 129: ' . $sql->getMessage() . ', ' . $sql->getDebugInfo());
      //   }
      $rs = $sql->execute($args);
      //if(PEAR::isError($rs)) {
// die('Failed to issue query 133: ' . $rs->getMessage() . ', ' . $rs->getDebugInfo());
      //   }
      return TRUE;
      }

   function gc() {
      // Garbage Collection
// Build DELETE query. Delete all records who have passed the expiration time $sql = 'DELETE FROM ' . $this->sesstable . ' WHERE expires < UNIX_TIMESTAMP();';
      $rs = $this->mdb2->execute($sql);
      // Always return TRUE
      return true;
      }

// APC functions
   function obfus($id) {
      // this reduces odds of session hijacking if
      // a cracker manages to get a dump of apc keys
      $key = 'sess_' . sha1($this->apcSalt . $id);
      return $key;
      }

   function wrap_delete($id) {
      $key = $this->obfus($id);
      if (function_exists('apc_delete')) {
         apc_delete($key);
         }
      return true;
      }

   function wrap_fetch($id) {
      $key = $this->obfus($id);
      if (function_exists('apc_fetch')) {
         $data = apc_fetch($key);
         return $data;
         } else {
         return false;
         }
      }

   function wrap_store($id,$data) {
      $key = $this->obfus($id);
      $expires = $this->life_time;
      if ($expires < 1) {
         // keep it in cache for 1 minute
         $expires = 60;
         } elseif ($expires > $this->apcMaxLife) {
         // keep it in cache for
         $expires = $this->apcMaxLife;
         }
       if (function_exists('apc_store')) {
          apc_store($key,$data,$expires);
          }
      return true;
      }

   }

//   CREATE TABLE new_sessions (
//      session_id varchar(32) NOT NULL default '',
//      session_data text,
//      expires int(11) NOT NULL default '0',
//      PRIMARY KEY  (session_id)
//      ) ENGINE = MYISAM;
?>

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux