PHP:SessionaraDocumentation

From xbe wiki

Jump to: navigation, search

Contents

[edit] Introduction

[edit] What is Sessionara?

Before this release, I described Sessionara as a class for "Session management with MySQL". But actually it's more, it's a "session based data environment with MySQL". This class enables you to open a virtual session (identified by an unique session ID), then set and access variables in this environment. If you pass the session ID within multiple pages (via GET/POST parameters), then you get an easy and powerful way to pass values between various pages. Taking this, the possibilities are only limited by your imagination ;-)

The class also includes good string functions and brings session handling together with some nice database functions. It enables you to query the MySQL server one time, store the entire result rows in the session and then looping through your records inside the class without fetching the same content from MySQL again.

Within this release the class is even more powerful. The "session queries" finally work like a charm and we've got an optional cookie support than can be enabled.

[edit] Reasons for Version 1.7

I was very lazy. I mean, a lot of folks sent me comments, suggestions and even really useful bugfixes for Sessionara and I didn't find the time to release a new version which fixes some ugly bugs that 1.5 had. So now i come out with a fresh new release with (hopefully) less to none bugs. 1.7 is a kind of bugfixing release but also introduces some new functions.

As you noticed, the downloadable Version of 1.5 had some serious bugs: the session time calculation wasn't pefect, the session queries didn't work at all (as far I know), some bad typos, and so on. Version 1.7 fixes all this and I really like to say sorry to all the people that sent me stuff - a year after the last release I finally did the incredible step to put something out ;-). I also hope for your continous support if you find something in this release.

[edit] Improvements

Sessionara made a long way to that what it is today. This 1.7 release fixes alot:

  • Fixed the sick session give_lifetime() bug
  • Finally, the session queries are fully working. All issues resolved (well, I hope so).
  • New optional cookie support. If enabled, you don't have to pass the SID through GET/POST anymore, the class handles that transparently.

[edit] Upgrading

If you want to upgrade from an older release, nothing really changes. Replace the older file with the new one. But if you enable the Strid functionality, you have to apply the following command on your Sessionara MySQL table:

ALTER TABLE `foo_sessions` CHANGE `addr` `addr` VARCHAR(100) NOT NULL;

Replace "foo_sessions" with your table name, you'll also find this in the file upgrade.sql. If you have access to a tool like PHPMyAdmin, use it. Just go to the table and change the field length to 100. The newer version needs more than 20 characters, the value given in the older releases.

[edit] License

Not much to say about that, Sessionara is released unter the GNU GPL.

[edit] Install and configure

[edit] Create table

Sessionara needs a MySQL table in order to operate. So I think you should create this table? ;-) Ah yes, you can name the table the way you like. It doesn't matter as you will specify the table name later.. The command is:

CREATE TABLE foo_sessions (
autoid int(11) NOT NULL auto_increment,
sid varchar(100) NOT NULL default ,
data text NOT NULL,
addr varchar(100) NOT NULL default ,
opened int(14) default NULL,
expire int(14) default NULL,
PRIMARY KEY (autoid)
) TYPE=MyISAM;

You can also find this command in the setup.sql file in the package.

[edit] Configure the class

Open the class file (session.inc.php) in a text editor (I'll recommend vi), skip the upper license part and go to the start of the class. You'll find a line with **** configuration ****, that's the beginning of the conf section. This is the class array $cfg filled with various settings which influence the class' behaviour.

The class works great with the default values, keep an eye on the db_table value, which specifies the class' MySQL table. You have to set your table name there in order to use it. It will not be capable of inserting rows into a table that isn't specified ;-)

Here is a little description of each configuration directive "name (type [default value])":

