session.inc
上传用户:xuanqunsh
上传日期:2007-01-04
资源大小:58k
文件大小:13k
源码类别:

WEB邮件程序

开发平台:

PHP

  1. <?php
  2. /*
  3.  * Session Management for PHP3
  4.  *
  5.  * Copyright (c) 1998,1999 SH Online Dienst GmbH
  6.  *                    Boris Erdmann, Kristian Koehntopp
  7.  *
  8.  * $Id: session.inc,v 1.2 2000/04/11 14:46:25 prenagha Exp $
  9.  *
  10.  */ 
  11. class Session {
  12.   var $classname = "Session";         ## Needed for object serialization.
  13.   ## Define the parameters of your session by either overwriting
  14.   ## these values or by subclassing session (recommended).
  15.   var $magic = "";                    ## Some string you should change.
  16.   var $mode = "cookie";               ## We propagate session IDs with cookies
  17.   var $fallback_mode;                 ## If this doesn't work, fall back...
  18.   var $lifetime = 0;                  ## 0 = do session cookies, else minutes
  19.   var $cookie_domain = "";            ## If set, the domain for which the
  20.                                       ## session cookie is set.
  21.   var $gc_time  = 1440;               ## Purge all session data older than 1440 minutes.
  22.   var $gc_probability = 1;            ## Garbage collect probability in percent
  23.   var $auto_init = "";                ## Name of the autoinit-File, if any.
  24.   var $secure_auto_init = 1;          ## Set to 0 only, if all pages call
  25.                                       ## page_close() guaranteed.
  26.   var $allowcache = "private";        ## Set this to 'private' to allow private
  27.                                       ## caching; set this to 'public' to allow
  28.                                       ## public caching; set this to 'no' to
  29.                                       ## never cache the page.
  30.   var $allowcache_expire = 1440;      ## If you allowcache, data expires in this
  31.                                       ## many minutes.
  32.   var $that_class = "";               ## Name of data storage container
  33.   ##
  34.   ## End of parameters.
  35.   ##
  36.   var $name;                          ## Session name
  37.   var $id;                            ## Unique Session ID
  38.   var $that;
  39.   var $pt = array();                  ## This Array contains the registered things
  40.   var $in = false;                    ## Marker: Did we already include the autoinit file?
  41.   ## register($things):
  42.   ##
  43.   ## call this function to register the things that should become persistent
  44.   function register($things) {
  45.     $things = explode(",",$things);
  46.     reset($things);
  47.     while ( list(,$thing) = each($things) ) {
  48.       $thing=trim($thing);
  49.       if ( $thing ) {
  50.         $this->pt[$thing] = true;
  51.       }
  52.     }
  53.   }
  54.   function is_registered($name) {
  55.     if ($this->pt[$name] == true)
  56.       return true;
  57.     return false;
  58.   }
  59.   function unregister($things) {
  60.     $things = explode(",", $things);
  61.     reset($things);
  62.     while (list(,$thing) = each($things)) {
  63.       $thing = trim($thing);
  64.       if ($thing) {
  65.         unset($this->pt[$thing]);
  66.       }
  67.     }
  68.   }
  69.   ## get_id():
  70.   ##
  71.   ## Propagate the session id according to mode and lifetime.
  72.   ## Will create a new id if necessary. To take over abandoned sessions,
  73.   ## one may provide the new session id as a parameter (not recommended).
  74.   function get_id($id = "") {
  75.     global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $QUERY_STRING;
  76.     $newid=true;
  77.  
  78.     $this->name = $this->cookiename==""?$this->classname:$this->cookiename;
  79.  
  80.     if ( "" == $id ) {
  81.       $newid=false;
  82.       switch ($this->mode) {
  83.         case "get":
  84.           if ("" == ($id = isset($HTTP_GET_VARS[$this->name]) ? $HTTP_GET_VARS[$this->name] : ""))
  85.             $id = isset($HTTP_POST_VARS[$this->name]) ? $HTTP_POST_VARS[$this->name] : "";
  86.         break;
  87.         case "cookie":
  88.           $id = isset($HTTP_COOKIE_VARS[$this->name]) ? $HTTP_COOKIE_VARS[$this->name] : "";
  89.         break;
  90.         default:
  91.           die("This has not been coded yet.");
  92.         break;
  93.       }
  94.     }
  95.  
  96.     if ( "" == $id ) {
  97.       $newid=true;
  98.       $id = $this->that->ac_newid(md5(uniqid($this->magic)), $this->name);
  99.     }
  100.  
  101.     switch ($this->mode) {
  102.       case "cookie":
  103.         if ( $newid && ( 0 == $this->lifetime ) ) {
  104.           SetCookie($this->name, $id, 0, "/", $this->cookie_domain);
  105.         }
  106.         if ( 0 < $this->lifetime ) {
  107.           SetCookie($this->name, $id, time()+$this->lifetime*60, "/", $this->$cookie_domain);
  108.         }
  109.       break;
  110.       case "get":
  111.         if ( isset($QUERY_STRING) ) {
  112.           $QUERY_STRING = ereg_replace(
  113.             "(^|&)".quotemeta(urlencode($this->name))."=".$id."(&|$)",
  114.             "\1", $QUERY_STRING);
  115.         }
  116.       break;
  117.       default:
  118.         ;
  119.       break;
  120.     }
  121.  
  122.     $this->id = $id;
  123.   }
  124.   ## put_id():
  125.   ## 
  126.   ## Stop using the current session id (unset cookie, ...) and
  127.   ## abandon a session.
  128.   function put_id() {
  129.     global $HTTP_COOKIE_VARS;
  130.  
  131.     $this->name = $this->cookiename==""?$this->classname:$this->cookiename;
  132.  
  133.     switch ($this->mode) {
  134.       case "inline":
  135.         die("This has not been coded yet.");
  136.       break;
  137.  
  138.       case "get":
  139.         die("This has not been coded yet.");
  140.       break;
  141.  
  142.       default:
  143.             SetCookie($this->name, "", 0, "/", $this->cookie_domain);
  144.             $HTTP_COOKIE_VARS[$this->name] = "";
  145.       break;
  146.     }
  147.   }
  148.   ## delete():
  149.   ##
  150.   ## Delete the current session record and put the session id.
  151.   
  152.   function delete() {
  153.       $this->that->ac_delete($this->id, $this->name);
  154.       $this->put_id();
  155.   }
  156.   ## url($url):
  157.   ##
  158.   ## Helper function: returns $url concatenated with the current 
  159.   ## session $id.
  160.    
  161.   function url($url){
  162.     $url=ereg_replace("[&?]+$", "", $url);
  163.  
  164.     switch ($this->mode) {
  165.       case "get":
  166.  
  167.         $url .= ( strpos($url, "?") != false ?  "&" : "?" ).
  168.                 urlencode($this->name)."=".$this->id;
  169.  
  170.       break;
  171.       default:
  172.         ;
  173.       break;
  174.     }
  175.     return $url;
  176.   }
  177.   function purl($url) {
  178.     print $this->url($url);
  179.   }
  180.   function self_url() {
  181.     global $PHP_SELF, $QUERY_STRING;
  182.     return $this->url($PHP_SELF.
  183.            ((isset($QUERY_STRING) && ("" != $QUERY_STRING)) ? "?".$QUERY_STRING : ""));
  184.   }
  185.   function pself_url() {
  186.     print $this->self_url();
  187.   }
  188.   
  189.   function hidden_session()
  190.   {
  191.     printf("<input type="hidden" name="%s" value="%s">n", $this->name, $this->id);
  192.   }
  193.   function add_query($qarray) {
  194.     global $PHP_SELF;
  195.     global $QUERY_STRING;
  196.     if ((isset($QUERY_STRING) && ("" != $QUERY_STRING))
  197.      || ($this->mode == "get")) {
  198.       $sep_char = "&";
  199.     } else {
  200.       $sep_char = "?";
  201.     }
  202.     $qstring = "";
  203.     while (list($k, $v) = each($qarray)) {
  204.       $qstring .= $sep_char . urlencode($k) . "=" . urlencode($v);
  205.       $sep_char = "&";
  206.     }
  207.     return $qstring;
  208.   }
  209.   function padd_query($qarray) {
  210.     print $this->add_query($qarray);
  211.   }
  212.   ## serialize($prefix,&$str):
  213.   ##
  214.   ## appends a serialized representation of $$prefix
  215.   ## at the end of $str.
  216.   ##
  217.   ## To be able to serialize an object, the object must implement
  218.   ## a variable $classname (containing the name of the class as string)
  219.   ## and a variable $persistent_slots (containing the names of the slots
  220.   ## to be saved as an array of strings).
  221.   ##
  222.   ## You don't need to know...
  223.   function serialize($prefix, $str) {
  224.     static $t,$l,$k;
  225.     ## Determine the type of $$prefix
  226.     eval("$t = gettype($$prefix);");
  227.     switch ( $t ) {
  228.       case "array":
  229.         ## $$prefix is an array. Enumerate the elements and serialize them.
  230.         eval("reset($$prefix); $l = gettype(list($k)=each($$prefix));");
  231.         $str .= "$$prefix = array(); ";
  232.         while ( "array" == $l ) {
  233.           ## Structural recursion
  234.           $this->serialize($prefix."['".ereg_replace("([\'])", "\\1", $k)."']", &$str);
  235.           eval("$l = gettype(list($k)=each($$prefix));");
  236.         }
  237.       break;
  238.       case "object":
  239.         ## $$prefix is an object. Enumerate the slots and serialize them.
  240.         eval("$k = $${prefix}->classname; $l = reset($${prefix}->persistent_slots);");
  241.         $str.="$$prefix = new $k; ";
  242.         while ( $l ) {
  243.           ## Structural recursion.
  244.           $this->serialize($prefix."->".$l,&$str);
  245.           eval("$l = next($${prefix}->persistent_slots);");
  246.         }
  247.       break;
  248.       default:
  249.         ## $$prefix is an atom. Extract it to $l, then generate code.
  250.         eval("$l = $$prefix;");
  251.         $str.="$$prefix = '".ereg_replace("([\'])", "\\1", $l)."'; ";
  252.       break;
  253.     }
  254.   }
  255.   function get_lock() {
  256.       $this->that->ac_get_lock();
  257.   }
  258.   function release_lock() {
  259.       $this->that->ac_release_lock();
  260.   }
  261.   ## freeze():
  262.   ##
  263.   ## freezes all registered things ( scalar variables, arrays, objects ) into
  264.   ## a database table
  265.   function freeze() {
  266.     $str="";
  267.     $this->serialize("this->in",&$str);
  268.     $this->serialize("this->pt",&$str);
  269.     reset($this->pt);
  270.     while ( list($thing) = each($this->pt) ) {
  271.       $thing=trim($thing);
  272.       if ( $thing ) {
  273.         $this->serialize("GLOBALS['".$thing."']",&$str);
  274.       }
  275.     }
  276.     
  277.     $r = $this->that->ac_store($this->id, $this->name, $str);
  278.     $this->release_lock();
  279.     if(!$r) $this->that->ac_halt("Session: freeze() failed.");
  280.   }
  281.   ## thaw:
  282.   ##
  283.   ## Reload frozen variables from the database and microwave them.
  284.   function thaw() {
  285.     $this->get_lock();
  286.     $vals = $this->that->ac_get_value($this->id, $this->name);
  287.     eval(sprintf(";%s",$vals));
  288.   }
  289.   ##
  290.   ## Garbage collection
  291.   ##
  292.   ## Destroy all session data older than this
  293.   ##
  294.   function gc() {
  295.       $this->that->ac_gc($this->gc_time, $this->name);
  296.   }
  297.   ##
  298.   ## Variable precedence functions
  299.   ##
  300.   function reimport_get_vars() {
  301.     $this->reimport_any_vars("HTTP_GET_VARS");
  302.   }
  303.   function reimport_post_vars() {
  304.     $this->reimport_any_vars("HTTP_POST_VARS");
  305.   }
  306.   function reimport_cookie_vars() {
  307.     $this->reimport_any_vars("HTTP_COOKIE_VARS");
  308.   }
  309.   function reimport_any_vars($arrayname) {
  310.     global $$arrayname;
  311.     if (!is_array($$arrayname))
  312.       return;
  313.     reset($$arrayname);
  314.     while(list($key, $val) = each($$arrayname)) {
  315.       $GLOBALS[$key] = $val;
  316.     }
  317.   }
  318.   ##
  319.   ## All this is support infrastructure for the start() method
  320.   ##
  321.   function set_container(){   
  322.     $name = $this->that_class;
  323.     $this->that = new $name;
  324.     $this->that->ac_start();
  325.   }
  326.   function set_tokenname(){
  327.     $this->name = $this->cookiename==""?$this->classname:$this->cookiename;
  328.   }
  329.   function release_token(){ 
  330.     global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_HOST, $HTTPS;
  331.     if (   isset($this->fallback_mode)
  332.     && ( "get" == $this->fallback_mode ) 
  333.     && ( "cookie" == $this->mode )
  334.     && ( ! isset($HTTP_COOKIE_VARS[$this->name]) ) ) {
  335.       if ( isset($HTTP_GET_VARS[$this->name]) ) {
  336.         $this->mode = $this->fallback_mode;
  337.       } else {
  338.         header("Status: 302 Moved Temporarily");
  339.         $this->get_id($sid);
  340. $this->mode = $this->fallback_mode;
  341.         if( isset($HTTPS) && $HTTPS == 'on' ){
  342.         ## You will need to fix suexec as well, if you use Apache and CGI PHP
  343.           $PROTOCOL='https';
  344.         } else {
  345.           $PROTOCOL='http';
  346.         }
  347.         header("Location: ". $PROTOCOL. "://".$HTTP_HOST.$this->self_url());
  348.         exit;
  349.       }
  350.     }
  351.   }   
  352.   function put_headers() {
  353.     # Allowing a limited amount of caching, as suggested by
  354.     # Padraic Renaghan on phplib@lists.netuse.de.
  355.     #
  356.     # Note that in HTTP/1.1 the Cache-Control headers override the Expires
  357.     # headers and HTTP/1.0 ignores headers it does not recognize (e.g,
  358.     # Cache-Control). Mulitple Cache-Control directives are split into 
  359.     # mulitple headers to better support MSIE 4.x.
  360.     #
  361.     # Added pre- and post-check for MSIE 5.x as suggested by R.C.Winters,
  362.     # see http://msdn.microsoft.com/workshop/author/perf/perftips.asp#Use%20Cache-Control%20Extensions
  363.     # for details
  364.     switch ($this->allowcache) {
  365.       case "public":
  366.         $exp_gmt = gmdate("D, d M Y H:i:s", time() + $this->allowcache_expire * 60) . " GMT";
  367.         $mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";                             
  368.         header("Expires: " . $exp_gmt);
  369.         header("Last-Modified: " . $mod_gmt);
  370.         header("Cache-Control: public");
  371.         header("Cache-Control: max-age=" . $this->allowcache_expire * 60);
  372.       break;
  373.  
  374.       case "private":
  375.         $mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
  376.         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  377.         header("Last-Modified: " . $mod_gmt);
  378.         header("Cache-Control: private");
  379.         header("Cache-Control: max-age=" . $this->allowcache_expire * 60);
  380.         header("Cache-Control: pre-check=" . $this->allowcache_expire * 60);
  381.       break;
  382.       default:
  383.         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  384.         header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  385.         header("Cache-Control: no-cache");
  386.         header("Cache-Control: post-check=0, pre-check=0");
  387.         header("Pragma: no-cache");
  388.       break;
  389.     }
  390.   }
  391.   ##
  392.   ## Garbage collection
  393.   ##
  394.   ## Destroy all session data older than this
  395.   ##
  396.   function gc() {
  397.     srand(time());
  398.     if ((rand()%100) < $this->gc_probability) {
  399.       $this->that->ac_gc($this->gc_time, $this->name);
  400.     }
  401.   }
  402.   ##
  403.   ## Initialization
  404.   ##
  405.   function start($sid = "") {
  406.     $this->set_container();
  407.     $this->set_tokenname(); 
  408.     $this->release_token($sid);
  409.     $this->put_headers();
  410.     $this->get_id($sid);
  411.     $this->thaw();
  412.     $this->gc();
  413.   }
  414. }
  415. ?>