PHP:SessionaraCode

From xbe wiki

Jump to: navigation, search

By the way, this source highlighting is done by my own mediawiki extension - really simple.. ;)

<?php

/*
* Sessionara - Session based data environment with MySQL
* Copyright (c) 2001-2004 Dario Nuevo
* http://php.xbe.ch | dn(*at*)xbe(*dot*)ch
* Release 1.7-r1 [build 20041103]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* ADDITION: Please send me improvement ideas and realized stuff. At least tell
* me about it *g*. I's great to have some input.
*
* You'll find the entire GNU GPL in the LICENSE file.
* --------------------------------------------------
* Quick guide
* For questions regarding the install process, take a look at the documentation (you'll find it on the website).
* Here's a little example how you could use it:
*
* $ses = new Sessionara("W/MYSQL");
* $ses->var_set("foo","bar");
* echo "Session has ID ".($ses->get_sid());
*
* (on another page, pass the $sid through GET or POST):
*
* $ses = new Sessionara(); // <- calling withough param = resuming session
* echo $ses->var_get("foo");
*/

class Sessionara
{

        var $cfg;
        var $sid;

        function Sessionara($sqlquery "") {

                // **** configuration **** [default]
                $this->cfg = array();
                // Generated $sid's string length [26]
                $this->cfg["sid_howlong"] = 26;
                // Session lifetime in minutes [10]
                $this->cfg["session_howlong"] = 10;
                // Class' table name
                $this->cfg["db_table"] = "foo_sessions";
                // What should the class do in a case of an expired session?
                $this->cfg["timeout_action"] = "error"// options "redir", "error"
                // In the case of an expired session, we'll send the user to this location
                $this->cfg["timeoutpage"] = "index.php";
                // Keyword to pass if you don't pass a sql select statement (V1.1)
                $this->cfg["placeholder"] = "W/MYSQL";
                // transport the sid automatically with a cookie? ("enable cookies?") (V1.7)
                $this->cfg["use_cookies"] = true;
                // BETA FEATURE: Decide to (not) use first "security" tries (V1.1) [false]
                $this->cfg["use_addr"] = true// true, false or "old" (last as string!)

                /*
                mysql table field names
                here you can alter the mysql field names that are used. if you just use the normal sql to create the table, don't care about this... *g
                but if you want to integrate this class into a project-based database scheme, it's useful that you can define the field names that are used..

                i hope i don't have to mention that you just have to change the _value_ of this array! i.e. $this->cfg["tfields"]["autoid"] = "ID";
                */
                $this->cfg["tfields"]["autoid"] = "autoid"// primary key
                $this->cfg["tfields"]["sid"] = "sid"// session id
                $this->cfg["tfields"]["data"] = "data"// data container
                $this->cfg["tfields"]["addr"] = "addr"// remote address or strid
                $this->cfg["tfields"]["opened"] = "opened"// timestamp open
                $this->cfg["tfields"]["expire"] = "expire"// timestamp expire time

                $this->session_table_cleanup();
                $this->logged_in false;
                $this->sid $this->lookup_sid();
                if((strlen($this->sid) == $this->cfg["sid_howlong"]) && (strlen($sqlquery)<1)) $this->resume_session();
                elseif(strlen($sqlquery) > 1$this->open_session($sqlquery);
                else $this->timeout();

                if($sqlquery == $this->cfg["placeholder"]) $this->login();
                $this->res = array();
        }

        function lookup_sid() {
                // bad coding, but variable variables doesnt't work on superglobals like $_POST..
                if(strlen($_GET["sid"]) == $this->cfg["sid_howlong"]) {
                        return $_GET["sid"];
                }else{
                        if(strlen($_POST["sid"]) == $this->cfg["sid_howlong"]) {
                                return $_POST["sid"];
                        }else{
                                if(strlen($_COOKIE["sid"]) == $this->cfg["sid_howlong"]) {
                                        return $_COOKIE["sid"];
                                }else{
                                        return false;
                                }
                        }
                }
        }

        /* *******************************************************************************************
        session creating, etc..
        */

        function open_session($sqlquery) {
                $this->sqlquery $sqlquery;
                $this->sid $this->get_hashy();
                return true;
        }

        function resume_session() {
                $query $this->complete_sql("SELECT `".$this->fname("autoid")."` FROM `{$this->cfg["db_table"]}` WHERE `".$this->fname("sid")."`='{$this->sid}'");
                $rs mysql_query($query);
                if(mysql_num_rows($rs) != 0) {
                        $this->logged_in true;
                        $this->var_load();
                        $this->give_lifetime();
                        return true;
                        $rs null;
                } else {
                        $this->timeout();
                }

        }

        function login() {
                /*
                * If you pass a SQL statement to open a session, you have to call this function to check
                * the query. Make a if($ses->login()) over it.
                * Returns true if the query returns more than 0 row, otherwise false.
                */

                if($this->logged_in == false) {
                        $this->data = array();
                        if($this->sqlquery != $this->cfg["placeholder"]) {
                                if(strtolower(substr($this->sqlquery,0,6)) != "select"$this->perror("Invalid call to login(). Pass SELECT statements only.");
                                $rs mysql_query($this->sqlquery);
                                if(mysql_num_rows($rs) == 0) {
                                        $makeit false;
                                } else {
                                        $makeit true;
                                        $resi mysql_fetch_array($rs);
                                        $rs null;
                                }
                        } else {
                                $makeit true;
                        }

                        if($makeit == true) {
                                if(($this->session_create($this->sid))==true) {
                                        $this->logged_in true;
                                        $this->var_set($resi);
                                        //$this->var_save();
                                        if($this->cfg["use_cookies"]) $this->send_cookie();
                                        return true;
                                } else {
                                        return false;
                                }
                        } else {
                                return false;
                        }
                } else {
                        return true;
                }
        }

        function session_create($sid) {
                $this->datavarset( array(
                "SESSION_START" => (time()),
                "SESSION_EXPIRE" => ((time())+(60*$this->cfg["session_howlong"])),
                "SESSION_STRID" => ($this->get_strid()),
                "SESSION_QUERIES" => array(),
                "SID" => $sid
                ));
                $rs mysql_query("INSERT INTO `{$this->cfg["db_table"]}` (`".$this->fname("sid")."`, `".$this->fname("opened")."`, `".$this->fname("expire")."`, `".$this->fname("addr")."`) VALUES ('{$sid}', '{$this->data["SESSION_START"]}', '{$this->data["SESSION_EXPIRE"]}', '".($this->get_strid())."');");
                if(mysql_affected_rows()==0$this->perror("DB error, could not insert new session row");
                else return true;
        }

        function session_close() {
                mysql_query(($this->complete_sql("UPDATE `{$this->cfg["db_table"]}` SET `".$this->fname("expire")."`=100 WHERE `".$this->fname("sid")."`='{$this->sid}'")));
                return $this->session_table_cleanup();
        }

        // lazy people like me make function for everything.. returns defined table name
        function fname($name) {
                if(isset($this->cfg["tfields"][$name])) return $this->cfg["tfields"][$name];
                else $this->perror("Invalid internal call! Didn't find a table field name...");
        }

        /* *******************************************************************************************
        session timing stuff
        */

        function session_table_cleanup() {
                /*
                * Deletes all outdated sessions from the table
                */
                mysql_query("DELETE FROM `{$this->cfg["db_table"]}` WHERE (`".$this->fname("expire")."` < ".(time()).");");
                return true;
        }

        function give_lifetime() {
                $this->data["SESSION_EXPIRE"] = (time()+(60*$this->cfg["session_howlong"]));
                mysql_query(($this->complete_sql("UPDATE `{$this->cfg["db_table"]}` SET `".$this->fname("expire")."`={$this->data["SESSION_EXPIRE"]} WHERE `".$this->fname("sid")."`='{$this->sid}'")));

                $this->set_cookie$timy );
                if(mysql_affected_rows() > 0) {
                        if($this->cfg["use_cookies"]) $this->set_cookie$this->data["SESSION_EXPIRE"] );
                        return $this->data["SESSION_EXPIRE"];
                }else{
                        return false;
                }
        }

        function timeout() {
                if($this->cfg["timeout_action"] == "redir"header("Location: {$this->cfg["timeoutpage"]}");
                else $this->perror("Session could not be established.");
        }

        /* *******************************************************************************************
        session variable stuff
        */

        // returns a session variable/query
        function var_get($name$number false) {
                if( $this->logged_in() ) {
                        if( $this->is_sessionquery$name ) ) {
                                if($number) return $this->data[$name][$number];
                                else return $this->next($name);
                        } else {
                                if(strlen($this->data[$name]) != 0) return $this->data[$name];
                                else return "";
                        }
                }
        }

        // sets a variable value
        function var_set($name$value ""$save true) {
                if($this->logged_in()) {
                        if(is_array($name)) {
                                foreach($name as $key=>$val) {
                                        if(strlen($key)>&& strlen($val)>0$this->var_set($key,$val,false);
                                }
                                $this->var_save();
                        }else{
                                $this->data[$name] = $value;
                                if($save$this->var_save();
                        }
                }else{
                        return false;
                }
        }

        // unsets ("deletes") a variable
        function var_unset($name) {
                if($this->logged_in()) {
                        if($this->is_sessionquery($name)) $this->data["SESSION_QUERIES"][$name] = null;
                        if(isset($this->data[$name])) unset($this->data[$name]);
                        return $this->var_save();
                }
        }

        // private; saves data to db table
        function var_save() {
                $this->data["cfg"] = $this->cfg;
                $tosave addslashes(serialize($this->data));
                $query $this->complete_sql("UPDATE `{$this->cfg["db_table"]}` SET ".$this->fname("data")."='{$tosave}' WHERE `".$this->fname("sid")."`='{$this->sid}'");
                $rs mysql_query($query);
                if(mysql_affected_rows()!=0) return true;
                else return false;
        }

        // private; loads data from db table
        function var_load() {
                $query $this->complete_sql("SELECT * FROM `{$this->cfg["db_table"]}` WHERE `".$this->fname("sid")."`='{$this->sid}'");
                $rs mysql_query($query);
                if(mysql_num_rows($rs)!=0) {
                        $resi mysql_fetch_array($rs);
                        $data stripslashes($resi["data"]);
                        $data unserialize($data);
                        $this->data $data;
                        $this->cfg $this->data["cfg"];
                        return true;
                } else {
                        return false;
                }
        }

        // abandoned as of release 1.7
        function rs2session(&$obj_recordset) {
                return false;
        }

        // private; internal way to set a variable group. this and the one below should be cleaned out..
        function datavarset($name$val "") {
                if(is_array($name)) {
                        foreach($name as $key=>$rval) {
                                $this->datavarset_single($key$rval);
                        }
                }else{
                        $this->datavarset_single($name$val);
                }
        }

        // private; single variable setting..
        function datavarset_single($name$val) {
                $this->data[$name] = $val;
        }

        /* *******************************************************************************************
        session queries
        */

        // sets/opens a session query - see the doc
        function sql2session($name$select_statement) {
                $data = array();
                $rs mysql_query($select_statement);

                if(mysql_num_rows($rs) != 0) {
                        while($resi mysql_fetch_array($rs)) {
                                $data[] = $resi;
                        }
                }

                $this->data[$name] = $data;
                $this->definequery($name);
                $this->var_save();

                $rs null;
                return true;
        }

        // returns next row of a session query
        function next($name) {
                if($this->is_sessionquery($name)) {
                        $return $this->data[$name][$this->data["SESSION_QUERIES"][$name]];
                        if($this->data["SESSION_QUERIES"][$name] < count($this->data[$name])+1) {
                                $this->data["SESSION_QUERIES"][$name]++;
                                $this->var_save();
                        }else{
                                $return false;
                        }
                        return $return;
                }else{
                        return false;
                }
        }

        // returns the number of element that a session query holds
        function count($name) {
                if($this->is_sessionquery($name)) return count($this->data[$name]);
                else return false;
        }

        // returns an entire content of a session query
        function sq_get($name) {
                if($this->is_sessionquery($name)) return $this->data[$name];
                else return false;
        }

        // resets a session query
        function reset($name) {
                return $this->definequery($name);
        }

        // private; "registers" a variable as a session query [V1.5]
        function definequery($name) {
                $this->data["SESSION_QUERIES"][$name] = (int)0;
                return true;
        }

        // private; check function
        function is_sessionquery($name) {
                if(array_key_exists($name,$this->data["SESSION_QUERIES"])) return true;
                else return false;
        }

        /* *******************************************************************************************
        cookies
        */

        // private; sends a cookie
        function send_cookie() {
                setcookie "sid"$this->sidtime() + ( 60 $this->cfg["session_howlong"] ), "/" );
        }

        // private; sends cookie with variable time
        function set_cookie$expire ) {
                setcookie "sid"$this->sid$expire"/" );
        }

