會話控制(session與cookie)

cookie簡介

Cookie是存儲在客戶端瀏覽器中的數(shù)據(jù),我們通過Cookie來跟蹤與存儲用戶數(shù)據(jù)嚷狞。一般情況下秽梅,Cookie通過HTTP headers從服務(wù)端返回到客戶端爷狈。多數(shù)web程序都支持Cookie的操作,因為Cookie是存在于HTTP的標(biāo)頭之中丰涉,所以必須在其他信息輸出以前進行設(shè)置拓巧,類似于header函數(shù)的使用限制。

PHP通過setcookie函數(shù)進行Cookie的設(shè)置一死,任何從瀏覽器發(fā)回的Cookie肛度,PHP都會自動的將他存儲在$_COOKIE的全局變量之中,因此我們可以通過$_COOKIE['key']的形式來讀取某個Cookie值投慈。

PHP中的Cookie具有非常廣泛的使用承耿,經(jīng)常用來存儲用戶的登錄信息,購物車等伪煤,且在使用會話Session時通常使用Cookie來存儲會話id來識別用戶加袋,Cookie具備有效期,當(dāng)有效期結(jié)束之后抱既,Cookie會自動的從客戶端刪除职烧。同時為了進行安全控制,Cookie還可以設(shè)置域跟路徑

<?php
setcookie('test', time());
ob_start();//打開輸出控制緩沖
print_r($_COOKIE);
$content = ob_get_contents();//復(fù)制緩沖區(qū)內(nèi)容到$content中
$content = str_replace(" ", ' ', $content);
ob_clean();//清空(擦掉)輸出緩沖區(qū)
header("content-type:text/html; charset=utf-8");
echo '當(dāng)前的Cookie為:<br/>';
echo nl2br($content);//nl2br 在字符串所有新行之前插入 HTML 換行標(biāo)記
?>

設(shè)置cookie

PHP設(shè)置Cookie最常用的方法就是使用setcookie函數(shù),setcookie具有7個可選參數(shù)蚀之,我們常用到的為前5個:

name( Cookie名)可以通過$_COOKIE['name'] 進行訪問
value(Cookie的值)
expire(過期時間)Unix時間戳格式蝗敢,默認(rèn)為0,表示瀏覽器關(guān)閉即失效
path(有效路徑)如果路徑設(shè)置為'/'足删,則整個網(wǎng)站都有效
domain(有效域)默認(rèn)整個域名都有效寿谴,如果設(shè)置了'http://www.huanghanlian.com/',則只在www子域中有效

<?php
$value = 'test';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600);  //有效期一小時
setcookie("TestCookie", $value, time()+3600, "/path/", "huanghanlian.com"); //設(shè)置路徑與域
?>

PHP中還有一個設(shè)置Cookie的函數(shù)setrawcookie,setrawcookie跟setcookie基本一樣失受,唯一的不同就是value值不會自動的進行urlencode讶泰,因此在需要的時候要手動的進行urlencode。

setrawcookie('cookie_name', rawurlencode($value), time()+60*60*24*365); 

因為Cookie是通過HTTP標(biāo)頭進行設(shè)置的拂到,所以也可以直接使用header方法進行設(shè)置峻厚。

header("Set-Cookie:cookie_name=value");

使用setcookie設(shè)置一個名為test,值為$value的Cookie谆焊。自己配置PHP環(huán)境,寫兩個頁面浦夷,第一個頁面寫入cookie辖试,第二個頁面輸出cookie。

//頁面1
<?php
$value = time();
//$value = 'test';
setcookie('test', $value); 
if (isset($_COOKIE['test'])) {
    echo 'success';
}
?>
//頁面2
<?php
    print_r($_COOKIE);
?>
//Array ( [test] => 1487095858 )

cookie的刪除與過期時間

在PHP中刪除cookie也是采用setcookie函數(shù)來實現(xiàn)劈狐。

setcookie('test', '', time()-1); 

可以看到將cookie的過期時間設(shè)置到當(dāng)前時間之前罐孝,則該cookie會自動失效,也就達到了刪除cookie的目的肥缔。之所以這么設(shè)計是因為cookie是通過HTTP的標(biāo)頭來傳遞的莲兢,客戶端根據(jù)服務(wù)端返回的Set-Cookie段來進行cookie的設(shè)置,如果刪除cookie需要使用新的Del-Cookie來實現(xiàn)续膳,則HTTP頭就會變得復(fù)雜改艇,實際上僅通過Set-Cookie就可以簡單明了的實現(xiàn)Cookie的設(shè)置、更新與刪除坟岔。

