This article describes how to customize PHP4 session processing. We provide an example of how to write a full-featured mysql database or DBM file.
First, preamble
The new PHP4 has a set of its own session processing functions. By default, each session stores in a separate file in the system temporary directory (for example, in the UNIX system).
This is suitable for or is not suitable, and it is based on your needs. For example: If your support of the PHP web server is distributed on a different machine, you can't easily share the session between them (of course, you can also save the sessions in NFS sharing). Another potential problem is that thousands or millions of session files on your machine make your file system scattered.
Fortunately, PHP4 developers are very vision (thank them), they provide you with users such as extended session processing interfaces.
This document explains the processing of a SESSION and provides two examples that can extend the session processing. Our first example will make the Session handler to save the session data into the DBM file. Our second example will save the session data into the MySQL database.
Before you start, please download Ying20000602.zip and unconfigure it to the web document directory. (I have already taken it in the end of this article)
Any SESSION handler we wrote will provide 6 basic functions that will be called by the PHP4 session handler, so you don't have to worry about calling them.
Fortunately, these customization session functions are completely transparent to you. So you can change them without affecting your own PHP scripts.
These functions are:
SESS_OPEN ($ sess_path, $ session_name);
This function is initialized by the SESSION handler. Two parameters that need to be passed are $ sess_path, which corresponds to the session.save_path option in your php.ini file; $ session_name, it corresponds to the session.name option in php.ini. How do they work, please see the example below.
sess_close ();
This function is called at the end of the page and the Session handler needs to be turned off. (Note, don't confuse the sess_destory, it is used to end session)
SESS_READ ($ Key);
This function reads the specified session key value ($ key) in the Session handler.
This function retrieves and returns Session data identified as $ key. (Note: You don't have to worry about how to serialize and reverse sequence data, if you don't know what this means, don't worry about it)
Translator Note: Serialization is to save variables or objects to files when the program is over or needed, and then transfer to memory in the next program runs or needs to be stored.
SESS_WRITE ($ KEY, $ VAL);
This letter data needs to be called when the SESSION handler needs to save data, which often occurs at the end of your program.
It is responsible for saving the data next time you can retrieve in the SESS_READ ($ Key) function.
SESS_DESTROY ($ Key);
This function is destroyed when it is destroyed. It is responsible for deleting the session and clears the environment.
SESS_GC ($ MaxLifetime);
This function is responsible for cleaning fragments. In this case, it is responsible for deleting outdated session data. The Session handler will occasionally call them.
Now we have clearly appointed our function. They are not named, but they must accept these parameters. (Whether you need them, you need them)
DBM session handler
Our first example is to write a custom session handler that saves session data into the DBM file. (This is a session_dbm.php file in ying20000602.zip)
There are a lot of sufficient reasons to make you do this, for example, if you have a shared server in ISP (the translation: equivalent to the virtual host we say) and you don't want your session data
It is mixed with others.
Important Note:
Your PHP4 must have DBM support when you test these programs. If this is not the case (the translation: If there is no DBM support) will be difficult, it is really difficult! These work we have to do will get a DBM file for all session data. (In case you don't know, the DBM file is like a very simple database that only saves the "key / value".
Implemented by 6 letter data:
SESS_OPEN ($ sess_path, $ session_name);
We will call dbmopen () open a DBM file in the read and write mode. Our DBM file will be named / TMP / PHPSESSID unless you have modified the session road in php.ini.
Vault and name setting.
sess_close ();
In this function, we will simply call the dbmclose () function to close the DBM file.
SESS_READ ($ Key);
Here we only call DBMFETCH () load and parameter $ key related session data.
When loading a session, we need to guarantee that reading is not an expired data, so we must give the session a time tag.
why? Because they fail, no matter what the reason is not deleted, we will not accidentally read expired data. This will be a big taboo.
We know that the DBM file only saves the key / value pair, so it has to be written together when writing Session data, and removes when reading the session data.
Any expired session will be ignored. Take a look at this source, it will make you clearer.
SESS_WRITE ($ KEY, $ VAL);
Write a session and we will use the dbmreplace () function. Note that we have to save the expiration time marker from the previous SESSION, so we have to tab to the value.
SESS_DESTROY ($ Key);
Destruction is easy, we only need to call the dbmdelete () function to remove it from the session file.
SESS_GC ($ MaxLifetime);
Expiral data collection is a bit annoying here, but it is necessary, in order to achieve the purpose we scan all SESSIONs saved in the DBM file in the loop and delete expiration. This will be very slow
Cycate all Session data saved in this file by all SESSION data stored in this file.
Now we already have a DBM Session handler, it's too cool!
Now we let these sessions saved to the MySQL database.
MySQL session handler
(This
Our next example is to write a custom session handler that stores the Session data to the MySQL database. (This is in the session_mysql.php file, see the end of the article)
You have a lot of servers that support PHP and you need to share the sessions between you want to save the session in the database. (For example, you serve many users and need
Load balance)
You Have a Bunch of Machines Doing Web / PHP stuff, a Machine Serving
You have a batch of machines that support PHP, you need a machine to make your normal database server, and another running MySQL database handles session. Only for most people
It is very killing. :) (Translation: It may mean too cool)
important hint:
Your PHP must support MySQL before you experiment. (Translation: This seems to be no problem, PHP has now built mysql support) If this is not this, things will be very ugly, really
very ugly.
First we create a session database in MySQL and create a session table. First run your MySQL client and run the following command:
Mysql> CREATE DATABASE sessions;
Mysql> Grant SELECT, INSERT, UPDATE, DELETE ON Sessions. * to phpsession @ localhost-> identified by 'phpsession'
Mysql> Create Table sessions
-> sesskey char (32) Not null,
-> EXPIRY INT (11) Unsigned Not Null,
-> Value Text Not Null,
-> Primary Key (sesskey)
->);
Next, modify the $ sess_db * variable of the session_mysql.php file makes it match the database settings on your machine. Before you continue, I am sure that everything looks good.
Our six functions rely on MySQL database work:
SESS_OPEN ($ sess_path, $ session_name);
We need to call mysql_pconnect (), then select the session database with mysql_selsect_db (). $ sess_path and $ session_name parameters
Nothing, but we have to retain them. (Translation: The original, it may be compatible)
sess_close ();
We want to open a MySQL permanent connection so we don't do anything in this function. (An empty function)
SESS_READ ($ Key);
This trick is a simple SELECT statement. We want to read the Session data given to the $ key, you need to specify expired time information.
SESS_WRITE ($ KEY, $ VAL);
Write session data for a small trick. We first try to save the session data into the database with an insert statement. If the failure (primary key constraint) means this key has been written, then we
Have to use an UPDATE statement instead.
SESS_DESTROY ($ Key);
Deleting a session is easy, we only need to delete this key value from the database.
SESS_GC ($ MaxLifetime);
It is also easy to deal with expired session, we only need to remove expired session () from the database.
As ending this small tutorial, I hope that you have a good feeling when you extend PHP4.
This example is just a simple demonstration of how you can extend them to adapt to your needs, if you find what bug, please let me know :)
FAQ:
If you are worried about the session file in / tmp directory confused, you just save them elsewhere.
That's why there is a session.save_path option.
If you are worried about performance, you can consider putting the session in shared memory. You only need to add MM support when compiling PHP and specify sessio.save_handler as mm
In .htaccess, php.ini or httpd.conf.
I feel that only multiple machines want to save session when they use the database.
(The last sentence is not translated, you have seen it)
session_dbm.php
============================================================================================================================================================================================================= =====================================================================================================================================================
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------
* session_dbm.php
* ------------------------------------------------- -----------------------
* PHP4 DBM Session Handler
* Version 1.00
* by ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ------------------------------------------------- -----------------------
* TERMS OF USAGE:
* ------------------------------------------------- -----------------------
* You are free to use this library in any way you want, no warranties are
* Expressed or Implied. this works for me, but I don't guarance at it
* Works for you, use at your own risk.
*
* While Not Required to Do So, I Would Appreciate IT IF you Would Retain
* this header information. if you make any modifications or improvements,
Please Send the Via Email to Ying Zhang
*
* ------------------------------------------------- -----------------------
* DESCRIPTION:
* ------------------------------------------------- -----------------------
* This library tells the php4 session handler to write to a dbm file
* INSTEAD OF CREANG INDIVIDUAL FILES for Each Session.
*
* ------------------------------------------------- -----------------------
* Installation:
* ------------------------------------------------- -----------------------
* Make Sure You Have DBM Support Compiled INTO PHP4. THEN COPY THIS
* Script to a directory That Is Accessible by the rest of your php
* Scripts.
*
* ------------------------------------------------- -----------------------
* USAGE:
* ------------------------------------------------- -----------------------
* Include this file in your scripts before you call session_start (), you
* Don't have to do anything special after this. * /
$ Sess_dbm = "";
$ Sess_life = GET_CFG_VAR ("session.gc_maxlifetime);
Function sess_open ($ save_path, $ session_name) {
GLOBAL $ sess_dbm;
$ Sess_dbm = dbmopen ("$ save_path / $ session_name", "c");
Return ($ sess_dbm);
}
Function sess_close () {
GLOBAL $ sess_dbm;
DBMClose ($ sess_dbm);
Return True;
}
Function sess_read ($ key) {
GLOBAL $ sess_dbm, $ sess_life;
$ VAR = "";
IF ($ TMP = DBMFETCH ($ sess_dbm, $ key)) {
$ expires_at = Substr ($ TMP, 0, STRPOS ($ TMP, "|"));
IF ($ expiRES_AT> time ()) {
$ VAR = SUBSTR ($ TMP, STRPOS ($ TMP, "|") 1);
}
}
Return $ VAR;
}
Function sess_write ($ key, $ val) {
GLOBAL $ sess_dbm, $ sess_life;
DBMREPLACE ($ sess_dbm, $ key, time () $ sess_life. "|". $ val);
Return True;
}
Function sess_destroy ($ key) {
GLOBAL $ sess_dbm;
DBMDELETE ($ sess_dbm, $ key);
Return True;
}
Function sess_gc ($ maxlifetime) {
GLOBAL $ sess_dbm;
$ now = Time ();
$ key = dbmfirstkey ($ sess_dbm);
While ($ key) {
IF ($ TMP = DBMFETCH ($ sess_dbm, $ key)) {
$ expires_at = Substr ($ TMP, 0, STRPOS ($ TMP, "|"));
IF ($ now> $ evires_at) {
SESS_DESTROY ($ Key);
}
}
$ key = dbmnextKey ($ sess_dbm, $ key);
}
}
Session_set_save_handler
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy",
"sess_gc");
?>
============================================================================================================================================================================================================= ========================================== session_mysql.php
============================================================================================================================================================================================================= =====================================
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------
* session_mysql.php
* ------------------------------------------------- -----------------------
* Php4 mysql session handler
* Version 1.00
* by ying@zippydesign.com)
* Last Modified: May 21 2000
*
* ------------------------------------------------- -----------------------
* TERMS OF USAGE:
* ------------------------------------------------- -----------------------
* You are free to use this library in any way you want, no warranties are
* Expressed or Implied. this works for me, but I don't guarance at it
* Works for you, use at your own risk.
*
* While Not Required to Do So, I Would Appreciate IT IF you Would Retain
* this header information. if you make any modifications or improvements,
* please send thevia email to ying zhang
* ------------------------------------------------- -----------------------
* DESCRIPTION:
* ------------------------------------------------- -----------------------
* This library tells the php4 session handler to write to a mysql database
* INSTEAD OF CREANG INDIVIDUAL FILES for Each Session.
*
* Create a New Database In MySQL Called "Sessions" like SO:
*
* Create Table sessions
* sesskey char (32) Not null,
* EXPIRY INT (11) Unsigned Not Null,
* Value Text Not Null,
* Primary Key (sesskey)
*);
*
* ------------------------------------------------- -----------------------
* Installation:
* ------------------------------------------------- -----------------------
* Make Sure You Have MySQL Support Compiled INTO PHP4. THEN COPY THIS
* Script to a directory That Is Accessible by the rest of your php
* Scripts.
*
* ------------------------------------------------- -----------------------
* USAGE:
* ------------------------------------------------- -----------------------
* Include this file in your scripts before you call session_start (), you
* DON 'THAVE to Do anything Special After That.
* /
$ Sess_dbhost = "localhost"; / * Database Server Hostname * /
$ Sess_dbname = "sessions"; / * database name * /
$ Sess_dbuser = "phpsession"; / * Database user * /
$ Sess_dbpass = "phpsession"; / * Database Password * /
$ Sess_dbh = "";
$ Sess_life = GET_CFG_VAR ("session.gc_maxlifetime);
Function sess_open ($ save_path, $ session_name) {
Global $ sess_dbhost, $ sess_dbname, $ sess_dbuser, $ sess_dbpass, $ sess_dbh;
IF (! $ sess_dbh = mysql_pconnect ($ sess_dbhost, $ sess_dbuser, $ sess_dbpass)) {echo "
Echo "
Die;
}
IF (! MySQL_SELECT_DB ($ sess_dbname, $ sess_dbh)) {
echo "
Die;
}
Return True;
}
Function sess_close () {
Return True;
}
Function sess_read ($ key) {
Global $ sess_dbh, $ sess_life;
$ qry = "SELECT VALUE from sessions where sesskey = '$ key' and expiry>". TIME ();
$ qi = mysql_query ($ QRY, $ sess_dbh);
IF (List ($ Value) = mysql_fetch_row ($ q)) {
Return $ Value;
}
Return False;
}
Function sess_write ($ key, $ val) {
Global $ sess_dbh, $ sess_life;
$ expiry = time () $ sess_life;
$ value = addslashes ($ val);
$ q = "INSERT INTO Sessions VALUES ('$ key', $ eviry, '$ value')";
$ qi = mysql_query ($ QRY, $ sess_dbh);
IF (! $ qid) {
$ q = "Update sessions set expiry = $ eviry, value = '$ value' where sesskey = '$ key' and expression>". Time ();
$ qi = mysql_query ($ QRY, $ sess_dbh);
}
Return $ QID;
}
Function sess_destroy ($ key) {
GLOBAL $ sess_dbh;
$ qry = "delete from sessions where sesskey = '$ key'";
$ qi = mysql_query ($ QRY, $ sess_dbh);
Return $ QID;
}
Function sess_gc ($ maxlifetime) {
GLOBAL $ sess_dbh;
$ qry = "delete from sessions where expiry <". Time ();
$ qi = mysql_query ($ QRY, $ sess_dbh);
RETURN MySQL_AFFECTED_ROWS ($ sess_dbh);
}
Session_set_save_handler
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy", "sess_gc");
?>
============================================================================================================================================================================================================= =====================================================================================================================================================
Test.php
============================================================================================================================================================================================================= =========================
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------
* Test.php
* ------------------------------------------------- -----------------------
* PHP4 Customer Session Handler Test Script
* Version 1.00
* by ying@zippydesign.com)
* Last Modified: May 21 2000
* /
/ * DEFAULT to DBM HANDLER * /
IF (! isset ($ handler) {
$ handler = "dbm";
}
/ * Default action is increment * /
IF (! isset ($ action) {
$ Action = "increment";
}
/ * Load Up the appropriate session handling script, depending on the handler * /
IF ($ handler == "dbm") {
INCLUDE ("session_dbm.php");
} elseif ($ handler == "mysql") {
INCLUDE ("session_mysql.php");
} else {
echo "
Die;
}
/ * Start the session and register a simple counter * /
session_start ();
Session_register ("count");
/ * Figure out what we shop do, depending on the action * / switch ($ action) {
Case "increment":
$ count = isset ($ count)? $ count 1: 0;
Break;
Case "Destroy":
session_destroy ();
Break;
Case "GC":
$ MaxLife = GET_CFG_VAR ("session.gc_maxlifetime);
SESS_GC ($ MAXLIFE);
Break;
DEFAULT:
Echo "
Break;
}
?>
ul>