EcStart PHP 技術討論論壇's Archiver

FIEND 發表於 2006-3-18 03:13

轉貼 - mysql+session 的使用技巧

來源 : <br> <a href="http://www.chinahtml.com/programming/2/2006/php-11398215593520.shtml" target="_blank">http://www.chinahtml.com/program ... 1398215593520.shtml</a><br> <br> <br> <strong>一、问题起源<br><br></strong>稍
大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的
二级域名,而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个模块中都是可以登录使用的。各个服务器共享用户数据是比较容易实
现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在这个服务器登录之后,进入另一个服务
器的别的模块时,仍然需要重新登录,这就是一次登录,全部通行的问题,映射到技术上,其实就是各个服务器之间如何实现共享 SESSION 数据的问题。<br> <br> <strong>二、PHP SESSION 的工作原理</strong><br> <br>
在 解决问题之前,先来了解一下 PHP SESSION 的工作原理。在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用
session_start() 打开 SESSION,这样就会产生客户端的唯一标识 SESSION ID(此 ID 可通过函数
session_id() 获取/设置)。SESSION ID 可以通过两种方式保留在客户端,使得请求不同的页面时,PHP 程序可以获知客户端的
SESSION ID;一种是将 SESSION ID 自动加入到 GET 的 URL 中,或者 POST 的表单中,默认情况下,变量名为
PHPSESSID;另一种是通过 COOKIE,将 SESSION ID 保存在 COOKIE 中,默认情况下,这个 COOKIE 的名字为
PHPSESSID。这里我们主要以 COOKIE 方式进行说明,因为应用比较广泛。 <br> 那么 SESSION
的数据保存在哪里呢?当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。默认情况下,php.ini 中设置的 SESSION
保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,而
SESSION 文件保存的目录由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION
ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION
数据了。如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION
文件的保存,效率会提高很多,设置方法为:session.save_path="N;/save_path",N 为分级的级数,save_path
为开始目录。当写入 SESSION 数据的时候,PHP 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的
SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件。读取 SESSION
数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。<br> <br> <strong>三、多服务器共享 SESSION 的主要障碍及解决办法</strong><br> <br> 通过了解 SESSION 的工作原理,我们可以发现,在默认情况下,各个服务器会各自分别对同<br>
一 个客户端产生 SESSION ID,如对于同一个用户浏览器,A 服务器产生的 SESSION ID 是
30de1e9de3192ba6ce2992d27a1b6a0a,而 B 服务器生成的则是
c72665af28a8b14c0fe11afe3b59b51b。另外,PHP 的 SESSION 数据都是分别保存在<br> 本服务器的文件系统中。如下图所示:<br> <img style="width: 511px; height: 324px;" src="http://www.chinahtml.com/d/file/programming/2/2006-02-13/60bd56382fd0446196f0dcf80480320e.gif" border="0" height="324" width="511"><br>
确 定了问题所在之后,就可以着手进行解决了。想要共享 SESSION 数据,那就必须实现两个目标:一个是各个服务器对同一个客户端产生的
SESSION ID 必须相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的
COOKIE;<br> 另一个是 SESSION 数据的存储方式/位置必须保证各个服务器都能够访问到。<font color="#008000">简单地说就是多<br>服务器共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。</font><br> <br> 第一个目标的实现其实很简单,只需要对 COOKIE 的域(domain)进行特殊地设置即可,<br> 默认情况下,COOKIE 的域是当前服务器的域名/IP 地址,而域不同的话,各个服务器所设<br> 置的 COOKIE 是不能相互访问的,如 <img style="width: 501px; height: 254px;" src="http://www.chinahtml.com/d/file/programming/2/2006-02-13/6bb945e3676b7a93242b001ebe504a1e.gif" border="0" height="254" width="501"><br> <strong>四、代码实现<br><br></strong>首先创建数据表,MySQL 的 SQL 语句如下: <pre>   CREATE TABLE `sess` (<br>     `sesskey` varchar(32) NOT NULL default '',<br>      `expiry` bigint(20) NOT NULL default '0',<br>      `data` longtext NOT NULL,<br>      PRIMARY KEY  (`sesskey`),<br>      KEY `expiry` (`expiry`)<br>    ) TYPE=MyISAM</pre> sesskey 为 SESSION ID,expiry 为 SESSION 过期时间,data 用于保存 SESSION 数据。<br> <br> 默认情况下 SESSION 数据是以文件方式保存,想要使用数据库方式保存,就必须重新定义 SESSION 各个操作的处理函数。PHP 提供了<a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php"><font color="#0000ff">session_set_save_handle()</font> 函数,可以用此函数自定义 SESSION 的处理过程,当然首先要先将 session.save_handler 改成 user,可在 PHP 中进行设置:</a> <pre><a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php">session_module_name('user');</a></pre> <a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php"><br>接下来着重讲一下 session_set_save_handle() 函数,<br>此函数有六个参数:</a> <pre><a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php">session_set_save_handler ( string open, string close, <br>string read, string write, string destroy, string gc )</a></pre> <a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php">各个参数为各项操作的函数名,这些操作依次是:<br>打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,<br>在这里我们使用 OO 的方式来实现这些操作,详细代码如下:</a> <pre><a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php"><font color="#0000bb">&lt;?php<br>define</font><font color="#007700">(</font><font color="#dd0000">'MY_SESS_TIME'</font><font color="#007700">, </font><font color="#0000bb">3600</font><font color="#007700">);   </font><font color="#ff8000">//SESSION 生存时长<br>//类定义<br></font><font color="#007700">class </font><font color="#0000bb">My_Sess<br></font><font color="#007700">{<br>    function </font><font color="#0000bb">init</font><font color="#007700">()<br>    {<br>        </font><font color="#0000bb">$domain </font><font color="#007700">= </font><font color="#dd0000">'.infor96.com'</font><font color="#007700">;<br>        </font><font color="#ff8000">//不使用 GET/POST 变量方式<br>        </font><font color="#0000bb">ini_set</font><font color="#007700">(</font><font color="#dd0000">'session.use_trans_sid'</font><font color="#007700">,    </font><font color="#0000bb">0</font><font color="#007700">);<br>        </font><font color="#ff8000">//设置垃圾回收最大生存时间<br>        </font><font color="#0000bb">ini_set</font><font color="#007700">(</font><font color="#dd0000">'session.gc_maxlifetime'</font><font color="#007700">,   </font><font color="#0000bb">MY_SESS_TIME</font><font color="#007700">);<br><br>        </font><font color="#ff8000">//使用 COOKIE 保存 SESSION ID 的方式<br>        </font><font color="#0000bb">ini_set</font><font color="#007700">(</font><font color="#dd0000">'session.use_cookies'</font><font color="#007700">,      </font><font color="#0000bb">1</font><font color="#007700">);<br>        </font><font color="#0000bb">ini_set</font><font color="#007700">(</font><font color="#dd0000">'session.cookie_path'</font><font color="#007700">,      </font><font color="#dd0000">'/'</font><font color="#007700">);<br>        </font><font color="#ff8000">//多主机共享保存 SESSION ID 的 COOKIE<br>        </font><font color="#0000bb">ini_set</font><font color="#007700">(</font><font color="#dd0000">'session.cookie_domain'</font><font color="#007700">,    </font><font color="#0000bb">$domain</font><font color="#007700">);<br><br>        </font><font color="#ff8000">//将 session.save_handler 设置为 user,<br>        //而不是默认的 files<br>        </font><font color="#0000bb">session_module_name</font><font color="#007700">(</font><font color="#dd0000">'user'</font><font color="#007700">);<br>        </font><font color="#ff8000">//定义 SESSION 各项操作所对应的方法名:<br>        </font><font color="#0000bb">session_set_save_handler</font><font color="#007700">(<br>            array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'open'</font><font color="#007700">),   <br>            </font><font color="#ff8000">//对应于静态方法 My_Sess:<img src="./images/smilies/shocked.gif" smilieid="7" alt=":o" border="0">pen(),下同。<br>            </font><font color="#007700">array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'close'</font><font color="#007700">),<br>            array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'read'</font><font color="#007700">),<br>            array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'write'</font><font color="#007700">),<br>            array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'destroy'</font><font color="#007700">),<br>            array(</font><font color="#dd0000">'My_Sess'</font><font color="#007700">, </font><font color="#dd0000">'gc'</font><font color="#007700">)<br>        );<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">open</font><font color="#007700">(</font><font color="#0000bb">$save_path</font><font color="#007700">, </font><font color="#0000bb">$session_name</font><font color="#007700">) {<br>        return </font><font color="#0000bb">true</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">close</font><font color="#007700">() {<br>        global </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">;<br><br>        if (</font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">) {    </font><font color="#ff8000">//关闭数据库连接<br>            </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Close</font><font color="#007700">();<br>        }<br>        return </font><font color="#0000bb">true</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">read</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">) {<br>        global </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">;<br><br>        </font><font color="#0000bb">$sql </font><font color="#007700">= </font><font color="#dd0000">'SELECT data FROM sess WHERE sesskey=' <br>        </font><font color="#007700">. </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">qstr</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">) . </font><font color="#dd0000">' AND expiry&gt;=' </font><font color="#007700">. </font><font color="#0000bb">time</font><font color="#007700">();<br>        </font><font color="#0000bb">$rs </font><font color="#007700">=&amp; </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Execute</font><font color="#007700">(</font><font color="#0000bb">$sql</font><font color="#007700">);<br>        if (</font><font color="#0000bb">$rs</font><font color="#007700">) {<br>            if (</font><font color="#0000bb">$rs</font><font color="#007700">-&gt;</font><font color="#0000bb">EOF</font><font color="#007700">) {<br>                return </font><font color="#dd0000">''</font><font color="#007700">;<br>            } else {    </font><font color="#ff8000">//读取到对应于 SESSION ID 的 SESSION 数据<br>                </font><font color="#0000bb">$v </font><font color="#007700">= </font><font color="#0000bb">$rs</font><font color="#007700">-&gt;</font><font color="#0000bb">fields</font><font color="#007700">[</font><font color="#0000bb">0</font><font color="#007700">];<br>                </font><font color="#0000bb">$rs</font><font color="#007700">-&gt;</font><font color="#0000bb">Close</font><font color="#007700">();<br>                return </font><font color="#0000bb">$v</font><font color="#007700">;<br>            }   </font><font color="#ff8000">//end if<br>        </font><font color="#007700">}   </font><font color="#ff8000">//end if<br>        </font><font color="#007700">return </font><font color="#dd0000">''</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">write</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">, </font><font color="#0000bb">$data</font><font color="#007700">) {<br>        global </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">;<br>        <br>        </font><font color="#0000bb">$qkey </font><font color="#007700">= </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">qstr</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">);<br>        </font><font color="#0000bb">$expiry </font><font color="#007700">= </font><font color="#0000bb">time</font><font color="#007700">() + </font><font color="#0000bb">My_SESS_TIME</font><font color="#007700">;    </font><font color="#ff8000">//设置过期时间<br>        <br>        //写入 SESSION<br>        </font><font color="#0000bb">$arr </font><font color="#007700">= array(<br>            </font><font color="#dd0000">'sesskey' </font><font color="#007700">=&gt; </font><font color="#0000bb">$qkey</font><font color="#007700">,<br>            </font><font color="#dd0000">'expiry'  </font><font color="#007700">=&gt; </font><font color="#0000bb">$expiry</font><font color="#007700">,<br>            </font><font color="#dd0000">'data'    </font><font color="#007700">=&gt; </font><font color="#0000bb">$data</font><font color="#007700">);<br>        </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Replace</font><font color="#007700">(</font><font color="#dd0000">'sess'</font><font color="#007700">, </font><font color="#0000bb">$arr</font><font color="#007700">, </font><font color="#dd0000">'sesskey'</font><font color="#007700">, </font><font color="#0000bb">$autoQuote </font><font color="#007700">= </font><font color="#0000bb">true</font><font color="#007700">);<br>        return </font><font color="#0000bb">true</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">destroy</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">) {<br>        global </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">;<br><br>        </font><font color="#0000bb">$sql </font><font color="#007700">= </font><font color="#dd0000">'DELETE FROM sess WHERE sesskey=' </font><font color="#007700">. </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">qstr</font><font color="#007700">(</font><font color="#0000bb">$sesskey</font><font color="#007700">);<br>        </font><font color="#0000bb">$rs </font><font color="#007700">=&amp; </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Execute</font><font color="#007700">(</font><font color="#0000bb">$sql</font><font color="#007700">);<br>        return </font><font color="#0000bb">true</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br><br>    </font><font color="#007700">function </font><font color="#0000bb">gc</font><font color="#007700">(</font><font color="#0000bb">$maxlifetime </font><font color="#007700">= </font><font color="#0000bb">null</font><font color="#007700">) {<br>        global </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">;<br><br>        </font><font color="#0000bb">$sql </font><font color="#007700">= </font><font color="#dd0000">'DELETE FROM sess WHERE expiry&lt;' </font><font color="#007700">. </font><font color="#0000bb">time</font><font color="#007700">();<br>        </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Execute</font><font color="#007700">(</font><font color="#0000bb">$sql</font><font color="#007700">);<br>        </font><font color="#ff8000">//由于经常性的对表 sess 做删除操作,容易产生碎片,<br>        //所以在垃圾回收中对该表进行优化操作。<br>        </font><font color="#0000bb">$sql </font><font color="#007700">= </font><font color="#dd0000">'OPTIMIZE TABLE sess'</font><font color="#007700">;<br>        </font><font color="#0000bb">$MY_SESS_CONN</font><font color="#007700">-&gt;</font><font color="#0000bb">Execute</font><font color="#007700">(</font><font color="#0000bb">$sql</font><font color="#007700">);<br>        return </font><font color="#0000bb">true</font><font color="#007700">;<br>    }   </font><font color="#ff8000">//end function<br></font><font color="#007700">}   </font><font color="#ff8000">///:~<br><br>//使用 ADOdb 作为数据库抽象层。<br></font><font color="#007700">require_once(</font><font color="#dd0000">'adodb/adodb.inc.php'</font><font color="#007700">);<br></font><font color="#ff8000">//数据库配置项,可放入配置文件中(如:config.inc.php)。<br></font><font color="#0000bb">$db_type </font><font color="#007700">= </font><font color="#dd0000">'mysql'</font><font color="#007700">;<br></font><font color="#0000bb">$db_host </font><font color="#007700">= </font><font color="#dd0000">'192.168.212.1'</font><font color="#007700">;<br></font><font color="#0000bb">$db_user </font><font color="#007700">= </font><font color="#dd0000">'sess_user'</font><font color="#007700">;<br></font><font color="#0000bb">$db_pass </font><font color="#007700">= </font><font color="#dd0000">'sess_pass'</font><font color="#007700">;<br></font><font color="#0000bb">$db_name </font><font color="#007700">= </font><font color="#dd0000">'sess_db'</font><font color="#007700">;<br></font><font color="#ff8000">//创建数据库连接,这是一个全局变量。<br></font><font color="#0000bb">$GLOBALS</font><font color="#007700">[</font><font color="#dd0000">'MY_SESS_CONN'</font><font color="#007700">] =&amp; </font><font color="#0000bb">ADONewConnection</font><font color="#007700">(</font><font color="#0000bb">$db_type</font><font color="#007700">);<br></font><font color="#0000bb">$GLOBALS</font><font color="#007700">[</font><font color="#dd0000">'MY_SESS_CONN'</font><font color="#007700">]-&gt;</font><font color="#0000bb">Connect</font><font color="#007700">( </font><font color="#0000bb">$db_host</font><font color="#007700">, </font><font color="#0000bb">$db_user</font><font color="#007700">, </font><font color="#0000bb">$db_pass</font><font color="#007700">, </font><font color="#0000bb">$db_name</font><font color="#007700">);<br></font><font color="#ff8000">//初始化 SESSION 设置,必须在 session_start() 之前运行!!<br></font><font color="#0000bb">My_Sess</font><font color="#007700">::</font><font color="#0000bb">init</font><font color="#007700">();<br></font><font color="#0000bb">?&gt;</font></a></pre> <a target="_blank" href="http://www.php.net/manual/zh/function.session-set-save-handler.php"><br><strong>五、遗留问题</strong><br><br>如
果网站的访问量很大的话,SESSION 的读写会频繁地对数据库进行操作,这样效率就会明显降低。考虑到 SESSION
数据一般不会很大,可以尝试用 C/Java 写个多线程的程序,用 HASH 表保存 SESSION 数据,并通过 socket
通信进行数据读写,这样 SESSION
就保存在内存中,读写速度应该会快很多。另外还可以通过负载均衡来分担服务器负载。不过这些都只是我自己的一些想法和假设,并没有实践过 <img src="./images/smilies/sad.gif" smilieid="2" alt=":(" border="0"></a>

