PHP基礎教程十七之會話技術COOKIE、SESSION

前言

我們用PHP開發後臺的時候,需要對一些數據進行保存,而我們通常的做法就是進行數據庫的保存,但是有時候我們一些是不需要保存在數據庫中的,比如我們在登錄網頁的時候,在網站中顯示我們上一次訪問網站的時間,這個上一次訪問的時間就可以不用保存在數據庫中,同時我們在登錄某個網頁後,保存的登錄的用戶名,這些我們都可以不用保存在數據庫中,而是使用PHP中的會話技術來解決。

會話的介紹

PHP的cookie技術和session技術都是針對會話來進行的。這裏的會話可以理解爲當一個用戶打開一個瀏覽器,訪問某個網站,從用戶訪問該網站開始,到用戶關閉訪問網站頁面結束,我們稱爲一個會話。在一次會話過程中,用戶可以點擊該網站頁面的各個超鏈接,可以點擊多次。

當我們訪問一個網站和網站裏面的頁面,知道我們推出這個網站。就是一次會話。

cookie講解

我們有時候在訪問某個網站的時候,一進入網站就可以在網頁上看到我們上次訪問當前網站的時間是多少。這個時間就可以使用cookie進行進行保存。

Cookie是客戶端技術,服務器把每個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着各自的數據去。這樣,web資源處理的就是用戶各自的數據了。注意cookie技術是寫在瀏覽器端的文件。同時cookie的保存方式是以鍵值對的形式進行保存的。

這裏寫圖片描述

從上面的流程圖中可以看出來,在服務器的PHP文件中如果要創建cookie,則服務器把創建cookie的信息封裝到http協議的響應頭中進行信息的傳遞,瀏覽器接受到響應頭後進行分析,知道了服務器需要在瀏覽器建立一個cookie,通過響應頭的信息在本地創建一個cookie文件,當瀏覽器再次訪問這個網站的時候會把本地的cookie信息發送給服務器。

Cookie:user=abc; PHPSESSID=v6ntsa42f4v0h5jpaoa1tot8r6

cookie的使用

關於cookie的使用,可以簡單的理解爲對cookie的增刪改查操作。

cookie的創建

創建cookie其實很簡單

<?php
    //通過setcookie函數進行cookie的創建
    setcookie('username','abc',time()+3600);

我們通過setcookie()函數進行cookie的創建,該cookie會保存在瀏覽器的緩存中。

Set-Cookie:username=abc; expires=Mon, 17-Oct-2016 08:55:51 GMT; Max-Age=3600
  • setcookie(參數1,參數2,參數3)我們在代碼中可以看到在這個函數中傳進去了三個參數,
    1. 第一個參數是保存信息的鍵的名字。
    2. 第二個參數是鍵對應的值
    3. 第三個參數是這個cookie保存的時間,這裏保存的時間是當前時間加上3600秒,當超過這個時間時,cookie將會失效。

當我們執行完上面的代碼我們可以在瀏覽器的緩存文件中看到創建的cookie的文件,裏面有我們的保存的數據。

username
abc
www.lijiafei.com/test3/
1536
2120470400
30550100
480638768
30550092
*

cookie的讀取

在上面我們進行了數據的保存,我們保存數據的目的就是讀取數據,而cookie的讀取可以理解爲:

  1. 當瀏覽器請求某個網站的頁面時,根據http協議規定: 該瀏覽器就會通過http的請求將該網站的cookie信息發送給服務器的請求頁面
  2. 服務器接收到cookie信息後,就會封裝到$_COOKIE數組中。
  3. 我們從$_COOKIE數組中進行讀取。

    <?php
        echo '<pre>';
        //自動封裝到這個數組裏面
        var_dump($_COOKIE);
        //通過鍵名取出值。
        $username = $_COOKIE['username'];
        echo $username;
        ......結果.......
        array(3) {
          ["user"]=>
          string(3) "abc"
          ["username"]=>
          string(3) "abc"
          ["PHPSESSID"]=>
          string(26) "v6ntsa42f4v0h5jpaoa1tot8r6"
        }
        abc
    

    當我們訪問文件的時候,通過請求頭把cookie信息傳遞過去。

    Cookie:user=abc; username=abc; PHPSESSID=v6ntsa42f4v0h5jpaoa1tot8r6
    

