1. 程式人生 > >PHP Session與Cookie詳解

PHP Session與Cookie詳解

本文介紹了PHP會話控制Session與Cookie,主要闡述以下幾點內容:

• 會話控制的產生背景/概念
• cookie的維護與生命週期 (有效時間)
• session的維護與生命週期 (回收機制)
• cookie與session之間的區別與聯絡
• 問題1:禁用cookie後session為什麼會失效?
• 問題2:IE瀏覽器下丟失session,每次重新整理頁面,都會生成新的sessionID(Firefox瀏覽器正常)
• session、cookie簡單例項

理解會話控制的概念

理解一個概念就需要理解他的背景及產生原因,這裡引入WEB環境及其HTTP協議。

會話控制產生的背景:

閱讀過HTTP協議相關資料的同學都會知道HTTP協議是WEB伺服器與客戶端(瀏覽器)相互通訊的協議,它是一種無狀態協議,所謂無狀態,指的是不會維護http請求資料,http請求是獨立的,不持久的。也就是說HTTP協議沒有一個內建的機制來維護兩個事務之間的狀態或者說是關係。當一個使用者在請求一個頁面後再去請求另外一個頁面時,HTTP將無法告訴我們這兩個請求是否來自同一個使用者。

由此我們就會覺得很奇怪了,平時我們在論壇逛帖子或電商網站購物時,只要我們在這個站點內,不論我們怎麼跳轉,從一個頁面跑到另一個頁面,網站總會記得我是誰,比如告訴你購買了哪些東西。這是怎麼做到的呢,估計大家猜到了,這就是運用了HTTP會話控制

。在網站中跟蹤一個變數,通過對變數的跟蹤,使多個請求事物之間建立聯絡,根據授權和使用者身份顯示不同的內容、不同頁面。

PHP Session會話控制:

PHP的session會話是通過唯一的會話ID來驅動的,會話ID是一個加密的隨機數字,由PHP生成,在會話的生命週期中都會儲存在客戶端。我們知道客戶端(也就是瀏覽器)儲存資料的地方只有cookie,所以PHP的會話ID一般儲存在使用者機器的cookie中。瞭解cookie後我們知道,瀏覽器是可以禁用cookie的,這樣會話就會失效。所以PHP會話控制還有一種模式,就是在URL中傳遞會話ID。如果在瀏覽網站時我們稍加留心的話,有些URL中有一串看起來像隨機數字的字串,那麼其實很有可能就是URL形式的會話控制。

講到這裡,有些人可能會有疑問了,客戶端只是儲存一個會話ID,那麼會話控制中儲存的會話變數比如你購物時買的物品列表等,它們是存放在哪個地方的呢?很顯然,會話變數是在伺服器端使用的,那麼這些會話變數必定存放在伺服器端。預設情況下,會話變數儲存在伺服器的普通檔案中(也可以自己配置使用資料庫來儲存,可以Google一下),會話ID的作用就像是一把鑰匙,在伺服器端儲存會話的檔案中找到該會話ID對應的會話變數,比如購買物品的列表。

那麼會話控制的整個過程可能就像這個樣子,使用者登入或者第一次瀏覽某個站點的頁面時,該站點會生成一個PHP的會話ID並通過cookie傳送到客戶端(瀏覽器)。當用戶點選該站點的另一個頁面時,瀏覽器開始連線這個URL。在連線之前,瀏覽器會先搜尋本地儲存的cookie,如果在cookie中有任何與正在連線的URL相關的cookie,就將它提交到伺服器。而剛好在登陸或第一次連線時,已經產生了一個與該網站URL相關的cookie(儲存的會話ID),所以當用戶再次連線這個站點時,站點就可以通過這個會話ID識別出使用者,從伺服器的會話檔案中取出與這個會話ID相關的會話變數,從而保持事務之間的連續。

接下來我們瞭解下兩個重要的概念:cookie和session

cookie的維護與生命週期

cookie是在伺服器端被建立並寫回到客戶端瀏覽器,瀏覽器接到響應頭中關於寫cookie的指令則在本地臨時資料夾中。

建立了一個cookie檔案,其中儲存了你的cookie內容,cookie內容的儲存是鍵值對的方式,鍵和值都只能是字串。例如:
檔案:Cookie:[email protected]/
內容格式:voteID100101localhost/15361167667230343893360385046430343691*

cookie的建立:

setcookie()函式設定cookie, 函式原型如下
setcookie(name, value, expire, path, domain);

註釋:cookie標題頭必須在傳送其他標題頭之前傳送,否則就無效(這是cookie的限制,而不是PHP的限制)。在傳送 cookie 時,cookie 的值會自動進行 URL 編碼,在取回時進行自動解碼,為防止 URL 編碼,請使用 setrawcookie() 取而代之。

