《PHP實戰(zhàn):深入講解PHP Session及如何保持其不過期的方法》要點:
本文介紹了PHP實戰(zhàn):深入講解PHP Session及如何保持其不過期的方法,希望對您有用。如果有疑問,可以聯(lián)系我們。
SESSION的實現(xiàn)中采用COOKIE技術(shù),SESSION會在客戶端保存一個包含session_id(SESSION編號)的COOKIE;在服務(wù)器端保存其他session變量,比如session_name等等.當(dāng)用戶哀求服務(wù)器時也把session_id一起發(fā)送到服務(wù)器,通過 session_id提取所保存在服務(wù)器端的變量,就能識別用戶是誰了.同時也不難理解為什么SESSION有時會失效了.PHP教程
當(dāng)客戶端禁用COOKIE時(點擊IE中的“工具”―“Internet選項”,在彈出的對話框里點擊“平安”―“自定義級別”項,將“允許每個對話COOKIE”設(shè)為禁用),session_id將無法傳遞,此時 SESSION失效.不過php5在linux/unix平臺可以自動檢查cookie狀態(tài),如果客戶端設(shè)置了禁用,則系統(tǒng)自動把session_id附加到url上傳遞.windows主機則無此功能.PHP教程
Session常見函數(shù)及用法?
Session_start() :開始一個會話或者返回已經(jīng)存在的會話.
說明:這個函數(shù)沒有參數(shù),且返回值均為true.如果你使用基于cookie的session(cookie-based sessions),那么在使用Session_start()之前瀏覽器不能有任何輸出,否則會發(fā)生以下錯誤:
Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2)…………PHP教程
你可以在php.ini里啟動session.auto_start=1,這樣就無需每次使用session之前都要調(diào)用session_start().但啟用該選項也有一些限制,如果確實啟用了 session.auto_start,則不能將對象放入會話中,因為類定義必須在啟動會話之前加載以在會話中重建對象.
哀求結(jié)束后所有注冊的變量都會被序列化.已注冊但未定義的變量被標(biāo)記為未定義.在之后的訪問中這些變量也未被會話模塊定義,除非用戶以后定義它們.PHP教程
警告: 有些類型的數(shù)據(jù)不能被序列化因此也就不能保存在會話中.包括 resource 變量或者有循環(huán)引用的對象(即某對象將一個指向自己的引用傳遞給另一個對象).PHP教程
注冊SESSION變量 :
PHP5使用$_SESSION[‘xxx']=xxx注冊SESSION全局變量.和GET,POST,COOKIE的使用方法相似.
注意:session_register(),session_unregister ,session_is_registered在php5下不再使用,除非在php.ini里把register_globle設(shè)為on,不過出于平安考慮,強烈建議關(guān)閉register_globle.HTTP_SESSION_VARS也不提倡使用了,官方建議用$_SESSION代替之.例如:PHP教程
??? Page1.php
PHP教程
<?php Session_start(); //使用SESSION前必須調(diào)用該函數(shù). $_SESSION[‘name']=”我是黑旋風(fēng)李逵!”; //注冊一個SESSION變量 $_SESSION[‘passwd']=”mynameislikui”; $_SESSION[‘time']=time(); echo ' 通過COOKIE傳遞SESSION'; //如果客戶端支持cookie,可通過該鏈接傳遞session到下一頁. echo ' . SID . '">通過URL傳遞SESSION';//客戶端不支持cookie時,使用該辦法傳遞session. ?>
??? Page2.php
PHP教程
<?php session_start(); echo $_SESSION['name']; // echo $_SESSION['passwd']; // echo date('Y m d H:i:s', $_SESSION['time']); echo ' 返回山一頁'; ?>
有兩種方法傳遞一個會話 ID:PHP教程
會話模塊支持這兩種方法.cookie 更優(yōu)化,但由于不總是可用,也提供替代的方法.第二種方法直接將會話 ID 嵌入到 URL 中間去.PHP教程
PHP 可以透明地轉(zhuǎn)換連接.除非是使用 PHP 4.2 或更新版本,需要手工在編譯 PHP 時激活.在 Unix 下,用 --enable-trans-sid 配置選項.如果此配置選項和運行時選項 session.use_trans_sid 都被激活(修改php.ini),相對 URI 將被自動修改為包含會話 ID.PHP教程
session_id
session_id() 用于設(shè)定或取得當(dāng)前session_id.php5中既可以使用session_id(),也可以通過附加在url上的SID取得當(dāng)前會話的session_id和session_name.
如果session_id()有具體指定值的話,將取代當(dāng)前的session_id值.使用該函數(shù)前必須啟動會話:session_start();
當(dāng)我們使用session cookies時,如果指定了一個session_id()值,每次啟動session_start()都會往客戶端發(fā)送一個cookie值.不論當(dāng)前session_id是否與指定值相等.
session_id()如果沒有指定值,則返回當(dāng)前session_id();當(dāng)前會話沒有啟動的話,則返回空字符串.PHP教程
檢查session是否存在?
在以往的php版本中通常使用session_is_register()檢查session是否存在,如果您使用$_SESSION[‘XXX']=XXX來注冊會話變量,則session_is_register()函數(shù)不再起作用.你可以使用
isset($_SESSION[‘xxx'])來替代.PHP教程
更改session_id session_regenerate_id() 更改成功則返回true,失敗則返回false.
使用該函數(shù)可以為當(dāng)前session更改session_id,但不改變當(dāng)前session的其他信息.例如:PHP教程
<?php session_start(); $old_sessionid = session_id(); session_regenerate_id(); $new_sessionid = session_id(); echo "原始 SessionID: $old_sessionid "; echo "新的 SessionID: $new_sessionid "; echo" "; print_r($_SESSION); echo""; ?>
session_name() 返回當(dāng)前session的name或改變當(dāng)前session的name.如果要改變當(dāng)前session的name,必須在session_start() 之前調(diào)用該函數(shù).注意:session_name不能只由數(shù)字組成,它至少包含一個字母.否則會在每時每刻都生成一個新的session id.
session改名示例:
PHP教程
$previous_name = session_name("WebsiteID"); echo "新的session名為: $previous_name "; ?>
如何刪除session?
1、unset ($_SESSION['xxx']) 刪除單個session,unset($_SESSION['xxx']) 用來unregister一個已注冊的session變量.其作用和session_unregister()相同. session_unregister()在PHP5中不再使用,可將之打入冷宮.
unset($_SESSION) 此函數(shù)千萬不可使用,它會將全局變量$_SESSION銷毀,而且還沒有可行的辦法將其恢復(fù).用戶也不再可以注冊$_SESSION變量.
2、$_SESSION=array() 刪除多個session
3、 session_destroy()結(jié)束當(dāng)前的會話,并清空會話中的所有資源..該函數(shù)不會unset(釋放)和當(dāng)前session相關(guān)的全局變量 (globalvariables),也不會刪除客戶端的session cookie.PHP默認(rèn)的session是基于cookie的,如果要刪除cookie的話,必須借助setcookie()函數(shù).
返回值:布爾值.
功能說明:這個函數(shù)結(jié)束當(dāng)前的session,此函數(shù)沒有參數(shù),且返回值均為truePHP教程
session_unset() 如果使用了$_SESSION,則該函數(shù)不再起作用.由于PHP5必定要使用$_SESSION,所以此函數(shù)可以打入冷宮了.PHP教程
下面是PHP官方關(guān)于刪除session的案例:PHP教程
<?php // 初始化session. session_start(); /*** 刪除所有的session變量..也可用unset($_SESSION[xxx])逐個刪除.****/ $_SESSION = array(); /***刪除sessin id.由于session默認(rèn)是基于cookie的,所以使用setcookie刪除包含session id的cookie.***/ if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } // 最后徹底銷毀session. session_destroy(); ?>
由此我們可以得出刪除Session的步驟:PHP教程
解決PHP Session不過期以及SessionId保持不變的問題PHP教程
session 回收機制:
?
PHP采用Garbage Collection process對過期session進行回收,然而并不是每次session建立時,都能夠喚起 ‘garbage collection' process ,gc是依照一定概率啟動的.這主要是出于對服務(wù)器性能方面的考慮,每個session都觸發(fā)gc,瀏覽量大的話,服務(wù)器吃不消,然而依照一定概率開啟gc,當(dāng)流覽量大的時候,session過期機制能夠正常運行,而且服務(wù)器效率得到節(jié)省.細(xì)節(jié)應(yīng)該都是多年的經(jīng)驗積累得出的.
?
三個與PHP session過期相關(guān)的參數(shù)(php.ini中):
?PHP教程
gc啟動概率 = gc_probability / gc_divisor = 0.1%
?
session過期時間 gc_maxlifetime 單位:秒
?
當(dāng)web服務(wù)正式提供時,session過期概率就需要根據(jù)web服務(wù)的瀏覽量和服務(wù)器的性能來綜合考慮session過期概率.為每個session都開啟gc,顯然是不明智的,感覺有點“碰運氣”的感覺,要是拜訪量小命中幾率就小.我在本機測試過程中,幾乎都沒有被命中過,sessionid幾天都不變,哪怕機器重啟.測試過程中,這個過期概率值要設(shè)置大一點命中幾率才高點.
?
通過修改php配置文件的過期概率值,可以“碰運氣”式的設(shè)置session過期,那有沒有更好的辦法呢?
?PHP教程
下面寫的這個session類可以徹底解決session不過期以及sessionid不變的問題.
?
PHP教程
<?php /** * 擴展Session類(簡單封裝) * * @author slimboy * */ class Session { /** * 初始化 */ static function _init(){ ini_set('session.auto_start', 0); //Session::start(); } /** * 啟動Session */ static function start() { session_start(); } /** * 設(shè)置Session * * @param $name Session名稱 * @param $value 值 * @param $time 超時時間(秒) */ public static function set($name,$value,$time){ if(empty($time)){ $time = 1800; //默認(rèn)值 } $_SESSION[$name] = $value; $_SESSION[$name.'_Expires'] = time() + $time; } /** * 獲取Session值 * * @param $name Session名稱 */ public static function get($name){ //檢查Session是否已過期 if(isset($_SESSION[$name.'_Expires']) && $_SESSION[$name.'_E xpires']>time()){ return $_SESSION[$name]; }else{ Session::clear($name); return null; } } /** * 設(shè)置Session Domain * * @param $sessionDomain 域 * @return string */ static function setDomain($sessionDomain = null) { $return = ini_get('session.cookie_domain'); if(!empty($sessionDomain)) { ini_set('session.cookie_domain', $sessionDomain);//跨 域拜訪Session } return $return; } /** * 清除某一Session值 * * @param $name Session名稱 */ static function clear($name){ unset($_SESSION[$name]); unset($_SESSION[$name.'_Expires']); } /** * 重置銷毀Session */ static function destroy(){ unset($_SESSION); session_destroy(); } /** * 獲取或設(shè)置Session id */ static function sessionid($id=null){ return session_id($id); } } ?> 簡單調(diào)用: <?php //設(shè)置session Session::set('UserId', $userid, 3600); //讀取session $userId = Session::get('UserId'); ?>
歡迎參與《PHP實戰(zhàn):深入講解PHP Session及如何保持其不過期的方法》討論,分享您的想法,維易PHP學(xué)院為您提供專業(yè)教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/8792.html