cookie的修改

當我們想修改一個cookie的值的時候,仍然是使用setcookie來完成修改,但是如果cookie沒有存在,則創建,如果已經有了,則修改。

<?php
//通過setcookie函數進行修改,但是如果瀏覽器沒有cookie則進行創建。
setcookie('username','abc123',time() + 1600);

我們在進行讀取cookie的值可以看到成功的修改了裏面的值。

array(3) {
  ["user"]=>
  string(3) "abc"
  ["username"]=>
  string(6) "abc123"
  ["PHPSESSID"]=>
  string(26) "v6ntsa42f4v0h5jpaoa1tot8r6"
}
abc123

cookie的刪除,銷燬

當我們不行使用到cookie的時候,可以進行手動的銷燬cookie的值。
刪除cookie的數據可以理解爲兩步,1、刪除保存在瀏覽器緩存的cookie文件,2、刪除保存在服務器$_COOKIE數組中數據。

<?php
    //使用setcookie這個函數進行刪除
    setcookie('username','',time()-1);

    //刪除保存在$_COOKIE裏面的數據
    if(isset($_COOKIE['username'])){
        unset($_COOKIE['username']);
    }

    //刪除保存在瀏覽器中這個網站的所有的cookie
    foreach ($_COOKIE as $key => $value) {
        setcookie($key,$value,time()-1);
    }
    //銷燬所有數據
    unset($_COOKIE);

我們運行上面的代碼就可以刪除所有的cookie信息。

cookie的深入理解

上面的就是cookie最基本的操作。但是我們還有許多需要注意的地方:

  1. 一個Cookie只能標識一種字符串信息,它至少含有一個標識該信息的名稱(NAME)和設置值(VALUE)。就是說cookie 總是 名=值的形式保存。

  2. 在默認的情況下,我們創建多個的cookie,將保存在同一個文件中.

  3. 一個WEB站點可以給一個瀏覽器發送多個Cookie,一個瀏覽器也可以存儲多個WEB站點提供的Cookie。

  4. 瀏覽器一般只允許存放300個Cookie, 每個站點最多存放20個,每個Cookie的大小限制在4K,但是不同的瀏覽器,情況可能不同。

  5. 如果創建了一個cookie,並將他發送到瀏覽器,默認情況下它是一個會話級別的cookie(即存儲在瀏覽器的內存中),用戶退出瀏覽器之後即被刪除。若希望瀏覽器將該cookie存儲在磁盤上,則需要使用setcookie()函數的第三個參數設置時間,並給出一個以秒爲單位的時間。要刪除 cookie 需要確保它的失效期是在過去,才能觸發瀏覽器的刪除機制。 就是說,我們的cookie默認的生命週期就是一個會話週期。如果希望設置,就需要 setcookie(‘name’, ‘val’, 時間)

  6. 如果希望cookie長久有效,可以這樣創建cookie setCookie(“key”,”val”,PHP_INT_MAX);

setcookie()函數

我們可以看到在操作cookie的時候,都是通過setcookie進行不同的設置,但是我們在查幫助文檔的時候,可以看到setcookie的參數並不是三個,而是可以七個參數。

bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )

而我們上面使用的就是前三個參數,設置鍵和值,同時設置保存的時間。

cookie有效路徑

在setcookie()函數中第四個參數是控制cookie的有效路徑的,當我們不設置的時候,默認的是當前路徑和後臺路徑有效,但是當我們設置成’/’的時候,cookie全站有效。

案例目錄結構:

...test
    |_readcookie.php(讀取cookie信息)
    |_abc
        |_createcookie.php(創建cookie)
        |_def
            |_readcookie.php(讀取cookie);

兩個readcookie.php代碼一樣:

<?php
    echo '<pre>';
    var_dump($_COOKIE);

創建cookie的代碼:

<?php
    //創建cookie保存數據
    setcookie('user','abc',time() + 1600,'');
    //再創建一個cookie信息,這兩個cookie會保存在一個cookie文件裏面
    setcookie('password','123',time() + 1600,'/');

創建cookie的時候,第一個鍵值使用默認的有效路徑第二個鍵值使用全站的有效路徑。
當訪問test目錄下的readcookie.php文件時,只能顯示password-123的鍵值信息。

array(1) {
  ["password"]=>
  string(3) "123"
}

