2006
10.19

  可能很多PHPer都用到了PHP提供的Session功能,可以方便的进行会话功能处理,PHP服务端默认的session存储是文件存放方式,在Windows上PHP默认的Session服务端文件存放在C:\WINDOWS\Temp下,*NIX下默认存放在/tmp下,如果说并发访问很大或者session建立太多,在这两个目录下就会存在大量类似sess_xxxxxx的session文件,同一个目录下文件数过多会导致性能下降,并且可能导致受到攻击最终出现文件系统错误。针对这样的情况,PHP本身体提供了比较好的解决办法。
  不少朋友可能都没有注意到php.ini里面Session设置部分中有这样一项:

;     session.save_path = "N;MODE;/path"


  这项设置提供给我们可以给session存放目录进行多级散列,其中“N”表示要设置的目录级数,“MODE”表示目录的权限属性,默认为600,在WINDOWS上基本是不用设置的,*NIX上也可以不用设置,后面的“/path”表示session文件存放的根目录路径,比如我们设置为下面的格式

session.save_path = "2;/tmp/phpsession"

  上面的设置表示我们把/tmp/phpsession目录作为php的session文件存放根目录,在该目录下进行两级目录散列,每一级目录分别是0-9和a-z共36个字母数字为目录名,这样存放session的目录可以达到36*36个,相信作为单台服务器来说,这是完全够用了,如果说您的系统架构设计为多台服务器共享session数据,可以把目录级增加到3级或者更多。
  需要注意的是,php自己并不会自动创建子目录,需要您自己动手去创建,网上找到这样的自动创建目录的代码,大家可以做个参考。下面的代码自动创建3级子目录,可以自己动手根据需要进行修改。

<?php
set_time_limit(0);
$string = '0123456789abcdefghijklmnopqrstuvwxyz';
$length = strlen($string);
function makeDir($param)
{
    
if(!file_exists($param)) {
        
makeDir(dirname($param));
        
mkdir($param);
    
}
}
for($i = 0; $i < $length; $i++) {
    
for($j = 0; $j < $length; $j++) {
        
for($k = 0; $k < $length; $k++) {
            
makeDir($string[$i].'/'.$string[$j].'/'.$string[$k]);
        
}
    
}
}
?>

  大家可能注意到前面的文字中提到了有关多服务器共享php的SESSION,这是很多应用都会遇到的问题,网上也有不少相关的资源,大家可以去google一下,Michael这里只提一下大概的思路。
  一般来说我们用到最多的方法有两种:
  1、NFS或者Samba共享的方法,让各个服务器上存放session文件的磁盘共享,这种方法简单可行。
  2、集中存储到数据库中,这是比较多的实现方法,通过php提供的session_set_save_handler()函数来重定义session函数,推荐使用这种方法。

  欢迎大家一起交流和讨论php中和session相关的技巧和经验。

8 comments so far

Add Your Comment
  1. Charles on April 9, 2007 at 3:36 pm  (Quote) said:

    有一个将 PHP Session 利用 memcached 来保存的类。好像是一个丹麦的人写的。 …

    这位朋友说得很对,我用数据库保存过,为了多台机器共享session,用memcached原理一样,就是存储和读取的时候把从数据库改成从memcached操作,另外还可以使用共享内存,比如PHP的APC扩展。

  2. 逆雪寒 on March 29, 2008 at 11:17 am  (Quote) said:

    我 PHP.INI 知道有这个设置。但真不知道可以设置散列目录储存。
    一般我用session_sa…

    最新的pecl_memcached 扩展可以支持直接在php.ini里面设置类似这样的东西:
    session.save_handler = memcache
    session.save_path = “tcp://host:port?persistent=1&weight=2&timeout=2&retry_interval=15,tcp://host2:port2″

    比如设置:session.save_path = “tcp://127.0.0.1:11211″, 连接本机上11211端口的memcached来存储session

    详细的语法可以参考官方文档 php_memcache.h cvs log

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word