sid_howlong (int [26]) 
Generated $sid's string length. Set to whatever you want ;-)
session_howlong (int [10]) 
Session lifetime in minutes
db_table (string ["foo_sessions"]) 
Class' MySQL table name
timeout_action (string ["redir"|"error"])) 
Specifies what the class should do in the case of an expired or invalid session. Valid values are "redir" and "error". "redir" sends a location header to the client, redirecting him to the page specified in $cfg~["timeoutpage"]. "error" shouts out an error message and dies. ~[V1.5]
timeoutpage (string ["index.php"]) 
In the case of an expired or invalid session, we'll send the user to this location.
placeholder (string ["W/MYSQL"]) 
Keyword to pass if you don't pass a SQL select statement.
use_cookies ([bool [false]) 
If set to true, Sessionara automatically sends a cookie to the client at object construction time. It is really the same as you work with GET/POST, but you don't have to care about passing the SID from page to page anymore - that's work that the class does now.
use_addr (bool [false]) 
Lets you choose if you want to use the Strid functionality. Possible values are the booleans true and false or the string "old". true will use it, false doesn't use any security mechanism and "old" uses the older approach, saving the plain IP address of the user.
tfields (array) 
[Introduced in Version 1.7-r1] This array inside the configuration directive defines the names of the MySQL table fields the class uses. Maybe you use Sessionara inside a project where your complete database layout follows a naming convention, so in this case it can be usefull to have this possibility. If you don't care about that, just leave this array as it is ;-)

[edit] Include

To actually use the class, just include the session.inc.php file in your document. Also needed is a file which opens a MySQL connection. If you work with MySQL, you'l have something like a connection.php or conn.php, include that before the class itself.

Would look like this:

<?php

include("connection.php");
include("session.inc.php");
 // ** your normal php code here..

?>

Also be sure that you have *no browser output* (HTML or a echo command) before the class include and instanciating. This is why Sessionara will send a HTTP Location header to the user in case of a expired or invalid session. And such headers shout out errors when output was sent to the user before.

[edit] Some features in depth

[edit] Session concept

[edit] Creating a session

Currently you've got two possibilities to create a Sessionara session. One is good if you're realizing an admin area-like project, the other method fits everytime and is easier to use. Let's examine the two ways..

Open with SQL SELECT statement

Imagine you make an admin area where the user logs in with his username/password pair. In this case you will make anyway a query like "select * from users where username='$user' and pw='$pw';=". You have to do this anyway to check if the user exists in the database. You then check if the query returns more then 0 records, if yes, the user exists. Good, but now Sessionara will take care of this. Look at this code snippet:

<?php

$query "SELECT * from `users` where `username`='$username' and `pw`='$pw';";
$s = new Sessionara($query);
if($s->login()) {
   echo "login ok! session id: ".$s->get_sid();
} else {
   echo "login failed!";
}

?>

Explanation: First we define a SQL query including the data the user entered ($username and $pw). We pass that statement directly to the class when creating a new instance of it. After that, we call the login() function to check if the record exists. This function is made for exactly this purpose, as it returns true if the prior passed statement returns more than 0 rows. So if login() returns true, the user exists and has entered the correct login information. Remember that you can pass any SELECT statement, as long it serves you and returns more than 0 rows if you need it. You can't continue using the class if login() returns false.

Open with keyword

You also can open an instance with the keyword specified in $cfg["placeholder"], the default value is "W/MYSQL". This is easier and doesn't need any special checks. Example:

<?php

$s = new Sessionara("W/MYSQL");
echo "Opened a new session with ID ";
echo $s->get_sid();

?>

Really simple way to get a new session. Since this release you don't have to call login() here anymore.

[edit] Resuming a session

It's easy to resume a session. If you call the constructor of the class without any arguments, the default action is "try to resume a session". To successfully resume a session, a POST/GET variable named $sid has to be defined. If you have opened a session before, just assure that you pass the session's ID either via GET (in a link, i.e. doc.php?sid=xxd3) or via POST (a hidden field in a form with POST method set) to the next page. If this is done, it's easy..

<?php

$s = new Sessionara();
echo $s->var_get("username");

?>

You just can create the instance without any parameters. If the session ID could not be resolved, is invalid, or isn't set, the class redirects to the $cfg["timeoutpage"] URI.

[edit] Autovarsets

The result of your initial SQL query (to open a session), if you use it, will be automatically set as session variables. Notice that only one result row will be added to the session. To use queries with multiple result rows, see #Session_queries.

See this snippet to understand the meaning of Autovarsets:

<?php

$s = new Sessionara("select auto_id, last_login, last_browser from users where username='$user' and pw='$pw';");
if($s->login()) {
   // login successfull, put out prior results.. (from SQL query)
   echo $s->var_get("auto_id");
   echo $s->var_get("last_login")." ".$s->var_get("last_browser");
} else {
   echo "bad login!";
}

?>

As you can see, after passing the specified select statement to the constructor (line 1), you can directly access those values like you do it with normal session variables.

[edit] Session queries

Session queries are the results from a SQL select statement stored inside the session. This functionality is very flexible, as all result rows are stored one time to the session. You can access the session queries the same way you access normal session variables, you can loop through them, etc. It's basically a special way of session variables. Session queries have a counter which is also stored in the session. If you don't loop through your entire result set, the counter will be saved there and you can continue to loop later.

The advantage of session queries is, that you don't have to bother the MySQL server everytime with a special query. It's always usefull if you need the result(s) of a particular query over various pages.

To visualize the possibilities, let's imagine a sample scenario: We have a simple MySQL table "employees" with two fields: "Name" and "City". Let's assume this table defines our employees. We have also a bunch of php scripts forming a "member area" for your employees. You need to display the employee list on every page, so you define a session query for that ;-) Our php scripts are named index.php (entry page), page1.php, page2.php and so on..