了解原理以后谒兄,我們也可以直接通過header來刪除cookie。

header("Set-Cookie:test=1393832059; expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1));

這里用到了gmdate社付,用來生成格林威治標(biāo)準(zhǔn)時間承疲,以便排除時差的影響。

<?php
setcookie('test', time());

//在這里試著刪除test的cookie值
setcookie('test', '', time()-1); 

var_dump($_COOKIE);
?>

cookie的有效路徑

cookie中的路徑用來控制設(shè)置的cookie在哪個路徑下有效鸥咖,默認(rèn)為'/'燕鸽,在所有路徑下都有,當(dāng)設(shè)定了其他路徑之后啼辣,則只在設(shè)定的路徑以及子路徑下有效啊研,例如:

setcookie('test', time(), 0, '/path');

上面的設(shè)置會使test在/path以及子路徑/path/abc下都有效,但是在根目錄下就讀取不到test的cookie值。

一般情況下悲伶,大多是使用所有路徑的艾恼,只有在極少數(shù)有特殊需求的時候,會設(shè)置路徑麸锉,這種情況下只在指定的路徑中才會傳遞cookie值钠绍,可以節(jié)省數(shù)據(jù)的傳輸,增強安全性以及提高性能花沉。

當(dāng)我們設(shè)置了有效路徑的時候柳爽,不在當(dāng)前路徑的時候則看不到當(dāng)前cookie

setcookie('test', '1',0, '/path');  
var_dump($_COOKIE['test']);  
<?php
//補充路徑參數(shù),實現(xiàn)有效路徑的設(shè)置
setcookie('test', '1', 0, '/path');
var_dump($_COOKIE['test']);
?>

session與cookie的異同

cookie將數(shù)據(jù)存儲在客戶端碱屁,建立起用戶與服務(wù)器之間的聯(lián)系磷脯,通常可以解決很多問題娩脾,但是cookie仍然具有一些局限:

cookie相對不是太安全赵誓,容易被盜用導(dǎo)致cookie欺騙
單個cookie的值最大只能存儲4k
每次請求都要進行網(wǎng)絡(luò)傳輸,占用帶寬

session是將用戶的會話數(shù)據(jù)存儲在服務(wù)端柿赊,沒有大小限制俩功,通過一個session_id進行用戶識別,PHP默認(rèn)情況下session id是通過cookie來保存的碰声,因此從某種程度上來說诡蜓,seesion依賴于cookie。但這不是絕對的胰挑,session id也可以通過參數(shù)來實現(xiàn)蔓罚,只要能將session id傳遞到服務(wù)端進行識別的機制都可以使用session。

<?php
//開始使用session
session_start();
//設(shè)置一個session
$_SESSION['test'] = time();
//顯示當(dāng)前的session_id
echo "session_id:".session_id();
echo "<br>";

//讀取session值
echo $_SESSION['test'];

//銷毀一個session
unset($_SESSION['test']);
echo "<br>";
var_dump($_SESSION);
?>

使用session

在PHP中使用session非常簡單瞻颂,先執(zhí)行session_start方法開啟session豺谈,然后通過全局變量$_SESSION進行session的讀寫。

session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);

session會自動的對要設(shè)置的值進行encode與decode贡这,因此session可以支持任意數(shù)據(jù)類型核无,包括數(shù)據(jù)與對象等。

session_start();
$_SESSION['ary'] = array('name' => 'jobs');
$_SESSION['obj'] = new stdClass();
var_dump($_SESSION);

默認(rèn)情況下藕坯,session是以文件形式存儲在服務(wù)器上的团南,因此當(dāng)一個頁面開啟了session之后,會獨占這個session文件炼彪,這樣會導(dǎo)致當(dāng)前用戶的其他并發(fā)訪問無法執(zhí)行而等待吐根。可以采用緩存或者數(shù)據(jù)庫的形式存儲來解決這個問題

session_start();
$_SESSION['name'] = 'jobs';
echo $_SESSION['name'];
?>
//jobs

刪除與銷毀session

刪除某個session值可以使用PHP的unset函數(shù)辐马,刪除后就會從全局變量$_SESSION中去除拷橘,無法訪問。

session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
echo $_SESSION['name']; //提示name不存在