FIEND 發表於 2006-3-18 03:17

這篇教學是用 MySQL 和 cookie 來記錄第一次和最後一次登入的時間。<br /> <br /> 首先輸入下面的 SQL:<br /> <div class="codeheader">程式碼:</div> <div class="code">CREATE TABLE `rw_sessions` (<br />`session_id` varchar(15) default NULL,<br />`started` datetime default NULL,<br />`lastaccess` datetime default NULL,<br />) TYPE=MyISAM; <br /></div> session_id 是 session 的 id。<br /> started 是建立 cookie 的時間,也就是第一次登入的時間。<br /> lastaccess 是最後登入的時間,每瀏覽一次頁面就會更新一次。<br /> <br /> 接下來是 setcookie.php 的內容:<br /> <div class="codeheader">程式碼:</div> <div class="code">// session manage functions<br />$connection = mysql_connect(&quot;localhost&quot;, &quot;tutorials&quot;, &quot;pass&quot;);<br />mysql_select_db(&quot;tutorials&quot;, $connection);<br /><br />function createSession()<br />{<br />&nbsp; &nbsp; // check to see if a cookie exists already.<br />&nbsp; &nbsp; $cookieid = $_COOKIE['cookiename'];<br />&nbsp; &nbsp; <br /><span style="white-space: pre">        </span>if (strlen($cookieid) &lt; 1)<br /><span style="white-space: pre">        </span>{<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// find a unique value.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>list($msec, $sec) = explode(&quot; &quot;, microtime());<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$cookiekey = ereg_replace(&quot;\.&quot;, &quot;&quot;, ($msec + $sec));<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// set expiry - 6 hours from now.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$cookieexpiry = (time() + 21600);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>setcookie(&quot;cookiename&quot;, $cookiekey, $cookieexpiry);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span><br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// Cookie will imediately available on the same page.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$_COOKIE['cookiename'] = $cookiekey;<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>unset($cookiekey);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>unset($msec);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>unset($sec);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>unset($cookieexpiry);<br /><span style="white-space: pre">        </span>}<br /><span style="white-space: pre">        </span>else<br /><span style="white-space: pre">        </span>{<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// if the cookie has been set then we are just going to adjust the expiry date.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// set expiry - 6 hours from now.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$cookieexpiry = (time() + 21600);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>setcookie(&quot;cookiename&quot;, $cookieid, $cookieexpiry);<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>unset($cookieexpiry);<br /><span style="white-space: pre">        </span>}<br /><span style="white-space: pre">        </span>unset($cookieid);<br />}<br /><br />function loadSession($cookieid)<br />{<br /><span style="white-space: pre">        </span>global $connection;<br /><span style="white-space: pre">        </span><br /><span style="white-space: pre">        </span>// check to see if there is an existing session.<br /><span style="white-space: pre">        </span>$query = mysql_query(&quot;SELECT * FROM rw_sessions WHERE session_id = '$cookieid'&quot;, $connection);<br /><span style="white-space: pre">        </span>$row = mysql_fetch_array($query);<br /><span style="white-space: pre">        </span><br /><span style="white-space: pre">        </span>// if there is no session - create it and load it as the active session.<br /><span style="white-space: pre">        </span>if ($row['session_id'] != $cookieid)<br /><span style="white-space: pre">        </span>{<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$query = mysql_query(&quot;INSERT INTO rw_sessions SET session_id = '$cookieid', started = '&quot; .date(&quot;Y-m-d H:i:s&quot;)<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span><span style="white-space: pre">        </span>.&quot;', lastaccess = '&quot; .date(&quot;Y-m-d H:i:s&quot;) .&quot;'&quot;, $connection);<br /><span style="white-space: pre">        </span>}<br /><span style="white-space: pre">        </span>else<br /><span style="white-space: pre">        </span>{<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>// if we have an active session already - update the last accessed to now.<br /><span style="white-space: pre">        </span><span style="white-space: pre">        </span>$query = mysql_query(&quot;UPDATE rw_sessions SET lastaccess='&quot; .date(&quot;Y-m-d H:i:s&quot;) .&quot;' WHERE session_id = '$cookieid'&quot;, $connection);<br /><span style="white-space: pre">        </span>}<br /><span style="white-space: pre">        </span><br /><span style="white-space: pre">        </span>// now load in the session as the current active one<br /><span style="white-space: pre">        </span>$query = mysql_query(&quot;SELECT * FROM rw_sessions WHERE session_id = '$cookieid'&quot;, $connection);<br /><span style="white-space: pre">        </span>$SESSION_VARS = mysql_fetch_array($query);<br /><span style="white-space: pre">        </span><br /><span style="white-space: pre">        </span>return $SESSION_VARS;<br />}<br /><br />createSession();<br />$session_info = loadSession($_COOKIE['cookiename']);<br />?&gt;<br /></div> 首先是連結資料庫的動作。<br /> <br /> 再來是 createSession() 的函式,用來建立 cookie。<br /> 一開始將 $_COOKIE['cookiename'] 傳進 $cookieid,如果它的值少於 1 表示沒有之前的 cookie。<br /> 再來用 microtime() 來建立特殊的數值,它會輸出兩個時間,分跟秒,從 Unix Epoch (1970 GMT) 的時間開始計算。<br /> 再來用 explode 將分跟秒放進陣列,在用 list() 放進 $msec 和 $sec。<br /> 接下來用 ereg_replace() 將分跟秒放進 $cookiekey,這就是特殊的數值。<br /> $cookieexpiry 變數會放 cookie 過期的時間,六個小時之後。<br /> 再來用 setcookie() 函式建立 cookie。<br /> 之後的動作是讓網頁可以馬上使用 cookie,不然要刷新或進入其它用相同 cookie 的頁面。<br /> unset() 會刪除變數。<br /> 之後的 else 是如果已經有舊的 cookie 存在。<br /> 然後重新設定過期的時間,一樣六個小時之後。<br /> <br /> 再來是 loadSession() 函式。<br /> 這個函式會在資料庫內讀取和建立 cookie 的資料。<br /> 一開始先檢查有沒有舊的資料,如果 $row['session_id'] 不等於 $cookieid 表示沒有。<br /> 如果沒有輸入 cookie 的 id,然後登入的時間。<br /> 如果有,更新資料庫裡的資料。<br /> 接下來選擇目前的 cookie,然後放進 $SESSION_VARS。<br /> <br /> 在函式外面的 createSession() 是用來建立 cookiename,之後用 cookiename 來比較資料庫的資料。<br /> <br /> 最後建立一個新的頁面,test.php:<br /> <div class="codeheader">程式碼:</div> <div class="code"><font color="#000000"><font color="#0000bb">&lt;?php<br /></font><font color="#007700">require(</font><font color="#dd0000">'setcookie.php'</font><font color="#007700">);<br /><br />echo </font><font color="#dd0000">'&lt;pre&gt;'</font><font color="#007700">;<br /></font><font color="#0000bb">print_r</font><font color="#007700">(</font><font color="#0000bb">$_COOKIE</font><font color="#007700">[</font><font color="#dd0000">'cookiename'</font><font color="#007700">]);<br />echo </font><font color="#dd0000">'&lt;/pre&gt;'</font><font color="#007700">;<br /></font><font color="#0000bb">?&gt;</font></font><br /></div> 一開始要用 include 或 require 上面的檔案。<br /> 之後在網頁顯示 cookie 裡的資料。<br /> <br /> <br /> 靈感:VTC - Real World PHP Programming