        // private; deletes the sid cookie
        function del_cookies$all false ) {
                setcookie "sid"""time()-3000"/" );
        }

        /* *******************************************************************************************
        strings
        */

        // returns html link with session id; customizable
        function get_link($document$text ""$target ""$qstring ""$getsid true) {
                if($getsid == true) {
                        $sid "?sid=".$this->data["SID"];
                        $sid .= "&";
                } else {
                        $sid "?";
                }
                if(strlen($target) != 0) {
                        $target " target=\"{$target}\"";
                }
                return "<a href=\"{$document}{$sid}{$qstring}\"{$target}>{$text}</a>";
        }

        // returns the current session id
        function get_sid() {
                return $this->sid;
        }

        // gets string for inclusion in query string
        function get_querystring() {
                return "sid=".$this->sid;
        }

        // gets html for input hidden field with the sid (or other values) for inclusion in web forms
        function get_hiddenfield($name ""$value "") {
                if(strlen($name) == 0) {
                        $name "sid";
                        $value $this->sid;
                }
                return "<input type=\"hidden\" name=\"{$name}\" value=\"{$value}\">";
        }

        // returns a random string
        function get_hashy() {
                srand ((float) microtime() * 10000000);
                return substr(md5(rand(0,9999999)),0,$this->cfg["sid_howlong"]);
        }

        // returns the "strid" string, see the doc V1.5
        function get_strid() {
                if($this->cfg["use_addr"] == true) {
                        $vals = array("REMOTE_ADDR","HTTP_USER_AGENT","HTTP_VIA");
                        foreach($vals as $val$strid .= $_SERVER[$val];
                        return md5($strid);
                }elseif($this->cfg["use_addr"] == "old") {
                        return $_SERVER["REMOTE_ADDR"];
                }else{
                        return "";
                }
        }

        /* *******************************************************************************************
        misc
        */

        // changes conf option during session
        function set_option($setting$value) {
                if(array_key_exists($setting,$this->cfg) == TRUE && $setting != "sid_howlong") {
                        $this->cfg[$setting] = $value;
                        $this->var_save();
                        return true;
                } else {
                        return false;
                }
        }

        // kept for compatibility (<-- difficult word)
        function set_timeoutpage($value) {
                return $this->set_option("timeoutpage",$value);
        }

        // private; completes queries
        function complete_sql($value) {
                return $this->return_sql("{$value} AND `".$this->fname("addr")."`='".($this->get_strid())."'");
        }

        // private; returns sql
        function return_sql($value) {
                if(strtolower(substr($value,0,6)) == "update") return "{$value};";
                else return "{$value} LIMIT 0,1;";
        }

        // prints out arrays in a nice way in browsers..
        function p_array($arr$pre true) {
                if(is_array($arr)) {
                        if($pre == true$ins = array("<code>","</code><br>\n","");
                        else $ins = array("","","\t");
                        $backy "{$ins[0]}Array (\n";
                        foreach($arr as $key=>$value) {
                                $value $this->p_array_returnval($value);
                                $backy .= "{$ins[2]}[{$key}] =&gt; {$value}\n";
                        }
                        $backy .= ");{$ins[1]}";
                        return $backy;
                } else {
                        return false;
                }
        }

        // subfunction for recursion..
        function p_array_returnval($value) {
                if(is_array($value)) return $this->p_array($value,false);
                else return $value;
        }

        // prints config
        function p_cfg() {
                echo $this->p_array($this->cfg);
        }

        /* *******************************************************************************************
        error stuff
        */

        // prints out error & dies ;(
        function perror($errormsg) {
                echo "<b>Error orcurred:</b>&nbsp;{$errormsg}\n";
                die;
        }

        // tells if user is "logged in" - if session exists
        function logged_in() {
                if($this->sqlquery != $this->cfg["placeholder"] AND $this->logged_in == false$this->perror("Session is not created. Call login() before trying to execute other session functions.");
                else return true;
        }

}

?>
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox