Date: 09/26/00
- Next message: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Previous message: uw: "[phplib-dev] cvs commit"
- Next in thread: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Reply: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
From: teo
Date: Tue Sep 26 18:22:15 2000
Modified files:
php-lib/php/session/session4.inc
Log message:
Started that long postponed job of rewriting session4.
See inside of the source comments on every functions, including some
proposals (at the very beginning of the file).
I also made a small test script for my `register_globals off' configuration
and it really looks ugly to work in such a configuration.
http://teo.digiro.net/php/play/ses/globals_off.php[s]
More ideas to come. happy hacking.
Index: php-lib/php/session/session4.inc
diff -u php-lib/php/session/session4.inc:1.3 php-lib/php/session/session4.inc:1.4
--- php-lib/php/session/session4.inc:1.3 Thu Sep 7 17:56:08 2000
+++ php-lib/php/session/session4.inc Tue Sep 26 18:22:13 2000
@@ -1,380 +1,278 @@
<?php
/*
- * Session Management for PHP3
+ * Session Management for PHP4
*
* Copyright (c) 1998,1999 NetUSE GmbH
* Boris Erdmann, Kristian Koehntopp
*
- * $Id: session4.inc,v 1.3 2000/09/07 15:56:08 kir Exp $
+ * Copyright (c) 2000 Teodor Cimpoesu <teo <email protected>>
*
+ * $Id: session4.inc,v 1.4 2000/09/26 16:22:13 teo Exp $
+ *
*/
-
-class Session {
-
- var $classname = "Session"; ## Needed for object serialization.
- ## Define the parameters of your session by either overwriting
- ## these values or by subclassing session (recommended).
-
- var $magic = ""; ## Some string you should change.
- var $mode = "cookie"; ## We propagate session IDs with cookies
- var $fallback_mode; ## If this doesn't work, fall back...
- var $lifetime = 0; ## 0 = do session cookies, else minutes
-
- var $cookie_domain = ""; ## If set, the domain for which the
- ## session cookie is set.
+/*-DEVELS-NOTE
+ * Request for further comments on the phplib-dev
+ *
+ * RFC - marks function which I don't think I understood them quite well
+ * or I propose to be pruned/changed
+ * OB - proposed as being obsolete. Most of then `helper' function for
+ * printing for which there is already the `<?=' hack.
+ *
+ * I also sow some watchers on this file. Hey there!
+ *
+ * o What do you think, should we have class members for session name
+ * and ID, or to fetch them using session_*() funcs?
+ * o Should we add a constructor to call session->start() and fill this
+ * properties?
+ * o What about the other session_* functions. Should we extend this
+ * API to include such functionalties like cookie params and save handlers
+ * or should we think another session class?
+ *
+ *-END-NOTE
+ */
- var $gc_time = 1440; ## Purge all session data older than 1440 minutes.
- var $gc_probability = 5; ## Garbage collect probability in percent
+/**
+ * Session class.
+ *
+ * Implemented API:
+ *
+ * bool start()
+ * string name ()
+ * string id ($sid = '')
+ * bool register ($var_names)
+ * bool is_registered ($var_name)
+ * bool unregister ($var_names)
+ * string get_id ($sid = '')
+ * bool put_id ()
+ * bool delete ()
+ * string url ($url)
+ * void purl ($url)
+ * string self_url ($url)
+ * string pself_url ($url)
+ * string get_hidden_session ()
+ * void hidden_session ()
+ * string get_hidden_id ()
+ * void hidden_id ()
+ * string add_query ($qs = '',$qarray)
+ * void padd_query ($qarray)
+ * string serialize ()
+ * bool deserialize ()
+ * void reimport_get_vars ()
+ * void reimport_post_vars ()
+ * void reimport_cookie_vars ()
+ * void reimport_any_vars ($arrayname)
+ */
+class Session {
- var $auto_init = ""; ## Name of the autoinit-File, if any.
+ var $auto_init = null; ## Name of the autoinit-File, if any.
var $secure_auto_init = 1; ## Set to 0 only, if all pages call
- ## page_close() guaranteed.
-
- var $allowcache = "passive"; ## "passive", "no", "private" or "public"
- var $allowcache_expire = 1440; ## If you allowcache, data expires in this
- ## many minutes.
- var $that_class = ""; ## Name of data storage container
-
- ##
- ## End of parameters.
- ##
-
- var $name; ## Session name
- var $id; ## Unique Session ID
- var $that;
-
- var $pt = array(); ## This Array contains the registered things
var $in = false; ## Marker: Did we already include the autoinit file?
- ## register($things):
- ##
- ## call this function to register the things that should become persistent
-
- function register($things) {
- $things = explode(",",$things);
- reset($things);
- while ( list(,$thing) = each($things) ) {
- $thing=trim($thing);
- if ( $thing ) {
- $this->pt[$thing] = true;
- }
- }
+ /**
+ * Start a new session or recovers from an existing session
+ */
+ function start() {
+ return <email protected>();
}
- function is_registered($name) {
- if ($this->pt[$name] == true)
- return true;
- return false;
- }
-
- function unregister($things) {
- $things = explode(",", $things);
- reset($things);
- while (list(,$thing) = each($things)) {
- $thing = trim($thing);
- if ($thing) {
- unset($this->pt[$thing]);
- }
- }
+ /**
+ * returns the variable name (cookie or GET/POST variable)
+ *
+ * <email protected> current session name, most likely php.ini->session.name
+ */
+ function name () {
+ return session_name ();
}
+
+ /**
+ * returns the session id for the current session. If id is
+ * specified, it will replace the current session id
+ *
+ * <email protected> $sid (optional) if given, sets the new session id
+ * <email protected> current session id
+ */
+ function id ($sid='') {
+ return ($sid != '' ? session_id($sid) : session_id());
+ }
+
+ /**
+ * register the variable(s) that should become persistent
+ *
+ * <email protected> $var_names a string/array with variable name(s)
+ * e.g. "foo"/"foo,bar,baz"/{"foo","bar","baz"}
+ * <email protected> false if registration failed, true on success.
+ */
+ function register ($var_names) {
+ return session_register (explode (',', $var_names));
+ }
+
+ /**
+ * see if a variable is registered in the current session
+ *
+ * <email protected> $var_name a string with the variable name
+ * <email protected> false if variable not registered true on success.
+ */
+ function is_registered ($var_name) {
+ return session_is_registered ($var_name);
+ }
+
+ /**
+ * recall the session registration for named variable(s)
+ *
+ * <email protected> $var_names a string with the variable names to be removed
+ * from the session
+ * <email protected> false if any error, true on success.
+ */
+ function unregister ($var_names) {
+ $ok = true;
+ foreach (explode (',', $var_names) as $var_name) {
+ $ok = $ok && session_unregister ($var_name);
+ }
+ return $ok;
+ }
- ## get_id():
- ##
- ## Propagate the session id according to mode and lifetime.
- ## Will create a new id if necessary. To take over abandoned sessions,
- ## one may provide the new session id as a parameter (not recommended).
-
- function get_id($id = "") {
- global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $QUERY_STRING;
- $newid=true;
-
- $this->name = $this->cookiename==""?$this->classname:$this->cookiename;
-
- if (empty($id)) {
- $newid=false;
- switch ($this->mode) {
- case "get":
- $id = isset($HTTP_GET_VARS[$this->name]) ?
- $HTTP_GET_VARS[$this->name] :
- ( isset($HTTP_POST_VARS[$this->name]) ?
- $HTTP_POST_VARS[$this->name] :
- "") ;
- break;
- case "cookie":
- $id = isset($HTTP_COOKIE_VARS[$this->name]) ?
- $HTTP_COOKIE_VARS[$this->name] : "";
- break;
- default:
- die("This has not been coded yet.");
- break;
- }
- }
-
- if ( "" == $id ) {
- $newid=true;
- $id = $this->that->ac_newid(md5(uniqid($this->magic)), $this->name);
- }
-
-
-
- switch ($this->mode) {
- case "cookie":
- if ( $newid && ( 0 == $this->lifetime ) ) {
- SetCookie($this->name, $id, 0, "/", $this->cookie_domain);
- }
- if ( 0 < $this->lifetime ) {
- SetCookie($this->name, $id, time()+$this->lifetime*60, "/", $this->cookie_domain);
- }
-
- // Remove session ID info from QUERY String - it is in cookie
- if ( !empty($QUERY_STRING) )
- {
- $QUERY_STRING = ereg_replace(
- "(^|&)".quotemeta(urlencode($this->name))."=".$id."(&|$)",
- "", $QUERY_STRING);
- }
- break;
- case "get":
- if ( !empty($QUERY_STRING) ) {
- $QUERY_STRING = ereg_replace(
- "(^|&)".quotemeta(urlencode($this->name))."=".$id."(&|$)",
- "\\1", $QUERY_STRING);
- }
- break;
- default:
- ;
- break;
- }
- $this->id = $id;
- }
-
- ## put_id():
- ##
- ## Stop using the current session id (unset cookie, ...) and
- ## abandon a session.
+ /* OB: compatibility func. Misleading, `get' with param actually `set's */
+ function get_id($sid = '') {
+ $this->id ($sid);
+ }
+
+ /**
+ * delete the cookie holding the session id
+ * XXX:RFC is this really needed? can we prune this function?
+ * the only reason to keep it is if one wants to also
+ * unset the cookie when session_destroy()ing,which PHP
+ * doesn't seem to do (looking @ the session.c:940)
+ */
function put_id() {
- switch ($this->mode) {
- case "cookie":
- global $HTTP_COOKIE_VARS;
- $this->name = $this->cookiename == '' ? $this->classname : $this->cookiename;
- SetCookie($this->name, '', 0, '/', $this->cookie_domain);
- $HTTP_COOKIE_VARS[$this->name] = '';
- break;
-
- default:
- // do nothing. We don't need to die for modes other than cookie here.
- break;
- }
+ if (get_cfg_var ('session.use_cookies') == 1) {
+ $cookie_params = session_get_cookie_params();
+ setCookie (session_name(), '',0,
+ $cookie_params['path'], $cookie_params['domain']);
+ }
+ return true;
}
- ## delete():
- ##
- ## Delete the current session record and put the session id.
-
- function delete() {
- $this->that->ac_delete($this->id, $this->name);
- $this->put_id();
+ /**
+ * delete the current session destroying all registered data
+ *
+ */
+ function delete () {
+ return (session_destroy() && $this->put_id());
+ }
+
+ /**
+ * Helper function: returns $url concatenated with the current session id
+ * Hint: now PHP has --enable-trans-sid for this
+ *
+ * <email protected> $url URL to which the session id wioll be appended
+ * <email protected> rewritten url with session id included
+ */
+ function url ($url) {
+ (strrpos ($url, '?') == false) && ($url .= '?');
+ $sin = session_name();
+ $sid = session_id();
+ $_url = '';
+
+ ( !strstr ($url, $sin)
+ and $_url = preg_replace ('/\?(.*)$/',"?$sin=$sid&\\1",$url) )
+ or (
+ $_url = preg_replace ("/($sin=[^&]+&|$sin=[^&]+$)/","$sin=$sid&",$url)
+ );
+
+ return $_url;
}
- ## url($url):
- ##
- ## Helper function: returns $url concatenated with the current
- ## session $id.
-
- function url($url){
- // Remove existing session info from url:
- if (strstr($url, $this->name) != false)
- {
- $url = ereg_replace("&*".$this->name."=[[:alnum:]]+", "", $url);
- }
-
- // Remove trailing ?/& if needed
- $url=ereg_replace("[&?]+$", "", $url);
-
-
- switch ($this->mode) {
- case "get":
- $url .= ( strpos($url, "?") != false ? "&" : "?" ).
- urlencode($this->name)."=".$this->id;
- break;
- }
- return $url;
- }
+ /* OB: print rewritten url */
function purl($url) {
- print $this->url($url);
+ print $this->url ($url);
}
-
+
+ /* OB: get current request URI */
function self_url() {
- global $PHP_SELF, $QUERY_STRING;
- return $this->url($PHP_SELF.
- ((!empty($QUERY_STRING)) ? "?".$QUERY_STRING : ""));
+ return getenv('REQUEST_URI');
}
+ /* OB: print current request URI */
function pself_url() {
print $this->self_url();
}
-
+
+ /**
+ * Stores session id in a hidden variable (part of a form)
+ */
function get_hidden_session() {
- return sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
- $this->name,
- $this->id);
+ return
+ sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
+ session_name(),
+ session_id()
+ );
}
+ /* OB: printer helper for the above one */
function hidden_session() {
print $this->get_hidden_session();
}
-
+
+ /* XXX:RFC I missed the logic in the original funcs (look damn similar
+ * to the above ones; should we prune this stuff? is anyone using it?
+ * say yes! fight the bloated i-faces and lazzy programmers ! :)
+ */
function get_hidden_id() {
- switch($this->mode) {
- case "get":
- return $this->hidden_session();
- break;
- }
+ return $this->get_hidden_session();
}
function hidden_id() {
print $this->get_hidden_id();
}
+
+ /**
+ * XXX:RFC what's the utility of this one? Shouldn't we store them in session?
+ * Prepend variables passed into an array to a query string.
+ *
+ * <email protected> $query_string probably getenv ('QUERY_STRING')
+ * <email protected> $qarray an array with var=>val pairs
+ * <email protected> the resulting quetry string, of course :)
+ */
+ function &add_query ($query_string ='', $qarray) {
+
+ ($query_string == '') && ($query_string = getenv ('QUERY_STRING'));
+
+ $qstring = $query_string . (strrpos ($query_string, '?') == false ? '?' : '&');
- function add_query($qarray) {
- global $PHP_SELF;
- global $QUERY_STRING;
-
- if ( !empty($QUERY_STRING)
- || ($this->mode == "get")) {
- $sep_char = "&";
- } else {
- $sep_char = "?";
- }
-
- $qstring = "";
- while (list($k, $v) = each($qarray)) {
- $qstring .= $sep_char . urlencode($k) . "=" . urlencode($v);
- $sep_char = "&";
- }
+ foreach ($qarray as $var => $val) {
+ $qstring .= sprintf ( '%s=%s&', $var, urlencode ($val)) ;
+ }
return $qstring;
}
- function padd_query($qarray) {
- print $this->add_query($qarray);
+ /* OB: print the resulting qstring */
+ function padd_query ($qarray) {
+ print $this->add_query ($qarray);
}
- ## serialize($prefix,&$str):
- ##
- ## appends a serialized representation of $$prefix
- ## at the end of $str.
- ##
- ## To be able to serialize an object, the object must implement
- ## a variable $classname (containing the name of the class as string)
- ## and a variable $persistent_slots (containing the names of the slots
- ## to be saved as an array of strings).
-
- function serialize($var, &$str) {
- static $t,$l,$k;
-
- ## Determine the type of $$var
- eval("\$t = gettype(\$$var);");
- switch ( $t ) {
-
- case "array":
- ## $$var is an array. Enumerate the elements and serialize them.
- eval("reset(\$$var); \$l = gettype(list(\$k)=each(\$$var));");
- $str .= "\$$var = array(); ";
- while ( "array" == $l ) {
- ## Structural recursion
- $this->serialize($var."['".ereg_replace("([\\'])", "\\\\1", $k)."']", $str);
- eval("\$l = gettype(list(\$k)=each(\$$var));");
- }
-
- break;
- case "object":
- eval('
- $str.="$$var=new ".$'.$var.'->classname.";";
- if ( is_array($'.$var.'->persistent_slots) ) {
- reset($'.$var.'->persistent_slots);
- while ( list(,$k) = each($'.$var.'->persistent_slots) ) {
- $this->serialize( "${var}->".$k, $str );
- }
- } else {
- reset($'.$var.');
- while ( list($k) = each($'.$var.') ) {
- $this->serialize( "${var}->".$k, $str );
- }
- }
-
- ');
-
-## old 'object' handler (will be gone)
-## ## $$var is an object. Enumerate the slots and serialize them.
-## eval("\$k = \$${var}->classname; \$l = reset(\$${var}->persistent_slots);");
-## $str.="\$$var = new $k; ";
-## while ( $l ) {
-## ## Structural recursion.
-## $this->serialize($var."->".$l, $str);
-## eval("\$l = next(\$${var}->persistent_slots);");
-## }
- break;
- default:
- ## $$var is an atom. Extract it to $l, then generate code.
- eval("\$l = \$$var;");
- $str.="\$$var = '".ereg_replace("([\\'])", "\\\\1", $l)."'; ";
- break;
- }
-
-# print "<br>var $var t $t str $str<br>\n";
- }
-
- function get_lock() {
- $this->that->ac_get_lock($this->name, $this->id);
- }
-
- function release_lock() {
- $this->that->ac_release_lock($this->name, $this->id);
- }
-
- ## freeze():
- ##
- ## freezes all registered things ( scalar variables, arrays, objects ) into
- ## a database table
-
- function freeze() {
- $str="";
-
- $this->serialize("this->in",&$str);
- $this->serialize("this->pt",&$str);
-
- reset($this->pt);
- while ( list($thing) = each($this->pt) ) {
- $thing=trim($thing);
- if ( $thing ) {
- $this->serialize("GLOBALS['".$thing."']",&$str);
- }
- }
-
- $r = $this->that->ac_store($this->id, $this->name, $str);
- $this->release_lock();
-
- if(!$r) $this->that->ac_halt("Session: freeze() failed.");
+ /**
+ * Get the serialized string of session variables
+ *
+ * <email protected> string
+ */
+ function serialize () {
+ return session_encode();
}
-
- ## thaw:
- ##
- ## Reload frozen variables from the database and microwave them.
-
- function thaw() {
- $this->get_lock();
-
- $vals = $this->that->ac_get_value($this->id, $this->name);
- eval(sprintf(";%s",$vals));
+
+ /**
+ * Import (session) variables from a string
+ *
+ * <email protected> boolean
+ */
+ function deserialize (&$data_string) {
+ return session_decode ($data_string);
}
- ##
- ## Variable precedence functions
- ##
+ /* OB: no clue on these functions utility */
function reimport_get_vars() {
$this->reimport_any_vars("HTTP_GET_VARS");
}
@@ -389,142 +287,9 @@
function reimport_any_vars($arrayname) {
global $$arrayname;
-
- if (!is_array($$arrayname))
- return;
-
- reset($$arrayname);
- while(list($key, $val) = each($$arrayname)) {
- $GLOBALS[$key] = $val;
- }
- }
-
- ##
- ## All this is support infrastructure for the start() method
- ##
-
- function set_container(){
- $name = $this->that_class;
- $this->that = new $name;
-
- $this->that->ac_start();
- }
-
- function set_tokenname(){
- $this->name = $this->cookiename==""?$this->classname:$this->cookiename;
- }
-
- function release_token( $sid = "" )
- {
- global $HTTP_COOKIE_VARS, $HTTP_POST_VARS, $HTTP_GET_VARS,
- $HTTP_HOST, $HTTPS;
-
- if ( isset($this->fallback_mode)
- && ( "get" == $this->fallback_mode )
- && ( "cookie" == $this->mode )
- && ( ! isset($HTTP_COOKIE_VARS[$this->name]) )
- )
- {
-
- // Looks like no cookie here - check GET/POST params
- if ( isset($HTTP_GET_VARS[$this->name]) ||
- isset($HTTP_POST_VARS[$this->name]) )
- {
- // Session info passed via GET/POST - go to fallback_mode
- $this->mode = $this->fallback_mode;
- }
- else
- {
- // It seems to be the first load of this page -
- // no cookie and no GET/POST params
-
- header("Status: 302 Moved Temporarily");
-
- // Generate session ID and setup cookie.
- $this->get_id($sid);
-
- // Next line is to generate correct self_url() later
- $this->mode = $this->fallback_mode;
-
- if( isset($HTTPS) && $HTTPS == 'on' ) {
- ## You will need to fix suexec as well,
- ## if you use Apache and CGI PHP
- $PROTOCOL='https';
- } else {
- $PROTOCOL='http';
- }
-
- header("Location: ". $PROTOCOL. "://".$HTTP_HOST.$this->self_url());
- exit;
- }
- }
- }
-
- function put_headers() {
- # Allowing a limited amount of caching, as suggested by
- # Padraic Renaghan on phplib <email protected>
- # Note that in HTTP/1.1 the Cache-Control headers override the Expires
- # headers and HTTP/1.0 ignores headers it does not recognize (e.g,
- # Cache-Control). Mulitple Cache-Control directives are contained
- # in a single header(), since PHP only sends one HTTP header per
- # header field-name (e.g., cache-control, Expires...)
- switch ($this->allowcache) {
-
- case "passive":
- $mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
- header("Last-Modified: " . $mod_gmt);
- break;
-
- case "public":
- $exp_gmt = gmdate("D, d M Y H:i:s", time() + $this->allowcache_expire * 60) . " GMT";
- $mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
- header("Expires: " . $exp_gmt);
- header("Last-Modified: " . $mod_gmt);
- header("Cache-Control: public, max-age=" . $this->allowcache_expire * 60);
- break;
-
- case "private":
- $mod_gmt = gmdate("D, d M Y H:i:s", getlastmod()) . " GMT";
- header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
- header("Last-Modified: " . $mod_gmt);
- header("Cache-Control: private, max-age=" . $this->allowcache_expire * 60);
- break;
-
- default:
- header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
- header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
- header("Cache-Control: no-cache");
- header("Pragma: no-cache");
- break;
- }
- }
-
- ##
- ## Garbage collection
- ##
- ## Destroy all session data older than this
- ##
- function gc() {
- srand(time());
- if ((rand()%100) < $this->gc_probability) {
- $this->that->ac_gc($this->gc_time, $this->name);
- }
+ $GLOBALS = array_merge ($GLOBALS, $arrayname);
}
-
- ##
- ## Initialization
- ##
-
- function start($sid = "") {
- $this->set_container();
- $this->set_tokenname();
- $this->put_headers();
- $this->release_token($sid);
- $this->get_id($sid);
- $this->thaw();
- $this->gc();
- }
}
?>
---------------------------------------------------------------------
To unsubscribe, e-mail: phplib-dev-unsubscribe <email protected>
For additional commands, e-mail: phplib-dev-help <email protected>
- Next message: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Previous message: uw: "[phplib-dev] cvs commit"
- Next in thread: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Reply: Sascha Schumann: "Re: [phplib-dev] cvs commit"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