cookie的維護:

cooke有四個識別符號:cookie的name,domain,path,secure標記。要想在將來改變這個cookie的值,需要傳送另一個具有相同cookie namedomainpath的Set-Cookie訊息頭,這將以一個新的值來覆蓋原來cookie的值。然而,如果僅僅只是改變這些選項的某一個也會建立一個完全不同的cookie,如只是更改了name值。

cookie失效時間:

可以設定過期時間,如果不設定則是會話級別的,即關閉瀏覽器就會消失。當cookie建立時包含了失效日期,這個失效日期則關聯了以name-domain-path-secure為標識的cookie。要改變一個cookie的失效日期,你必須指定同樣的組合。當改變一個cookie的值時,你不必每次都設定失效日期,因為它不是cookie標識資訊的組成部分。例如:

setcookie(vote , $id+1, time()+3600*24);
setcookie(vote, $id);

在cookie上的失效日期並沒有改變,因為cookie的識別符號是相同的。實際上,只有你手工的改變cookie的失效日期,否則其失效日期不會改變。這意味著在同一個會話中,一個會話cookie可以變成一個持久化cookie(一個可以在多個會話中存在的),反之則不可。為了要將一個持久化cookie變為一個會話cookie,你必須刪除這個持久化cookie,這隻要設定它的失效日期為過去某個時間之後再建立一個同名的會話cookie就可以實現

需要記得的是失效日期是以瀏覽器執行的電腦上的系統時間為基準進行核實的。沒有任何辦法來來驗證這個系統時間是否和伺服器的時間同步,所以當伺服器時間和瀏覽器所處系統時間存在差異時這樣的設定會出現錯誤。

cookie自動刪除:

cookie會被瀏覽器自動刪除,通常存在以下幾種原因:
會話cookeSession cookie在會話結束時(瀏覽器關閉)會被刪除
持久化cookie(Persistent cookie)在到達失效日期時(主動設定過期時間)會被刪除,如:

setcookie(“vote”, “”, time()-3600);

如果瀏覽器中的cookie限制到達,那麼cookies會被刪除以為新建cookies建立空間。

session的維護與生命週期

Session是由應用伺服器維持的一個伺服器端的儲存空間(session儲存在伺服器端,不同於cookie儲存在客戶端),使用者在連線伺服器時,會由伺服器建立生成一個唯一的sessionID,用該sessionID為識別符號來存取伺服器端的Session儲存空間,在會話期間分配給客戶端的唯一sessionID,用來標識當前使用者,與其他使用者進行區分。通過SessionID接受每一次訪問的請求,從而識別當前使用者跟蹤和保持使用者的具體資料以及session變數,可在session中儲存數字或文字資料,比如session_name,這些資訊都儲存在伺服器端

當然,sessionID也可以作為會話資訊儲存到資料庫中,進行session持久化。這樣可以跟蹤使用者的登陸次數、線上與否、線上時間等從而維護HTTP無狀態事物之間的關係。session的內容儲存是鍵值對的列表,鍵是字串型別,session的儲存更方便,值可以是物件。

在session會話期間,session會分別儲存在客戶端和伺服器端兩個檔案,客戶端可以是cookie方式儲存的sessionID(預設的儲存方式)或通過url字串形式傳遞。伺服器端一般以文字的形式儲存在指定的session目錄中。在伺服器端我們可以通過session.use_cookies來控制客戶端使用哪一種儲存方式。如果定義為cookie儲存方式,我們可以通過session.cookie_lifetime(預設值0,關閉瀏覽器就清除)來控制被儲存在client上的cookie的有效期。而如果客戶端用cookie方式儲存的sessionID,則使用“臨時”的cookie儲存(cookie的名稱為PHPSESSID,通過Firebug你可以瞭解到詳細的資訊,該名稱你可以通過php.ini session.name進行更改),使用者提交頁面時,會將這一SessionID提交到伺服器端,來存取session資料。這一過程,是不用開發人員干預的。

Session的建立:

session_start()  //開始一個會話及返回已經存在會話

功能:初始化Session,也標識著session生命週期的開始。要使用session,必須初始化一個session環境,有點類似於OOP概念中呼叫建構函式構建立物件例項一樣。session初始化操作,宣告一個全域性陣列$_SESSION,對映寄存在記憶體的session資料。如果session檔案已經存在,並且儲存有session資料,session_start()則會讀取session資料,填入$_SESSION中,開始一個新的session生命週期。

說明:這個函式沒有引數,且返回值為true,如果使用基於cookie的sessin,那麼在session_satrt()之前不能有任何的輸出,包括空白
如果在php.ini中session.auto_start=1開啟,則在每個頁面執行session_start(),不需要手工設定,該選項預設為關閉狀態,開啟後不能將物件放入session中。

Session ID:

使用者session唯一識別符號,隨機生成的一串字串,具有唯一性,隨機性。主要用於區分其它使用者的session資料。使用者第一次訪問web頁面的時候,php的session初始化函式呼叫會分配給當前來訪使用者一個唯一的ID,也稱之為session_id。

獲得session_id():

echo $_COOKIE[‘PHPSESSID’].'<br/>';
echo $_COOKIE[session_name()].'<br/>';
echo session_id().'<br/>';

session資料:

我們把需要通過session儲存的使用者狀態資訊,稱為使用者session資料,也稱為session data。一般是在當前session生命週期內,相應的$_SESSION資料。一旦呼叫了session_start()初始化session,就意味著開始了一個session生命週期。也就是宣佈了,可以使用相關函式操作$_SESSION來管理session資料。這個session生命週期產生的資料並沒有實時地寫入session檔案,而是通過$_SESSION變數寄存在記憶體中。$_SESSION是一個全域性變數,型別是Array,映射了session生命週期的session資料,寄存在記憶體中。在session初始化的時候,從session檔案中讀取資料,填入該變數中。在session(生命週期)結束時,將$_SESSION資料寫回session檔案。

註冊一個會話變數:

從PHP4.1以後,會話變數儲存在超級全域性陣列$_SESSION中。要建立一會話變數,只需要在陣列中設定一個元素,如:

$_SESSION[‘domain’] = blog.jb51.net;
$_SESSION[‘poll’]=$_SESSION[poll] + 1;

使用一個會話變數:

echo $_SESSION[‘blogdomain’];   //打印出blog.jb51.net,使用會話前必須先使用session_start()函式啟動一個會話

登出Session變數/銷燬會話:

unset($_SESSION);  //銷燬單個會話變數
如:unset($_SESSION[‘blogdomain’]);
#unset($_SESSION)這個函式會將全域性變數$_SESSION銷燬,而且還沒有可行的辦法將其恢復。使用者也不再可以註冊$_SESSION變數,所以此函數千萬不可使用。

session_unset(); //多項釋放。將所有登陸在session檔案裡的變數釋放出來
#在session生命週期,從當前session中登出全部session資料,讓$_SESSION成為一個空陣列。它與unset($_SESSION)的區別在於:unset直接刪除$_SESSION變數,釋放記憶體資源;另一個區別在於,session_unset()僅在session生命週期能夠操作$_SESSION陣列,而unset()則在整個頁面(page)生命週期都能操作$_SESSION陣列。session_unset()同樣不進行任何IO操作,隻影響$_SESSION陣列。

$_SESSION=array();  //多項釋放,釋放所有登入在$_SESSION引數裡的變數

session_destroy(); 
#當使用完一個會話後,首先應該登出所有的變數,然後再呼叫該函式結束當前的會話,並清空會話中的所有資源,刪除伺服器上的session檔案.該函式不會unset(釋放)和當前session相關的全域性變數,也不會刪除客戶端的session cookie
#如果說session_start()初始化一個session的話,而它則登出一個session。意味著session生命週期結束了。在session生命週期結整後, session_unset, $_SESSION[‘domain’] 都將不能操作$_SESSION陣列,而$_SESSION陣列依然可以被unset()等函式操作。這時,session意味著是未定義的,而$_SESSION依然是一個全域性變數,他們脫離了關對映關係。
通過session_destroy()登出session,除了結束session生命週期外,它還會刪除sesion檔案,但不會影響當前$_SESSION變數。即它會產生一個IO操作。

備註:

1、php預設的session是基於cookie的,如果要刪除cookie的話,必須藉助setcookie()函式
2、session_unset()和unset()函式區別:

在session生命週期,session_unset()從當前session中登出全部session資料,讓$_SESSION成為一個空陣列。它與unset($_SESSION)的區別在於:unset直接刪除$_SESSION變數,釋放記憶體資源;另一個區別在於,session_unset()僅在session生命週期能夠操作$_SESSION陣列,而unset()則在整個頁面(page)生命週期都能操作$_SESSION陣列。session_unset()同樣不進行任何IO操作,隻影響$_SESSION陣列。

Session生命週期(session lifetime):Session失效時間與過期回收機制
我們把初始化session開始,直到登出session這段期間,稱為session生命週期
預設的,php會將session儲存在php.ini配置中session.save_path設定的目錄下,檔名為這個樣子:sess_ves0d7uvdsab9k6sig73mnn592。每一個檔案對應了一個session(會話)。session檔案格式大致如下:

poll_200|i:1;poll_100|i:3;   //#變數名|型別:長度:值

設定SESSION的生命週期:

php session是基於cookie的,所以要設定session的生命週期,首先要設定cookie的失效時間。因為在客戶端(如瀏覽器)登入網站時,SESSION 是否有用,首先找客戶端是否有 COOKIE,通過COOKIE 中的 SESSION ID 去找伺服器上的檔案。

session_start(); 
$lifeTime = 24 * 3600; // 儲存一天 
setcookie(session_name(), session_id(), time() + $lifeTime, “/”); 

其實PHP5 Session還提供了一個函式 session_set_cookie_params(); 來設定PHP5 Session的生存期的,該函式必須在 session_start() 函式呼叫之前呼叫:

$lifeTime = 24 * 3600; // 儲存一天 
session_set_cookie_params($lifeTime); 
session_start(); 

在伺服器端,php如何判斷session檔案是否過期?

session.gc_maxlifetime = 1440 (初始值)
#設定session存活時間,單位是秒。每次GC啟動後, 會通過stat得到session檔案最後訪問的unix時間,通過現在時間減去檔案最後訪問時間之間大於session.gc_maxlifetime,則會刪除該檔案。

如果”最後的修改時間”到”現在”超過了session.gc_maxlifetime(預設是1440)秒,也就是說在這裡設定的時間內,該檔案沒有被修改過,這個session檔案就被認為是過期了,由於php5的session採用被動的回收機制,過期的session檔案不會自己消失,而是通過觸發“回收”來處理過期的session,那麼在下一次session回收的時候,如果這個檔案仍然沒有被更改過,這個session檔案就會被刪除(session就過期了)。

session回收何時發生?

預設情況下,每一次php請求,就會有1%的概率發生回收,所以可能簡單的理解為“每100次php請求就可能有一次回收概率發生”。這個概率是通過以下引數控制的:

session.gc_probability = 1 (初始值)
session.gc_divisor = 100 (初始值)
#由這二個函式決定了啟用GC的概率,預設是1/1000。也就是說,每一千次使用者請求中有一次會啟動GC回收session。啟動GC程序不宜過於頻繁。過於頻繁訪問的網站,併發量大的網站,可減小PHP GC的啟動頻率。PHP GC回收session會降低php的執行效率。

這兩個合起來就是啟動Gabadge Collection(gc)程序管理概率的,在session初使化時(session_start())。Gabadge Collection啟動後跟蹤session資訊檔案。其啟動概率為session.gc_probability/session.gc_divisor。也就是說不是每個session資訊檔案都有100%的被系統當作垃圾來處理的。如果直接關閉瀏覽器的話,session資訊檔案很多情況下都是留在了伺服器上,如果把概率改成了100%,雖然Gabadge Collection百分之百被啟動了,但是這會對伺服器新增負荷,也就失去了GC本身的意義了。

補充說明:

1、假設這種情況session.gc_maxlifetime=1440,如果某個session檔案最後修改時間是1440秒之前,那麼在下一次回收(1/100的概率)發生前,這個session仍然是有效的;

2、如果你的session使用session.save_path中使用別的地方儲存session,session回收機制有可能不會自動處理過期session檔案。這時需要定時手動(或者crontab)的刪除過期的session:cd /path/to/sessions; find -cmin +24 | xargs rm;

3、注意,當伺服器端session檔案數量沒有得到有效的回收,逐漸增長到GB或更大級別時可能你的站點在存取session時就會越來越緩慢,多見於站點登入登出會受到影響;

4、寫日誌、週報、月報等時候我們最後提交的關頭,有時會出現”無效的操作,請登陸後重試”等訊息,其原因也不言而喻,可能就是session失效,gc清除那些已經“超時”的session檔案。

一些特殊情況:

因為回收機制會檢查檔案的“最後修改時間”,所以如果某個會話是活躍的,但是session的內容沒有改變過,那麼對應的session檔案也就沒有改變過,回收機制會認為這是一個長時間沒有活躍的session而將其刪除。這是我們不願看到的,可以通過增加如下的簡單程式碼解決這個問題:

<?php
if(!isset($_SESSION[‘last_access’])||(time()-$_SESSION[‘last_access’])>120)
  $_SESSION[‘last_access’] = time(); 
?>   //程式碼會每隔120秒,嘗試修改修改一次session

cookie與session之間的區別與聯絡

相同點:都可以在解決HTTP無狀態的問題,使同一個客戶端在訪問網站的多次請求中,可以儲存,設定資訊,並且在請求事物之間建立聯絡。