FIEND 發表於 2006-3-18 03:18

作者:PHP教程收集 来源:<a target="_blank" href="http://d9soft.com/">[url]http://d9soft.com[/url]</a>              时间:2005-6-27 4:53:59                                                                    <br />  <div style="background-color: #f2f3f7">  </div>                                         <p>files:<br />common/Common.config.php<br />include/session.inc.php<br />session_test.php<br />get_session_test.php<br />get_session_test2.php </p>  <p><br />Common.config.php<br />&nbsp;&nbsp; <br />&lt;?php<br />/*<br />* Common config<br />* By 恋太后天<br />*/</p>  <p><br />/*<br />* Database config<br />*/<br />define( &quot;DBTYPE&quot;, &quot;mysql&quot; );<br />$database = array<br />(<br />&nbsp;&nbsp;&nbsp; &quot;mysql&quot; =&gt; array<br />&nbsp;&nbsp;&nbsp; ( <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;default&quot; =&gt; array<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;host&quot;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &quot;localhost&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;user&quot;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &quot;root&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;password&quot; =&gt; &quot;&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;dbname&quot;&nbsp;&nbsp; =&gt; &quot;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;session&quot; =&gt; array<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;host&quot;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &quot;localhost&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;user&quot;&nbsp;&nbsp;&nbsp;&nbsp; =&gt; &quot;session&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;password&quot; =&gt; &quot;session&quot;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;dbname&quot;&nbsp;&nbsp; =&gt; &quot;sessions&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br />&nbsp;&nbsp;&nbsp; )<br />);</p>  <p>?&gt; </p>  <p><br />session.inc.php</p>  <p>&nbsp;<br />&lt;?php<br />//使用mysql存放session 函数表<br />// by 恋太后天 2005-4-28</p>  <p>if (!isset($include_path)) $include_path = '';</p>  <p>if (!is_array($database))<br />{<br />&nbsp;&nbsp;&nbsp; include ($include_path.&quot;common/Common.config.php&quot;);<br />}</p>  <p>$DBsess&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = $database[DBTYPE][&quot;session&quot;];<br />$DBsess_link = mysql_connect($DBsess[&quot;host&quot;], $DBsess[&quot;user&quot;], $DBsess[&quot;password&quot;]) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or die (&quot;Error:&lt;em&gt;Can not connect to Mysql server.&lt;/em&gt;&quot;);</p>  <p>$SESS_LIFE = get_cfg_var(&quot;session.gc_maxlifetime&quot;);</p>  <p>function sess_open($path, $name)<br />{<br />&nbsp;&nbsp;&nbsp; return true;<br />}</p>  <p>function sess_close()<br />{<br />&nbsp;&nbsp;&nbsp; return true;<br />}</p>  <p>function sess_read($id)<br />{<br />&nbsp;&nbsp;&nbsp; global $DBsess , $DBsess_link;<br />&nbsp;&nbsp;&nbsp; mysql_select_db($DBsess[&quot;dbname&quot;]);<br />&nbsp;&nbsp;&nbsp; $now = time();<br />&nbsp;&nbsp;&nbsp; $result = mysql_query(&quot;SELECT `data` FROM `sessions` <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE `id`= '$id' AND `expiry_time` &gt; $now&quot;, $DBsess_link);&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; if (list($data) = mysql_fetch_row($result))<br />&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $data;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; return false; <br />}</p>  <p>function sess_write($id, $data)<br />{<br />&nbsp;&nbsp;&nbsp; global $DBsess , $DBsess_link, $SESS_LIFE;<br />&nbsp;&nbsp;&nbsp; mysql_select_db($DBsess[&quot;dbname&quot;]);</p>  <p>&nbsp;&nbsp;&nbsp; $expiry_time = time() + $SESS_LIFE;</p>  <p>&nbsp;&nbsp;&nbsp; if ( !get_magic_quotes_gpc() )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $data = addslashes($data);<br />&nbsp;&nbsp;&nbsp; }</p>  <p>&nbsp;&nbsp;&nbsp; $now = time();</p>  <p>&nbsp;&nbsp;&nbsp; $result = mysql_query(&quot;INSERT into `sessions` (`id`, `expiry_time`,&nbsp; `data`)&quot;, $DBsess_link);</p>  <p>&nbsp;&nbsp;&nbsp; if ( !$result )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result = mysql_query(&quot;UPDATE `sessions` SET `data`='$data', `expiry_time`=$expiry_time <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE `id` = '$id' AND `expiry_time` &gt; $now&quot;, $DBsess_link);<br />&nbsp;&nbsp;&nbsp; }</p>  <p>&nbsp;&nbsp;&nbsp; return $result;<br />}</p>  <p>function sess_destroy($id)<br />{<br />&nbsp;&nbsp;&nbsp; global $DBsess , $DBsess_link;<br />&nbsp;&nbsp;&nbsp; mysql_select_db($DBsess[&quot;dbname&quot;]);<br />&nbsp;&nbsp;&nbsp; $query = mysql_query(&quot;DELETE FROM `session` WHERE `id`='$id'&quot;);<br />&nbsp;&nbsp;&nbsp; return $query;<br />}</p>  <p>function sess_gc($maxlifetime)<br />{<br />&nbsp;&nbsp;&nbsp; global $DBsess , $DBsess_link;&nbsp; <br />&nbsp;&nbsp;&nbsp; $query = mysql_query(&quot;DELETE FROM `sessions` WHERE `expiry_time` &lt; &quot; . time(), $DBsess_link);&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; return mysql_affected_rows($DBsess_link);&nbsp;&nbsp; </p>  <p>}</p>  <p>session_module_name();<br />session_set_save_handler(&quot;sess_open&quot;, &quot;sess_close&quot;, &quot;sess_read&quot;, &quot;sess_write&quot;, &quot;sess_destroy&quot;, &quot;sess_gc&quot;);</p>  <p>?&gt; </p>  <p><br />session_test.php<br />&nbsp;&nbsp; <br />&lt;?php<br />// test for using session<br />include (&quot;common/Common.config.php&quot;);<br />include (&quot;include/session.inc.php&quot;);</p>  <p>session_start();</p>  <p>$_SESSION[&quot;abc&quot;] = &quot;A: I will be back!&quot;;<br />$_SESSION[&quot;meto&quot;] = &quot;B: Me too &quot;;<br />echo &quot;&lt;a xhref=\&quot;get_session_test.php\&quot;&gt;click me&lt;/a&gt;&quot;;</p>  <p>?&gt; </p>  <p>get_session_test.php</p>  <p><br />&nbsp;&nbsp; <br />&lt;?php<br />// test for using session<br />include (&quot;common/Common.config.php&quot;);<br />include (&quot;include/session.inc.php&quot;);</p>  <p>session_start();<br />/*<br />* <a href="http://www.knowsky.com/">[url]www.knowsky.com[/url]</a><br />*/<br />$_SESSION[&quot;c&quot;] = &quot;&lt;br&gt;C: I will follow U. ^0^!&quot;;<br />print($_SESSION[&quot;abc&quot;]);<br />print(&quot;&lt;br&gt;&quot;);<br />print($_SESSION[&quot;meto&quot;]);<br />echo &quot;&lt;br&gt;&quot;.<br />&nbsp;&nbsp;&nbsp;&nbsp; &quot;&lt;a xhref=\&quot;get_session_test2.php\&quot;&gt;click again&lt;/a&gt;&quot;;</p>  <p>?&gt; </p>  <p><br />get_session_test2.php</p>  <p>&nbsp;&nbsp; <br />&lt;?php<br />//get_session_test2.php<br />// test for using session<br />include (&quot;common/Common.config.php&quot;);<br />include (&quot;include/session.inc.php&quot;);</p>  <p>session_start();<br />print($_SESSION[&quot;c&quot;]);<br />?&gt; </p>

awelkije 發表於 2006-8-27 23:31

<p>圖片無法顯示</p>

sonnos 發表於 2009-5-30 14:50

THX!!好有用

sonnos 發表於 2009-6-1 19:30

thx@@@useful

rick711003 發表於 2009-8-19 22:12

真厲害!!!謝謝大大分享

頁: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.