增加PHP的Session存储和处理能力

  可能很多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相关的技巧和经验。

Category: PHP / Zend
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
10 Responses
  1. diogin says:

    不错,以前就注意到这个功能,不过一直没试过,现在正好一试:)
    另外,关于session,我遇到了一个调试了几乎一个下午也没解决的问题,不知Michael有没有遇到过,简单地说就是下面的三段代码:

    index.php:

    diogin.php:

    another.php:

    这样,访问index.php,将新建一个session,然后删除,再检查cookie数组。这三段代码是能正常工作的,可以把session使用的cookie删除。但当我把类似的代码集成进系统后,想用setcookie来删除会话cookie,就行不通,调试了一下午都没解决。不知这里是不是有什么需要注意的事情我没察觉到,Michael遇到过类似的情况吗?

  2. diogin says:

    啊,奇怪,源代码怎么给过滤掉了?
    那再发一次,不好意思:)

    index.php:

    session_save_path(‘./’);
    session_name(‘DIOGIN_SESSID’);
    session_start();
    $_SESSION[‘diogin’] = ‘haha’;
    header(‘Location: diogin.php’);

    diogin.php:

    session_save_path(‘./’);
    session_name(‘DIOGIN_SESSID’);
    if (isset($_COOKIE[‘DIOGIN_SESSID’])) {
    session_start();
    $_SESSION = array();
    session_destroy();
    setcookie(‘DIOGIN_SESSID’, false);
    header(‘Location: another.php’);
    }

    another.php:

    var_dump($_COOKIE);

  3. Michael says:

    说实话,我仔细看了您的留言,但是我还没有搞明白你到底想实现的需求和功能,从你的代码来看,很少看到这样使用cookie和session的,不知道是为了满足什么需求,通常来说,session在我们的应用里面,迫不得已才使用,比如验证码图片,别的地方如果要使用到session,我们都是使用自己开发的session管理,session存储在内存数据库中。
    如有可能,你可以再把要实现的需求整理一下告知。

  4. Charles says:

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

  5. Michael says:

    [Comment ID #13354 Will Be Quoted Here]

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

  6. 逆雪寒 says:

    我 PHP.INI 知道有这个设置。但真不知道可以设置散列目录储存。
    一般我用session_save_path 不过好象这个函数并不支持目录散列。呵呵

  7. Michael says:

    [Comment ID #25801 Will Be Quoted Here]

    最新的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

  8. Michael says:

    最新的session共享和性能提升将使用memcached来存储session,见php.ini的文档部分就明白了,可以设置多个memcached给php的session来使用,并且可以配置各个mc的权重,这是我们现在主流的使用手段。

  9. 小赵 says:

    你好! 我想问一下 我用了 session_save_path 更改了session保存路径 后来发现我生成的sesion文件夹一直都没有删除过。 就是生成一个之后这一个文件一直都会在。请问这种 情况是什么 原因呢

  10. Michael says:

    你好!我想问一下 我用了 session_save_path 更改了session保存路径 后来发现我生成的sesion文件夹一直都没有删除过。 就是生成一个之后这一个文件一直都会在。请问这种 情况是什么 原因呢

    这个问题是这样的,php的session有自动回收机制,通过session.cookie_lifetime,session.gc_probability,session.gc_divisor以及session.gc_maxlifetime几个参数来控制,在满足条件的情况下,系统会自动进行垃圾回收,但是有一种情况,如果你在session.save_path选项中设定使用子目录来存储session数据文件,垃圾回收程序不会自动启动,你必须使用自己编写的shell脚本、cron项或者其他办法来执行垃圾文件处理。

    如我前面所说的,现在普遍采用的办法已经不是使用多集目录的方式来存储session文件,而是采用更高效的memcached或者redis等内存缓存来实现,建议你研究研究,在机器上配置一个memcached,很简单的,这样一劳永逸,还可以实现分布式的服务器之间共享session

  11. minecraft says:

    That is really interesting, You are an overly professional
    blogger. I’ve joined your rss feed and look forward to
    in quest of extra of your great post. Additionally, I have shared your website in my social networks

  12. minecraft says:

    Wow! In the end I got a website from where I know how
    to actually take useful facts concerning my study and knowledge.

  13. minecraft says:

    I think the admin of this web page is in fact working hard in favor
    of his web page, as here every data is quality based material.

  14. minecraft says:

    Pretty! This has been an incredibly wonderful article. Thank you for supplying
    this info.

  15. Tremendous issues here. I’m very glad to peer your article.
    Thank you a lot and I am having a look forward to touch you.
    Will you please drop me a e-mail?

  16. Amazing! This blog looks exactly like my old one! It’s on a entirely different topic but it has
    pretty much the same page layout and design. Wonderful choice of
    colors!

  17. Hello, I do believe your site could possibly be
    having internet browser compatibility problems. Whenever I look at your web site in Safari, it looks
    fine however when opening in IE, it has some overlapping issues.
    I just wanted to give you a quick heads up! Other than that,
    fantastic blog!

  18. I was able to find good information from your articles.

  19. Hi there I am so thrilled I found your blog, I really found you by accident, while
    I was searching on Yahoo for something else, Nonetheless I am here now and would just like to say thank you for a marvelous post and a all
    round interesting blog (I also love the theme/design),
    I don’t have time to browse it all at the moment but I have book-marked it and also
    added your RSS feeds, so when I have time I will be back to read much more, Please do keep up
    the superb work.

  20. Keep this going please, great job!

  21. Sling TV says:

    This design is wicked! You obviously know how to keep a reader entertained.

    Between your wit and your videos, I was almost moved to start my own blog (well,
    almost…HaHa!) Wonderful job. I really loved what you had to
    say, and more than that, how you presented it. Too cool!

  22. Write more, thats all I have to say. Literally, it seems as
    though you relied on the video to make your point.
    You definitely know what youre talking about, why throw away your intelligence on just posting videos to your site when you could be giving us something enlightening to
    read?

  23. Thank you for the good writeup. It if truth be told used to be a enjoyment account
    it. Glance complex to more delivered agreeable from you!
    However, how could we keep in touch?

  24. Hi, the whole thing is going fine here and ofcourse every one is sharing data, that’s actually
    fine, keep up writing.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
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.
Anti-spam image