程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php中session與thinkphp中session的一些用法

php中session與thinkphp中session的一些用法

編輯:關於PHP編程

session是php中一個很常用的全局變量了,下面我來給初學者來介紹關於php session一些用法總結,希望些方法對各位初學php朋友會有幫助哦,下面大家一起來看看吧。

PHP服務端默認的session存儲是文件存放方式,在Windows上PHP默認的Session服務端文件存放在C:/WINDOWS/Temp下,*NIX下默認存放在/tmp下,如果說並發訪問很大或者session建立太多,在這兩個目錄下就會存在大量類似sess_xxxxxx的session文件,同一個目錄下文件數過多會導致性能下降,並且可能導致受到攻擊最終出現文件系統錯誤。針對這樣的情況,PHP本身體提供了比較好的解決辦法。
不少朋友可能都沒有注意到php.ini裡面Session設置部分中有這樣一項:
; session.save_path = "N; MODE; /path"

這項設置提供給我們可以給session存放目錄進行多級散列,其中“N”表示要設置的目錄級數,“MODE”表示目錄的權限屬性,默認為600,在WINDOWS上基本是不用設置的,*NIX上也可以不用設置,後面的“/path”表示session文件存放的根目錄路徑,比如我們設置為下面的格式

session.save_path = "2; /tmp/phpsession"

上面的設置表示我們把/tmp/phpsession目錄作為php的session文件存放根目錄,在該目錄下進行兩級目錄散列,每一級目錄分別是0-9和a-z共36個字母數字為目錄名,這樣存放session的目錄可以達到36*36個,相信作為單台服務器來說,這是完全夠用了,如果說您的系統架構設計為多台服務器共享session數據,可以把目錄級增加到3級或者更多。

需要注意的是,php自己並不會自動創建子目錄,需要您自己動手去創建,以下自動創建目錄的代碼,大家可以做個參考。下面的代碼自動創建3級子目錄,可以自己動手根據需要進行修改。

 代碼如下 復制代碼 <?php
set_time_limit(0);
 
$string = '0123456789abcdefghijklmnopqrstuvwxyz';
 
$length = strlen($string);
 
function makeDir($param)
 
{
 
if(!file_exists($param)) {
 
makeDir(dirname($param));
 
mkdir($param);
 
}
 
}
 
for($i = 0; $i < $length; $i++) {
 
for($j = 0; $j < $length; $j++) {
 
for($k = 0; $k < $length; $k++) {
 
makeDir($string[$i].'/'.$string[$j].'/'.$string[$k]);
 
}
 
}
 
}
 
?>

下面提供兩種更好的解決方案:
1.session入庫

利用session_set_save_handler函數

作用:自定義SESSION 存儲機制。

可用於修改session存儲介質,如進行session入庫等操作。

實例代碼

 代碼如下 復制代碼 class sessionsTable extends db{
    protected $table_name = 'sessions';
    public function __construct(){
        parent::__construct();
        session_set_save_handler(
        array($this,'sess_open'),
        array($this,'sess_close'),
        array($this,'sess_read'),
        array($this,'sess_write'),
        array($this,'sess_destroy'),
        array($this,'sess_gc')
        );
        session_start();
    }
    public function sess_open($save_path,$session_name){
        return true;
 
    }
    public function sess_close(){
        return true;
    }
 
 
    public function sess_read($sess_id){
        $sql = "select * from {$this->getTable()} where sess_id='{$sess_id}'";
        $row = $this->getRow($sql);
        return $row['sess_data'];
    }
    public function sess_write($sess_id,$sess_data){
 
        $expire = time();
        $sql = "insert into {$this->getTable()} values('{$sess_id}','{$sess_data}','{$expire}') on duplicate key
        update sess_data='{$sess_data}',expire='{$expire}'";
        return $this->query($sql);
    }
 
    public function sess_destroy($sess_id){
 
        $sql = "delete from {$this->getTable()} where sess_id='{$sess_id}'";
 
        return $this->query($sql);
 
    }
    public function sess_gc($life_time){
        $expire = time() - $life_time;
        $sql = "delete from {$this->getTable()} where expire < {$expire} ";
        return $this->query($sql);
    }
 
 
 
}

2.用memcache來存儲session


方法I: 在 php.ini 中全局設置
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"

方法II:在某個一個應用中利用ini_set設置
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");

使用多個 memcached server 時用逗號","隔開,並且和 Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數"persistent"、"weight"、"timeout"、"retry_interval" 等等,類似這樣的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。

1.在php中如何操作session:

session_start();   //使用該函數打開session功能

$_SESSION       //使用預定義全局變量操作數據

使用unset($_SESSION['key']) //銷毀一個session的值

簡單地操作,一切都是由服務器實現;由於處理在後台,一切看起來也很安全。但是session采用什麼樣機制,又是怎樣被實現,並且如何來保持會話的狀態的呢?

 

2.session實現與工作原理

浏覽器和服務器采用http無狀態的通訊,為了保持客戶端的狀態,使用session來達到這個目的。然而服務端是怎麼樣標示不同的客戶端或用戶呢?
這裡我們可以使用生活中的一個例子,假如你參加一個晚會,認識了很多人,你會采取什麼方式來區分不同的人呢!你可能根據臉型,也有可能根據用戶的名字,
或者人的身份證,即采用一個獨一無二的標示。在session機制中,也采用了這樣的一個唯一的session_id來標示不同的用戶,不同的是:浏覽器每次請求都會帶上
由服務器為它生成的session_id.

