1. PHP
的
COOKIE
cookie
是一種在遠程瀏覽器端儲存數據並以此來跟蹤和識別用戶的機制。
PHP
在
http
協議的頭信息裏發送
cookie,
所以
setcookie
()
函數必須在其它信息被輸出到瀏覽器前調用,這和對
header
()
函數的限制相似。
1.1
設置
cookie:
能夠用
setcookie
()
或
setrawcookie
()
函數來設置
cookie
。也能夠經過向客戶端直接發送
http
頭來設置
.
1.1.1
使用
setcookie()
函數設置
cookie:
bool
setcookie
(
string
name [,
string
value [, int expire [,
string
path [,
string
domain [, bool secure [, bool httponly]]]]]] )
name: cookie
變量名
value: cookie
變量的值
expire:
有效期結束的時間
,
path:
有效目錄
,
domain:
有效域名
,
頂級域惟一
secure:
若是值爲
1,
則
cookie
只能在
https
鏈接上有效
,
若是爲默認值
0,
則
http
和
https
均可以
.
例子
:
<?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
變量
.
1.1.2.
使用
header()
設置
cookie;
header
("Set-Cookie: name=$value[;path=$path[;domain=xxx.com[; ]]");
後面的參數和上面列出
setcookie
函數的參數同樣
.
好比
:
$value
= 'something from somewhere';
header
("Set-Cookie:name=$value");
1.2 Cookie
的讀取
:
直接用
php
內置超級全局變量
$_COOKIE
就能夠讀取瀏覽器端的
cookie
.
上面例子中設置了
cookie"TestCookie",
如今咱們來讀取
:
print
$_COOKIE
['TestCookie'];
COOKIE
是否是被輸出了
?!
1.3
刪除
cookie
只需把有效時間設爲小於當前時間
,
和把值設置爲空
.
例如
:
setcookie
("name","",
time
()-1);
用
header()
相似
.
1.4
常見問題解決
:
1)
用
setcookie()
時有錯誤提示
,
多是由於調用
setcookie()
前面有輸出或空格
.
也可能你的文檔使從其餘字符集轉換過來
,
文檔後面可能帶有
BOM
簽名
(
就是在文件內容添加一些隱藏的
BOM
字符
).
解決的辦法就是使你的文檔不出現這種狀況
.
還有經過使用
ob_start()
函數有也能處理一點
.
2)
$_COOKIE
受
magic_quotes_gpc
影響
,
可能自動轉義
3)
使用的時候
,
有必要測試用戶是否支持
cookie
<!--[
if
!supportLineBreakNewLine]-->
1.5 cookie
工做機理
:
有些學習者比較衝動
,
沒心思把原理研究
,
因此我把它放後面
.
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=/');
的結果
.
<!--[
endif
]-->
2. PHP
的
Session
session
使用過時時間設爲
0
的
cookie,
而且將一個稱爲
session ID
的惟一標識符
(
一長串字符串
),
在服務器端同步生成一些
session
文件
(
能夠本身定義
session
的保存類型
),
與用戶機關聯起來
.web
應用程序存貯與這些
session
相關的數據
,
而且讓數據隨着用戶在頁面之間傳遞
.
訪問網站的來客會被分配一個惟一的標識符,即所謂的會話
ID
。它要麼存放在客戶端的
cookie
,要麼經由
URL
傳遞。
會話支持容許用戶註冊任意數目的變量並保留給各個請求使用。當來客訪問網站時,
PHP
會自動(若是
session.auto_start
被設爲
1
)或在用戶請求時(由
session_start
()
明確調用或
session_register
()
暗中調用)檢查請求中是否發送了特定的會話
ID
。若是是,則以前保存的環境就被重建。
2.1 sessionID
的傳送
2.1.1
經過
cookie
傳送
sessin 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
數據
,
若是沒找到
,
則新建一個數據集
.
2.1.2
經過
URL
傳送
session ID
只有在用戶禁止使用
cookie
的時候才用這種方法
,
由於瀏覽器
cookie
已經通用
,
爲安全起見
,
可不用該方法
.
<a href="p.php?<?php print session_name() ?>=<?php print session_id() ?>">xxx</a>,
也能夠經過
POST
來傳遞
session
值
.
2.2 session
基本用法實例
<?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 /><a href="page2.php">page 2</a>';
//
若是客戶端禁用
cookie
echo
'<br /><a href="page2.php?' . SID . '">page 2</a>';
/*
默認
php5.2.1
下
,SID
只有在
cookie
被寫入的同時纔會有值
,
若是該
session
對應的
cookie
已經存在
,
那麼
SID
將爲
(
未定義
)
空
*/
?>
<?php
// page2.php
session_start
();
print
$_SESSION
['animal'];
//
打印出單個
session
var_dump
(
$_SESSION
);
//
打印出
page1.php
傳過來的
session
值
?>
2.3
使用
session
函數控制頁面緩存
.
不少狀況下
,
咱們要肯定咱們的網頁是否在客戶端緩存
,
或要設置緩存的有效時間
,
好比咱們的網頁上有些敏感內容而且要登陸才能查看
,
若是緩存到本地了
,
能夠直接打開本地的緩存就能夠不登陸而瀏覽到網頁了
.
使用
session_cache_limiter('private');
能夠控制頁面客戶端緩存
,
必須在
session_start()
以前調用
.
更多參數見
http:
//blog.chinaunix.net/u/27731/showart.php?id=258087
的客戶端緩存控制
.
控制客戶端緩存時間用
session_cache_expire
(int);
單位
(s).
也要在
session_start()
前調用
.
這只是使用
session
的狀況下控制緩存的方法
,
咱們還能夠在
header()
中控制控制頁面的緩存
.
2.4
刪除
session
要三步實現
.
<?php
session_destroy
();
//
第一步
:
刪除服務器端
session
文件
,
這使用
setcookie
(
session_name
(),'',
time
()-3600);
//
第二步
:
刪除實際的
session:
$_SESSION
=
array
();
//
第三步
:
刪除
$_SESSION
全局變量數組
?>
2.5 session
在
PHP
大型
web
應用中的使用
對於訪問量大的站點
,
用默認的
session
存貯方式並不適合
,
目前最優的方法是用數據庫存取
session.
這時
,
函數
bool
session_set_save_handler
(
callback
open,
callback
close,
callback
read,
callback
write,
callback
destroy,
callback
gc )
就是提供給咱們解決這個問題的方案
.
該函數使用的
6
個函數以下
:
1. bool open()
用來打開會話存儲機制
,
2. bool close()
關閉會話存儲操做
.
3. mixde read()
從存儲中裝在
session
數據時使用這個函數
4. bool write()
將給定
session ID
的全部數據寫到存儲中
5. bool destroy()
破壞與指定的會話
ID
相關聯的數據
6. bool gc()
對存儲系統中的數據進行垃圾收集
例子見
php
手冊
session_set_save_handler()
函數
.
若是用類來處理
,
用
session_set_save_handler
(
array
('className','open'),
array
('className','close'),
array
('className','read'),
array
('className','write'),
array
('className','destroy'),
array
('className','gc'),
)
調用
className
類中的
6
個靜態方法
.className
能夠換對象就不用調用靜態方法
,
可是用靜態成員不用生成對象
,
性能更好
.
2.6
經常使用
session
函數
:
bool
session_start
(void);
初始化
session
bool
session_destroy
(void):
刪除服務器端
session
關聯文件。
string
session_id
()
當前
session
的
id
string
session_name
()
當前存取的
session
名稱
,
也就是客戶端保存
session ID
的
cookie
名稱
.
默認
PHPSESSID
。
array
session_get_cookie_params
()
與這個
session
相關聯的
session
的細節
.
string
session_cache_limiter
()
控制使用
session
的頁面的客戶端緩存
ini
session_cache_expire
()
控制客戶端緩存時間
bool
session_destroy
()
刪除服務器端保存
session
信息的文件
void
session_set_cookie_params
( int lifetime [,
string
path [,
string
domain [, bool secure [, bool httponly]]]] )
設置與這個
session
相關聯的
session
的細節
bool
session_set_save_handler
(
callback
open,
callback
close,
callback
read,
callback
write,
callback
destroy,
callback
gc )
定義處理
session
的函數
,(
不是使用默認的方式
)
bool
session_regenerate_id
([bool delete_old_session])
分配新的
session id
2.7 session
安全問題
***者經過投入很大的精力嘗試得到現有用戶的有效會話
ID,
有了會話
id,
他們就有可能可以在系統中擁有與此用戶相同的能力
.
所以
,
咱們主要解決的思路是效驗
session ID
的有效性
.
<?php
if
(!
isset
(
$_SESSION
['user_agent'])){
$_SESSION
['user_agent'] =
$_SERVER
['REMOTE_ADDR'].
$_SERVER
['HTTP_USER_AGENT'];
}
/*
若是用戶
session ID
是僞造
*/
elseif
(
$_SESSION
['user_agent'] !=
$_SERVER
['REMOTE_ADDR'] .
$_SERVER
['HTTP_USER_AGENT']) {
session_regenerate_id
();
}
?>
2.8 Session
經過
cookie
傳遞和經過
SID
傳遞的不一樣
:
在
php5.2.1
的
session
的默認配置的狀況下
,
當生成
session
的同時
,
服務器端將在發送
header set-cookie
同時生成預約義超級全局變量
SID(
也就是說
,
寫入
cookie
和拋出
SID
是等價的
.),
當
$_COOKIE
['PHPSESSID']
存在之後
,
將再也不寫入
cookie,
也再也不生成超級全局變量
SID,
此時
,SID
將是空的
.
2.9 session
使用實例
<?php
/**
*
效驗
session
的合法性
*
*/
function
sessionVerify() {
if
(!
isset
(
$_SESSION
['user_agent'])){
$_SESSION
['user_agent'] =
MD5
(
$_SERVER
['REMOTE_ADDR']
.
$_SERVER
['HTTP_USER_AGENT']);
}
/*
若是用戶
session ID
是僞造
,
則從新分配
session ID */
elseif
(
$_SESSION
['user_agent'] !=
MD5
(
$_SERVER
['REMOTE_ADDR']
.
$_SERVER
['HTTP_USER_AGENT'])) {
session_regenerate_id
();
}
}
/**
*
銷燬
session
*
三步完美實現
,
不可漏
*
*/
function
sessionDestroy() {
session_destroy
();
setcookie
(
session_name
(),'',
time
()-3600);
$_SESSION
=
array
();
}
?>
註明
:
session
出現頭信息已經發出的緣由與
cookie
同樣
.
在
php5
中
,
全部
php session
的註冊表配置選項都是編程時可配置的
,
通常狀況下
,
咱們是不用修改其配置的
.
要了解
php
的
session
註冊表配置選項
,
請參考手冊的
Session
會話處理函數處
.
session
的保存數據的時候,是經過系列化
$_SESSION
數組來存貯
,因此有系列化所擁有的問題,可能有特殊字符的值要用
base64_encode
函數編碼,讀取的時候再用
base64_decode
解碼