---
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。

3. Browser 在每次對 Server 發出 Request 的時候會帶上 Cookie 的 Header,讓 Server 能夠正確的存取當前 Cookie。

### 優點
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>
```


## 刪除 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://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