如果要刪除所有的session,可以使用session_destroy函數(shù)銷毀當(dāng)前session冗疮,session_destroy會刪除所有數(shù)據(jù)萄唇,但是session_id仍然存在。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();

值得注意的是术幔,session_destroy并不會立即的銷毀全局變量$_SESSION中的值另萤,只有當(dāng)下次再訪問的時候,$_SESSION才為空诅挑,因此如果需要立即銷毀$_SESSION四敞,可以使用unset函數(shù)。

session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
unset($_SESSION);
session_destroy(); 
var_dump($_SESSION); //此時已為空

如果需要同時銷毀cookie中的session_id拔妥,通常在用戶退出的時候可能會用到忿危,則還需要顯式的調(diào)用setcookie方法刪除session_id的cookie值。

?php
session_start();
$_SESSION['name'] = 'jobs';
//在這里刪除name的session值
unset($_SESSION['name']);
if (isset($_SESSION['name'])) {
    echo $_SESSION['name'];
}
?>

使用session來存儲用戶的登錄信息

session可以用來存儲多種類型的數(shù)據(jù)没龙,因此具有很多的用途铺厨,常用來存儲用戶的登錄信息,購物車數(shù)據(jù)硬纤,或者一些臨時使用的暫存數(shù)據(jù)等解滓。

用戶在登錄成功以后,通骋б。可以將用戶的信息存儲在session中,一般的會單獨的將一些重要的字段單獨存儲煞躬,然后所有的用戶信息獨立存儲肛鹏。

$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['userinfo'] = $userinfo;

一般來說,登錄信息既可以存儲在sessioin中恩沛,也可以存儲在cookie中在扰,他們之間的差別在于session可以方便的存取多種數(shù)據(jù)類型,而cookie只支持字符串類型雷客,同時對于一些安全性比較高的數(shù)據(jù)芒珠,cookie需要進行格式化與加密存儲,而session存儲在服務(wù)端則安全性較高搅裙。

<?php
session_start();
//假設(shè)用戶登錄成功獲得了以下用戶數(shù)據(jù)
$userinfo = array(
    'uid'  => 10000,
    'name' => 'spark',
    'email' => 'spark@imooc.com',
    'sex'  => 'man',
    'age'  => '18'
);
header("content-type:text/html; charset=utf-8");

/* 將用戶信息保存到session中 */
$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['name'] = $userinfo['name'];
$_SESSION['userinfo'] = $userinfo;

//* 將用戶數(shù)據(jù)保存到cookie中的一個簡單方法 */
$secureKey = 'imooc'; //加密密鑰
$str = serialize($userinfo); //將用戶信息序列化
//用戶信息加密前
$str = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), $str, MCRYPT_MODE_ECB));
//用戶信息加密后
//將加密后的用戶數(shù)據(jù)存儲到cookie中
setcookie('userinfo', $str);

//當(dāng)需要使用時進行解密
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($secureKey), base64_decode($str), MCRYPT_MODE_ECB);
$uinfo = unserialize($str);
echo "解密后的用戶信息:<br>";
print_r($uinfo);
?>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皱卓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子部逮,更是在濱河造成了極大的恐慌娜汁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兄朋,死亡現(xiàn)場離奇詭異掐禁,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門傅事,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缕允,“玉大人,你說我怎么就攤上這事蹭越≌媳荆” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵般又,是天一觀的道長彼绷。 經(jīng)常有香客問我,道長茴迁,這世上最難降的妖魔是什么寄悯? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮堕义,結(jié)果婚禮上猜旬,老公的妹妹穿的比我還像新娘。我一直安慰自己倦卖,他們只是感情好洒擦,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怕膛,像睡著了一般熟嫩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上褐捻,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天掸茅,我揣著相機與錄音,去河邊找鬼柠逞。 笑死昧狮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的板壮。 我是一名探鬼主播逗鸣,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绰精!你這毒婦竟也來了撒璧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笨使,失蹤者是張志新(化名)和其女友劉穎沪悲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阱表,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡殿如,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年贡珊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涉馁。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡门岔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烤送,到底是詐尸還是另有隱情寒随,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布帮坚,位于F島的核電站妻往,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏试和。R本人自食惡果不足惜讯泣,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阅悍。 院中可真熱鬧好渠,春花似錦、人聲如沸节视。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寻行。三九已至霍掺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拌蜘,已是汗流浹背杆烁。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拦坠,地道東北人连躏。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓剩岳,卻偏偏與公主長得像贞滨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拍棕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容