Session 扩展
在线手册:中文 英文
PHP手册

Session Handling


Session 扩展
在线手册:中文 英文
PHP手册
PHP手册 - N: Session Handling

用户评论:

roberto at spadim dot com dot br (21-Mar-2011 06:28)

instead of memcache, you should consider using redis
http://redis.io/commands

it have KEYS command (http://redis.io/commands/keys) that can return all keys (like 'ls'/'dir' at php sessions directory)

it allow replication too (cluster use)

i don't know if anyone wrote a version of phpsessions using redis yet, but since memcache don't have KEYS command, it's hard to know if the users is connected (at app side) or what sessions still active (not expired/not logged)

elephant at punx dot pl (28-Feb-2011 07:51)

Please note, that database is NOT recommended for session storage. It can be a big performance bottleneck, especially in replicated environments.

For saving sessions, file handler seems to be very effective for most setups, except those situations:
 - if performance is an issue, the directory which stores session files can be mounted as tmpfs (ram disk).
 - if sharing sessions across multiple webservers is needed (in clustered environments), use memcache for storing session information (tip: you can setup more than one instance of memcache eliminate single point of failure). This method, however, sets a limitation of session size to 64k (this should be enough for most applications)
 - don't use NFS for sharing session files between webservers, it does not handle locking correctly and can cause corruption of session data.

php_engineer_bk at yahoo dot com (29-Sep-2010 07:39)

<?php
/**
 * PHP session handling with MySQL-DB
 *
 */

class Session
{
   
/**
     * a database connection resource
     * @var resource
     */
   
private static $_sess_db;

   
/**
     * Open the session
     * @return bool
     */
   
public static function open() {
        if (
self::$_sess_db = mysql_connect('localhost',
                                           
'root',
                                           
'')) {
            return
mysql_select_db('trading', self::$_sess_db);
        }
        return
false;
    }

   
/**
     * Close the session
     * @return bool
     */
   
public static function close() {
        return
mysql_close(self::$_sess_db);
    }

   
/**
     * Read the session
     * @param int session id
     * @return string string of the sessoin
     */
   
public static function read($id) {
       
$id = mysql_real_escape_string($id);
       
$sql = sprintf("SELECT `session_data` FROM `sessions` " .
                      
"WHERE `session` = '%s'", $id);
        if (
$result = mysql_query($sql, self::$_sess_db)) {
            if (
mysql_num_rows($result)) {
               
$record = mysql_fetch_assoc($result);
                return
$record['session_data'];
            }
        }
        return
'';
    }

   
/**
     * Write the session
     * @param int session id
     * @param string data of the session
     */
   
public static function write($id, $data) {
       
$sql = sprintf("REPLACE INTO `sessions` VALUES('%s', '%s', '%s')",
                      
mysql_real_escape_string($id),
                      
mysql_real_escape_string(time()),
                      
mysql_real_escape_string($data)
                       );
        return
mysql_query($sql, self::$_sess_db);
    }

   
/**
     * Destoroy the session
     * @param int session id
     * @return bool
     */
   
public static function destroy($id) {
       
$sql = sprintf("DELETE FROM `sessions` WHERE `session` = '%s'", $id);
        return
mysql_query($sql, self::$_sess_db);
    }

   
/**
     * Garbage Collector
     * @param int life time (sec.)
     * @return bool
     * @see session.gc_divisor      100
     * @see session.gc_maxlifetime 1440
     * @see session.gc_probability    1
     * @usage execution rate 1/100
     *        (session.gc_probability/session.gc_divisor)
     */
   
public static function gc($max) {
       
$sql = sprintf("DELETE FROM `sessions` WHERE `session_expires` < '%s'",
                      
mysql_real_escape_string(time() - $max));
        return
mysql_query($sql, self::$_sess_db);
    }
}

//ini_set('session.gc_probability', 50);

?>
Iranian php programming (farhad zandmoghadam)

e dot mortoray at ecircle dot com (17-Apr-2009 01:02)

There is a nuance we found with session timing out although the user is still active in the session.  The problem has to do with never modifying the session variable.

The GC will clear the session data files based on their last modification time.  Thus if you never modify the session, you simply read from it, then the GC will eventually clean up.

To prevent this you need to ensure that your session is modified within the GC delete time.  You can accomplish this like below.

<?php
if( !isset($_SESSION['last_access']) || (time() - $_SESSION['last_access']) > 60 )
 
$_SESSION['last_access'] = time();
?>

This will update the session every 60s to ensure that the modification date is altered.

Some Guy (16-Jan-2009 12:26)

Just some notes - it seems that php does the session writing after the script exits.
For example, if you set a bunch of session variables and then run session_regenerate_id() - the session variables are never written to the old session. The new session id is generated when you ask it to be generated, but the session exists only in memory until after the script exits - when the session is written and any and all session variables are written to it.

This caused me some confusion, as I'm running sessions in an sql database rather than flat file, trying to do any manipulation of the session database directly in a script where you have run session_regenerate_id() will fail for the new session ID because the insert hasn't been done yet, and setting any session variables will only be written to the new session, even if set before you regenerate the session ID.

Also - if using a database for sessions, make sure to use mysql_real_escape_string() before saving any session variables.

Anonymous (06-Dec-2008 05:07)

Variations from Http://, Https:// and http://www. will throw off session data.

master dot twinkle at virgin dot net (08-Sep-2008 07:32)

If you have links from your website to other domains even if they open in new windows, session data will be lost.  I am using a session variable to store the number of hits and avoid the problem by opening links in the top location - this will of course give you the bonus of an extra hit when the visitor returns!

SebastianJu (21-Aug-2008 09:41)

Cant believe this problem isnt described herein. I wondered why my session-variables lost their values when going from first site to second site. Both had a session_start();.

A session is working only on one domain. Subdomains dont use the Session of the maindomain. That means if someone comes to your site at yourdomain.com and the session is started there and then clicks a link where he is lead to www.yourdomain.com then the old session isnt working there anymore. Because www. is a subdomain.

In the practice that will mean a lot of lost sessions only because webmasters dont know this behaviour. I have never read a word about this in manuals or somewhere...

The solution is to put this code before the first session_start();

ini_set("session.cookie_domain",substr($_SERVER[HTTP_HOST],3));

Now it works. At the second place of parameters has to come in ".yourdomain.com" (with a dot before). With that the subdomains will use the same session like the maindomain. In this example domainname taken from Server-variable.

Greetings!
Sebastian

zareef at zareef dot net (11-Aug-2008 12:54)

Persistence of session data in included file also has one more aspects if you are including a file using/over the http connection.
Session will not be available without refresh (it's a separate thread even if you are on the same domain/server), which is again a correct behavior, but if you are including a file from local file system then it should have session data if you are setting and accessing the $_SESSION variable even before page refresh because it is available globally.

<?php
session_start
();
$_SESSION['example']="yes";

Include(
"otherfile");

?>

Session variable will be available in included file.

<?php
session_start
();
$_SESSION['example']="yes";

Include(
"http://domain.com/otherfile.php");

?>

Session will NOT be available in other file.
BUt if both files are on same server then after refresh values will be available.

Madster (28-Jul-2008 08:45)

When you include a php file in your current script it's included, not processed separately, thus it's still within the same page and the current page hasn't finished processing.
Thus, session is not set yet. This is the expected behaviour.

If you need to load a page after setting session data, you should set session data and then send a redirection or refresh header (remember not to send anything, not even whitespace before sending headers).

Always consider session data to be updated after the next page load (as in http request completed).

mike at basementideas dot com (08-Jul-2008 01:05)

The note about an included file not being able to access the sessions is not true.  You just have to do a session_start(); in the included file.

This is what drove me here today, because I was noticing the same thing.  But I tried the above on a whim and it works fine.  You wouldn't think you'd need to start a session twice, but I guess the scripts are looked on as separate in that regard.

Mike

pushedx (02-Jul-2008 11:01)

Here is something to watch out for when working with sessions.

Let's say you have two pages, Page A and Template Z. If Page A sets session data and includes Template Z, the session data is not properly registered for the execution of Template Z due to how session data is written *after* a script has executed [1].

As a result, your second page will not have the right session data, so you are a bit in a pickle. I'm sure there are other work arounds, perhaps with cookies or flat files, but you cannot use session data in that fashion.

The reason I have this setup is because I will have a number of Page A-Z's that will contain page specific content and one Template Z page that renders each page's specific content in the site layout. This way, the site content changing is independent of the style the site uses and the site style can change without modifying the actual content. It's a dynamically configurable site template design.

[1] See the  "session_write_close" documentation page.