簡單介紹一下流程:當客戶端訪問服務器時,服務器根據需求設置session,將會話信息保存在服務器上,同時將標示session的session_id傳遞給客戶端浏覽器,
浏覽器將這個session_id保存在內存中(還有其他的存儲方式,例如寫在url中),我們稱之為無過期時間的cookie。浏覽器關閉後,這個cookie就清掉了,它不會存在用戶的cookie臨時文件。
以後浏覽器每次請求都會額外加上這個參數值,再服務器根據這個session_id,就能取得客戶端的數據狀態。

如果客戶端浏覽器意外關閉,服務器保存的session數據不是立即釋放,此時數據還會存在,只要我們知道那個session_id,就可以繼續通過請求獲得此session的信息;但是這個時候後台的session還存在,但是session的保存有一個過期
時間,一旦超過規定時間沒有客戶端請求時,他就會清除這個session。

下面介紹一下session的存儲機制,默認的session是保存在files中,即以文件的方式保存session數據。在php中主要根據php.ini的配置session.save_handler
 來選擇保存session的方式。

這裡順便說明一下,如果要做服務器的lvs,即多台server的話,我們一般使用memcached的方式session,否則會導致一些請求找不到session。
一個簡單的memcache配置:
session.save_handler = memcache
session.save_path = "tcp://10.28.41.84:10001"

當然如果一定要使用files文件緩存,我們可以將文件作nfs,將所有的保存session文件定位到一個地方。

剛才講返回給用戶的session-id最終保存在內存中,這裡我們也可以設置參數將其保存在用戶的url中。

ThinkPHP官方的說明文檔

01.start 啟動session

02.pause 暫停session
03.clear 清除session
04.destroy 銷毀session
05.get 獲取session值
06.getLocal 獲取私有session值
07.set 設置session值
08.setLocal 設置私有session值
09.name 獲取或者設置session_name
10.is_set 是否設置session值
11.is_setLocal 是否設置私有session值
12.id 獲取或者設置session_id
13.path 獲取或者設置session_save_path
14.setExpire 設置session過期時 間
15.setCookieDomain 設置有效域名
16.setCallback 設置Session 對象反序列化時候的回調函數
最常用的操作方法示例:

代碼: 01.// 檢測Session變量是否存在

 代碼如下 復制代碼

02.Session::is_set('name');

03.
// 給Session變 量賦值
04.
Session::set('name','value');
05.
// 獲取Session變量
06.
Session::get('name');

和Session相關的配置參數:

代碼:

 代碼如下 復制代碼

01.'SESSION_NAME'=>'ThinkID',                // 默認Session_name

02.       
'SESSION_PATH'=>'',                        // 采用默認的Session save path
03.       
'SESSION_TYPE'=>'File',                        // 默認Session類型 支持 DB 和 File 
04.       
'SESSION_EXPIRE'=>'300000',                // 默認Session有效期
05.       
'SESSION_TABLE'=>'think_session',        // 數據庫Session方式表名
06.       
'SESSION_CALLBACK'=>'',                        // 反序列化對象的回調方法

其中SESSION_NAME 參數需要注意,如果需要在不同的項目之間不共享傳遞Session的值,請設置不同的值,否則請保留相同的默認值。
如 果設置了相同的SESSION_NAME的值,但是又希望創建基於項目的私有Session空間,應該怎麼處理呢?ThinkPHP還支持以項目為 Session空間的私有Session操作,以之前的常用操作為例,我們更改如下:

代碼:

 代碼如下 復制代碼

01.// 檢測Session變量是否存在(當前項目有效)
02.Session::is_setLocal('name');

03.
// 給Session變 量賦值(當前項目有效)
04.
Session::setLocal('name','value');
05.
// 獲取Session變量(當前 項目有效)
06.
Session::getLocal('name');

這樣,和全局的Session操作就不會沖突,可以用於一些特殊情況的需要。

ThinkPHP支持數據庫方式的Session操 作,設置SESSION_TYPE的值為DB就可以了,如果使用數據庫方式,還要確保設置好SESSION_TABLE的值,並且導入下面的DDL到你的 數據庫(以MySQL為例子):

代碼:

 代碼如下 復制代碼

01.CREATE TABLE `think_session` (

02.  `
id` int(11) unsigned NOT NULL auto_increment,
03.  `
session_id` varchar(255) NOT NULL,
04.  `
session_expires` int(11) NOT NULL,
05.  `
session_data` blob,
06. 
PRIMARY KEY  (`id`)        
07.)

注意,Db Session方式的數據庫連接會采用項目的數據庫配置信息進行連接。除了數據庫方式外,還可以增加其它方式的Session保存機制,例如內存方式、 Memcache方式等,我們只要增加相應的過濾器就行了,使用session_set_save_handler 方法,具體的方法定義參考Think.Util.Filter下面的FilterSessionDb.class.php 文件的實現。

 制作了一個簡單的登陸判斷

登陸檢測之後賦予Session值,使Session的值為非空即為假的false

 代碼如下 復制代碼 $_SESSION[C('USER_AUTH_KEY')] = $logInFind['id'] ;

其中 [C('USER_AUTH_KEY')]為ThinkPHP的內置方法和函數類。在未配置config.php文件時默認為空
把$logInFind['id'] 取出的帳號值賦予它,默認為關閉頁面Session就自動刪除消失!

其它頁面使用下面格式判斷

 代碼如下 復制代碼 if(!isset($_SESSION[C('USER_AUTH_KEY')])) {  //isset 是檢測變量是否賦值!
     $this->redirect('Login','Login'); //轉到注冊頁面
    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved