PHP SESSION機制,從存儲到讀取


 

PHP中,如果要獲取SESSION數據,必須要有對應的session_id,session_id的獲取方式有兩種

1.基於客戶端的cookie

2.基於url

先說第一種情況,基於客戶端的cookie.服務器端的腳本在開啟session后,會依據php.ini來存儲session,下面列舉一些

session.save_handler 定義存儲和獲取與會話關聯的數據的處理器的名字。默認為 files。如果設定為files(session.save_handler = files),則采用的是php內置機制,如果想自定義存儲方式(比如存儲到數據庫中),則使用session_set_save_handler()進行自定義設置

session.save_path 定義了傳遞給存儲處理器的參數(注釋1)。如果選擇了默認的 files 文件處理器,則此值是創建文件的路徑。默認為 /tmp,也可以修改,比如session.save_path = "e:/wamp/tmp"。也可以使用session_save_path()在腳本中設定(一定在session_start前設定)

舉例

假設腳本是session.php

session_save_path(getcwd()."/session_folder");//為方便我已經創建好session_folder這個目錄
session_start();
$_SESSION['aa']='bb';
$_SESSION['cc']='dd';

運行完畢,查看session_folder目錄

如果一個服務器上有多個項目,那么每個項目設定不同的session_save_path是有必要的,因為PHP會根據session的的垃圾回收機制,來清理默認session目錄下的session文件:項目A的php腳本在運行時,極有可能刪掉項目B的php腳本生成的session文件.所以,每個項目采用不同的session路徑,並在session_start()前,就指定session路徑,就互不干擾了.

看這個session文件的名字,其中sess_后面的一大串就是session_id,可以用session_id()設置/讀取;

打開這個文件,看一下

aa|s:2:"bb";cc|s:2:"dd";

這是session的序列化處理器序列化的數據,默認值是php(session.serialize_handler = php),

瀏覽器請求這個文件后,服務器會返回這樣的響應頭

response header

Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Fri, 18 Nov 2016 14:55:24 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=100
Pragma:no-cache
Server:Apache/2.4.9 (Win32) PHP/5.5.12
Set-Cookie:PHPSESSID=193tha35k5fj547nbj6o108as3; path=/
X-Powered-By:PHP/5.5.12

黃色部分就是服務器返回的cookie

這個cookie是php生成的,

名:PHPSESSD;

這個PHPSESSID是會話名,是在php.ini中設定:session.name = PHPSESSID,也可以使用session_name()來讀取/設定

值:193tha35k5fj547nbj6o108as3;

這個id值就是存儲在服務器端的文件的名字啦

路徑:/

路徑也是php.ini中設定:session.cookie_path = /  ,也可以session_set_cookie_params() 設定或session_get_cookie_params()讀取.

另外,查看這個cookie的生命周期,偷懶我就直接看瀏覽器了

可以看到過期時間是關閉瀏覽器的時候

這個值是php.ini中session.cookie_lifetime設定的(session.cookie_lifetime = 0), 以秒數指定了發送到瀏覽器的 cookie 的生命周期。值為 0 表示“直到關閉瀏覽器”。默認為 0。也可用 session_get_cookie_params()讀取或session_set_cookie_params() 設定

另外,我再次訪問session.php,使用js讀取cookie

這么重要的數據,js竟然讀取到了,萬一被XSS攻擊了怎么辦,不行,這個cookie不能被js獲取,要設定一下

php.ini中,session.cookie_httponly=on,這樣js就不會獲取到啦

如果用戶的瀏覽器禁用cookie怎么辦?

如果禁用了cookie,而php又沒有進行額外設置,則php無法讀取cookie,也無法獲取session值,因為php.ini中默認是這樣設定的:

session.use_only_cookies = 1,意思是說,php只能根據cookie中的PHPSESSID的值來存入/獲取/修改會話id,這樣做是相對安全的,也是php推薦的,因而在此設定值下,如果禁用了cookie,就獲取不到session啦

可是,我就是想在禁用cookie的情況下也要設定/讀取session值怎么辦?php也是允許的,這就是session的第二種獲取方式,就是基於URL

php.ini有個選項值:session.use_trans_sid,

設置session.use_trans_sid=on,就可以基於URL來傳遞會話id,比如我設定session時把session_id()存儲在一個隱藏域中,

<input type="hidden" name="<?php echo session_name() ?> value=<?php echo session_id() ?>>

再次訪問是,我就可以使用諸如http://php.com/session.php?PHPSESSID=p7iqqncndjmf13si9r6bafg1h1的URL,這樣就可以獲取session了,但這是很不安全的,極力不推薦.因為url被竊取就完蛋了.

使用這個配置項有個前提,就是session.use_only_cookies = 0

注釋1

即session_set_save_handler()中指定的處理器的參數,處理器的一種方法按手冊是這樣設置

session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] ),

其中的第一個方法open(string $savePath, string $sessionName),$savepath就是根據session.save_path的值來獲得的

以上絕大部分都是摘自手冊,大家可以去看手冊,更詳細,尤其是會話安全方面,更要注意.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM