PHP版本--HTTP session cookie原理及应用

PHP 的COOKIE cookie 是一種在遠程浏覽器端儲存數據并以此來跟蹤和識别用戶的機制。 PHP在http 協議的頭信息裏發送cookie,因此 setcookie()函數必須在其它信息被輸出到浏覽器前調用,這和對header()函數的限制類似。 ------------------------------------------------------------------------------------------------------------------------------ 1.設置cookie: a.可以用 setcookie()或 setrawcookie()函數來設置 cookie。也可以通過向客戶端直接發送http頭來設置。 eg: Php代碼 收藏代碼 $value = 'something from somewhere'; setcookie("TestCookie", $value); /* 簡單 cookie設置 */ setcookie("TestCookie", $value, time()+3600); /* 有效期 1個小時 */ setcookie("TestCookie", $value, time()+3600, "/~rasmus/", ".example.com", 1); /* 有效目錄 /~rasmus,有效域名 example.com及其所有子域名 */ 設置多個 cookie 變量:setcookie('var[a]','value'); 用數組來表示變量,但他的下标不用引号。這樣就可以用$_COOKIE[‘var’][‘a’]來讀取該COOKIE 變量。 b. 使用 header()設置cookie; header("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[;...]]"); eg: Php代碼 收藏代碼 $value = 'something from somewhere'; header("Set-Cookie:name=$value"); ------------------------------------------------------------------------------------------------------------------------------ 2.讀取cookie: 直接用php 内置超級全局變量$_COOKIE 就可以讀取浏覽器端的cookie。 上面例子中設置了cookie "TestCookie",現在我們來讀取: eg: Php代碼 收藏代碼 print $_COOKIE['TestCookie']; ------------------------------------------------------------------------------------------------------------------------------ 3.删除cookie 隻需把有效時間設爲小于當前時間,和把值設置爲空。例如: eg: Php代碼 收藏代碼 setcookie("name", "", time()-1); 用header()類似。 note: a.用setcookie()時有錯誤提示,可能是因爲調用setcookie()前面有輸出或空格。也可能你的文檔是從其他字符集轉 換過來,文檔後面可能帶有 BOM 簽名(就是在文件内容添加一些隐藏的BOM 字符)。解決的辦法就是使你的文檔不出現這種情況。還有通過使用ob_start()函數 也能處理一點。 b.$_COOKIE 受magic_quotes_gpc 影響,可能自動轉義 c.使用的時候,有必要測試用戶是否支持cookie ------------------------------------------------------------------------------------------------------------------------------ 4.原理. a.服務器通過随着響應發送一個http 的Set-Cookie 頭,在客戶機中設置一個cookie(多個cookie 要多個頭)。 b.客戶端自動向服務器端發送一個http 的cookie 頭,服務器接收讀取。 HTTP/1.x 200 OK X-Powered-By: PHP/5.2.1 Set-Cookie: TestCookie=something from somewhere; path=/ Expires: Thu, 19 Nov 2007 18:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-type: text/html 這一行實現了cookie 功能,收到這行後 Set-Cookie: TestCookie=something from somewhere; path=/ 浏覽器将在客戶端的磁盤上創建一個cookie 文件,并在裏面寫入: TestCookie=something from somewhere; 這一行就是我們用 setcookie('TestCookie','something from somewhere','/'); 的結果。也就是用 header('Set-Cookie: TestCookie=something from somewhere; path=/');的結果。 -------------------------------------------------分割線-------------------------------------------------------------------- PHP 的SESSION session 使用過期時間設爲0 的cookie,并且将一個稱爲session ID 的唯一标識符(一長串字符串),在服務器端同步生成一些 session 文件(可以自己定義 session 的保存類型),與用戶機關聯起來。web應用程序存貯與這些 session 相關的數據,并且讓數據随着用戶在頁面之間傳遞.訪問網站的來客會被分配一個唯一的标識符,即所謂的 SESSION ID。它要麽存放在客戶端的cookie,要麽經由 URL 傳遞.SESSION 允許用戶注冊任意數目的變量并保留給各個請求使用。當來客訪問網站時,PHP會自動(如果session.auto_start 被設爲1)或在用戶請求時(由session_start()明确調用或session_register() 暗中調用)檢查請求中是否發送了特定的SESSION ID。如果是,則之前保存的環境就被重建。 session最最核心的概念就是:網頁間跳轉的額外數據,保存在服務器,用一個id标識,浏覽器要維持session,需要每次提交都帶上這個id. ------------------------------------------------------------------------------------------------------------------------------ session id的傳遞有兩種方式: a.通過 cookie 傳送 SESSION ID 使用 session_start()調用 session,服務器端在生成session 文件的同時,生成 session ID 哈希值和默認值爲PHPSESSID 的session name,并向客戶端發送變量爲(默認的是)PHPSESSID(session name),值爲一個 128 位的哈希值。服務器端将通過該 cookie 與客戶端進行交互。session 變量的值經php内部序列化後保存在服務器機器上的文本文件中,和客戶端的變量名默認情況下爲PHPSESSID 的coolie 進行對應交互.即服務器自動發送了http 頭:header('Set-Cookie: session_name()=session_id(); path=/'); 即setcookie(session_name(),session_id()); 當從該頁跳轉到的新頁面并調用session_start()後,PHP 将檢查與給定ID 相關聯的服務器端存貯的session 數據,如果沒找到,則新建一個數據集。 b.通過URL傳送 session ID 隻有在用戶禁止使用cookie 的時候才用這種方法,因爲浏覽器cookie 已經通用,爲安全起見,可不用該方法。 =<?php print session_id() ?>"&gt;xxx,也可以通過 POST 來傳遞 session 值。 ------------------------------------------------------------------------------------------------------------------------------ 如果客戶端禁止使用cookie,可以使用如下辦法: a、設置php.ini中的session.use_trans_sid = 1或者編譯時打開打開了--enable-trans-sid選項,讓PHP自動跨頁傳遞session id。 b、手動通過URL傳值、隐藏表單傳遞session id。 c、用文件、數據庫等形式保存session_id,在跨頁過程中手動調用。 link:http://apps.hi.baidu.com/share/detail/41643457 session也可以在禁用cookie的情況下使用: php.ini中session.use_cookies=1,改爲0,session會保存在服務器端,而不是客戶端的cookie。 可以通過session.save_path來查看服務器的session存放位置 session的使用: eg: Php代碼 收藏代碼 // page1.php session_start(); echo 'Welcome to page #1'; /* 創建 session變量并給 session變量賦值 */ $_SESSION['favcolor'] = 'green'; $_SESSION['animal'] = 'cat'; $_SESSION['time'] = time(); // 如果客戶端使用 cookie,可直接傳遞 session到page2.php echo '<BR>page 2'; // 如果客戶端禁用 cookie echo '<BR>page 2'; /* 默認php5.2.1下,SID隻有在 cookie被寫入的同時才會有值,如果該 session 對應的 cookie 已經存在,那麽 SID将爲 (未定義)空 */ Php代碼 收藏代碼 // page2.php session_start(); print $_SESSION['animal']; // 打印出單個 session var_dump($_SESSION); // 打印出page1.php傳過來的 session值 删除session: eg: Php代碼 收藏代碼 session_destroy(); // 第一步: 删除服務器端 session文件,這使用 setcookie(session_name(),'',time()-3600); // 第 二 步 : 删 除 實 際 的session: $_SESSION = array(); // 第三步: 删除$_SESSION全局變量數組 ?&gt; ------------------------------------------------------------------------------------------------------------------------------ 一個簡單的示例: php code: Php代碼 收藏代碼 session_start(); if (isset($_SESSION['test_sess'])){ $_SESSION['test_sess']++; }else{ $_SESSION['test_sess'] = 0; } echo $_SESSION['test_sess']; 使用的一個叫做httplook的http包嗅探工具來抓包: 第一次請求服務器: GET /test.php HTTP/1.1 Accept: */* Referer: http://localhost/ Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive 服務器第一次返回: HTTP/1.1 200 OK Date: Fri, 26 Aug 2005 07:44:22 GMT Server: Apache/2.0.54 (Win32) SVN/1.2.1 PHP/5.0.4 DAV/2 X-Powered-By: PHP/5.0.4 Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 1 Keep-Alive: timeout=15, max=99 Connection: Keep-Alive Content-Type: text/html; charset=utf-8 Content-Language: Off 第二次請求服務器: GET /test.php HTTP/1.1 Accept: */* Referer: http://localhost/ Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3 服務器第二次返回: HTTP/1.1 200 OK Date: Fri, 26 Aug 2005 07:44:23 GMT Server: Apache/2.0.54 (Win32) SVN/1.2.1 PHP/5.0.4 DAV/2 X-Powered-By: PHP/5.0.4 Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 1 Keep-Alive: timeout=15, max=98 Connection: Keep-Alive Content-Type: text/html; charset=utf-8 Content-Language: Off 仔細對比這些輸出,第二次請求比第一次請求多出來的就是: Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3 這個header将會向服務器發送一個cookie信息,告訴服務器我有一個cookie,名字叫PHPSESSID,内容是bmmc3mfc94ncdr15ujitjogma3。這個cookie是怎麽來的呢?看第一次服務器返回的信息裏邊有: Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/ 這是服務器向客戶端浏覽器寫一個cookie,名字是PHPSESSID,值是bmmc3mfc94ncdr15ujitjogma3,這個值實際就是所謂的session_id。繼續看第二次向服務器發出的請求,仍然向服務器發送了PHPSESSID這個cookie 可以得到以下結論: 1、隻要使用了session,就會通過cookie的方式向客戶端浏覽器發送session 2、每次向服務器發出請求的時候,本地浏覽器會把cookie附帶在請求信息中 總結: 隻要使用了session,就會通過cookie的方式向客戶端浏覽器發送session 實際上session完全是一個抽象的概念,session真正要做的,是在除了http提供的get和post提供的參數之外,針對某個用戶(可能是個浏覽器,或是台電腦,甚至是個ip),能保存額外的信息。如果我們不用系統提供的session,完全也可以傳遞數據,比如把我們原本要存入session的數據,序列化後再加密,形成一個字符串,在頁面上所有的url和form裏傳遞。服務器收到頁面請求後,從get或post裏取出機密串,揭開,還原數據,實際上和session要做的東西一個樣。隻不過這種方式超級bt,要實現需要做太多額外的工作。 session從技術角度講,就是把在網頁鏈接之間,額外要存儲的數據,用一個id命名,保存在服務器端,而浏覽器隻需要每次get或post的适合,隻提供這個id,就能獲得之前存儲的數據。php默認是用文件來保存數據的。unix下,php一般會在/tmp下面,創建 "sess_"+$session_id 這樣的文件名,通過這個名字,就能直接找到session_id對應的數據。 所以session最最核心的概念就是:網頁間跳轉的額外數據,保存在服務器,用一個id标識,浏覽器要維持session,需要每次提交都帶上這個id。 怎麽能讓浏覽器每次請求都能帶上這個id呢,笨辦法當然是在每個url鏈接或form的post裏都加個id的參數,有些webmail實際上就是這麽做的。當然更簡單的辦法就是通過cookie保存。但cookie方案還有個問題,如果浏覽器不支持cookie怎麽辦,上面也有陳述. 上述的session,是php4,5提供的session功能,要知道php4之前系統都沒有提供session功能!而且很多cgi程序,都是完全自己實現的session。php(4,5)提供的session,系統默認會用cookie來保存session_id 我之前一個項目,用戶都在内網使用web。爲了方便管理,直接把浏覽器ip綁死到一個session,就是用浏覽器ip地址代替了sessionid。這個方案裏沒有cookie,但還算是session,應爲他沒脫出session的定義。 每次向服務器發出請求的時候,本地浏覽器會把cookie附帶在請求信息中實際上和session完全沒有關系,說的隻是http協議裏cookie的工作方式。這個cookie是session_start()函數寫的,我們也完全可以自己任意寫cookie,隻要寫了,并且沒超過有效期,浏覽器都能送。

posted @ 2013-01-31 17:59  外贸乐  阅读(306)  评论(0编辑  收藏  举报