PHP會話控制中session的使用
簡單介紹
基本功能:
通過為每個獨立使用者分配唯一的會話 ID,可以實現針對不同使用者分別儲存資料的功能。 會話通常被用來在多個頁面請求之間儲存及共享資訊。一般來說,會話 ID 通過 cookie 的方式傳送到瀏覽器,並且在伺服器端也是通過會話 ID 來取回會話中的資料。 如果請求中不包含會話ID 資訊,那麼 PHP 就會建立一個新的會話,併為新建立的會話分配新的 ID。【摘自官方文件】
簡單來說其作用類似於cookies但是相比較cookies更加安全。cookies儲存在使用者的瀏覽器上,使用者可以非常方便的更改,然而session儲存在伺服器,使用者只會拿到一個ID(session_id)號因此使用者不能直接修改session中儲存的資訊。
工作流程
當開始一個會話時,PHP 會嘗試從請求中查詢會話 ID (通常通過會話 cookie), 如果請求中不包含會話 ID 資訊,PHP 就會建立一個新的會話。 會話開始之後,PHP 就會將會話中的資料設定到 $_SESSION 變數中。 當 PHP 停止的時候,它會自動讀取 $_SESSION 中的內容,並將其進行序列化, 然後傳送給會話儲存管理器來進行儲存。PHP 指令碼執行完畢之後,會話會自動關閉。 同時,也可以通過呼叫函式 session_write_close() 來手動關閉會話。 【摘自官方文件】
①接受使用者請求,並查詢ID(session_id)。
②如果ID(session_id)存在,則開始會話;如果不存在則建立一個新會話,之後開啟會話
$_SESSION
中。④PHP結束前將
$_SESSION
經序列化後提交給管理器。⑤結束會話。
常見配置
session.save_handler : 修改預設會話儲存機制(預設狀態是以檔案形式儲存到某個路徑下,可以修改session_set_save_handler來把session儲存到資料庫)
session.save_path:session檔案的儲存位置。如圖:
session.auto_start : 會話自動開啟,預設是0表示不開啟,修改為1表示開啟。PHP程式碼中可以呼叫session.start()手動開啟。
session.name:
session.gc_maxlifetime: session的最長有效期,以ms為單位。如果超過這個時間sessio將自動刪除。預設是1440(24分鐘)
serialize_handler: 預設PHP,處理連續資料的方式,本功能只有WDDX模組或PHP內部使用【說人話就是用WDDX還是PHP格式來序列化得出session儲存的字串】注意如果這裡的序列化方式是PHP那麼就可能會出現反序列化漏洞。
session.gc_probability = n: 以千分之n的概率回收(刪除)session
其他:Session 上傳進度
當一個上傳在處理中,同時POST一個與INI中設定的session.upload_progress.name同名變數時,上傳進度可以在$_SESSION中獲得。
當 session.upload_progress.enabled INI 選項開啟時,PHP 能夠在每一個檔案上傳時監測上傳進度。
這個資訊對上傳請求自身並沒有什麼幫助,但在檔案上傳時應用可以傳送一個POST請求到終端(例如通過XHR)來檢查這個狀態當一個上傳在處理中,同時POST一個與INI中設定的session.upload_progress.name同名變數時,上傳進度可以在 S E S S I O N 中 獲 得 。 當 P H P 檢 測 到 這 種 P O S T 請 求 時 , 它 會 在 _SESSION中獲得。 當PHP檢測到這種POST請求時,它會在 SESSION中獲得。當PHP檢測到這種POST請求時,它會在_SESSION中新增一組資料, 索引是
session.upload_progress.prefix 與 session.upload_progress.name連線在一起的值。
通常這些鍵值可以通過讀取INI設定來獲得
利用session實現登陸後在頁面之間的切換
一共設定了五個頁面
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="Login" content="width=3, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="./login.php" method="post">
<p>登入</p>
<p>賬號:<input type="text" name="name" id="" /></p>
<p>密碼:<input type="password" name="passwd" id=""/></p>
<input type="submit" value="登入">
</form>
</body>
</html>
login.php
<?php
header("content-type:text/html;charset=utf-8");
if($_POST['name']=='admin' && $_POST['passwd']=='passwd'){
session_start();
$_SESSION['user']['islogin']="true";
$_SESSION['user']['username']=$_POST['name'];
echo "<script>alert('登入成功');location='./index.php'</script>";
}
else{
echo $_POST['name'];
echo "登入失敗!";
}
index.php:
<?PHP
session_start();
header("content-type:text/html;charset=utf-8");
//phpinfo();
if(isset($_SESSION['user']['islogin']) && $_SESSION['user']['islogin'] == true){
echo "Hi ".$_SESSION['user']['username'].",歡迎您的到來index.php!<br>";
echo "<a href='a.php'>前往頁面a</a><br>";
echo "<a href='b.php'>前往頁面b</a><br>";
echo "<a href='logout.php'>退出登入</a><br>";
print_r($_SESSION);
}else{
echo "你無權訪問,請登入(3s後跳轉。。。)";
echo "<meta http-equiv='refresh' content='3;url=./login.html'/>";
}
logout.php:
<?PHP
session_start();
header("content-type:text/html;charset=utf-8");
//phpinfo();
if(isset($_SESSION['user']['islogin']) && $_SESSION['user']['islogin'] == true){
$_SESSION['user']=array();//把當前user幸喜置空
setcookie(session_name(),null,time()-1,'/');//把存在cookie裡的session_id給刪了
session_destroy();//刪除伺服器上的session(檔案)
echo "即將返回登入頁面。。。";
echo "<meta http-equiv='refresh' content='2;url=./login.html'/>";
}else{
echo "你無權訪問,請登入(3s後跳轉。。。)";
echo "<meta http-equiv='refresh' content='3;url=./login.html'/>";
}
a.php和b.php基本一致
<?php
session_start();
header("content-type:text/html;charset=utf-8");
if(isset($_SESSION['user']['islogin']) && $_SESSION['user']['islogin'] == true){
echo "Hi ".$_SESSION['user']['username'].",歡迎您的到來a.php!<br>";
echo "<a href='index.php'>前往頁面index</a><br>";
echo "<a href='b.php'>前往頁面b</a><br>";
echo "<a href='logout.php'>退出登入</a><br>";
}
else{
echo $_POST['name'];
echo "你無權訪問該頁面!";
}