We provide an example of how to write a full-featured session processing program based on the mysql database or dbm file. 1. the new php4 has a set of session processing functions. By default, each session is stored in an independent file in a temporary directory of the system (for example,/tmp in a unix system ). This is suitable or not suitable, depending on your needs. For example, we provide an example of how to write a full-featured session handler based on the mysql database or dbm file.
I. Preface
The new php4 has its own session processing function. By default, each session is stored in an independent file in a temporary directory of the system (for example,/tmp in a unix system ).
This is suitable or not suitable, depending on your needs. For example, if your web servers that support php are distributed on different machines, you cannot easily share sessions between them (of course, you can also save sessions in NFS sharing ). Another potential problem is that thousands or millions of session files on your machine make your file system messy.
Fortunately for us, the php4 developers are very far-sighted (thanks to them) and they provide you with interfaces for extending session processing for users like me.
This document explains how to process a session and provides two examples of how to extend the session processing. In our first example, the session handler will save the session data to the DBM file. In our second example, session data is saved to the MYSQL database.
Before you start, download ying20000602.zip and release it to the web document directory. (I have brought it to the end of this article)
Any session handler we write will provide six basic functions which will be called by the session handler of php4, so you don't have to worry about how to call them.
Fortunately, these custom session processing functions are completely transparent to you. So you can modify them without affecting your own PHP scripts.
These functions are:
Sess_open ($ sess_path, $ session_name );
This function is called by the session handler for initialization. The two parameters to be passed to it are $ sess_path, which corresponds to the session. save_path option in your php. ini file; $ session_name, which corresponds to the session. name option in php. ini. For details about how they work, see the following example.
Sess_close ();
This function is called when the page ends and the session processing program needs to be closed. (Note: Do not confuse it with sess_destory. it is used to end the session)
Sess_read ($ key );
This function is used when the session handler reads the specified session key value ($ key.
This function retrieves and returns session data identified as $ key. (Note: You don't have to worry about how to serialize or deserialize the data. if you don't know what this means, don't worry about it)
Note: serialization is a technology that stores variables or objects in files when the program ends or needs to be stored. it is different from the method that only saves data when the program runs or needs to be transferred to memory next time.
Sess_write ($ key, $ val );
This function is called when the session handler needs to save data, which often occurs when your program ends.
It stores the data in the location where the sess_read ($ key) function can be used for retrieval next time.
Sess_destroy ($ key );
This function is required to destroy the session. It is responsible for deleting sessions and clearing the environment.
Sess_gc ($ maxlifetime );
This function is responsible for clearing fragments. In this case, it is responsible for deleting outdated session data. Session handlers occasionally call them.
Now we know the functions we provide. They do not have to be named like this, but must accept these parameters. (Whether you need them or not)
DBM session handler
The first example is to write a custom session handler that saves session data to the DBM file. (This is the session_dbm.php file in ying20000602.zip)
There are many good reasons for you to do this. for example, if you have a shared server on your isp) and you don't want your session data
Mixed with others.
Important notes:
When you test these programs, your php4 must have DBM support. If this is not the case (note: without DBM support), it will be ugly and really ugly!
The work we need to do will get a DBM file of all session data. (In case you don't know, the DBM file is like a very simple database that only saves "key/value" pairs.
Implemented by the following six function data:
Sess_open ($ sess_path, $ session_name );
We will call dbmopen () to open a DBM file in read/write mode. Our DBM file will be named/tmp/PHPSESSID, unless you have modified the session path in php. ini
Path and name settings.
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 () to load session data related to the parameter $ key.
When loading a session, we need to ensure that the read data is not an expired data, so we must add a time mark to the session.
Why? Because they are invalid and are not deleted for whatever reason, we will not accidentally read the expired data. This is a big taboo.
We know that the DBM file only stores key/value pairs, so we have to write the time mark with the "value" when writing session data, and remove it when reading session data.
Any expired sessions will be ignored. Look at this source program, it will make you more clear.
Sess_write ($ key, $ val );
Write a session and we will use the dbmreplace () function. Note: From the above descriptions, we need to save the expiration time in the session, so we need to bind the time Mark to the value.
Sess_destroy ($ key );
It is easy to destroy a session. we only need to call the dbmdelete () function to delete it from the session file.
Sess_gc ($ maxlifetime );
It is annoying but necessary to collect expired data here. to achieve this, We cyclically scan all sessions stored in the DBM file and delete expired sessions. This is slow because
It cyclically uses all session data stored in this file.
Now we have a DBM session processing program. it's so cool!
Now let's save these sessions to the mysql database.
Mysql session processing program
(This
The next example is to write a custom session processing program that stores session data to the mysql database. (In the session_mysql.php file, see the end of the article)
When you have many servers that support PHP and you need to share sessions between them, you will want to save the session in the database. (For example, you serve many users and need
Load balancing)
You have a bunch of machines doing web/PHP stuff, a machine serving
You have a batch of servers that support php. you need one server as your normal database server, and the other server runs the mysql database to process sessions. This is the only way for most people
It is highly lethal. )
Important:
Before you test, your php must support mysql. (Note: this does not seem to be a problem. php now has built-in mysql support.) if this is not the case, it will be difficult to understand.
It's ugly.
First, create a session database in mysql and create a session table. Run your mysql client and 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 in the session_mysql.php file to match the database settings on your machine. Make sure everything looks good before you proceed.
Our six functions rely on the mysql database:
Sess_open ($ sess_path, $ session_name );
We need to call mysql_Pconnect (), and then use mysql_selsect_db () to select the session database. $ Sess_path and $ session_name
They are irrelevant, but we have to keep them. This may be true for compatibility purposes)
Sess_close ();
We need to open a mysql permanent connection, so we will not do anything in this function. (An empty function)
Sess_read ($ key );
This tip is a simple select statement. to read the session data of the given $ key, you must specify the Expiration Time.
Sess_write ($ key, $ val );
A trick is used to write session data. First, we try to use the insert statement to save session data to the database. If it fails (PRIMARY key constraint), it means that the key has been written, and then we
Instead of using an update statement.
Sess_destroy ($ key );
It is easy to delete a session. we only need to delete this key value from the database.
Sess_gc ($ maxlifetime );
It is also easy to process expired sessions. we only need to delete expired sessions () from the database ().
To end this tutorial, I hope you will have a good feeling when extending the php4 session processing.
This example simply demonstrates how you can expand them to suit your needs. if you find any bugs, please let me know :)
Faq:
If you are worried that session files will be confused with other virtual machines in the/tmp Directory, they will be saved elsewhere.
This is why the session. save_path option exists.
If you are worried about performance, you can consider storing the session in the shared memory. You only need to add MM support (-- with-mm) during php compilation and specify sessio. save_handler as mm
In. htaccess, php. ini or httpd. conf.
I think databases are used only when multiple machines need to save sessions.
(The last sentence is really not easy to translate. let's take a look)
Session_dbm.php
========================================================== ======================================
/*------------------------------------------------------------------------
* Session_dbm.php
*------------------------------------------------------------------------
* PHP4 DBM Session Handler
* Version 1.00
* By Ying Zhang (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 guarantee that it
* Works for you, use at your own risk.
*
* While not required to do so, I wowould appreciate it if you wowould retain
* This header information. If you make any modifications or improvements,
* Please send them via email to Ying Zhang .
*
*------------------------------------------------------------------------
* DESCRIPTION:
*------------------------------------------------------------------------
* This library tells the PHP4 session handler to write to a DBM file
* Instead of creating 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 that.
*/
$ 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, "success "));
If ($ expires_at> time ()){
$ Var = substr ($ tmp, strpos ($ tmp, "success") + 1 );
}
}
Return $ var;
}
Function sess_write ($ key, $ val ){
Global $ SESS_DBM, $ SESS_LIFE;
Dbmreplace ($ SESS_DBM, $ key, time () + $ SESS_LIFE. "interval". $ 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, "success "));
If ($ now> $ expires_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 Zhang (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 guarantee that it
* Works for you, use at your own risk.
*
* While not required to do so, I wowould appreciate it if you wowould retain
* This header information. If you make any modifications or improvements,
* Please send them via email to Ying Zhang .
*
*------------------------------------------------------------------------
* DESCRIPTION:
*------------------------------------------------------------------------
* This library tells the PHP4 session handler to write to a MySQL database
* Instead of creating 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't have 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"
Can't connect to $ SESS_DBHOST as $ SESS_DBUSER ";
Echo"
MySQL Error: ", mysql_error ();
Die;
}
If (! Mysql_select_db ($ SESS_DBNAME, $ SESS_DBH )){
Echo"
Unable to select database $ SESS_DBNAME ";
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 ();
$ Qid = mysql_query ($ qry, $ SESS_DBH );
If (list ($ value) = mysql_fetch_row ($ qid )){
Return $ value;
}
Return false;
}
Function sess_write ($ key, $ val ){
Global $ SESS_DBH, $ SESS_LIFE;
$ Expiry = time () + $ SESS_LIFE;
$ Value = addslashes ($ val );
$ Qry = "insert into sessions VALUES ('$ key', $ expiry,' $ value ')";
$ Qid = mysql_query ($ qry, $ SESS_DBH );
If (! $ Qid ){
$ Qry = "UPDATE sessions SET expiry = $ expiry, value = '$ value' WHERE sesskey =' $ key' AND expiry>". time ();
$ Qid = mysql_query ($ qry, $ SESS_DBH );
}
Return $ qid;
}
Function sess_destroy ($ key ){
Global $ SESS_DBH;
$ Qry = "delete from sessions WHERE sesskey = '$ key '";
$ Qid = mysql_query ($ qry, $ SESS_DBH );
Return $ qid;
}
Function sess_gc ($ maxlifetime ){
Global $ SESS_DBH;
$ Qry = "delete from sessions WHERE expiry <". time ();
$ Qid = 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 Zhang (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"
Unrecognized handler ($ handler )";
Die;
}
/* Start the session and register a simple counter */
Session_start ();
Session_register ("count ");
/* Figure out what we should 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"
Unknown action ($ action )";
Break;
}
?>
Session Test Script
========================================================== ========================================================== ==========
(Author: Ying Yang