cookie域名共享

我們在開發中可能出現在一個網站(www.test.com)下面有兩個域(www.a.test.com,www.b.test.com)名,如果我們不對cookie進行設置,這兩個域名是不能互相訪問對方的cookie的,但是如果我們對cookie進行設置,就可以實現域名共享。而setcookie()的第五個參數就是控制域名共享的。

<?php
    //設置第五個參數表示兩個域名可以共享cookie數據。
    setcookie('username','abc','','','.test.com');

cookie安全傳輸

在我們在瀏覽網頁的時候,大多數使用的的協議是HTTP協議,但是還有一種協議是HTTPs協議,這種協議比http協議更加安全,在開發中有時候當我們需要對某些重要的cookie數據必須在https協議下才能被傳輸,這是就會用到setcookie()函數的第六個參數進行設置。

<?php
//第五個參數設置爲false表示可以在http協議和https協議下傳輸。
setcookie('username','abc','','','',false);
//第五個參數設置爲false表示只能在https協議下傳輸。
setcookie('password','123','','','',true);

cookie的httponly

在默認情況下,cookie值是可以被其他腳本獲取的,比如是JavaScript,這是就可能存在安全問題,那我們怎麼防止其他腳本來讀取cookie呢?

在setcookie()函數的最後一個參數就是控制cookie只能http協議進行讀取。

<?php
//最後一個參數,設置爲true表示只能是https協議進行讀取。
setcookie('username','abc','','','',false,false);

上面的就是對會話技術cookie的介紹。在會話技術中還有之中技術也就是session。

session講解

在我們登錄網頁時,輸入正確的賬號和密碼後,我們可以使用會話技術的session技術進行保存數據。
Session是服務器端技術,利用這個技術,服務器在運行時可以爲每一個用戶的瀏覽器創建一個其獨享的session文件,由於session爲用戶瀏覽器獨享,所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session中,當用戶再去訪問服務器中的其它web資源時,其它web資源再從用戶各自的session中取出數據爲用戶服務

這裏寫圖片描述

當我們在服務器需要創建一個session的時候,會在服務器創建一個session文件,並且每個會話獨享一份session文件,在服務器session文件默認存在在 c:/windows/temp 目錄, 但是我們也可以在php.ini中進行修改。當服務器創建session後,會在返回數據的時候把session的id號封裝到http協議的響應頭中。

SetCookie:PHPSESSID=58j6c68qo6fhn31qrmt6bbrv70; path=/

這個響應信息和創建cookie的信息很想,但是瀏覽器並不會在瀏覽器的緩存中創建cookie文件。當瀏覽器保存住session的ID後,如果又要訪問網頁,瀏覽器會把session的ID封裝在請求頭中發送給服務器。

Cookie:PHPSESSID=58j6c68qo6fhn31qrmt6bbrv70

session操作

session的操作大致也可以分爲增刪改查四個步驟。
但是不管是什麼操作都需要在操作前開啓session機制,使用sessio_start()函數進行開啓。同時session數據的保存也是通過鍵值對的方式進行保存的。session保存的數據類型可以是int,float,boolean,string,array,object。

session的創建

<?php
    //開啓session機制
    session_start();
    //把數據保存在$_SESSION數組裏面。
    $_SESSION['user'] = 'abc';

先開啓session機制,然後把需要的數據保存在$_SESSION數組裏面當我們運行代碼可以在http協議的響應頭中添加了一段話:

Set-Cookie:PHPSESSID=p4lsn4vrdjtmkou1qc3tn3n577; path=/

同時我們也可以參看我們在服務器保存的session文件。

user|s:3:"abc";

session的讀取

<?php
    //先開啓session機制
    session_start();
    echo '<pre>';
    //保存在session裏面的數據會自動封裝到$_SESSION數組裏面
    var_dump($_SESSION);
    ......結果......
    array(1) {
      ["user"]=>
      string(3) "abc"
    }

當我們讀取session的數據的時候,先開啓session機制,這樣服務器就會把session文件裏面的數據封裝到$_SESSION數組中,從而就可以對數據進行操作。

session的修改

session的修改和cookie的修改是一樣的,session怎麼創建,就怎麼修改,如果數據不存在就創建,如果數據存在就修改。

session的刪除