<?php

// --- index.php --- //
$s = new Sessionara("W/MYSQL"); // instance without initial sql query; easier
// now, let's define the session query
$s->sql2session("employees","select Name, City from employees order by Name;");

?>

After we defined such a session query through the sql2session() function, we are able to loop through the results of that query at every moment we wish. We'll do that now on another page of the member area. We assume that we have passed the session ID to this other page in order to resume the session.

<?php

// --- page1.php --- (or any other page) //
$s = new Sessionara(); // session resuming
// let's loop ;-)
while($data $s->next("employees")) {
   echo $data["Name"]." lives in ".$data["City"];
}

?>

As you see, the next() function returns a result array (identical to that one you would get from mysql_fetch_array()!). With every call of next() you get the next element of your results. next() also increments the internal counter. As mentioned, if you stop to loop (you can do that at any time), you need to call reset() first to be able to loop through your results from the beginning.

[edit] Strid's (Security)

After the last release, some attempts were made to integrate more security into the class. A nice comment from a user on the page brought light into the tunnel, so we integrated this new feature. Now we don't identify a user solely by his IP, we take some identifying information together, form one string, hash (md5) this one and save this hash to the database.

In our tests, this technique is really reliable and confident. We never had a case when one user had two different strid's during one session. An exception are networks configured with "load balancing", where a request from a user can be go through various proxies with different IPs. Why is this good?

Because if you use it, no one can "steal" a session anymore until he has exact the same browser and comes through the same proxy. This is really rare and will not happen so fast ;) So it's clearly a boost in terms of security.

We will try to increase the level of security in the coming releases, but it will be hard (without cookies). This is really a clean and good approach and we recommend to enable it if you need more security than nothing ;-)

Note: This feature is not enabled by default. You have to change the value of the config parameter use_addr to true to use it. And you have to make the addr field longer in the database, mentioned here.

[edit] Cookie Support

Since version 1.7, you can enable an optional cookie support by setting the corresponding configure directive to true. That's really the only thing you have to do, just modify the class file by setting this to =true= and then the class will handle the SID stuff through cookies - you don't have to care about passing the SID anymore.

[edit] Function reference

This function reference doesn't feature _all_ functions. There are some functions which are thought for internal calling only, so we don't list them here. Take a look at the source to see all functions ;-). Functions with the note "~[private!]" are also thought for internal calling, but you _could_ call them from outside. Generic

public Sessionara([string $sqlquery = ""])
The Constructor. PHP automatically executes this function on instanciating the class. When creating a new session, you've got two options what parameter to pass (value of $sqlquery):
  • Pass a SQL SELECT statement
    Doing so, Sessionara can "check" this SQL query. Read this section for further information on this. After passing a SQL query, you have to call the login() function to really create the session.
  • Pass the placeholder
    The placeholder is the string you specified here in $cfg["placeholder"]. This way no query needs to be checked, you get your session immediatelly. Since V1.5 (this release) you don't have to call the login() function anymore if you pass the placeholder.
If you want to resume an existing session, you don't have to specify any parameter. Read this section.
public login()
This function creates the session and creates the table row. You have to call this function if you pass a SQL statement on opening a session. If you work with the placeholder, the function gets called automatically. This function returns true if the passed SQL statement results in more than 0 (zero) rows. Otherwise, false is returned. Read this for more information.
public session_close()
Call this if you want to close your current session. You don't have to call that, the class removes all expired sessions automatically. If you don't want to wait until a session is expired, call this one.
private session_table_cleanup()
Automatically called with every instance creation, this function deletes all expired sessions from the database.
private timeout()
Causes the class to do whatever happens in a case of timeout or if someone tries to resume an invalid session. You can specify the timeout_action in the directive in the $cfg array.

[edit] Variables

public var_get(string $name)
Returns the value of session variable $name. As of Sessionara 1.7, if $name is a defined session query, this function returns the 'next' row of the session query, incremeting the internal counter.
public var_set(string $name, mixed $value)
Set the variable $name to value $value. $value can be any variable type, from string over arrays to objects.
New in Sessionara 1.7: If $name is an array, $value will be ignored. $name is expected as $key => $value association, where $key is the name of the variable and $value it's value to set.
Example:
$ses->var_set("foo","bar"); // sets variable "foo" with value "bar"
$ses->var_set( array("foo"=>"bar","jimmy"=>"the cow") ); // sets *two* variables, "foo" with value "bar" and "jimmy" with value "the cow"
public var_unset(string $name)
Unsets (removes) variable $name from the database.
public sql2session(string $name, string $select_statement)
See here

[edit] Strings

public get_link(string $document, string $text = "", string $target = "", string $qstring = "", bool $getsid = true)
This function returns a HTML <a> tag. The tag links to the file $document, has the linktext (text between <a></a>) $text and target $target. As long $getsid is true, the function attaches the session-id to the link (that is the comfortable point). $qstring is a string which should be attached after the session-id in the link's query string (i.e. other needed parameters).
Example:
$user = $s->var_get("username");
echo $s->get_link("index.php", "overview", "", "user={$user}&cat=2");
Output:
<a href="index.php?sid=s35sfggc3s&user=fran&cat=2">overview</a>
public get_sid()
Returns the actual session ID (sid). You can call this directly after creating the instance, even before calling login().
public get_querystring()
Call this if you need the session ID as a query string parameter for linking to a file. The values are already urlencoded.
Example output:
sid=s35sfggc3sddfdf3ds
public get_hiddenfield(string $name = "", string $value = "")
Returns a HTML <input> tag. Precisely a hidden field. This is useful to include it in forms. If you want to resume a session after a POST by the user, you'll need to pass the session ID, easy done with a hidden field.
Example:
echo $s->get_hiddenfield();
echo $s->get_hiddenfield("newfield", "whattavalue");
Output:
<input type="hidden" name="sid" value="sk342Xa3852Mnx1@d">
<input type="hidden" name="newfield" value="whattavalue">
private get_hashy()
This function generates the session ID. If you call this method during runtime, the function returns a new randomly generated ID, not the current session ID!
public get_strid()
Returns the host specific strid. Read this to learn what a strid is.

[edit] Session queries

You should already know what this is, read this for more information.

public sql2session(string $name, string $select_statement)
Defines a new session query saved under the name $name (you access the query through that name later). The content of the query is defined by the returned rows from the string $select_statement. That can be any valid SQL select statement that returns something using the current database connection.
public next(string $name)
Main function for looping through a session query, as it increases the counter and then returns the actual element (an array) via var_get(). Returns false if there is no more element to return (reached the end, EOF). Then you need to call reset() again.
public count(string $name)
Returns the number of elements that the session query $name holds. [V1.7]
public reset(string $name)
Resets the counter of the session query $name. After that you can loop again through the entire session query.

[edit] Misc

public set_option(string $setting, string $value)
Lets you override your settings in $cfg during runtime. You can change all value
Personal tools