不同點:簡單的說cookie的資訊儲存在客戶端,session的資訊儲存在伺服器端。

Session採用鍵值對,也就是說ID存放客戶端,而值放在伺服器端,是通過使用者的ID去找伺服器上對應的值,這種方式值放置在伺服器端,有個時間限制,時間到則伺服器自動回收/釋放。

Cookies則有兩種方法,一種方法是把值儲存在瀏覽器的變數中,當瀏覽器關閉時結束,另一種方法是儲存在硬碟中,只要時間不過期,下次還可使用。

聯絡:當客戶端使用基於Cookie方式儲存的SessionID時,SessionID一般儲存在cookie中。

備註:cookie在相同核心的瀏覽器之間是共享的,不同核心瀏覽器是不共享的例如火狐和IE(存放位置都不同,當然不共享)。不同核心瀏覽器不能共享cookie,也會產生不同sessionid。

問題1:禁用cookie後session為什麼會失效?

首先說明一點:session不一定必須依賴cookie,只是php預設客戶端sessionid基於cookie方式儲存。

到此,我想你也應該瞭解了php預設的session客戶端儲存方式是基於cookie的,所以一旦客戶端禁用Cookie,那麼session跨頁將會失效,不知道這麼描述是否合適,通俗的說無狀態的東西要變的有狀態,只能兩邊都進行比對,如果用cookie方式儲存的SessionID,客戶端這邊的比對條件就放到cookie裡,所以客戶端禁用cookie,session便也會隨之失效。php的session客戶端ID一般有兩種儲存方式:cookie和url方式。如果是cookie中儲存session ID,就可以看到瀏覽器的cookie中有一個PHPSESID變數(可以通過firefox檢視)。如果是URL傳遞的(建議使用隱藏表單傳遞),就可以看到形如:index.php?PHPSESID=ves0d7uvdsab9k6sig73mnn592的URL。例如:

demo1.php
<?php
session_start();
$_SESSION[‘blog’]=’http://blog.jb51.net';
echo “<a href=’demo2.php’>test2</a>”;
?>

demo2.php
<?php
session_start();
echo ‘session值為’.$_SESSION[‘blog’];
?>

執行上面的程式碼,在客戶端cookie正常情況下,我麼可以在demo2.php中打印出$_SESSION[‘blog’]的值為:http://blog.jb51.net。但是,現在如果你手動禁用客戶端的cookie,再執行該例項,可能就得不到結果了。因為預設的客戶端sessionid儲存方式在跨頁後,讀取不到前一頁的sessionid,當執行session_start();將又會產生一個session檔案,與之對應產生相應的session id,用這個session id是取不出前面提到的第一個session檔案中的變數的,因為這個session id不是開啟它的“鑰匙”。如果在session_start();之前加程式碼session_id($sessionid);將不產生新的session檔案,直接讀取與這個id對應的session檔案。簡單的說就是在前一頁取得session id,然後想辦法傳遞到下一頁,在下一頁的session_start();程式碼之前加程式碼session_id(傳過來的sessionid); 例如:

demo.php
<?php
$sid = $_GET[‘sid’];
if(!empty($sid)){
  session_id($sid);
  session_start();
}else{
  session_start();
  $sid = session_id();
}
?>
<form action=”demo2.php?sid=<?php echo $sid ?>” method=”post”>
<input type=”text” name=”id” value=”100″ />
<input type=”submit” value=”提交”/>
</form>

demo2.php
<?php
$sid = $_GET[‘sid’];
if(!empty($sid)){
  session_id($sid);
  session_start();
}else{
  session_start();
  $sid = session_id();
}
$id = $_POST[‘id’];
$key = ‘poll_’.$id;
if($id!=”){
  echo $key = ‘poll’.$id;
  if(!empty($_SESSION[$key])){
    $_SESSION[$key]=$_SESSION[$key] + 1;
  }else{
    $_SESSION[$key]=1;
    setcookie($key ,$id+1,time()+3600*24);
  }
  echo ‘<script>alert(“success”);javascript:location.href=”demo.php?sid=’.$sid.'”;</script>';
}else{
  echo ‘<script>alert(“failed!ID Null”);javascript:history.back(-1);</script>';
}
?>

除此之外,我們還可以將客戶端PHPSESID存放到檔案中,如:

demo.php
session_start();
$_SESSION[‘blogdomain’]= ‘http://blog.jb51.net';
$sid=session_id();
$fp=fopen(“D:\tmp\websid.txt”,”w+”);
fwrite($fp,$sid);
fclose($fp);
echo ‘<a href=”demo2.php”>demo2</a>';

