瞭解HTTP(超文本傳輸協議)可以知道,它採用請求與響應的模式,最大的特點就是無連接無狀態。 無連接:每次連接僅處理一個客戶端的請求,得到伺服器響應後,連接就結束了 無狀態:每個請求都是獨立的,伺服器無法識別和區分它們的身份 這就造成了一個問題,在不同網頁之間如何傳遞信息,會話控制的思想就是為瞭解決 ...
瞭解HTTP(超文本傳輸協議)可以知道,它採用請求與響應的模式,最大的特點就是無連接無狀態。
- 無連接:每次連接僅處理一個客戶端的請求,得到伺服器響應後,連接就結束了
- 無狀態:每個請求都是獨立的,伺服器無法識別和區分它們的身份
這就造成了一個問題,在不同網頁之間如何傳遞信息,會話控制的思想就是為瞭解決這個問題的,它的解決方案主要分為Cookie和Session。
一、Cookie
保存在客戶端中,又分為記憶體cookie和硬碟cookie。
- 記憶體cookie:由瀏覽器維護,保存在記憶體中,瀏覽器關閉之後就消失了,存在時間短暫
- 硬碟cookie:保存在硬碟中,有一個過期時間,僅手動刪除或過期才消失
Cookie的使用場景主要有記住登錄,購物車等,在PHP中操作cookie主要通過setcookie和setrawcookie兩個方法來設置。
setcookie(name,value,[expire],[path],[domain],[secure],[httponly])
- name 必需。名稱。
- value 必需。值。
- expire 可選。有效期。
- path 可選。伺服器有效路徑(預設當前路徑)。
- domain 可選。作用域(預設本域)。
- secure 可選。僅HTTPS可用(預設false)。
- httponly可選。僅http可訪問(預設false),防止JS修改,減少XSS攻擊。
setcookie("abc","123",time()+3600)
讀取cookie使用$_COOKIE,更新和刪除均使用setcookie方法,註意保證path和domain與之前一致,刪除設置過期即可,如time()-1。
還可以通過header設置cookie:
header("Set-Cookie:abc=123; expires=".gmstrftime("%A,%d-%b-%Y %H:%M:%S GMT",time()+3600));
通過JS操作cookie的值,下麵是一個封裝的實例:
var Cookie={ set:function(key,val,expire){ // 判斷是否設置了過期時間 if(expire){ var date=new Date(); date.setTime(date.getTime()+expire*24*3600*1000);//格式化時間 var expireStr="expires="+date.toGMTString()+';'; }else{ var expireStr=''; } document.cookie=key+'='+escape(val)+';'+expireStr; }, get:function(key){ var getCookie=document.cookie.replace(/[ ]/g,'');//去空格 var resArr=getCookie.split(';') var res; for(var i=0,l=resArr.length;i<l;i++){ var arr=resArr.split('='); if(arr[0]===key){ res=arr[1];break; } } return unescape(res); } }
cookie實現自動登錄,主要通過生成令牌存儲到本地,下次訪問時獲取令牌中的id,查詢資料庫得到用戶名和密碼,加上掩值重新生成令牌與之比對,如相同則直接登錄。
<?php define('GAVIN', true);//許可權標示常量,申明後方可引入文件 include("../include/Gavin.class.php"); $username=$_POST['username']; $password=md5($_POST['password']); $autologin=$_POST['autologin']; Gavin::connDb(); $res = Gavin::dbSelect("SELECT * FROM main WHERE name='$username' and password='$password'"); if(count($res)===1){ if($autologin==="1"){ setcookie("username",$username,strtotime('+7 days')); // 給用戶一個登錄憑證 $salt='xiaoguge';//加密掩值 $tokens=md5($username.$password.$salt).":".$res[0][0];//拼接令牌:加密(用戶名+密碼+掩值)拼接用戶id setcookie("tokens",$tokens,strtotime('+7 days')); }else{setcookie("username",$username);}echo Gavin::createJson(200,"登錄成功!"); } else{echo Gavin::createJson(400,"登錄失敗,用戶名或密碼錯誤!");} ?>
cookie的缺點:不夠安全數據容易被截取;每個功能變數名稱下大小有限制,cookie中最大位元組數為4K;cookie每次都附著在http請求頭中。
為瞭解決cookie在存儲上的這些缺陷,HTML5提出了本地存儲方案localStorage和sessionStorage。
二、session
session的工作原理:
- 準備建立會話時,PHP首先查看請求的cookie中是否包含session_id,如果沒有則創建一條session信息(一般以文件形式存在伺服器上)。
- 伺服器將新創建session信息的session_id發送給瀏覽器,一般瀏覽器將其存放在cookie中。
- 當瀏覽器再次訪問伺服器時,會攜帶這個session_id,憑藉此到伺服器session認領對應信息。
- 取消會話,可以刪除伺服器中session的信息。
在PHP中使用會話,必須先使用session_start()開啟,再使用$_SESSION進行設置和讀取
session_start(); $_SESSION['account']=$account;
刪除session:
session_start(); //將session數據清空 $_SESSION=[]; //刪除會話cookie if(ini_get('session.use_cookie')){ $params=session_get_cookie_params(); setcookie(session_name(),'',time()-1,$params['path'],$params['domain'],$params['secure'],$params['httponly']) } //銷毀會話 session_destroy();
session預設是採用文件形式存儲,當然也可也修改PHP的設置,將其存儲到資料庫中(加快查詢速度)。