PHP之會話控制小結


      會話控制是一種跟蹤用戶的通信方式,使用會話控制主要基於以下幾點:由於http協議的無狀態性,使得不能通過協議來建立兩次請求之間的關聯;對於通常的頁面之間的數據傳遞方式get和post而言,主要處理參數的傳遞、資料的輸入兩個頁面間簡單的數據傳遞,對於一個用戶的在網站上的多個頁面,多種不同的數據,可能還有權限的不同而導致頁面的不同、操作方式的不同等等,使用get和post非常繁瑣。

      1.cookie方式

      為了對用戶進行跟蹤,就必須對用戶進行標記,cookie的思想就是,當用戶訪問網站的第一個頁面時,通過設置用戶的信息標識,web服務器將其以文本文件的形式存放到用戶的電腦上面,這些文件就是所謂的cookie,以鍵值對的方式存儲,當用戶再訪問第二個該網站的頁面時,將通過http頭信息,將攜帶cookie文件中的信息一起訪問服務器,並重新對剛才的用戶信息進行驗證,這樣避免了每次訪問都輸入用戶信息,可以確定多個頁面之間的訪問是不是同一用戶了。

      將信息設置到cookie的函數:setcookie($key, $value, $expire, $path, $domain, $secure)。

      參數依次是:鍵、值、過期時間(UNIX時間戳,默認為0表示關閉瀏覽器則cookie消失)、存取cookie的路徑,設定后服務器上該路徑下的腳本可存取cookie(默認為根目錄)、存取cookie的域名,只有該域名(比如www.example.com)下的網站網頁可存取cookie、是否是https安全連接才啟用cookie。

      比如通過post提交表單后記錄一些信息

<?php
    if(isset($_POST)){
        $time = time();
        setcookie('user', $_POST['user'], $time+3600);  // 時間參數需要比當前時間點大,以表示cookie信息的有效時間
        setcookie('data', array(1,2,3), $time+1200);  // 可以存放各種數據 
    }

       保存cookie成功后,可直接到$_COOKIE超全局數組中以鍵名取得該值,非常方便,如echo $_COOKIE['user'],基本的數據類型都支持

       cookie的刪除仍是通過setcookie進行,最好寫成將時間提前的形式,或者直接寫一個鍵名,比如在用戶點擊退出時進行該項操作

    setcookie('user', '', time()-200);  // 時間提前,相對當前時間
    setcookie('user');  // 簡寫,只寫鍵名

      2.session方式

      session與cookie相似,只是原來將信息存在用戶端的,現在改為存到服務端,但在用戶端產生一個標識id,這個id默認是保存到用戶本地的cookie中,所以session又和cookie扯上了關系。這樣用戶第一次訪問時將信息存到web服務器,並隨機分配給用戶一個固定長度的字符串(session id),以后用戶再訪問其他頁面,就帶着這個id去服務端里找對應用戶數據信息,於是就可以跟蹤用戶了,使用cookie的session稱為基於cookie的session。

      但是用戶可以將瀏覽器設為禁用cookie(雖一般不會這么做),有的網站在檢測到禁用cookie后會強制讓用戶去開啟,但卻是存在這么一種情況,如此一來通過基於cookie的方式行不通了,這時就可以通過在URL后附帶一個session id的get形式傳遞了,當然也可以通過http post。

      session的使用

      首先,要用session_start()開啟一個會話。注意對於這類網絡函數,在它前面不准有輸出,哪怕是<?php標識符前面有空格也不行(必須有輸出可以用ob_start()控制,先輸出到緩存 )。(注意,有時單獨一句session_start()會報警告,后面會談到)

      然后,注冊會話變量,也就是存取用戶信息或有用的數據,不需要使用什么函數,直接存入$_SESSION超全局數組,比如$_SESSION['user'] = $_POST[['user'],這些數據將被保存到服務端的某個文件中,當然也可能是緩存(memcache、redis)中。

      當跳轉到其他頁面時,在其他頁面也要先開啟這個會話,依然是session_start(),如果會話已經開啟,該函數返回當前會話,如果沒有則重新開啟。

      最后,用戶退出或某些原因銷毀對話,要注銷這些變量。分四步走:

      1.仍然是先開啟會話,或者是跳轉到其他頁面時,再次返回已經存在的會話,需要確保前面沒有輸出

    session_start();   // 開啟或返回一個會話

 

      2.清空$_SESSION數組中的相關變量

    unset($_SESSION['robert'])  // 銷毀某一個變量
    $_SESSION = array();  // 或者一次性全部銷毀會話變量

 

      3.清除保存在客戶端的cookie,別忘了session id還在用戶計算機上面

    if(isset($_COOKIE[session_name()])){
        unset($_COOKIE[session_name()]);    // session_name()獲取sesion的名,session id也是以名和值的形式存儲的
    }

      4.徹底銷毀存儲到服務器的信息

    session_destroy();

       四步走完,就結束了一次session會話。

       以上是簡單的對php會話控制做一個小結,在實際編程中,可能會遇到其他問題。我就出現了以下問題:

       1、此網頁包含重定向循環

       我自以為安全的設了一個檢查用戶是否登錄的判斷腳本,只要是一個腳本中就include它,想法是檢測到沒有登錄就跳轉到登錄頁面。問題是不要跳轉到本頁面,因為你本來就是訪問本頁面,然后又header跳轉到本頁面,這就是一個死循環了,瀏覽器可檢測出來。

       2、警告:session已經在***腳本中開啟

      前面說的只是簡單session_start()就行,開啟了就返回會話,書上也這么說,但是,實現的時候卻不行,已經開啟就意味着沒必要重復開啟,可以這樣判斷下

    if(!isset($_COOKIE[session_name()])){
        session_start();
    }

       如果已經開啟,$_COOKIE中會有一個session id,所以檢查有了就不開啟。

       3.以URL GET形式傳遞session id時,session不在$_GET數組中

    <form action="login.php?<?php echo session_name();?>=<?php echo session_id(); ?>" method="post"> 
        <table align="center" border="1">
        <tr>
           <td>username</td>
           <td><input type="text" name="username"  /></td>
       </tr>
       <tr>
           <td>password</td>
           <td><input type="password" name="password" /></td>
       </tr>
       <tr>
           <td colspan="2" align="center"><input type="submit" name="sub" value="login" /></td>
       </tr>
       </table>
    </form>

       本意是通過表單簡單的傳個用戶名和密碼過去,在form的action屬性提交到本頁面,提交的時候在后面附帶上session id,但注意,如果表單的提交方法method也定為get,則這個URL傳遞並不成功GET數組中沒有這個session id,如果form表單的method提交方法定為post后,這時表單提交的action地址后面的get傳參是成功的。不知道為什么原因,也問過,暫且記下吧。

       4.session沒有成功銷毀

       完全按照那銷毀四步來的,檢查數遍沒有問題,可就是銷毀不了,兩次登錄的session是一樣的,除非關閉瀏覽器后重新登錄,不知道是不是用的機子蛋疼,重啟電腦吧,tm居然又正常了-_-

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM