如何通過Session對用戶操作權限進行判斷
在大多數的網站開發程序中,根據實際的需要,需要劃分管理員和普通用戶對操作網站的權限,下面通過一個具體的代碼實體進行一下全面的講解,
(1) 設計一個登陸的頁面,添加一個form表單,使用POST方式進行引數傳遞, action 指向的資料處理頁面為 default.php , 添加一個用戶名文本框并命名為 user,添加一個密碼域文本框并命名為 pwd ,通過submit按鈕進行提交跳轉,其主要的代碼如下所示,
<html> <head> <script type="text/javascript"> function check(form){ if(form.user.value =https://www.cnblogs.com/chenyingying0/p/=""){ alert("請輸入用戶名"); } if(form.pwd.value =https://www.cnblogs.com/chenyingying0/p/=""){ alert("請輸入密碼"); } form.submit(); } </script> </head> <body> <form name="form1" method="post" action="default.php"> <table width="520" height="390" border="0" cellpadding="0" cellspacing="0"> <tr> <td valign="top"> <table width="520" border="0" cellspacing="0" cellpadding="0"> <tr> <td height="24" align="right">用戶名:</td> <td height="24" align="left"> <input name="user" type="text" id="user" size="20"> </td> </tr> <tr> <td height="24" align="right">密 碼:</td> <td height="24" align="left"> <input name="pwd" type="password" id="pwd" size="20"> </td> </tr> <tr align="center"> <td height="24" colspan="2"> <input name="submit" type="submit" value="https://www.cnblogs.com/chenyingying0/p/提交" onclick="return check(form);"> <input type="reset" name="reset" value="https://www.cnblogs.com/chenyingying0/p/重置"> </td> </tr> <tr> <td height="76"> <span>超級用戶: admin 密 碼:111 </span> <br> <span>普通用戶: cyy 密 碼:000 </span> </td> </tr> </table> </td> </tr> </table> </form> </body> </html>
(2)在 “提交” 按鈕的單擊事件下,呼叫自定義函式 check() 來驗證表單元素是否為空,這里使用了javascript代碼進行驗證,
<script type="text/javascript"> function check(form){ if(form.user.value =https://www.cnblogs.com/chenyingying0/p/=""){ alert("請輸入用戶名"); } if(form.pwd.value =https://www.cnblogs.com/chenyingying0/p/=""){ alert("請輸入密碼"); } form.submit(); } </script>
(3) 提交表單元素到資料處理頁 default.php,首先使用 session_start() 函式初始化 session變數,在使用 POST方法 接收表單元素的值,將獲取的用戶名和密碼分別賦值給 session變數,其代碼如下所示:
<?php session_start(); $_SESSION['user']=$_POST['user']; $_SESSION['pwd']=$_POST['pwd']; ?>
(4)為防止其他用戶非法登錄本系統,使用if 條件陳述句對 session變數的值進行判斷,這里繼續使用了javascript的知識,其代碼如下所示:
if($_SESSION['user']==""){ echo '<script type="text/javascript">alert("請使用正確途徑登錄"); history.back();</script>'; }
(5)在資料處理頁面 default.php 中添加如下的導航欄代碼,判斷當前用戶的級別,看已登錄的用戶是管理員還是普通用戶,然后區別的輸出顯示:
<?php session_start(); $_SESSION['user']=$_POST['user']; $_SESSION['pwd']=$_POST['pwd']; if($_SESSION['user']==""){ echo '<script type="text/javascript">alert("請使用正確途徑登錄"); history.back();</script>'; } ?> <table align="center" cellpadding="0" cellspacing="0"> <tr align="center" valign="middle"> <td style="width: 140px; color: red;">當前用戶: <!-- 輸出當前登錄用戶級別--> <?php if($_SESSION['user']=="admin" && $_SESSION['pwd']=="111"){ echo "管理員"; }else{ echo "普通用戶"; } ?> </td> <td width="70"><a href="https://www.cnblogs.com/chenyingying0/p/default.php">首頁</a><td> <td width="70">|<a href="https://www.cnblogs.com/chenyingying0/p/default.php">文章</a><td> <td width="70">|<a href="https://www.cnblogs.com/chenyingying0/p/default.php">相冊</a><td> <td width="100">|<a href="https://www.cnblogs.com/chenyingying0/p/default.php">修改密碼</a><td> <?php if($_SESSION['user']=="admin" && $_SESSION['pwd']=="111") { //如果當前用戶是管理員 //如果當前用戶是管理員 則輸出 用戶管理 echo '<td width="100">|<a href="https://www.cnblogs.com/chenyingying0/p/default.php">用戶管理</a><td>'; } ?> <td width="100">|<a href="https://www.cnblogs.com/chenyingying0/p/safe.php">注銷用戶</a><td> </tr> </table>
(6)在上面的 default.php 頁面中添加 “注銷用戶”的超鏈接頁面 safe.php,并在 safe.php 中寫入如下的代碼,進行洗掉用戶 Session,回傳登錄頁面:
<?php session_start(); unset($_SESSION['user']); unset($_SESSION['pwd']); session_destroy(); header('location:index.php');
(7) 運行這個實體,在網站用戶登錄頁面輸入用戶名和密碼 ,分別以超級用戶的身份登錄網站或者使用普通用戶身份登錄網站運行一下,


php自定義Session的資訊處理說明
在系統中使用 Session 技術追蹤用戶時,Session 默認的處理方式是 Web 服務器中的檔案來記錄每個用戶的會話資訊,通過 php.ini 中的 session.save_path 創建會話資料檔案的路徑,這種默認的處理方式雖然方便,但也是有缺陷的,最主要的原因是本身的 Session 機制不能跨機,因為對于訪問量比較大的系統,通常會采用多臺服務器進行并發處理,如果每臺服務器都單獨的處理 Session,就無法達到跟蹤用戶的目的,這時就需要改變 Session的處理方式,可以將 Session 資訊使用共享技術保存到其他服務器中,或是使用資料庫來保存 Session 資訊,
無論是用資料庫,還是使用共享技術來共享 Session 資訊,其中的原理基本是一樣的,都是通過 PHP中 的 session_set_save_handler()函式來改變默認的處理方式,指定回呼函式來自定義處理,該函式如下所示:
session_set_save_handler(open, close, read, write, destroy, gc)
更多資訊自己查檔案吧,我還沒用過
php中session臨時檔案和快取說明
1. session 臨時檔案
在服務器中,如果將所有用戶的 session 都保存到臨時目錄中,會降低服務器的安全性和效率,打開服務器存盤的站點會非常慢,在Windows上PHP默認的Session服務端檔案存放在C:\WINDOWS\Temp下,如果說并發訪問很大或者 session建立太多,目錄下就會存在大量類似sess_xxxxxx的session檔案,同一個目錄下檔案數過多會導致性能下降,并且可能導致受到 攻擊最終出現檔案系統錯誤,針對這樣的情況,PHP本身體提供了比較好的解決辦法,在php中,使用函式 session_save_path() 可以解決這個問題,
使用php函式 session_save_path() 存盤 session 臨時檔案,可以緩解因臨時檔案的存盤導致服務器效率降低和站點打開緩慢的問題,其實體代碼如下所示:
<?php $path = './tmp'; session_save_path($path); session_start(); $_SESSION['username'] = true;
注意: session_save_path() 函式應在 session_start()函式之前呼叫,
2. session 快取
Session快取的作用
(1) 減少訪問資料庫的頻率,應用程式從快取中讀取持久化物件的速度顯然優于從資料庫中檢索資料的速度,
(2) 當快取中的持久化物件之間存在回圈關聯關系時,Session會保證不出現訪問物件圖的死回圈,以及由死回圈引發的JVM堆疊溢位,
(3) 保證資料庫中的相關記錄與快取中的記錄同步,Session在清理快取的時,會自動進行臟資料檢查(dirty-check),如果發現Session快取中的物件與資料庫中相應記錄不一致,則會按最新的物件屬性更新資料庫,
session 快取使用的是 session_cache_limiter()函式,其語法格式如下:
session_cache_limiter(cache_limiter)
引數 cache_limiter 為 public 或者 private, 同時 session 快取 并不是指在服務器端而是在客戶端快取,在服務器中沒有顯示,
快取時間的設定,使用的是 session_cache_expire()函式,其語法格式如下:
session_cache_expire(new_cache_expire);
引數cache_expire 是 session 快取的時間,單位為分鐘,
注意:這兩個 session 快取函式必須在 session_start()函式之前呼叫,否則會出錯,
下面通過實體了解 session 快取頁面程序,其實作的代碼如下所示:
<?php session_cache_limiter('private'); $cache_limit = session_cache_limiter(); // 開啟客戶端快取 session_cache_expire(30); $cache_expire = session_cache_expire(); // 設定客戶端快取時間 session_start();
php中session資料庫存盤實體詳解
雖然通過改變 Session 存盤檔案夾使 Session 不至于將臨時檔案夾填滿而造成站點癱瘓,但是可以計算一下,如果一個大型網站一天登錄 1000 人,一個月登陸了30000人,這時站點中存在 30000 個Session 檔案 ,然而要在這 30000 個檔案夾中查詢一個 session_id 應該不是一件很輕松的事情,這個時候就需要應用到 session 資料庫存盤, 也就是PHP 中的 session_set_save_handle()函式,
設計程序
首先在Mysql資料庫創建存盤SESSION的表:
表名為tb_session
表結構為

說明:session_key:是用來存會話ID的
session_data:是用來存經序列化后的$_SESSION[]里的值;
session_time:是用來存時間戳的,這個時間戳指的是當前session在創建時的 time()+session的有效期,需要注意的是這 里的session_time的型別是int,這樣可以在操作資料庫時,進行大小比較!
修改php.ini檔案里session_set_save_handler的值,將其修改為user,如圖:


index.php用戶登錄界面
<?php include("session_set_save_handler.php");//引入自定義的會話存盤機制 if(isset($_GET["login"])){//判斷login是否有值,若有值則要進行注銷, session_start();//只要需要 用到$_session變數的地方,就需要開啟回呼函式open session_destroy();//這里就是上文提到的 小細節了,當有session_destroy的時候,它是先于read回呼函式執行的 }else{ session_start(); if(isset($_SESSION["user"])){//判斷此值是否有定義,若有定義則說明 存入的session還未到期,則直接轉到主內容 echo "<script>alert('您不久前剛來過');window.location.href='https://www.cnblogs.com/chenyingying0/p/main.php';</script>"; } } ?> <html> <meta charset="utf-8"> <body> <form action="index_ok.php" method="post"> 賬 戶:<input type="text" name="user"><br> 密 碼:<input type="text" name="pwd"> <input type="submit" name="sub"> </form> </body> </html>

index_ok.php表單提交處理檔案
<?php include("session_set_save_handler.php"); session_start(); if($_POST["sub"]){//$_post["sub"]它若有值就是 提交查詢 echo $_POST["sub"]; if($_POST["user"]!="" && $_POST["pwd"]!=""){ $_SESSION["user"]=$_POST["user"]; $_SESSION["pwd"]=$_POST["pwd"];//這里自定義的會話管理機制將會呼叫回呼函式write,將已由序列化處理器處理好的(由$_session[]變數形成)字串寫入資料庫 echo "<script>alert('登錄成功!');window.location.href='https://www.cnblogs.com/chenyingying0/p/main.php';</script>"; } } ?>

main.php主內容頁
<?php include("session_set_save_handler.php"); session_start(); if(isset($_SESSION["user"])){ echo "歡迎".$_SESSION["user"]; echo "<a href='https://www.cnblogs.com/chenyingying0/p/index.php?login=0'>注銷</a>"; }else{ echo "您還沒登錄,請先登錄!"; echo "<a href='https://www.cnblogs.com/chenyingying0/p/index.php'>登錄</a>"; } ?>

session_set_save_handler.php自定義session存盤機制函式檔案
<?php //打開會話 function open(){ //連接mysql資料庫 global $con; $con = mysqli_connect('localhost','root','123456','test') or die('資料庫連接失敗'); mysqli_query($con,'set names utf8'); return(true); } //關閉資料庫 function close(){ global $con; mysqli_close($con); return(true); } //讀取session_data function read($key){ global $con; //設定當前時間 $time = time(); $sql = "select session_data from tb_session where session_key = '$key' and session_time > $time "; $res = mysqli_query($con,$sql) or die('查詢失敗'); if(!$res){ printf("Error:%s\n",mysqli_error($con)); exit; } $row = mysqli_fetch_array($res); if($row!=false){ return($row['session_data']); }else{ return "";//一定要回傳空值,而不是false } } //存盤session function write($key,$data){ global $con; //設定失效時間 $time = 60*60;//1小時 //得到unix時間戳 $lapse_time = time()+$time; $sql = "select session_data from tb_session where session_key = '$key' "; $res = mysqli_query($con,$sql); if(mysqli_num_rows($res) == 0){ //不存在,創建 $sql = "insert into tb_session(session_key,session_time,session_data) values ('$key',$lapse_time,'$data')"; //字串要加單引號,數字不用 $res = mysqli_query($con,$sql); if(!$res){ printf("Error:%s\n",mysqli_error($con)); exit; } }else{ //已存在,更新 $sql = "update tb_session set session_key = '$key' ,session_data = 'https://www.cnblogs.com/chenyingying0/p/$data' ,session_time = $lapse_time where session_key = '$key' "; $res = mysqli_query($con,$sql); } return($res); } //清除session資料 function destroy($key){ global $con; //洗掉session $sql = "delete from tb_session where session_key = '$key' "; $res = mysqli_query($con,$sql); return($res); } //垃圾回收 function overdue($expire_time){//這個引數是自動傳進去的,就是session.gc_maxlifetime最大有效時間,例如1440s; global $con; $lapse_time = time(); $sql = "delete from tb_session where session_time < $lapse_time ";//清除過期session $res = mysqli_query($con,$sql); return($res); } session_set_save_handler('open','close', 'read', 'write','destroy', 'overdue');
資料庫如下:

php中session時間設定詳解
1. 客戶端沒有禁止Cookie
(1)使用session_set_cookie_params()設定 Session失效時間,此函式是 Session 結合 Cookie設定失效時間,如果要讓 Session 在一分鐘后失效,其代碼示例如下所示:
<?php $time = 1*60; session_set_cookie_params($time); session_start(); $_SESSION['username'] = 'cyy';
注意: session_set_cookie_params() 必須要在 session_start()之前呼叫,
說明:不推薦使用此函式,此函式在一些瀏覽器上會出現問題, 所以一般會用手動設定失效時間,
(2)使用 setcookie()函式可對 Session 設定失效時間,要讓 Session 在一分鐘后失效,其代碼示例如下所示:
<?php session_start(); $time = 1*60; setcookie(session_name(),session_id(),time()+$time.'/'); $_SESSION['username'] = 'cyy';
說明: 在上例代碼 setcookie()函式中,session_name 是 Session的名稱, session_id 是判斷客戶端用戶的標識,因為 session_id 是隨機產生的唯一名稱, 所以Session 是相對安全的,失效時間和 Cookie 的失效時間一樣,最后一個引數為可選引數,是放置 Cookie 的路徑,
2. 客戶端禁止Cookie
(1)在登陸之前提醒用戶必須打開 Cookie,這是很多論壇的做法,
(2)設定php.ini 檔案中的 session.use_trans_sid =1,或者編譯時打開 -enable-trans-sid 選項,讓PHP自動跨頁面傳遞 session_id,
(3)通過 GET方法,隱藏表單傳遞 session_id,
(4)使用檔案或者資料庫存盤 session_id,在頁面間傳遞中手動呼叫,
以上第2種方法不做詳細的介紹,因為用戶不能修改服務器中的php.ini檔案,第3中方法我們就不可以使用 Cookie 設定失效時間,但是登錄情況沒有變化, 第4種也是最為重要的一種,在開發企業級網站時,如果遇到session檔案 使服務器速度變慢,就可以使用,這里我們介紹一下第3種方法使用 GET 方法傳輸,其示例代碼如下所示,接收頁面頭部的代碼:
<?php $session_name = session_name(); $session_id = $_GET[$session_name]; session_id($session_id); session_start(); $_SESSION['username'] = 'cyy';
說明: Session 為請求該頁面之后會產生一個 session_id ,如果這時禁止了 Cookie 就無法傳遞 session_id,在請求下一個頁面是將會重新產生一個 session_id ,這樣就造成了 session 在頁面間傳遞失效,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/33655.html
標籤:PHP
上一篇:php Session配置
