<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>浮山狼de博客 &#187; session</title>
	<atom:link href="https://www.fushanlang.com/tag/session/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fushanlang.com</link>
	<description>next station - 下一站，活在当下，且行且思</description>
	<lastBuildDate>Sat, 29 Nov 2014 15:14:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.5</generator>
	<item>
		<title>PHP store session with couchbase</title>
		<link>https://www.fushanlang.com/php-store-session-with-couchbase-2302/</link>
		<comments>https://www.fushanlang.com/php-store-session-with-couchbase-2302/#comments</comments>
		<pubDate>Wed, 11 Sep 2013 06:10:34 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2302</guid>
		<description><![CDATA[如何用couchbase存储session <p>有两种常见方式： 1.采用memcache模式连接couchbase 只需两句修改：</p> ini_set('session.save_handler', 'memcache'); ini_set('session.save_path', 'tcp://couchbase_host:9999'); <p>注意里面的9999是couchbase 里面创建的bucket的对外memcache端口，这种访问方式运行以memcache兼容的模式访问couchbase。 2.采用couchbase扩展添加一个sessionhandler如下：</p> /**** * php storage session with couchbase * by fushanlang@gmail.com */ /*** * SessionHandlerInterface is a internal interface only for PHP_VERSION>=5.4.0 * so if interface_exists() false we need to define by yourself. */ if (!interface_exists('SessionHandlerInterface')) { interface SessionHandlerInterface { public function close(); public <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/php-store-session-with-couchbase-2302/">PHP store session with couchbase</a></span>]]></description>
				<content:encoded><![CDATA[<h2>如何用couchbase存储session</h2>
<p>有两种常见方式：<br />
1.采用memcache模式连接couchbase 只需两句修改：</p>
<pre name="code" class="php">
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://couchbase_host:9999');
</pre>
<p>注意里面的9999是couchbase 里面创建的bucket的对外memcache端口，这种访问方式运行以memcache兼容的模式访问couchbase。<br />
2.采用couchbase扩展添加一个sessionhandler如下：</p>
<pre name="code" class="php">
/****
 * php storage session with couchbase
 * by fushanlang@gmail.com
 */

/***
 * SessionHandlerInterface is a internal interface only for PHP_VERSION>=5.4.0
 * so if interface_exists() false we need to define by yourself.
 */
if (!interface_exists('SessionHandlerInterface')) {
    interface SessionHandlerInterface
    {
        public function close();

        public function destroy($session_id);

        public function gc($maxlifetime);

        public function open($save_path, $session_id);

        public function  read($session_id);

        public function write($session_id, $session_data);
    }
}
/**
 * A reference implementation of a custom Couchbase session handler.
 */
class CouchbaseSessionHandler implements SessionHandlerInterface
{

    /**
     * Holds the Couchbase connection.
     */
    protected $_connection = null;

    /**
     * The Couchbase host and port.
     */
    protected $_host = null;

    /**
     * The Couchbase bucket name.
     */
    protected $_bucket = null;

    /**
     * The prefix to be used in Couchbase keynames.
     */
    protected $_keyPrefix = 'session:';

    /**
     * Define a expiration time of 10 minutes.
     */
    protected $_expire = 600;

    /**
     * Set the default configuration params on init.
     */
    public function __construct($host = '127.0.0.1:8091', $bucket = 'default')
    {
        $this->_host = $host;
        $this->_bucket = $bucket;
    }

    /**
     * Open the connection to Couchbase (called by PHP on `session_start()`)
     */
    public function open($savePath, $sessionName)
    {
        $this->_connection = new Couchbase($this->_host, '', '', $this->_bucket);
        return $this->_connection ? true : false;
    }

    /**
     * Close the connection. Called by PHP when the script ends.
     */
    public function close()
    {
        unset($this->_connection);
        return true;
    }

    /**
     * Read data from the session.
     */
    public function read($sessionId)
    {
        $key = $this->_keyPrefix . $sessionId;
        $result = $this->_connection->get($key);

        return $result ? : null;
    }

    /**
     * Write data to the session.
     */
    public function write($sessionId, $sessionData)
    {
        $key = $this->_keyPrefix . $sessionId;
        if (empty($sessionData)) {
            return false;
        }

        $result = $this->_connection->set($key, $sessionData, $this->_expire);
        return $result ? true : false;
    }

    /**
     * Delete data from the session.
     */
    public function destroy($sessionId)
    {
        $key = $this->_keyPrefix . $sessionId;
        $result = $this->_connection->delete($key);

        return $result ? true : false;
    }

    /**
     * Run the garbage collection.
     */
    public function gc($maxLifetime)
    {
        return true;
    }

}

//usage example
define('COUCHBASE_HOST_PORT','xxxxx:8091');
define('COUCHBASE_BUCKET','session');

if(class_exists('Couchbase')&#038;&#038;defined('COUCHBASE_HOST_PORT')&#038;&#038;defined('COUCHBASE_BUCKET')){
    $handler = new CouchbaseSessionHandler(COUCHBASE_HOST_PORT,COUCHBASE_BUCKET);
    if(version_compare(PHP_VERSION,'5.4.0')>=0){
        session_set_save_handler($handler,true);
    }else{
        session_set_save_handler(
            array($handler, 'open'),
            array($handler, 'close'),
            array($handler, 'read'),
            array($handler, 'write'),
            array($handler, 'destroy'),
            array($handler, 'gc'));
    }
}
session_start();
</pre>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/php-store-session-with-couchbase-2302/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>理解PHP session机制(zhuan)</title>
		<link>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/</link>
		<comments>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/#comments</comments>
		<pubDate>Wed, 11 Sep 2013 05:55:12 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=2300</guid>
		<description><![CDATA[<p>1.session.save_handler = files</p> <p>* 1. session_start() 1. session_start()是session机制的开始，它有一定概率开启垃圾回收,因为session是存放在文件中， PHP自身的垃圾回收是无效的，SESSION的回收是要删文件的，这个概率是根据php.ini的配置决定的， 但是有的系统是 session.gc_probability = 0，这也就是说概率是0，而是通过cron脚本来实现垃圾回收。</p> <p>session.gc_probability = 1 session.gc_divisor = 1000 session.gc_maxlifetime = 1440//过期时间 默认24分钟 //概率是 session.gc_probability/session.gc_divisor 结果 1/1000, //不建议设置过小，因为session的垃圾回收，是需要检查每个文件是否过期的。 session.save_path = //好像不同的系统默认不一样，有一种设置是 &#8220;N;/path&#8221; //这是随机分级存储，这个样的话，垃圾回收将不起作用，需要自己写脚本</p> <p>2. session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值， 这个值可以从php.ini找到</p> <p>session.name = PHPSESSID //默认值PHPSESSID</p> <p>3. 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端. 相当于执行了下面COOKIE 操作，注意的是，这一步执行了setcookie()操作，COOKIE是在header头中发送的， 这之前是不能有输出的，PHP有另外一个函数 session_regenerate_id() 如果使用这个函数，这之前也是不能有输出的。</p> <p>setcookie(session_name(), session_id(), session.cookie_lifetime,//默认0 session.cookie_path,//默认&#8217;/&#8217;当前程序跟目录下都有效 session.cookie_domain,//默认为空 )</p> <p>4. <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/">理解PHP session机制(zhuan)</a></span>]]></description>
				<content:encoded><![CDATA[<p>1.session.save_handler = files</p>
<p>* 1. session_start()<br />
1. session_start()是session机制的开始，它有一定概率开启垃圾回收,因为session是存放在文件中，<br />
PHP自身的垃圾回收是无效的，SESSION的回收是要删文件的，这个概率是根据php.ini的配置决定的，<br />
但是有的系统是 session.gc_probability = 0，这也就是说概率是0，而是通过cron脚本来实现垃圾回收。</p>
<p>session.gc_probability = 1<br />
session.gc_divisor = 1000<br />
session.gc_maxlifetime = 1440//过期时间 默认24分钟<br />
//概率是 session.gc_probability/session.gc_divisor 结果 1/1000,<br />
//不建议设置过小，因为session的垃圾回收，是需要检查每个文件是否过期的。<br />
session.save_path = //好像不同的系统默认不一样，有一种设置是 &#8220;N;/path&#8221;<br />
//这是随机分级存储，这个样的话，垃圾回收将不起作用，需要自己写脚本</p>
<p>2. session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值，<br />
这个值可以从php.ini找到</p>
<p>session.name = PHPSESSID //默认值PHPSESSID</p>
<p>3. 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端.<br />
相当于执行了下面COOKIE 操作，注意的是，这一步执行了setcookie()操作，COOKIE是在header头中发送的，<br />
这之前是不能有输出的，PHP有另外一个函数 session_regenerate_id() 如果使用这个函数，这之前也是不能有输出的。</p>
<p>setcookie(session_name(),<br />
session_id(),<br />
session.cookie_lifetime,//默认0<br />
session.cookie_path,//默认&#8217;/&#8217;当前程序跟目录下都有效<br />
session.cookie_domain,//默认为空<br />
)</p>
<p>4. 如果存在那么session_id = $_COOKIE[session_name];<br />
然后去session.save_path指定的文件夹里去找名字为&#8217;SESS_&#8217; . session_id()的文件.<br />
读取文件的内容反序列化，然后放到$_SESSION中<br />
* 2. 为$_SESSION赋值<br />
比如新添加一个值$_SESSION[&#8216;test&#8217;] = &#8216;blah'; 那么这个$_SESSION只会维护在内存中，当脚本执行结束的时候，<br />
用把$_SESSION的值写入到session_id指定的文件夹中，然后关闭相关资源. 这个阶段有可能执行更改session_id的操作，<br />
比如销毁一个旧的的session_id，生成一个全新的session_id.一半用在自定义 session操作，角色的转换上，<br />
比如Drupal.Drupal的匿名用户有一个SESSION的，当它登录后需要换用新的session_id</p>
<p>if (isset($_COOKIE[session_name()])) {<br />
setcookie(session_name(), &#8221;, time() &#8211; 42000, &#8216;/&#8217;);//旧session cookie过期<br />
}<br />
session_regenerate_id();//这一步会生成新的session_id<br />
//session_id()返回的是新的值</p>
<p>3.写入SESSION操作<br />
在脚本结束的时候会执行SESSION写入操作，把$_SESSION中值写入到session_id命名的文件中，可能已经存在，<br />
可能需要创建新的文件。<br />
* 4. 销毁SESSION<br />
SESSION发出去的COOKIE一般属于即时COOKIE，保存在内存中，当浏览器关闭后，才会过期，假如需要人为强制过期，<br />
比如 退出登录，而不是关闭浏览器，那么就需要在代码里销毁SESSION，方法有很多，<br />
o 1. setcookie(session_name(), session_id(), time() &#8211; 8000000, ..);//退出登录前执行<br />
o 2. usset($_SESSION);//这会删除所有的$_SESSION数据，刷新后，有COOKIE传过来，但是没有数据。<br />
o 3. session_destroy();//这个作用更彻底，删除$_SESSION 删除session文件，和session_id</p>
<p>当不关闭浏览器的情况下，再次刷新，2和3都会有COOKIE传过来，但是找不到数据</p>
<p>2.session.save_handler = user</p>
<p>用户自定义session处理机制，更加直观<br />
* session_set_save_handler(&#8216;open&#8217;, &#8216;close&#8217;, &#8216;read&#8217;, &#8216;write&#8217;, &#8216;destroy&#8217;, &#8216;gc&#8217;);<br />
1.session_start(),<br />
执行open($save_path, $session_name)打开session操作句柄<br />
$save_path 在session.save_handler = files的情况下它就是session.save_path，<br />
但是如果用户自定的话，这个两个参数都用不上，直接返回TRUE</p>
<p>执行read($id)从中读取数据.//这个参数是自动传递的就是session_id(),可以通过这个值进行操作。<br />
* 2.脚本执行结束<br />
执行write($id, $sess_data) //两个参数，很简单<br />
* 3.假如用户需要session_destroy()<br />
先执行destroy.在执行第2步</p>
<p>一个实际例子：</p>
<p>//SESSION初始化的时候调用<br />
function open($save_path, $session_name)<br />
{<br />
global $sess_save_path;<br />
$sess_save_path = $save_path;<br />
return(true);<br />
}</p>
<p>//关闭的时候调用<br />
function close()<br />
{<br />
return(true);<br />
}</p>
<p>function read($id)<br />
{<br />
global $sess_save_path;<br />
$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
return (string) @file_get_contents($sess_file);<br />
}<br />
//脚本执行结束之前，执行写入操作<br />
function write($id, $sess_data)<br />
{<br />
echo &#8220;sdfsf&#8221;;<br />
global $sess_save_path;</p>
<p>$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
if ($fp = @fopen($sess_file, &#8220;w&#8221;)) {<br />
$return = fwrite($fp, $sess_data);<br />
fclose($fp);<br />
return $return;<br />
} else {<br />
return(false);<br />
}</p>
<p>}</p>
<p>function destroy($id)<br />
{<br />
global $sess_save_path;</p>
<p>$sess_file = &#8220;$sess_save_path/sess_$id&#8221;;<br />
return(@unlink($sess_file));<br />
}</p>
<p>function gc($maxlifetime)<br />
{<br />
global $sess_save_path;</p>
<p>foreach (glob(&#8220;$sess_save_path/sess_*&#8221;) as $filename) {<br />
if (filemtime($filename) + $maxlifetime &lt; time()) {<br />
@unlink($filename);<br />
}<br />
}<br />
return true;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/understanding-of-php-session-mechanism-zhuan-2300/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP中的Session机制</title>
		<link>https://www.fushanlang.com/php-session-mechanism-in-339/</link>
		<comments>https://www.fushanlang.com/php-session-mechanism-in-339/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 02:27:48 +0000</pubDate>
		<dc:creator><![CDATA[fushanlang]]></dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://www.fushanlang.com/blog/?p=339</guid>
		<description><![CDATA[<p>做web开发，必然会涉及到Session，这是由于http协议本身是无状态的（每次响应都是独立的，彼此间没有联系），所以如果需要在页面跳转间保持某个用户的身份，就要在每次连接时告诉服务器端你的唯一标示号，即Session ID。这样，服务器端便可通过Session ID得到所需的数据。</p> <p>在PHP中，Session是通过$_SESSION这个全局变量来set/get的，不过在使用之前要先初始化。初始化是通过 session_start函数（如果php.ini中将session.auto_start设为1，则会自动初始化），之后PHP会为request 自动生成一个唯一随机数作为Session ID，生成算法默认提供了MD5 (128 bits) 和SHA-1 (160 bits)，由php.ini中session.hash_function设定。其实也可以自定义，比如在随机数基础上将来访者的IP地址也加入到算法中，像CodeIgniter1.7.2中代码： </p> Php代码 $sessid = &#8221;; while (strlen($sessid) &#60; 32) { $sessid .= mt_rand(0, mt_getrandmax()); } // To make the session ID even more secure we&#8217;ll combine it with the user&#8217;s IP $sessid .= $this-&#62;CI-&#62;input-&#62;ip_address(); $sessid = md5(uniqid($sessid, TRUE)) $sessid = ''; while (strlen($sessid) &#60; 32) { $sessid .= mt_rand(0, mt_getrandmax()); } // To make the session ID even more secure we'll combine it with the user's IP $sessid .= $this-&#62;CI-&#62;input-&#62;ip_address(); <span style="color:#777"> . . . &#8594; Read More: <a href="https://www.fushanlang.com/php-session-mechanism-in-339/">PHP中的Session机制</a></span>]]></description>
				<content:encoded><![CDATA[<p>做web开发，必然会涉及到Session，这是由于http协议本身是无状态的（每次响应都是独立的，彼此间没有联系），所以如果需要在页面跳转间保持某个用户的身份，就要在每次连接时告诉服务器端你的唯一标示号，即Session  ID。这样，服务器端便可通过Session ID得到所需的数据。</p>
<p>在PHP中，Session是通过$_SESSION这个全局变量来set/get的，不过在使用之前要先初始化。初始化是通过  session_start函数（如果php.ini中将session.auto_start设为1，则会自动初始化），之后PHP会为request  自动生成一个唯一随机数作为Session ID，生成算法默认提供了MD5 (128 bits) 和SHA-1 (160  bits)，由php.ini中session.hash_function设定。其实也可以自定义，比如在随机数基础上将来访者的IP地址也加入到算法中，像CodeIgniter1.7.2中代码：  <span id="more-339"></span></p>
<div>
<div>
<div>Php代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://koda.javaeye.com/blog/734265#"><img src="http://koda.javaeye.com/images/icon_copy.gif" alt="复制代码" /></a></div>
</div>
<ol>
<li>$sessid = &#8221;;</li>
<li>while (strlen($sessid) &lt; 32)</li>
<li>{</li>
<li> $sessid .= mt_rand(0, mt_getrandmax());</li>
<li>}</li>
<li>// To make the session ID even more secure we&#8217;ll combine it with the user&#8217;s IP</li>
<li>$sessid .= $this-&gt;CI-&gt;input-&gt;ip_address();</li>
<li>$sessid = md5(uniqid($sessid, TRUE))</li>
</ol>
</div>
<pre>$sessid = '';
while (strlen($sessid) &lt; 32)
{
	$sessid .= mt_rand(0, mt_getrandmax());
}
// To make the session ID even more secure we'll combine it with the user's IP
$sessid .= $this-&gt;CI-&gt;input-&gt;ip_address();
$sessid = md5(uniqid($sessid, TRUE))
</pre>
<p>生成的ID存放在服务器的某一目录下，这由php.ini中session.save_path配置。如果要在多个服务器中同步session  id，你可以将其存放在数据库或共享缓存中。这需要你自定义一系列Session的读写方法，并在调用session_start函数前先设定好，以下面代码为例(来自php  document中的一段示例代码)：</p>
<div>
<div>
<div>Sql代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://koda.javaeye.com/blog/734265#"><img src="http://koda.javaeye.com/images/icon_copy.gif" alt="复制代码" /></a></div>
</div>
<ol>
<li>CREATE TABLE `ws_sessions` (</li>
<li> `session_id` varchar(255) BINARY NOT NULL DEFAULT &#8221;,</li>
<li> `session_expires` int(10) UNSIGNED NOT NULL DEFAULT &#8216;0&#8217;,</li>
<li> `session_data` text,</li>
<li> PRIMARY KEY  (`session_id`)</li>
<li>) TYPE=InnoDB;</li>
</ol>
</div>
<pre>CREATE TABLE `ws_sessions` (
  `session_id` varchar(255) BINARY NOT NULL DEFAULT '',
  `session_expires` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `session_data` text,
  PRIMARY KEY  (`session_id`)
) TYPE=InnoDB;</pre>
<div>
<div>
<div>Php代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://koda.javaeye.com/blog/734265#"><img src="http://koda.javaeye.com/images/icon_copy.gif" alt="复制代码" /></a></div>
</div>
<ol>
<li>&lt;?php</li>
<li>class session {</li>
<li> // session-lifetime</li>
<li> var $lifeTime;</li>
<li> // mysql-handle</li>
<li> var $dbHandle;</li>
<li> function open($savePath, $sessName) {</li>
<li> // get session-lifetime</li>
<li> $this-&gt;lifeTime = get_cfg_var(&#8220;session.gc_maxlifetime&#8221;);</li>
<li> // open database-connection</li>
<li> $dbHandle = @mysql_connect(&#8220;server&#8221;,&#8221;user&#8221;,&#8221;password&#8221;);</li>
<li> $dbSel = @mysql_select_db(&#8220;database&#8221;,$dbHandle);</li>
<li> // return success</li>
<li> if(!$dbHandle || !$dbSel)</li>
<li> return false;</li>
<li> $this-&gt;dbHandle = $dbHandle;</li>
<li> return true;</li>
<li> }</li>
<li> function close() {</li>
<li> $this-&gt;gc(ini_get(&#8216;session.gc_maxlifetime&#8217;));</li>
<li> // close database-connection</li>
<li> return @mysql_close($this-&gt;dbHandle);</li>
<li> }</li>
<li> function read($sessID) {</li>
<li> // fetch session-data</li>
<li> $res = mysql_query(&#8220;SELECT session_data AS d FROM ws_sessions</li>
<li> WHERE session_id = &#8216;$sessID&#8217;</li>
<li> AND session_expires &gt; &#8220;.time(),$this-&gt;dbHandle);</li>
<li> // return data or an empty string at failure</li>
<li> if($row = mysql_fetch_assoc($res))</li>
<li> return $row[&#8216;d&#8217;];</li>
<li> return &#8220;&#8221;;</li>
<li> }</li>
<li> function write($sessID,$sessData) {</li>
<li> // new session-expire-time</li>
<li> $newExp = time() + $this-&gt;lifeTime;</li>
<li> // is a session with this id in the database?</li>
<li> $res = mysql_query(&#8220;SELECT * FROM ws_sessions</li>
<li> WHERE session_id = &#8216;$sessID'&#8221;,$this-&gt;dbHandle);</li>
<li> // if yes,</li>
<li> if(mysql_num_rows($res)) {</li>
<li> // &#8230;update session-data</li>
<li> mysql_query(&#8220;UPDATE ws_sessions</li>
<li> SET session_expires = &#8216;$newExp&#8217;,</li>
<li> session_data = &#8216;$sessData&#8217;</li>
<li> WHERE session_id = &#8216;$sessID'&#8221;,$this-&gt;dbHandle);</li>
<li> // if something happened, return true</li>
<li> if(mysql_affected_rows($this-&gt;dbHandle))</li>
<li> return true;</li>
<li> }</li>
<li> // if no session-data was found,</li>
<li> else {</li>
<li> // create a new row</li>
<li> mysql_query(&#8220;INSERT INTO ws_sessions (</li>
<li> session_id,</li>
<li> session_expires,</li>
<li> session_data)</li>
<li> VALUES(</li>
<li> &#8216;$sessID&#8217;,</li>
<li> &#8216;$newExp&#8217;,</li>
<li> &#8216;$sessData&#8217;)&#8221;,$this-&gt;dbHandle);</li>
<li> // if row was created, return true</li>
<li> if(mysql_affected_rows($this-&gt;dbHandle))</li>
<li> return true;</li>
<li> }</li>
<li> // an unknown error occured</li>
<li> return false;</li>
<li> }</li>
<li> function destroy($sessID) {</li>
<li> // delete session-data</li>
<li> mysql_query(&#8220;DELETE FROM ws_sessions WHERE session_id = &#8216;$sessID'&#8221;,$this-&gt;dbHandle);</li>
<li> // if session was deleted, return true,</li>
<li> if(mysql_affected_rows($this-&gt;dbHandle))</li>
<li> return true;</li>
<li> // &#8230;else return false</li>
<li> return false;</li>
<li> }</li>
<li> function gc($sessMaxLifeTime) {</li>
<li> // delete old sessions</li>
<li> mysql_query(&#8220;DELETE FROM ws_sessions WHERE session_expires &lt; &#8220;.time(),$this-&gt;dbHandle);</li>
<li> // return affected rows</li>
<li> return mysql_affected_rows($this-&gt;dbHandle);</li>
<li> }</li>
<li>}</li>
<li>$session = new session();</li>
<li>session_set_save_handler(array(&amp;$session,&#8221;open&#8221;),</li>
<li> array(&amp;$session,&#8221;close&#8221;),</li>
<li> array(&amp;$session,&#8221;read&#8221;),</li>
<li> array(&amp;$session,&#8221;write&#8221;),</li>
<li> array(&amp;$session,&#8221;destroy&#8221;),</li>
<li> array(&amp;$session,&#8221;gc&#8221;));</li>
<li>session_start();</li>
<li>// etc&#8230;</li>
<li>?&gt;</li>
</ol>
</div>
<pre>&lt;?php
class session {
   // session-lifetime
   var $lifeTime;
   // mysql-handle
   var $dbHandle;
   function open($savePath, $sessName) {
       // get session-lifetime
       $this-&gt;lifeTime = get_cfg_var("session.gc_maxlifetime");
       // open database-connection
       $dbHandle = @mysql_connect("server","user","password");
       $dbSel = @mysql_select_db("database",$dbHandle);
       // return success
       if(!$dbHandle || !$dbSel)
           return false;
       $this-&gt;dbHandle = $dbHandle;
       return true;
   }
   function close() {
       $this-&gt;gc(ini_get('session.gc_maxlifetime'));
       // close database-connection
       return @mysql_close($this-&gt;dbHandle);
   }
   function read($sessID) {
       // fetch session-data
       $res = mysql_query("SELECT session_data AS d FROM ws_sessions
                           WHERE session_id = '$sessID'
                           AND session_expires &gt; ".time(),$this-&gt;dbHandle);
       // return data or an empty string at failure
       if($row = mysql_fetch_assoc($res))
           return $row['d'];
       return "";
   }
   function write($sessID,$sessData) {
       // new session-expire-time
       $newExp = time() + $this-&gt;lifeTime;
       // is a session with this id in the database?
       $res = mysql_query("SELECT * FROM ws_sessions
                           WHERE session_id = '$sessID'",$this-&gt;dbHandle);
       // if yes,
       if(mysql_num_rows($res)) {
           // ...update session-data
           mysql_query("UPDATE ws_sessions
                         SET session_expires = '$newExp',
                         session_data = '$sessData'
                         WHERE session_id = '$sessID'",$this-&gt;dbHandle);
           // if something happened, return true
           if(mysql_affected_rows($this-&gt;dbHandle))
               return true;
       }
       // if no session-data was found,
       else {
           // create a new row
           mysql_query("INSERT INTO ws_sessions (
                         session_id,
                         session_expires,
                         session_data)
                         VALUES(
                         '$sessID',
                         '$newExp',
                         '$sessData')",$this-&gt;dbHandle);
           // if row was created, return true
           if(mysql_affected_rows($this-&gt;dbHandle))
               return true;
       }
       // an unknown error occured
       return false;
   }
   function destroy($sessID) {
       // delete session-data
       mysql_query("DELETE FROM ws_sessions WHERE session_id = '$sessID'",$this-&gt;dbHandle);
       // if session was deleted, return true,
       if(mysql_affected_rows($this-&gt;dbHandle))
           return true;
       // ...else return false
       return false;
   }
   function gc($sessMaxLifeTime) {
       // delete old sessions
       mysql_query("DELETE FROM ws_sessions WHERE session_expires &lt; ".time(),$this-&gt;dbHandle);
       // return affected rows
       return mysql_affected_rows($this-&gt;dbHandle);
   }
}
$session = new session();
session_set_save_handler(array(&amp;$session,"open"),
                         array(&amp;$session,"close"),
                         array(&amp;$session,"read"),
                         array(&amp;$session,"write"),
                         array(&amp;$session,"destroy"),
                         array(&amp;$session,"gc"));
session_start();
// etc...
?&gt;
</pre>
<p>除了上述方法外还有其他办法可以保持Session的同步，可以参考PHP SESSION解惑一文中第四部分“session的同步”。</p>
<p>下面再谈谈Session ID的传递方式：Cookie和URL传递。<br />
Cookie是比较常用的方式，在这种模式下，启动Session后服务器会在HTTP Response中自动加上header(‘Set-Cookie:  session_name()=session_id();  path=/’)，并在以后的请求中加上这个Cookie。当从该页跳转到的新页面并调用session_start()后，PHP将检查与给定ID相关联的服务器端存贮的session数据，如果没找到，则新建一个数据集。但是有一点，这种传递方式必须在用户浏览器开启Cookie的情况下才可用，如果万一用户关闭了Cookie，那么只好选择另外一种通过URL参数传递Session  ID。<br />
开启URL传递需要在php.ini中设置session.use_trans_sid（文档中提示使用这种方式会有安全风险，因为它显示地将Session  ID放在url中，所以除非迫不得已不要选择此方式），并在代码中做如下修改：</p>
<div>
<div>
<div>Php代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://koda.javaeye.com/blog/734265#"><img src="http://koda.javaeye.com/images/icon_copy.gif" alt="复制代码" /></a></div>
</div>
<ol>
<li>// 如果客户端使用cookie,可直接传递session到page2.php</li>
<li>echo &#8216;&lt;br /&gt;&lt;a href=&#8221;page2.php&#8221;&gt;page 2&lt;/a&gt;';</li>
<li>// 如果客户端禁用cookie</li>
<li>echo &#8216;&lt;br /&gt;&lt;a href=&#8221;page2.php?&#8217; . SID . &#8216;&#8221;&gt;page 2&lt;/a&gt;';</li>
<li>/*</li>
<li> 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session</li>
<li> 对应的cookie已经存在,那么SID将为(未定义)空</li>
<li>*/</li>
</ol>
</div>
<pre>// 如果客户端使用cookie,可直接传递session到page2.php
echo '&lt;br /&gt;&lt;a href="page2.php"&gt;page 2&lt;/a&gt;';
// 如果客户端禁用cookie
echo '&lt;br /&gt;&lt;a href="page2.php?' . SID . '"&gt;page 2&lt;/a&gt;';
/*
 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session
 对应的cookie已经存在,那么SID将为(未定义)空
*/</pre>
<p>关于Session的内容还有很多，具体可查看官方手册，如果有新的总结会继续更新。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fushanlang.com/php-session-mechanism-in-339/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.146 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2025-12-17 17:18:42 -->
