<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post/4830/</link>
<title><![CDATA[[回收机制]PHP中SESSION机制探究,PHP中如何保持SESSION以及由此引发的一些思考，及共享内存实现方法探究之eaccelerator相关函数介绍  ]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Sun, 04 Dec 2011 03:18:23 +0000</pubDate> 
<guid>http://www.jackxiang.com/post/4830/</guid> 
<description>
<![CDATA[ 
	重点是：<br/>php中session的过期回收机制&nbsp;&nbsp; <br/>php中session的客户端存储机制<br/><br/>1、php中session的生成机制<br/><br/>我们先来分析一下PHP中是怎么生成一个session的。设计出session的目的是保持每一个用户的各种状态来弥补HTTP协议的不足(无状 态)。我们现在有一个疑问，我们都知道session是保存在服务器的，既然它用于保持每一个用户的状态那它利用什么来区别用户的呢？这个时候就得借助 cookie了。当我们在代码中调用session_start();时，PHP会同时往SESSION的存放目录(默认为/tmp/)和客户端的 cookie目录各生成一个文件。session文件名称像这样：<br/><br/>格式为sess_&#123;SESSIONID&#125; ，这时session文件中没有任何内容，当我们在session_start();添加了这两行代码：<br/><br/>$_SESSION[&#039;name&#039;] = &#039;wanchun0222&#039;;<br/><br/>$_SESSION[&#039;blog&#039;] = &#039;coderbolg.com&#039;; 这时文件就有内容了：<br/><br/>name&#124;s:11:&quot;wanchun0222&quot;;blog&#124;s:13:&quot;coderbolg.com&quot;; 这时再看看cookie：<br/><br/>可以看到服务器为我们自动生成了一个cookie,cookie名称为&quot;PHPSESSID&quot;，cookie内容是一串字符，其实这串字符就是 &#123;SESSIONID&#125;。也许你已经明白了，当我们使用session时，PHP就先生成一个唯一的SESSIONID号(如 2bd170b3f86523f1b1b60b55ffde0f66)，再在我们服务器的默认目录下生成一个文件，文件名为 sess_&#123;SESSIONID&#125;，同时在当前用户的客户端生成一个cookie，内容已经说过了。这样PHP会为每一个用户生成一个 SESSIONID，也就是说一个用户一个session文件。PHP第一次为某个用户使用session时就向客户端写入了cookie，当这个用户以 后访问时，浏览器会带上这个cookie，PHP在拿到cookie后就读出里面的SESSIONID，拿着这个SESSIONID去session目录 下找session文件。找到后在调用$_SESSION[&#039;blog&#039;]的时候显示出来。<br/><br/>2、php中session的过期回收机制<br/><br/>我们明白了session的生成及工作原理，发现在session目录下会有许多session文件。当然这些文件一定不是永远存在的，PHP一定 提供了一种过期回收机制。在php.ini中session.gc_maxlifetime为session设置了生存时间(默认为1440s)。如果 session文件的最后更新时间到现在超过了生存时间，这个session文件就被认为是过期的了。在下一次session回收的<br/><br/>时候就会被删除。那下一次session回收是在什么时候呢？这和php请求次数有关的。在PHP内部机制中，当php被请求了N次后就会有一次触发回收机制。到底是请求多少次触发一次是通过以下两个参数控制的： session.gc_probability = 1<br/><br/>session.gc_divisor = 100<br/><br/>这是php.ini的默认设置，意思是每100次PHP请求就有一次回收发生。概率是<br/><br/>gc_probability/gc_divisor 。我们了解了服务器端的session过期机制，再来看看客户端的cookie的过期机制。<br/><br/>如果cookie失效了浏览器自然发送不了cookie到服务器，这时即使服务器的session文件存在也没用，因为PHP不知道要读取哪个 session文件。我们知道PHP的cookie过期时间是在创建时设置的，那么PHP在创建session的同时为客户端创建的cookie的生命周 期是多久呢？这个在php.ini中有设置：session.cookie_lifetime 。这个值默认是0，代表浏览器一关闭SESSIONID就失效。那就是说我们把session.gc_maxlifetime和 session.cookie_lifetime设置成同一个值就可以控制session的失效时间了。 3、php中session的客户端存储机制<br/><br/>由上面的介绍我们可以知道，如果用户关闭了cookie，那我们的session就完全没法工作了。是的，确实是这样。php中session的客 户端存储机制只有cookie吗？不是的。既然我们的SESSIONID 不能通过cookie传递到各个页面，那我们还有另一个法宝，就是通过页面GET传值的方式。 PHP可以在cookie被禁用时自动通过GET方式跨页传递SESSIONID，前提是设置php.ini的<br/><br/>session.use_trans_sid为1。这时当我们在客户端禁用了cookie时使用了session，并在当前页面通过点击链接到另一页面 时，PHP会自动在链接上添加SESSIONID参数，像这 样：<br/><br/>nextpage.php?SESSIONID=2bd170b3f86523f1b1b60b55ffde0f66。我想你应该看到了这种方式的缺 点：好像不够安全啊。 <br/>==========================================================================================<br/> <br/>&nbsp;&nbsp;&nbsp;&nbsp; 最近的一个项目，里面有一个比较大的表单，用户完成它需要很多时间，很多用户花了千辛万苦完成之后，一提交发现SESSION过期，系统退出了，所以引起了研究如何设置SESSION以及保持SESSION在线的需要，下面是一些心得体会。<br/>什么是SESSION？<br/>按照WIKI的解释，SESSION是存在于两个通信设备间的交互信息，在某一时间建立，经过一定的时间后失效。常见的SESSION有：TCP SESSION、WEB SESSION（HTTP SESSION）、LOGIN SESSION等。<br/>根 据OSI模型中，会话实现的位置不同，SESSION主要分为几种，一种是应用层会话，包括WEB SESSION（HTTP　SESSION）和telnet远程登录session；会话层实现的，包括Session Initiation Protocol（SIP）和Internet Phone Call；在传输层实现的有TCP　SESSION。<br/>本文主要讨论WEB SESSION，其一般有两种：客户端SESSION和服务器端SESSION，后一种最常见的属于Java Beans提供的。<br/>SESSION是做什么的？<br/>在计算机领域，特别是网络方面，SESSION使用的特别广泛，也可以称为是对话（Dialogue）、会话等，一般是指在两个通信设备间存储的状态，有时也发生在用户和计算机之间（Login　SESSION）。<br/>区别于无状态的通信，SESSION通常用来存储通信状态，因此通信的双方至少有一方需要存储SESSION的历史记录，从而实现两者间的通信。<br/>SESSION（WEB　SESSION）是怎么实现的？<br/>浏览器和服务器之间进行HTTP通信时，通常会包含一个　HTTP Cookie 来标识状态，通常会有一个唯一的　SESSIONID　，SESSION通常记录着用户的一些验证信息和级别。<br/>在 几中编程语言中最常用的Http Session Token是，JSESSIONID（JSP），PHPSESSID（PHP），ASPSESSIONID（ASP），这个标识通常由哈希函数产生，能够 唯一表示这个用户的身份，在服务器和客户端通信时，作为GET或者POST的参数存储在客户端。<br/>SESSION的实现方式通常有两种，服务器端SESSION和客户端SESSION，两种方式各有优缺点。<br/>服 务器端SESSION实现容易并且效率比较高，但是遇到负载均衡或者高可用性需求的时候，处理起来就比较困难，对于那种内生系统不存在存储设备的时候，也 是不可用的。负载均衡可以通过共享文件系统或者强制客户只能登录到一台服务器上来实现，但是这样会降低效率。对于没有存储的设备，也可以通过使用RAM （参考参考资料6）来解决服务器端SESSION的实现，这种方法这对哪些客户端链接有限的系统有效（诸如路由或者接入点设备）。<br/>客户端 SESSION的使用可以解决服务器端SESSION的一些问题，比如避免了负载均衡的算法等，但是同时也会产生一些自身的问题。客户端SESSION使 用Cookie和加密技术来在不同的请求间保存状态。在每一个动态页面结束后，会统计当前的SESSION，并把它发回客户端。每次成功请求后，会把 cookie再发送到服务器端，来让服务器“记起”这个用户的身份。客户端SESSION最重要的问题就是安全问题，一旦cookie被劫持或者篡改了， 用户的信息的安全性就丧失了。<br/>PHP中如何设置SESSION？<br/>搭建好PHP的开发环境后，通过phpinfo()可以查看到与SESSION有关的部分包括：<br/>SESSION模块，在PHP V5.2.9版本中，一共有25个变量。其中，平时设置中常会用到的几个有：<br/>session.cookie_lifetime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;设置存储SESSIONID的cookie过期时间<br/>session.name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SESSION的COOKIE名称，默认为PHPSESSID<br/>session.save_handler&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SESSION的存储方式，默认为FILE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>session.save_path&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fedora下面默认存储在/var/lib/php/session<br/>session.gc_probability<br/>session.gc_divisor<br/>session.gc_maxlifetime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这三个选项用来处理GC机制发生的机率<br/>session.cache_limiter&nbsp;&nbsp;&nbsp;&nbsp;（nocache,private,private_no_expire,public）<br/>session.cache_expire&nbsp;&nbsp;&nbsp;&nbsp;这两个选项是用来缓存SESSION的页面<br/>先 来考虑第一个问题，SESSION多久会过期，他是如何过期的？如果要在PHP程序中使用SESSION，一定要先引用session_start()， 这个函数一执行，就会在SESSION的存储目录（如果使用了file handler)生成一个SESSION文件，里面内容是空的，同时浏览器会见里一个name为PHPSESSID的cookie，里面存储着一个 hash出来的SESSION的名字。<br/>SESSION的过期依赖于一个垃圾回收机制（Garbage Collection），SESSION创建后作为一个文件存放在服务器上，客户端脚本每访问一次SESSION中的变量，SESSION文件的访问时间 就会进行更新。每次访问都是根据客户端存储的SESSIONID去请求服务器中存储的唯一的SESSION，当客户端的cookie过期后，就无法知道要 访问的是哪一个SESSION，尽管此时服务器上的SESSION文件还没有被过期收回，这样就会造成服务器资源的浪费。<br/>但是同时，如果我们希望 用户的session马上过期的话，我们就可以通过设置cookie的办法来实现。SESSION的回收是在每次访问页面的时候进行的，回收的机率由 session.gc_probability，session_gc_divisor指定，默认士1/100。如果设置为1，则每次超过了 SESSION的生存周期去访问的话，SESSION一定会被回收。<br/>两种需求：1、保持SESSION不过期或延长SESSION过期时间；2、使SESSION立即过期。 <br/>1、 保持SESSION不过期和延长SESSION过期时间非常必要，特别是在内部应用系统中或者有很大的表单的时候。想想你的老板在填写一个表单，刚好碰上 午饭时间，留着这个表单等吃饭回来，填写完剩余的内容，提交后他看到什么，一般来说都是一个登录界面。想要提高用户体验，关键是要让老板的表单不出问题， 我们就必须延长SESSION的生存周期。<br/>保持SESSION不过期和延长SESSION过期时间，可以通过设置 session.gc_maxlifetime来实现，不过首先需要保证客户端的cookie不会在gc执行回收之前失效。通过设置一个较长的 gc_maxlifetime可以实现延长session的生存周期，可是对于不是所有请求都会保持很久的应用来说，这么做对于服务器配置显然不是一个最 佳的选择。<br/>我们知道SESSION的回收机制是根据SESSION文件的最后访问时间来判断的，如果超过了maxlifetime，则根据回收机率进行回收。所以我们只需要定期的去访问一下SESSION就可以了，而这可以通过刷新页面来实现，根据这个思路，解决的方法就有了。<br/>通过JS定期的去访问页面；<br/>利用Iframe定期的刷新页面；<br/>直接利用程序发送HTTP请求，这样就可以避免在页面中嵌入其他的元素；<br/>下面是利用JS发送请求实现的保持SESSION不过期的实现方法，这样我们就只需要在需要SESSION保持长时间的页面（比如大表单页面）。<br/>&lt;script type=&quot;text/javascript&quot;&gt;<br/>function keepMeAlive(imgName)&#123;<br/>myImg = document.getElementById(imgName);<br/>if(myImg) myImg.src = myImg.src.replace(/&#92;?.*$/, &#039;?&#039; + Math.random());<br/>&#125;<br/>window.setInterval(&quot;keepMeAlive(&#039;phpImg&#039;);&quot;, 4000);<br/>&lt;/script&gt;<br/>&lt;img id=&quot;phpImg&quot; src=&quot;http://www.phpplot.com/phpplot/session/sess_refresh.php?&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;<br/>其中URL后加入一个随机数是为了避免这个链接的请求被浏览器缓存。<br/>2、使SESSION立即过期的方法就比较多了，我们可以session_destroy()，也可以用上面的思路，请求一个session_destroy的页面。<br/>SESSION安全吗？<br/>PHP的手册中明确写出：SESSION并不能保证储存在SESSION中的信息一定只能被他的创建者所看到。<br/>如 果想要安全的处理一些远程的操作，那么HTTPS是唯一的选择。最基本的，不要认为一个用户信息在SESSION中存在就认为这个用户一定就是他本人，虽 然SESSION中的信息会给你他已经经过了用户名和密码验证的假象。所以，如果需要做一些修改密码或者类似的事情的时候，让用户重新输入密码是一个比较 好的选择。<br/>早期的Apache版本并没有采用COOKIE的方式来存储PHPSESSID，而是采用的URL-rewrite，也就是每个URL 后面都会加上PHPSESSID=&lt;sessionid&gt;来表明它属于那个激活的SESSION，新版的Apache已经将这个属性设置为默 认关闭。<br/>session.use_trans_id = 0;<br/>所以从这个意义上来讲，延长SESSION的时间过长或者保持 SESSION一直在线对于安全来说始终不是一件好事情。终极的解决办法就是用户提交跳转到登录窗口，登录后又能够回到填写页面，并且所有的数据都还在。 这个的实现方式现在用Ajax来解决应该没什么困难，每隔一定时间就把当前的用户数据POST到一个存储位置，不管是XML或者JSON。<br/>拾遗：<br/>对于客户端不支持JavaScript的情况可以采用的方法：<br/>1、写一个浮层，显示在最顶层，如果用户未禁用JS，则让浮层消失；<br/>2、将所有的INPUT都设置为disable，然后再用JS设置为enabled；<br/>以上这两种方式都是在JS被禁用的时候，所有功能都不能用，如何在JS被禁用的情况下使我们的应用仍然正常工作，这个貌似就比较困难。实现这个的所花的时间和所收到的效果大家要权衡一下。<br/>参考资料<br/>1、SESSION Security&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://uk2.php.net/manual/en/session.security.php<br/>2、WIKI&nbsp;&nbsp;&nbsp;&nbsp;SESSION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://en.wikipedia.org/wiki/Session<br/>3、SESSION（computer science）&nbsp;&nbsp;&nbsp;&nbsp;http://en.wikipedia.org/wiki/Session_(computer_science)<br/>4、Http Cookie&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://en.wikipedia.org/wiki/HTTP_cookie<br/>5、PHP.net SESSION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://cn.php.net/manual/en/intro.session.php<br/>6、OSSP mm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.ossp.org/pkg/lib/mm/<br/>http://www.cnblogs.com/cocowool/archive/2009/08/01/1536737.html<br/>1，如何设置长生命期的session ？ <br/>将 session.cookie_lifetime ，session.gc_maxlifetime 的时间设置长一点。<br/>2，为什么初始化session的时候报错？<br/>a,检查session文件的存储路径，路径是否对，操作权限是否够<br/>b,检查session初始化之前是否有html 内容输出<br/>3，客户端在禁止使用cookie的时候，session会有影响吗？<br/>当客户端的cookie拒绝使用的情况下。将会带来很多的一些的不方便：<br/>php 会自动在页面的链接和表单等地方添加sessionId参数。以保证会话的<br/>继续，但是这个时候，在一个浏览器上多次手工输入一样地址，session<br/>会认作为多次会话而不是一次。<br/>4，为什么我的session 过几分钟就失效了？<br/>1,检查浏览器的cookie 是否启用，如果没有启用的话检查<br/>系统是否允许使用url传递sessionID,最后检查url_rewriter.tags设置<br/>2，检查session的垃圾标识时间，和回收概率<br/>5，如何将我的session 存储在数据库内？<br/>利用session_set_save_handler(&quot;open&quot;, &quot;close&quot;, &quot;read&quot;, &quot;write&quot;, &quot;destroy&quot;, &quot;gc&quot;)<br/>定制自己的处理方式。<br/>6，如何利用session 得到当前的用户数量和列表？<br/>如果将session存储在数据库内，就会很容易实现，但是不管用什么<br/>方式得到的数据不一定是精确数据。<br/>7，为什么我填写的表单在后退之后内容就不见了？<br/>检查脚本内有没有初始化session的动作，如果有的话，使用：<br/>session_cache_limiter(&#039;private, must-revalidate&#039;);<br/>6，如何利用session来控制网页的缓存？<br/>调整session.cache_limiter ，session.cache_expire<br/>8，我用session管理会话，如果同一个帐户在两台机器上同时登陆会有影响吗？<br/>不会有影响。因为这是两个sessionID.也就是说服务器上有两个session文件<br/>来保证各自的会话。<br/>////////////////////////////////////&nbsp;&nbsp; SESSION 工作原理 ////////////////////////////////////<br/>client---------&gt;1.request-------------------------&gt;server<br/>2. session_start();<br/>&#124;&lt;-------------3.reponse(SESSION_ID)&lt;--------&#124;<br/>&#124;-------------&gt;4.request(SESSION_ID)---------&gt;&#124;<br/>5. session_start();<br/>&#124;&lt;-------------6.reponse(SESSION_ID)&lt;---------&#124;<br/>&#124;-------------&gt;7. request(SESSION_ID + logout)--&gt;&#124;<br/>8. session_destroy();<br/>&#124;&lt;-------------9. reponse(删除cookie文件)&lt;-------&#124;<br/>1．client打开网页，向server发出请求，client上由于没有相应的cookie文件存在，在请求中不输送SESSION_ID<br/>2．服务器在接受到client的请求后，通过执行session_start()函数开始进行session的处理，首先确认请求中有没有 SESSION_ID，如果没有的话，发行一个新的SESSION_ID；如果有的话，则调用那个存有SESSION_ID的文件，并把信息写 入$_SESSION里去，并存入以sess_开头的文件里。<br/>3．把写入信息的$_SESSION参数发回给client，client在GET服务器发来的信息后，把这些信息保存在cookie里。<br/>4．client把cookie里的SESSION_ID一起写入header后再次向server发出请求。重复1-3的操作<br/>7．client发出登出请求<br/>8．服务器接受请求后，通过执行session_destroy()函数开始删除session文件处理<br/>9．服务器向client发出删除保存在client上的cookie文件的命令:&nbsp;&nbsp; setcookie(session_name(), &#039;&#039;, time()-60, &#039;/&#039;);<br/>(转载)<br/>////////////////////////////////////&nbsp;&nbsp; SESSION处理 ////////////////////////////////////<br/>● SESSION开始<br/>·执行SESSION开始处理的函数：session_start();<br/>·SESSION开始后的处理：<br/>1．如果服务器上还没有保存SESSION变量的话，那么首先确保保存SESSION变量的空间<br/>2．如果client有session id送出的话，那么把保存的SESSION变量复原到$_SESSION里去<br/>3．Gabadge Collection功能根据启动概率来启动<br/>注意点：1．如果php.ini中“session.auto_start = 1”的话，那么不执行session_start()，session也会自动开始。<br/>2．session_start(); 命令有2个目的。如果client和sever之间还没有建立session关系的话，那么服务器发行一个新的SESSION_ID，如果有的话，读取那个session文件的信息<br/>·在一句script完了后，要做以下的输出工作：<br/>1．在被确保了空间的SESSION变量中写入信息数据<br/>2．向client发送含有session id的Cookie (这个信息在HTTP的response header里)<br/>如果客户端的cookie无效的时候，将session.use_trans_sid设定为“1”，将session id的信息通过URL或者hidden field来传输。<br/>3．将session信息包村起来。初始化状态的session文件名为sess_&lt;SESSIONID&gt;<br/>●SESSION手动删除<br/>session_unset();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 多项释放。将所有登陆在session文件里的变量释放出来<br/>unset($_SESSION[‘登录的变量名’]);&nbsp;&nbsp;&nbsp;&nbsp;单项释放。释放所指定的登录在$_SESSION参数里的变量<br/>$_SESSION = array();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 多项释放。释放所有登录在$_SESSION参数里的变量<br/>session_destroy();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除服务器上的session文件<br/>注意：<br/>1．unset($_SESSION)这个函数会将全局变量$_SESSION销毁，而且还没有可行的办法将其恢复。<br/>用户也不再可以注册$_SESSION变量，所以此函数千万不可使用。<br/>2．session_unset() 和 $_SESSION = array()两者的目的都是一样的，都是多项释放登陆在session文件里的变量。<br/>但是对于PHP4.06以前的版本来说，session函数方面使用了session_register()、 session_unregister()、session_is_registered()、session_unset()，可以把global变量 作为session变量进行登陆，对于维持互换性的继续，建议使用session_unset()。<br/>对于新版本PHP4.06以后的版本来说比较推荐使用$_SESSION = array();<br/>●SESSION系统设定废弃法(垃圾处理)<br/>session.gc_maxlifetime = 1440 （初始值）<br/>最后一次access以后过了1440秒，自动删除被跟踪的session信息文件<br/>session.gc_probability = 1 （初始值）<br/>session.gc_divisor = 100 （初始值）<br/>Gabadge Collection启动后跟踪session信息文件。其启动概率为session.gc_probability/ session.gc_divisor<br/>也就是说不是每个session信息文件都有100%的被系统当作垃圾来处理的。<br/>如果直接关闭浏览器的话，session信息文件很多情况下都是留在了服务器上<br/>如果把概率改成了100%，虽然Gabadge Collection百分之百被启动了，但是这会对服务器添加负荷，<br/>也就失去了GC本身的意义了<br/>////////////////////////////////////&nbsp;&nbsp; 关于SESSION的其他有关函数 ////////////////////////////////////<br/>●session.cookie_path和session.cookie_domain<br/>session.cookie_path 是指浏览器在打开指定的path时，向服务器发送cookie<br/>譬如：session.cookie_path = “/app/portal”，那么在打开/app/portal/list.php时就向服务器发送cookie信息<br/>而如果打开的是/mro/index.php的时候，就不发送cookie信息了。<br/>这个优点类似于我们在IE上设定什么样的网站启动Cookie功能，什么样的网站阻止Cookie功能一样<br/>session.cookie_domain 的设定就是把路径改成了domain，一般其色定内容和session.cookie_path一样<br/>●session.cookie_lifetime<br/>session.cookie_lifetime = 0 （初始值）<br/>这里的有效期是指被保存在client上的cookie的有效期。初始值为0，也就是关闭浏览器的话，<br/>在client上被保存的cookie就被清除了。<br/>●session.use_cookies<br/>session.use_cookies = 1 （初始值）<br/>session.use_cookies是设置client在保存session id的时候是否利用cookie的一个参数。当它为“1”时，<br/>就说明启动了session cookie，可以用下面的查询来得到目前的session id：<br/>&lt;? echo &quot;现在的session id = &quot;. $_COOKIE[&quot;PHPSESSID&quot;]; ?&gt;<br/>当然，如果client的浏览器不支持cookie的话，即使这个参数等于“1”，用上述的查询也只会得到null。<br/>※为了和setcookie区别开，这里用session cookie的名字，除了两者在client上被保存的地方不同，其他还有什么区别不太明白。<br/>●session.use_trans_sid 和 session.use_only_cookies<br/>session.use_only_cookies = Off （初始值）<br/>当它为无效的时候，允许利用cookie通过URL来传递session id，对于一些不支持cookie的浏览器<br/>而又需要session管理的来说，虽然在 security上有被攻击的可能，但这个值必须为无效，否则无法进行网页转移。<br/>※对于不支持cookie而又用到session来进行管理的浏览器的安全问题，我只了解这些，希望大家多多给予其他方案<br/>如果客户的浏览器是支持cookie的，那么强烈推荐“session.use_only_cookies = On”，<br/>当session.use_only_cookies为有效时，即使想通过URL来传递session id也会被认为无效，<br/>这样可以减少通过sessionid被攻击的可能性。<br/>session.use_trans_sid = 0 （初始值）<br/>对于一些不支持cookie的浏览器而又用到了session管理的网页，在网页转移时必须将session id填入URL里<br/>&lt;form action=”nextpage.php?&lt;?=SID?&gt;”&gt;，但是每个网页上都写的话就比较累人了，这里如果把<br/>session.use_trans_sid设定为“1”的话，那么只要写&lt;formaction=”nextpage.php”&gt;，session id就会自动加在URL上了。<br/>※这里的URL必须是相对路径<br/>当利用session.use_trans_sid为有效时，session.use_only_cookies一定要设置为无效，否则就无法<br/>(转载)<br/><br/>=========================解决方法平自网上======================================<br/><br/>eaccelerator的功能除了对php预编译代码进行优化、缓存之外，还提供了php开发下的共享内存操作、session内存存储、内容缓存等功能。<br/>php默认的session存储方式是在磁盘，虽然可以配置php生成的文件目录到内存盘中，但最终还是需要依赖于文件系统，势必产生文件操纵的开销。当 网站并发请求很高的时候，还会产生另为一个性能问题：session目录下的文件数目过多，达到操纵系统瓶颈，虽然这时也可以通过配置为多级目录，但依旧 无法摆脱文件系统的魔爪。<br/>“session.save_path = “N;/path””<br/>eaccelerator专门针对PHP的这个Session存储效率问题，通过使用共享内存技术为我们提供了高效的解决方案。注意，要启用对 session支持，再编译安装eaccelerator时需要启用-with-eaccelerator-sessions选项，例如：<br/>./configure –with-php-config=/usr/local/bin/php-config –enable-eaccelerator=shared –with-eaccelerator-shared-memory –with-eaccelerator-sessions –with-eaccelerator-content-caching –with-eaccelerator-disassembler –with-eaccelerator-debug<br/>然后我们便可以在php.ini中修改配置来启用它：<br/>session.save_handler = eaccelerator<br/>最后重启apache，并执行如下测试：session.php<br/><textarea name="code" class="html" rows="15" cols="100">
&lt;?php
/**
* new session hander test.
* by lowell from www.zhongguowen.com
*/
if(!function_exists(“eaccelerator_set_session_handlers”))
&#123;
die(“eaccelerator is in trouble!”);
&#125;
switch($_GET[&quot;act&quot;])
&#123;
case “logout”:
session_unset();
session_destroy();
header(“Location: “ . $_SERVER[&quot;PHP_SELF&quot;]);
break; case “login”:
$_SESSION[&quot;user&quot;] = “Lowell Zhong”;
header(“Location: “ . $_SERVER[&quot;PHP_SELF&quot;]);
break;
&#125;
if(isset($_SESSION[&quot;user&quot;]) &amp;&amp; $_SESSION[&quot;user&quot;] != “”)
&#123;
echo “Welcome “ . $_SESSION[&quot;user&quot;] . “ [logout]&#92;n“;
&#125;else&#123;
echo “Click me for logining”;
&#125;
?&gt;
</textarea><br/>这里再推荐另外还一个php session的共享内存存储模块：http://www.ossp.org/pkg/lib/mm/<br/><br/>[缓存]　一个最最最简单的eAccelerator缓冲计数器 <br/>简单说明：把他理解为一个最最最简单的数据库，其只能使用索引来操作值： <br/>函数说明： <br/>查询值：eaccelerator_get(string $key) 没有结果返回NULL <br/>更新值：eaccelerator_put(string $key, mixed $needle, int $ttl); <br/>删除值：eaccelerator_rm(string $key); <br/>计数器说明： <br/>每$intUpdateBase次计数才更新到记录文件（你可以操作到数据库） <br/><textarea name="code" class="html" rows="15" cols="100"> 
&lt;?php
$strCountKey = &#039;count_key&#039;;
$intUpdateBase = 100;
$intCount = eaccelerator_get(&quot;$strCountKey&quot;);
if(!$intCount &#124;&#124; $intCount&lt;1)&#123;
&nbsp;&nbsp;if(file_exists(dirname(__FILE__).&quot;/$strCountKey.log&quot;))&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$strCount = file_get_contents(dirname(__FILE__).&quot;/$strCountKey.log&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;$strCount = trim($strCount);
&nbsp;&nbsp;&nbsp;&nbsp;$intCount = intval($strCount);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if(!$intCount &#124;&#124; $intCount&lt;1)&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$intCount = 0;
&nbsp;&nbsp;&#125;
&#125;
eaccelerator_put(&quot;$strCountKey&quot;, ++$intCount, 86400);
echo($intCount);
if($intCount%$intUpdateBase==0)&#123;
&nbsp;&nbsp;$fp = fopen(dirname(__FILE__).&quot;/$strCountKey.log&quot;,&#039;w&#039;);
&nbsp;&nbsp;fputs($fp,$intCount);
&nbsp;&nbsp;fclose($fp);
&#125;
/// eaccelerator_rm(&quot;$strCountKey&quot;);
exit;
?&gt;
</textarea><br/><br/>eaccelerator默认安装没有eaccelerator_put等函数问题：<br/>配置的时候一定要加上<br/><br/>$./configure --enable-eaccelerator --with-php-config=/usr/bin/php-config --with-eaccelerator-content-caching&nbsp;&nbsp;--with-eaccelerator-debug --with-eaccelerator-sessions --with-eaccelerator-shared-memory<br/>$make<br/>$sudo cp modules/eaccelerator.* /usr/lib/php5/20060613+lfs/<br/>$more /etc/php5/apache2/php.ini<br/><br/>extension=&quot;eaccelerator.so&quot;<br/>eaccelerator.shm_size=&quot;16&quot;<br/>eaccelerator.cache_dir=&quot;/opt/all_in_one/eaccelerator&quot;<br/>eaccelerator.enable=&quot;1&quot;<br/>eaccelerator.optimizer=&quot;1&quot;<br/>eaccelerator.check_mtime=&quot;1&quot;<br/>eaccelerator.debug=&quot;0&quot;<br/>eaccelerator.filter=&quot;&quot;<br/>eaccelerator.shm_max=&quot;0&quot;<br/>eaccelerator.shm_ttl=&quot;0&quot;<br/>eaccelerator.shm_prune_period=&quot;0&quot;<br/>eaccelerator.shm_only=&quot;0&quot;<br/>eaccelerator.compress=&quot;1&quot;<br/>eaccelerator.compress_level=&quot;9&quot;<br/><br/>===================================<br/>eaccelerator相关函数介绍 <br/>1. eaccelerator_put($key, $value, $ttl=0) <br/>&nbsp;&nbsp; 将 $value 以 $key 为键名存进缓存(php4下支持对像类型，看源码好像zend2里不支持了)，$ttl 是这个缓存的生命周期，单位是秒，省略该参数或指定为 0 表示不限时，直到服务器重启清空为止。 <br/><br/>2. eaccelerator_get($key) <br/>&nbsp;&nbsp; 根据 $key 从缓存中返回相应的 eaccelerator_put() 存进去的数据，如果这项缓存已经过期或不存在那么返回值是 NULL <br/><br/>3. eaccelerator_rm($key) <br/>&nbsp;&nbsp; 根据 $key 移除缓存 <br/><br/>4. eaccelerator_gc() <br/>&nbsp;&nbsp; 移除清理所有已过期的 key <br/><br/>5. eaccelerator_lock($key) <br/>&nbsp;&nbsp; 为 $key 加上锁定操作，以保证多进程多线程操作时数据的同步。需要调用 eaccelerator_unlock($key) 来释放这个锁或等待程序请求结束时自动释放这个锁。 <br/>&nbsp;&nbsp; 例如: <br/>&nbsp;&nbsp; &lt;?php <br/>&nbsp;&nbsp;&nbsp;&nbsp; eaccelerator_lock(&quot;count&quot;); <br/>&nbsp;&nbsp;&nbsp;&nbsp; eaccelerator_put(&quot;count&quot;,eaccelerator_get(&quot;count&quot;)+1)); <br/>&nbsp;&nbsp; ?&gt; <br/><br/>6. eaccelerator_unlock($key) <br/>&nbsp;&nbsp; 根据 $key 释放锁 <br/><br/>7. eaccelerator_cache_output($key, $eval_code, $ttl=0) <br/>&nbsp;&nbsp; 将 $eval_code 代码的输出缓存 $ttl 秒，（$ttl参数同 eacclerator_put） <br/>&nbsp;&nbsp;&nbsp;&nbsp;For Example: <br/>&nbsp;&nbsp; &lt;?php eaccelerator_cache_output(&#039;test&#039;, &#039;echo time(); phpinfo();&#039;, 30); ?&gt; <br/><br/>8. eaccelerator_cache_result($key, $eval_code, $ttl=0) <br/>&nbsp;&nbsp; 将 $eval_code 代码的执行结果缓存 $ttl 秒，（$ttl参数同 eacclerator_put），类似 cache_output <br/>&nbsp;&nbsp;&nbsp;&nbsp;For Example: <br/>&nbsp;&nbsp; &lt;?php eaccelerator_cache_result(&#039;test&#039;, &#039; time() . &quot;Hello&quot;;&#039;, 30); ?&gt; <br/><br/>9. eaccelerator_cache_page($key, $ttl=0) <br/>&nbsp;&nbsp; 将当前整页缓存 $ttl 秒。 <br/>&nbsp;&nbsp; For Example: <br/>&nbsp;&nbsp; &lt;?php <br/>&nbsp;&nbsp;&nbsp;&nbsp; eaccelerator_cache_page($_SERVER[&#039;PHP_SELF&#039;].&#039;?GET=&#039;.serialize($_GET),30); <br/>&nbsp;&nbsp;&nbsp;&nbsp; echo time(); <br/>&nbsp;&nbsp;&nbsp;&nbsp; phpinfo(); <br/>&nbsp;&nbsp; ?&gt; <br/><br/>10. eaccelerator_rm_page($key) <br/>&nbsp;&nbsp; 删除由&nbsp;&nbsp; eaccelerator_cache_page() 执行的缓存，参数也是 $key<br/><br/>=============================================================<br/>什么是eAccelerator<br/>概念： <br/>eAccelerator 是一个免费开源的PHP加速、优化、编译和动态缓存的项目，它可以通过缓存PHP代码编译后的结果来提高PHP脚本的性能，使得一向很复杂和离我们很远的PHP脚本编译问题完全得到解决。通过使用eAccelerator，可以优化你的PHP代码执行速度，降低服务器负载，可以提高PHP应用执行速度最高达10倍。<br/>原理： <br/>eAccelerator 通过把经过编译后的PHP代码缓存到共享内存中，并在用户访问的时候直接调用从而起到高效的加速作用。它的效率非常高，从创建共享内存到查找编译后的代码都在非常短的时间内完成，对于不能缓存到共享内存中的文件和代码，eAccelerator还可以把他们缓存到系统磁盘上。 <br/>eAccelerator 同样还支持PHP代码的编译和解释执行，你可以通过encoder.php脚本来对php代码进行编译达到保护代码的目的，经过编译后的代码必须运行在安装了eAccelerator的环境下。eAccelerator编译后的代码不能被反编译，它不象其他一些编译工具那样可以进行反编译，这将使得代码更加安全和高效。<br/>注意：在共享内存里面寻找编译好的PHP程序时，会在很短的时间内产生一些锁定，所以一个程序可以被多个进程同时执行。不适合放入共享内存的文件将被缓存到硬盘上。<br/>配置： <br/>eaccelerator.enable<br/>决定eAccelerator是否有效。“1”为有效，“0”为无效，默认为“1”。<br/>eaccelerator.optimizer<br/>是否使用内置的优化工具加速代码的执行。“1”为是，“0”为否，默认为“1”。<br/>eaccelerator.debug<br/>是否记录eAccelerator debug log。“1”为是，“0”为否，默认为“0”。<br/>eaccelerator.shm_size<br/>eAccelerator使用共享内存的总数。单位是MB，设置为“0”，则为操作系统默认值，默认为“0”。<br/>eaccelerator.check_mtime<br/>是否检查php程序更新时间。“1”为是，“0”为否。如果你想改变php程序后重编译程序到共享内存，那就应该设置为“1”，默认为“1”，如果设置为“0”，那么修改php脚本后的产生的效果将不被显示。<br/>eaccelerator.filter<br/>决定哪些php文件被缓存。你可能需要指定哪些文件（如：&quot;*.php *.phtml&quot;）需要被缓存。如果在文件前加上“!”,那么符合条件的文件将被忽略。默认为&quot;&quot;，这以为着所有php文件都会被缓存。<br/>eaccelerator.shm_max<br/>设置诸如“eaccelerator_put()”之类的函数能往共享内存里面加载数据的大小。单位为MB。“0”为不限制，默认为“0”。<br/>eaccelerator.shm_ttl<br/>当共享内存空间已满，将删除在“shm_ttl”秒前没有使用的程序。默认为0，为不删除任何文件。<br/>eaccelerator.shm_prune_period<br/>共享内存已满。前一次操作是在shm_prune_period秒之前，那么这一次将删除所有的旧程序。默认为“0”,意为不删除任何程序。<br/>eaccelerator.shm_only<br/>是否把编译后程序缓存到硬盘上。这个选项对session数据和内容（content）缓存无效。默认为“0”，意为同时使用共享内存和硬盘做缓存。<br/>eaccelerator.allowed_admin_path<br/>允许得到管理信息和管理操作的脚本路径。复制control.php文件到你的跟目录下，你可以在control.php文件中设置用户名和密码以进入控制面板。<br/>eaccelerator.keys<br/>eaccelerator.sessions<br/>eaccelerator.content<br/>缓存方式，这些可能的值是： <br/>&quot;shm_and_disk&quot;<br/>- 缓存数据在共享内存和硬盘上（默认值）<br/>&quot;shm&quot;<br/>- 缓存数据在共享内存，如果共享内存已满或者提交的数据大小超过eaccelerator.shm_max，则存储在硬盘上。<br/>&quot;shm_only&quot;<br/>- 只缓存数据在共享内存<br/>&quot;disk_only&quot;<br/>- 只缓存数据在硬盘<br/>&quot;none&quot;<br/>- 不缓存数据<br/>eaccelerator.name_space<br/>一个对所有键值假拟的字符串。通过在.htaccess文件中设置的这个值，允许两个应用使用相同的键值运行在同一个主机上。否则不同虚拟主机的键值不会相互影响的，所以不同虚拟主机一般有各自的：control.php。<br/>函数： <br/>eaccelerator_put($key, $value, $time);<br/>将 $value 以 $key 为键名存进缓存，$time 为0或不指定时，表示不限时，为其它数字时，单位是秒。返回bool值。<br/>eaccelerator_get($key);<br/>根据 $key 从缓存中返回相应的 eaccelerator_put() 存进去的数据，如果这项缓存已经过期或不存在那么返回值是 NULL。<br/>eaccelerator_rm($key);<br/>根据 $key 移除缓存<br/>eaccelerator_gc();<br/>移除清理所有已过期的 $key<br/>eaccelerator_lock(&quot;count&quot;);//为 $key 加上锁定操作，以保证多进程多线程操作时数据的同步。<br/>eaccelerator_put(&quot;count&quot;,eaccelerator_get(&quot;count&quot;)+1));<br/>eaccelerator_unlock(&quot;count&quot;);//根据 $key 释放锁<br/>eaccelerator_cache_output($key, $php_code, $time);<br/>将 $php_code 代码的执行输出缓存 $time 秒，（$time参数同 eacclerator_put），例如：<br/>eaccelerator_cache_output(&#039;test&#039;, &#039;echo time(); phpinfo();&#039;, 5);<br/>eaccelerator_cache_result($key, $php_code, $time);<br/>将 $php_code 代码的执行结果缓存 $time 秒，（$time参数同 eacclerator_put），例如：<br/>echo eaccelerator_cache_result(&#039;test&#039;, &#039;time().&quot; Hello&quot;;&#039;, 10);<br/>eaccelerator_cache_page($key, $time);<br/>将当前整页缓存 $time 秒（$time参数同 eacclerator_put）<br/>eaccelerator_rm_page($key);<br/>删除由 eaccelerator_cache_page() 执行的缓存，参数也是 $key。<br/>eaccelerator_caching ($bool);<br/>是否开启eaccelerator缓存，$bool可以为TRUE或FALSE。这个操作具有全局性，一个脚本设置后全局有效，所以并不常用。<br/>eaccelerator_optimizer ($bool);<br/>是否开启eaccelerator优化，$bool可以为TRUE或FALSE。这个操作具有全局性，一个脚本设置后全局有效，所以并不常用。<br/>eaccelerator_info();<br/>返回关于eaccelerator信息的数组。<br/>eaccelerator_list_keys()<br/>返回包含所有键名的缓存信息的数组，包括过期的键名。包含创建时间、失效时间、是否失效等等。<br/>eaccelerator_clear()<br/>清除缓存，是全部。相当于重启服务器对eaccelerator的影响，即清除所有在共享内存及硬盘中的缓存。<br/>eaccelerator_clean()<br/>清理缓存，清理过期的缓存。<br/><br/><br/>========<br/>另外有没有测试过XCache和eaccelerator以及APC哪个好一点？谢谢～！<br/>张宴 回复于 2008-6-11 09:09<br/>xcache、eaccelerator 可以和Zend Optimizer 共用，而APC不能。<br/>xcache、eaccelerator的性能对比，有人做过测试，有时间你也可以自己试试：<br/>http://hi.baidu.com/jgs80/blog/item/449508467188340a6b63e59d.html [访问失效了]<br/>可以参考下这个：http://hi.baidu.com/leolance/blog/item/be607350bcd49a43574e00e2.html<br/><br/>通过用strace去了解情况：<br/>http://blog.csdn.net/ei__nino/article/details/7825195
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post/4830/#blogcomment63392</link>
<title><![CDATA[[评论] [回收机制]PHP中SESSION机制探究,PHP中如何保持SESSION以及由此引发的一些思考，及共享内存实现方法探究之eaccelerator相关函数介绍  ]]></title> 
<author>gdmlclean72 &lt;nyth56@mail114.net&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Sun, 11 Dec 2011 11:58:41 +0000</pubDate> 
<guid>http://www.jackxiang.com/post/4830/#blogcomment63392</guid> 
<description>
<![CDATA[ 
	路过这里，支持一下子！！！！！！！！
]]>
</description>
</item>
</channel>
</rss>