--- tags: PHP --- # PHP快速入門 7 -- 資料暫存處理 Cookie & Session ## Cookie ### **What** 什麼是Cookie? Cookie 屬於一種小型的文字檔案,是伺服器端(Server Side)透過加密的方式儲存在用戶端(Client Side)上的資料。 ### **Where** Cookie存放在哪? Cookie 可以儲存的地方有兩個:記憶體或硬體內。記憶體 Cookie 是由瀏覽器來維護的,通常會在瀏覽器關閉後清除,而各個瀏覽器之間的 Cookie 是無法相互使用,也就是說對於在同一台電腦上使用 Chorme 或是 Firefox,僅管操作的是同一個人,卻是會認成兩個不一樣的角色。而硬體 Cookie 則會有一個保存期限,除非過期或是手動刪除,不然他的儲存時間會較瀏覽器來的長。 ### **Why** 為什麼需要Cookie? 瀏覽器與伺服器之間是透過 HTTP 協議來進行通訊,而這樣的協議是一種無法紀錄狀態的協議。即伺服器不知道用戶上一次做了什麼。 在典型的網路購物場景中,用戶瀏覽了幾個頁面,買了一盒餅乾和兩瓶飲料。最後結帳時,由於 HTTP 的無狀態性,不通過額外的手段,伺服器並不知道用戶到底買了什麼,所以Cookie 就是用來繞開 HTTP 的無狀態性的「額外手段」之一。伺服器可以設定或讀取Cookies 中包含資訊,藉此維護使用者在使用服務時,在背景完成並可以持續跟伺服器發送請求以及對談中的狀態。 ### **When** 何時需要Cookie? 一般來說 Cookie 會紀錄用戶的資訊,比較常見的做法是應用在購物車、會員登入或瀏覽紀錄、停留時間等等的,使伺服器端可以透過辨別用戶身分,來取得相關的資訊。 像是登入的應用為例,就是使用者登入一個網站時,伺服器端往往會請求用戶輸入使用者帳號及密碼,並且用戶可以勾選「下次自動登入」,這就是觸發使用Cookie的開關了,如果勾選了,在使用者前一次登入時,伺服器就會傳送了包含登入憑據(使用者名稱加密碼的某種加密形式)的 Cookie 到使用者的硬碟(或記憶體上),在之後登入時,只要 Cookie 尚未到期,瀏覽器會傳送該 Cookie 給伺服器作驗證憑據,來減少重複登入的輸入行為。 ### **How** Cookie如何運作? 1. Client 請求 Server 給予頁面 2. Server 回 Response 給 Browser 的時候,HTTP Header 帶上 **Set-Cookie**。Browser 接收到 Set-Cookie 指令時,會將 Cookie 的名稱和值儲存在 Browser 的 Cookie。 ![](https://i.imgur.com/V24QuCk.png) 3. Browser 在每次對 Server 發出 Request 的時候會帶上 Cookie 的 Header,讓 Server 能夠正確的存取當前 Cookie。 ![](https://i.imgur.com/dBudP1p.png) ### 優點 1. 伺服器無紀錄的負擔 2. 輕量級 3. 方便使用 ### 缺點 1. 安全性低。 > 因為 HTTP 請求中的 Cookie 是明文傳遞的,除非用 HTTPS。 2. 增加流量負擔。 > 因為 Cookie 會被附加在每個 HTTP 請求中,所以無形中增加了流量。 3. 儲存量低。 > 因為 Cookie 的大小限制在4KB左右,對於複雜的儲存需求來說是不夠用的。且一個域名能存放的 Cookie 數量也有限 4. 用戶可能會禁用 Cookie > 參考資料: > * [Cookie,維基百科](https://zh.wikipedia.org/wiki/Cookie) > * [Web 基本功 - Cookie 與 Session](https://codingluka.com/web-foundation-the-different-of-cookie-and-session/) > * [HTTP cookies ](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Cookies) > * [[不是工程師] Cookie 是文檔還是餅乾?簡述HTTP網頁紀錄會員資訊的一大功臣。](https://progressbar.tw/posts/91) ## $_COOKIE $_COOKIE 為 php 預定義變數 ## 設置 Cookie ### 語法 ```php setcookie(name,value,expire,path,domain,secure); setcookie(“變數名稱”,“值”,“期限”,“路徑”,“網域”,“安全”); ``` | 參數 | 描述 | | -------- | -------- | | name | 必需。規定 Cookie 的名稱 | | value | 必需。必需。規定 Cookie 的值 | | expire | 可選。規定 Cookie 的有效期 | | path | 可選。規定 Cookie 的服務器路徑 | | domain | 可選。規定 Cookie 的域名 | | secure | 可選。規定是否通過安全的 HTTPS 連接來傳輸 Cookie | 1. expires:表示 Cookie 的保存期限,在默認的情況下為暫時性的 Cookie,只要關閉瀏覽器就會消失 2. path:指定與 Cookie 關連在一起的網頁,默認的狀況下為和當前網頁同一目錄的網頁中有效 3. domain:設定 Cookie 有效的網域名稱,可以和path一同設定,讓相同/類似的 domain 可以享有同樣的cookie 4. secure:算是 Cookie 的安全值,在默認的情況 Cookie 的傳輸上是不安全的,可以通過一個不安全且一般的 http,若設置為安全的狀況下,可以讓 Cookie 只在安全的 http 上進行傳輸 ### 用法 setcookie 撰寫位置必須放在任何輸出(echo或print_r)之前 :warning: 剛設定後馬上使用 $_COOKIE 會無法取用,會顯示錯誤。因為電腦才剛建立 cookie 檔,還無法馬上存取 #### 範例1 ```php setcookie("test", "good", time()+60*60*24); ``` 存活時間為從現在開始的時間 + 60秒\*60\*24 = 1天 若無設定存放時間,當瀏覽器關閉後,該 Cookie 自動過期 #### 範例2 ```php <?php $setResult=setcookie("TestCookie", "這是Cookie的內容"); ?> <html> <head> <title>Cookie 存取測試 </title> </head> <body> <?php if($setResult) { if(isset($_COOKIE["TestCookie"])){ echo "Cookie的內容為:".$_COOKIE["TestCookie"]; } else { echo "Cookie 儲存成功,請重整頁面顯示"; } } ?> </body> </html> ``` ![](https://i.imgur.com/FyiDa0M.png) ![](https://i.imgur.com/EIRPOfO.png) ## 刪除 Cookie ### 方法1 把值填入空白,但變數還是存在,會佔用記憶體 ```php= setcookie("test", "", time()+60*60*24); ``` ### 方法2 將存放時間改為現在,所以下一秒就失效了 >> 較好 ```php= setcookie("test", "", time()); ``` :::info * 設置Cookie:setcookie("變數名稱","值","期限","路徑","網域","安全"); >> 前三項為必填 * 刪除Cookie:setcookie("變數名稱","值", time()-60 ,"路徑","網域","安全"); >> 期限用"--"表示刪除,單位為秒(s) ::: ### 預定義變數 $_SESSION * Session:資料儲存在伺服器端(server) * 優點:安全性高;不用擔心用戶禁用session * 缺點:伺服器有紀錄的負擔 :::info * 設置Session:session_start( ) >::: warning >使用Session時必須在每個開頭使用 >::: * 刪除單一Session:session_unregister("變數名稱"); * 刪除所有Session:session_destroy ::: * isset($變數名稱):檢測變數是否已設置且非Null,為boolean型態 範例: 設計一網頁可用來記錄使用者到訪紀錄 ![](https://i.imgur.com/zXHX6tX.png) ![](https://i.imgur.com/Z5xnPCQ.png) >參考資料: >* https://www.webtech.tw/info.php?tid=33 >* https://blog.xuite.net/coke750101/networkprogramming/18668630-php+session%E8%88%87cookie%E9%81%8B%E4%BD%9C%E5%8E%9F%E7%90%86 >* http://www.jollen.org/php/216_session_cookies/ >* https://ithelp.ithome.com.tw/articles/10157724 ## magic_quotes_gpc * 當 magic_quotes_gpc=on 時,\$_GET、\$_POST、\$_COOKIE 等等從 user 端來的資料,如果含有單引號、雙引號、反斜線等內容,會自動被加一條反斜線在前面,把該字元跳脫掉,也就是做 addslashes( ) 的處理 > 參考資料 > * https://ithelp.ithome.com.tw/articles/10113856 > * https://itstudy.000webhostapp.com/2017/12/php-%e5%81%9a%e5%88%b0%e5%9f%ba%e6%9c%ac%e7%9a%84sql-injection%e9%98%b2%e7%a6%a6%e5%8f%8amagic_quotes_gpc%e7%9a%84%e8%a7%80%e5%bf%b5