我們用PHP開發後台的時候,需要對一些資料進行保存,而我們通常的做法就是進行資料庫的保存,但是有時候我們一些是不需要保存在資料庫中的,例如我們在登入網頁的時候,在網站中顯示我們上一次訪問網站的時間,這個上一次訪問的時間就可以不用保存在資料庫中,同時我們登入某個網頁後,儲存的登入的用戶名,這些我們都可以不用儲存在資料庫中,而是使用PHP中的會話技術來解決。
PHP的cookie技術和session技術都是針對會話來進行的。這裡的會話可以理解為當一個使用者開啟一個瀏覽器,造訪某個網站,從使用者造訪該網站開始,到使用者關閉造訪網站頁面結束,我們稱為一個會話。在一次會話過程中,使用者可以點擊該網站頁面的各個超鏈接,可以點擊多次。
當我們造訪一個網站和網站裡面的頁面,知道我們推出這個網站。就是一次會話。
我們有時在造訪某個網站的時候,一進入網站就可以在網頁上看到我們上次造訪目前網站的時間是多少。這個時間就可以使用cookie來儲存。
Cookie是客戶端技術,伺服器把每個使用者的資料以cookie的形式寫給使用者各自的瀏覽器。當使用者使用瀏覽器再去存取伺服器中的web資源時,就會帶著各自的資料去。這樣,web資源處理的就是使用者各自的資料了。注意cookie技術是寫在瀏覽器端的檔案。同時cookie的保存方式是以鍵值對的形式進行保存的。
從上面的流程圖中可以看出來,在伺服器的PHP檔案中如果要建立cookie,則伺服器把建立cookie的資訊封裝到http協定的回應頭中進行訊息的傳遞,瀏覽器接受到回應頭後進行分析,知道了伺服器需要在瀏覽器建立一個cookie,透過回應頭的資訊在本地創建一個cookie文件,當瀏覽器再次造訪這個網站的時候會把本地的cookie訊息發送給伺服器。
Cookie:user=abc; PHPSESSID=v6ntsa42f4v0h5jpaoa1tot8r6
關於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
username abc www.lijiafei.com/test3/ 1536 2120470400 30550100 480638768 30550092 *
<?php echo '<pre class="brush:php;toolbar:false">'; //自动封装到这个数组里面 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
<?php //通过setcookie函数进行修改,但是如果浏览器没有cookie则进行创建。 setcookie('username','abc123',time() + 1600);
#當我們想要修改一個cookie的值的時候,仍然是使用setcookie來完成修改,但是如果cookie沒有存在,則創建,如果已經有了,則修改。
array(3) { ["user"]=> string(3) "abc" ["username"]=> string(6) "abc123" ["PHPSESSID"]=> string(26) "v6ntsa42f4v0h5jpaoa1tot8r6" } abc123
<?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的資料可以理解為兩個步驟,1、刪除儲存在瀏覽器快取的cookie文件,2、刪除儲存在伺服器$_COOKIE陣列中資料。
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
一个Cookie只能标识一种字符串信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。就是说cookie 总是 名=值的形式保存。
在默认的情况下,我们创建多个的cookie,将保存在同一个文件中.
一个WEB站点可以给一个浏览器发送多个Cookie,一个浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie, 每个站点最多存放20个,每个Cookie的大小限制在4K,但是不同的浏览器,情况可能不同。
如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用setcookie()函数的第三个参数设置时间,并给出一个以秒为单位的时间。要删除 cookie 需要确保它的失效期是在过去,才能触发浏览器的删除机制。 就是说,我们的cookie默认的生命周期就是一个会话周期。如果希望设置,就需要 setcookie(‘name’, ‘val’, 时间)
如果希望cookie长久有效,可以这样创建cookie setCookie(“key”,”val”,PHP_INT_MAX);
我们可以看到在操作cookie的时候,都是通过setcookie进行不同的设置,但是我们在查帮助文档的时候,可以看到setcookie的参数并不是三个,而是可以七个参数。
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
而我们上面使用的就是前三个参数,设置键和值,同时设置保存的时间。
在setcookie()函数中第四个参数是控制cookie的有效路径的,当我们不设置的时候,默认的是当前路径和后台路径有效,但是当我们设置成’/’的时候,cookie全站有效。
案例目录结构:
...test |_readcookie.php(读取cookie信息) |_abc |_createcookie.php(创建cookie) |_def |_readcookie.php(读取cookie);
两个readcookie.php代码一样:
<?php echo '<pre class="brush:php;toolbar:false">'; 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" }
我们在开发中可能出现在一个网站(www.test.com)下面有两个域(www.a.test.com,www.b.test.com)名,如果我们不对cookie进行设置,这两个域名是不能互相访问对方的cookie的,但是如果我们对cookie进行设置,就可以实现域名共享。而setcookie()的第五个参数就是控制域名共享的。
<?php //设置第五个参数表示两个域名可以共享cookie数据。 setcookie('username','abc','','','.test.com');
在我们在浏览网页的时候,大多数使用的的协议是HTTP协议,但是还有一种协议是HTTPs协议,这种协议比http协议更加安全,在开发中有时候当我们需要对某些重要的cookie数据必须在https协议下才能被传输,这是就会用到setcookie()函数的第六个参数进行设置。
<?php //第五个参数设置为false表示可以在http协议和https协议下传输。 setcookie('username','abc','','','',false); //第五个参数设置为false表示只能在https协议下传输。 setcookie('password','123','','','',true);
在默认情况下,cookie值是可以被其他脚本获取的,比如是JavaScript,这是就可能存在安全问题,那我们怎么防止其他脚本来读取cookie呢?
在setcookie()函数的最后一个参数就是控制cookie只能http协议进行读取。
<?php //最后一个参数,设置为true表示只能是https协议进行读取。 setcookie('username','abc','','','',false,false);
上面的就是对会话技术cookie的介绍。在会话技术中还有之中技术也就是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机制,使用sessio_start()函数进行开启。同时session数据的保存也是通过键值对的方式进行保存的。session保存的数据类型可以是int,float,boolean,string,array,object。
<?php //开启session机制 session_start(); //把数据保存在$_SESSION数组里面。 $_SESSION['user'] = 'abc';
先开启session机制,然后把需要的数据保存在$_SESSION数组里面当我们运行代码可以在http协议的响应头中添加了一段话:
Set-Cookie:PHPSESSID=p4lsn4vrdjtmkou1qc3tn3n577; path=/
同时我们也可以参看我们在服务器保存的session文件。
user|s:3:"abc";
<?php //先开启session机制 session_start(); echo '<pre class="brush:php;toolbar:false">'; //保存在session里面的数据会自动封装到$_SESSION数组里面 var_dump($_SESSION); ......结果...... array(1) { ["user"]=> string(3) "abc" }
当我们读取session的数据的时候,先开启session机制,这样服务器就会把session文件里面的数据封装到$_SESSION数组中,从而就可以对数据进行操作。
session的修改和cookie的修改是一样的,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_start()函数来启动session机制,其实PHP给我们提供了两种方式来开启session
直接在php文件中使用session_start()函数;这种方式比较灵活,推荐使用这种方式。
直接在php.ini 文件中,配置session.auto_start = 1 设置1就可以自动打开session机制. 默认情况下这个值是 0,这种方式不推荐使用。
关于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_start()函数开启session机制,并且把数据封装到$_SESSION数组里面,但是我们并没有了解其中的过程,数据是怎么存储在数组里面,又是在什么时候保存在session文件中的,当destroy掉session文件的时候又是在哪里进行执行的,都没有了解。
session的存储机制大致可以分为三步,从session_start开始,到一个文件运行结束
在session_start()开启session机制后,
判断浏览器传过来的数据中是否带有session_id,如果有就使用,没有就创建一个session文件。
将session文件中的数据读取到$_SESSION数组中。
启用session的垃圾回收机制,判断哪些session是失效的,删除失效的session文件。
在脚本周期内,我们可以对$_SESSION数组进行增删改查的操作,注意在这里操作的数据并不会对保存在服务器端的session文件有影响。同时如果在这里使用session_destroy(),就会删除session文件并关闭session机制。
在腳本結束時,先判斷session機制是否關閉,如果沒有關閉就會把$_SESSION數組裡面的資料寫入session檔。
上面就是session的儲存機制,理解並掌握儲存機制,對我們使用session有很好的幫助。
在上面的儲存機制中我們知道在開啟session機制後第一步中通過判斷哪些是無效的文件,然後session會啟用垃圾回收機制(GC)進行回收,但是並不是每此開啟都要進行回收的,其實在php.ini檔案中有兩個參數,設定了啟用gc的機率。
session.gc_probability
session.gc_pisor= 10000
它們是一對,表示垃圾回收的機率是多少,而機率的計算公式是session.gc_probability/ session.gc_pisor = 1/10000, 是說,當呼叫10000次session_start() 函數,有一次會觸發垃圾回收機制。
但是針對不同的網站我們設定不同的機率,對於大型網站,session.gc_pisor 設定大點,例如10000, 中型網站 500-1000, 小網站,200-300,避免頻繁的觸發GC。
會話技術cookie和session在PHP開發中用到的還是很多的,理解兩個技術不同的特點,讓我們在開發中更加靈活的儲存不同的資料。
以上就是PHP基礎教學十七之會話技術COOKIE、SESSION的內容,更多相關內容請關注PHP中文網(www.php.cn)!