demo2.php
$fp=fopen(“D:\tmp\websid.txt”,”r”);
$sid=fread($fp,1024);
fclose($fp);
session_id($sid);
session_start();
print_r($_SESSION);

當客戶端禁用cookie,可以通過以下幾種方式改變session對客戶端cookie的依賴,使session拋開客戶端cookie:

1、設定php.ini中的session.use_trans_sid = 1或者編譯時開啟打開了–enable-trans-sid選項,讓PHP自動跨頁傳遞session id。當session.use_trans_sid為有效時,ession.use_only_cookies一定要設定為無效0。

2、手動通過URL傳值、隱藏表單傳遞session id。

3、用檔案、資料庫等形式儲存session_id,在跨頁過程中手動呼叫。

PHP也提供一個函式:

output_add_rewrite_var  ( string $name , string $value ) # 變數名 變數值

說明:此函式給URL重寫機制新增名/值對。 這種名值對將被新增到URL(以GET引數的形式)和表單(以input隱藏域的形式),當透明URL重寫用 session.use_trans_sid 開啟時同樣可以新增到session ID。 要注意,絕對URL(http://jb51.net/..)不能被重寫。此函式的行為由url_rewriter.tags php.ini 引數控制。

<?
session_start();
output_add_rewrite_var(‘PHPSESSID’,session_id ());
echo ‘<a href=”demo2.php”>demo</a>';
?>

這樣sessionID會跟在URL後面而且from中會出現sessionID的hidden值。

改變session客戶端ID儲存方式:

session.use_cookies //控制客戶端儲存SessionID時使用哪一種方式,當它為“1”時,就說明啟動了session cookie(初始值為1)
可以使用上面我們提到的函式來查詢得到目前的session id:echo $_COOKIE[“PHPSESSID”];
但是,如果client的瀏覽器不支援cookie的話,即使session.use_cookies這個引數的值等於“1”,用上述的查詢也只會得到null。

php.ini中兩個和該選項相關的配置引數:

session.use_cookies = 1  //是否使用cookies(預設值為1)
session.use_only_cookies=1  //為1時只使用cookie;為0時可使用cookie和其它方式,這時如果客戶端cookie可用,則session還是預設用cookie(預設值為1)

注意:如果客戶的瀏覽器是支援cookie的,強烈推薦“session.use_only_cookies = 1”,當session.use_only_cookies為有效時,即使想通過URL來傳遞session id也會被認為無效,這樣可以減少通過sessionid被攻擊的可能性。上面兩個配置,在php程式碼頁面中設定方式:

ini_set(‘session.use_cookies’,’1′);
ini_set(‘session.use_only_cookies’,’1′);

IE下丟失session,每次重新整理頁面,都會生成新的sessionID(Firefox瀏覽器都正常)

如果你的伺服器或站點出現這種問題,請正確配置session.cookie_path網站域,如果配置錯誤可能會引起以下常見故障:

(1)客戶端的每個PHPSESSID在伺服器端都會一對一的對應生成一個獨立的session記錄儲存在伺服器端,故伺服器端session檔案冗餘將會增多(GC回收機制異常時、站點訪問量較大時)

(2)使用session記錄相關資訊的站點可能在除Firefox(Chrome未測試)之外的瀏覽器下訪問出現問題,例如:購物車無法記錄選購專案、站點登入失敗等

session.cookie_path 是指 session 生效的網站域;
session.save_path 是指儲存 session 臨時檔案的路徑。
例如:session.cookie_path= /        //cookie的有效路徑

補充:如果所有瀏覽器訪問重新整理產生新sessionID,請檢查客戶端是否禁用了cookie。

session簡單例項

使用session防止表單重複提交:

<?php
session_start();
$_SESSION[“num”] = 0;
if(isset($_POST[“action”] && $_POST[“action”]==”post”)){
if($_SESSION[“num”] == 0){
    echo “提交成功!”;
   $_SESSION[“num”] = 1;
}else{
   echo “請勿重複提交!”;
}
}
?>

使用session方式的登入驗證例項程式碼:

<?php
session_start();//啟動session,必須放在第一句,否則會出錯。
if($_GET[‘out’]){
unset($_SESSION[‘id’]);
unset($_SESSION[‘pass’]);
}
if($_POST[‘name’]&&$_POST[‘password’]){
<span style=”font-family: 微軟雅黑;”><span style=”font-size: 16px;line-height:2.5em;”>//用於設定session</span></span>
$_SESSION[‘id’]=$_POST[‘name’];
$_SESSION[‘pass’]=$_POST[‘password’];
}
if($_SESSION[‘id’]&&$_SESSION[‘pass’]){
echo “登入成功!
使用者ID:”.$_SESSION[‘id’].”
使用者密碼:”.$_SESSION[‘pass’];
echo “<br />”;
echo “<a href=’login.php?out=out’>登出session</a>”;
}
 
?>
<form action=”login.php” method=”post”>
使用者ID:<input type=”text” name=”name” />
密碼:<input type=”password” name=”password” />
<br />
<input type=”submit” name=”submit”>
</form>

使用cookie方式的登入驗證例項程式碼:

if($_GET[‘out’]){ //用於登出cookies
setcookie(‘id’,””);
setcookie(‘pass’,””);
echo “<script>location.href=’login.php'</script>”; //因為cookies不是及時生效的,只有你再次重新整理時才生效,所以,登出後讓頁面自動重新整理。
}
if($_POST[‘name’]&&$_POST[‘password’]) //如果變數使用者名稱和密碼存在時,在下面設定cookies
{ //用於設定cookies
setcookie(‘id’,$_POST[‘name’],time()+3600);
setcookie(‘pass’,$_POST[‘password’],time()+3600);
echo “<script>location.href=’login.php'</script>”; //讓cookies及時生效
}
if($_COOKIE[‘id’]&&$_COOKIE[‘pass’]){ //cookies設定成功後,用於顯示cookies
echo “登入成功!<br />使用者名稱:”.$_COOKIE[‘id’].”
密碼:”.$_COOKIE[‘pass’];
echo “<br />”;
echo “<a href=’login.php?out=out’>登出cookies</a>”; 
}
?>
<form action=”” method=”post”>
使用者ID:<input type=”text” name=”name” />
密 碼:<input type=”password” name=”password” />
<br />
<input type=”submit” name=”submit”>
</form>

使用session隨機碼驗證投票合法性:

list.php 選項頁面
session_start();
$tokenKey = md5(rand(1,100));
$_SESSION[‘tokenKey’] = $tokenKey;
注意:在傳值時同時傳入隨機碼$tokenKey

vote.php  投票動作執行頁面
$tokenKey = $_SESSION[‘tokenKey’];
if($_POST[‘tokenKey’] !=  $tokenKey){     //判斷隨機碼是否和上一頁相同
  echo “<script>alert(‘請重新投票!’);location.href=’list.php';</script>”;   //隨機碼無效
  exit;
}else{
  執行投票操作;
  清空session儲存的隨機碼
}

相關推薦

PHP SessionCookie

本文介紹了PHP會話控制Session與Cookie,主要闡述以下幾點內容: • 會話控制的產生背景/概念 • cookie的維護與生命週期 (有效時間) • session的維護與生命週期 (回收機制) • cookie與session之間的區別與聯絡 • 問題1:禁用cookie後session為什麼會

SessionCookie

服務器端 瀏覽器中 客戶端 attribute 其他 sso seconds 磁盤 www 1. 什麽是會話 會話的目的 https://www.cnblogs.com/teeva/p/4474602.html 1.1會話:客戶端向瀏覽器發送一個連接請求開始,客戶端明確

express使用sessioncookie

無狀態的http 我們都知道http的請求和響應式相互獨立的,伺服器無法識別兩條http請求是否是同一個使用者傳送的。也就是說伺服器端並沒有記錄通訊狀態的能力。我們通常使用cookie和session來確定會話雙方的身份。 cookie cookie 是從伺服器端傳送的,伺服

HttpServletRequest使用者請求cookie

HttpServletRequest 使用者請求物件 1.使用者請求物件包含:  請求行  請求頭  請求體      // 獲取請求的網址     System.out.println(request.getRequestURL());     // http://loc

JavaEE基礎(04):會話跟蹤技術,SessionCookie

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、會話跟蹤 1、場景描述 比如登入某個購物網站,身份識別成功後,在網站下單,支付 等操作,這些操作中當前登入使用者資訊必須是共享的,這樣這些操作結果才能和登入使用者做關聯。 2、概念簡介 可以把會話理解為客戶端與伺服器之間的一次互動,在一次互動

cookiesession 的區別

重復 處理方式 一行 所有 有效 依據 是把 存儲 一個 二者的定義: 當你在瀏覽網站的時候,WEB 服務器會先送一小小資料放在你的計算機上,Cookie 會幫你在網站上所打的文字或是一些選擇, 都紀錄下來。當下次你再光臨同一個網站,WEB 服務器會先看看有沒有它上次留下的

PHP中常用的超全局變量 表單中get和post提交方式的區別 sessioncookie的區別 GD庫是做什麽用的

屬性 過程 生成報表 用戶訪問 服務器 接收 file pla request PHP中常用的超全局變量 $_GET ----->get傳送方式$_POST ----->post傳送方式$_REQUEST ----->可以接收到get和post兩種方式的值

PHP面向對象:繼承、封裝多態

gets key copy nes col 成員變量 ret 封裝 文字 首先,在解釋面向對象之前先解釋下什麽是面向對象? [面向對象]1、什麽是類? 具有相同屬性(特征)和方法(行為)的一系列個體的集合,類是一個抽象的概念2、什麽是對象?從類中拿到的具有具體屬性值得個體,

PHP中VC6、VC9、TS、NTS版本的區別用法

進行 系統資源 stc 詳解 ron 線程安全 info 啟動 win 1. VC6與VC9的區別: VC6版本是使用Visual Studio 6編譯器編譯的,如果你的PHP是用Apache來架設的,那你就選擇VC6版本。 VC9版本是使用Visual Studio 20

cookiesession的區別

這些都是基礎知識,不過有必要做深入瞭解。先簡單介紹一下。 二者的定義: 當你在瀏覽網站的時候,WEB 伺服器會先送一小小資料放在你的計算機上,Cookie 會幫你在網站上所打的文字或是一些選擇, 都紀錄下來。當下次你再光臨同一個網站,WEB 伺服器會先看看有沒有它上次留

PHPSessionCookie

一、通過Session 和 Cookie 實現會話處理 1、HTTP協議是無狀態的   伺服器無法區分哪些請求來自哪些客戶端,或者客戶端是處於連線狀態還是斷開狀態 2、Session   在使用者訪問網

22:24 2016/6/9 PHP基礎練習題答案

第一章 開始編寫PHP程式 以下是練習題: 一、選擇題1.下列哪一項屬於伺服器端Scripts?( ) A.VBScript B.JavaScript C.Java Applet D.PHP 2

PHP反射機制原理用法

本文例項講述了PHP反射機制原理與用法。分享給大家供大家參考,具體如下: 反射 面向物件程式設計中物件被賦予了自省的能力,而這個自省的過程就是反射。 反射,直觀理解就是根據到達地找到出發地和來源。比如,一個光禿禿的物件,我們可以僅僅通過這個物件就能知道它所屬的類、擁有哪些方

php進階篇--3.會話控制(sessioncookie

一、cookie簡介 Cookie是儲存在客戶端瀏覽器中的資料,我們通過Cookie來跟蹤與儲存使用者資料。一般情況下,Cookie通過HTTP headers從服務端返回到客戶端。多數web程式都支援Cookie的操作,因為Cookie是存在於HTTP的標頭

sessioncookie-----2017-05-08

之前 控制 uid -- 5-0 php代碼 會話 默認 安全性 會話控制:目的是記錄不同用戶身份。 1、session:有實效性 特點: (1)存在在服務器 (2)每個用戶都會存一份 (3)可以存儲任意類型的數據 優點:安全性高 缺點:服務器壓力過大 2、

Javascript中的applycall

選項 this 模式 div sun fun object 面向 傳遞     JavaScript中有一個call和apply方法,其作用基本相同,但也有略微的區別。  一、方法定義   1、call 方法   語法:call([thisObj[,arg1[, arg2[

SessionCookie

瀏覽器支持 .html 條件 index .cn () 電子商務 hive edi Session: Session是“會話”的意思,然而,因為http協議是無狀態的,那麽每次客戶端請求服務器端,服務器端都會以“嶄新”的頁面展示給客戶端,這在靜態的html頁面中是不會存在

letconst

沒有 而在 不能 解析 引入 cti lar 語言 reference 在ES6中,js首次引入了塊級作用域的概念,而什麽是塊級作用域? 眾所就知,在js當中存在預解析的概念,就是變量提升。並且只存在全局作用域和私有作用域。在全局定義的變量就是全局變量,而在函數內部定義的

PHP配置文件php.ini

php配置文件詳解php.iniPHP配置文件詳解php.ini [PHP] ; PHP還是一個不斷發展的工具,其功能還在不斷地刪減 ; 而php.ini的設置更改可以反映出相當的變化, ; 在使用新的PHP版本前,研究一下php.ini會有好處的 ;;;;;;;;;;;;;;;;;;; ; 關於這個

sessionCookie的區別

瀏覽器 cookie 通信設備 Cookie與session的區別此文章 來自烏龜運維wuguiyunwei.comQQ群:602183872主要區別:Cookie,也稱為HTTP cookie,Web cookie或瀏覽器cookie,是從網站發送到服務器並存儲在用戶的Web瀏覽器中的一小部分數