當我們不需要某些session數據的時候,我們可以進行數據的刪除,當然,我們可以刪除一個數據,也可以刪除全部數據,甚至也可以刪除session文件。

<?php

    session_start();
    // if(isset($_SESSION['user'])){
    //  //刪除其中一個數據
    //  unset($_SESSION['user']);
    // }

    // //通過循環刪除全部的數據。
    // foreach ($_SESSION as $key => $value) {
    //  unset($_SESSION[$key]);
    // }
    //刪除session文件
    session_destroy();

我們可以根據自己的需求進行不同數據的刪除。

從上面的講解中可以看到操作session的函數並不像cookie一樣只是一個函數,關於session的操作函數有許多。

這裏寫圖片描述

session的深入瞭解

session啓動方式

在上面我們都是使用了session_start()函數來啓動session機制,其實PHP給我們提供了兩種方式來開啓session

  1. 直接在php文件中使用session_start()函數;這種方式比較靈活,推薦使用這種方式。
  2. 直接在php.ini 文件中,配置session.auto_start = 1 設置1就可以自動打開session機制. 默認情況下這個值是 0,這種方式不推薦使用。

session的安全設置

關於session的安全和cookie的安全設置一樣,但是session不是通過函數的參數進行設置的,而是在php.ini文件中進行配置的。其中有幾個關鍵的值:

  • session.save_path:session數據保存在服務器的路徑。
  • session.cookie_secure:這個參數的作用和cookie很像,在傳輸給服務器時,是否安全傳輸,即是否使用https傳輸。
  • session.cookie_httponly:只能http協議進行讀取。
  • session.cookie_domain:在傳輸給服務器時,有效域名的設置。

上面的參數我們都是直接在php.ini配置裏面修改的,這種修改是永久性的,但有時我們要求只是臨時的修改php.ini文件,就可以使用ini_set()函數進行配置。ini_set函數可以去臨時修改php.ini 的設置,而且設置只對當前的這個會話有影響。但是有一點ini_set函數要在 session_start()前,才能生效.

session的存儲機制

在上面我們在使用session的時候,只是簡單的進行session_start()函數開啓session機制,並且把數據封裝到$_SESSION數組裏面,但是我們並沒有瞭解其中的過程,數據是怎麼存儲在數組裏面,又是在什麼時候保存在session文件中的,當destroy掉session文件的時候又是在哪裏進行執行的,都沒有了解。

session的存儲機制大致可以分爲三步,從session_start開始,到一個文件運行結束

這裏寫圖片描述

在session_start()開啓session機制後,

  1. 判斷瀏覽器傳過來的數據中是否帶有session_id,如果有就使用,沒有就創建一個session文件。
  2. 將session文件中的數據讀取到$_SESSION數組中。
  3. 啓用session的垃圾回收機制,判斷哪些session是失效的,刪除失效的session文件。

這裏寫圖片描述

在腳本週期內,我們可以對$_SESSION數組進行增刪改查的操作,注意在這裏操作的數據並不會對保存在服務器端的session文件有影響。同時如果在這裏使用session_destroy(),就會刪除session文件並關閉session機制。

這裏寫圖片描述

在腳本結束時,先判斷session機制是否關閉,如果沒有關閉就會把$_SESSION數組裏面的數據寫入session文件。

上面就是session的存儲機制,理解並掌握存儲機制,對我們使用session有很好的幫助。

session的GC

在上面的存儲機制中我們知道在開啓session機制後第一步中通過判斷哪些是無效的文件,然後session會啓用垃圾回收機制(GC)進行回收,但是並不是每此開啓都要進行回收的,其實在php.ini文件中有兩個參數,設置了啓用gc的概率。

  1. session.gc_probability
  2. session.gc_divisor= 10000

它們是一對,表示垃圾回收的概率是多少,而概率的計算公式是session.gc_probability/ session.gc_divisor = 1/10000, 就是說,當調用10000次session_start() 函數,有一次會觸發垃圾回收機制。

但是針對不同的網站我們設置不同的概率,對於大型網站,session.gc_divisor 設置大點,比如10000, 中型網站 500-1000, 小網站, 200-300,避免頻繁的觸發GC。

總結

會話技術cookie和session在PHP開發中用到的還是很多的,理解兩個技術不同的特點,讓我們在開發中更加靈活的存儲不同的數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章