2008年10月2日 星期四

有關PHP的session

之前用PHP寫會員系統的網頁 有用到session
大家都知道會員系統常常會用到session跟cookie這兩種東西
但是對網頁沒什麼概念的我 一開始對這兩種東西有點搞混了
查找資料後 在這邊把一些經驗跟觀念寫下來(在這邊就不講cookie了 單講session)

首先 當一個PHP程式要使用session時 必須在使用前先呼叫session_start()這個函數
當一個瀏覽器一瀏覽到有呼叫session_start()的網頁時 一個session檔案就會在伺服器中產生了
這個檔案是存在server的硬碟之中 存放的位置依據php.ini中的session.save_path而定
這個部分跟cookie類似 只是cookie是存放在client端的檔案 session是存放在server端
session檔案產生之後 server端的頁面需要使用到的session變數全都會存到這個檔案之中

好了 現在有個問題 一個頁面可能同時被很多人瀏覽 在這種情況下 session檔案也應該要有很多個才對
並且server還必須要知道哪個session檔案是屬於哪個正在瀏覽頁面的使用者擁有的
沒錯 當session檔案產生時 一個可以用來辨別使用者的token也會跟著產生 也就是所謂的session_id
並且session_id會直接寫在session檔的檔名上 例如像這樣:

sess_gge0ci41lnm57npqhp9m7riqn2

這是一個session檔的檔名 sess_後面的就是session_id

==========接下來是我自己的理解 可能有錯誤的地方============
上面說這個session_id可以讓server用來辨認使用者 其實精確一點來說
是用來辨認client端"正在瀏覽網頁的process"
例如同一個使用者 開了兩個ie視窗來瀏覽網頁 這兩個ie是不同process
則server端其實會產生兩個session檔

好 現在來一個瀏覽網頁的流程舉例
1.client端一個瀏覽器瀏覽了呼叫session_start()的網頁 server對這個瀏覽器給出一個session_id
2.根據這個session_id session檔案產生了
3.每當這個瀏覽器要瀏覽server端其他頁面時 都會把session_id也傳給server
server以此去找尋屬於這個瀏覽器的session檔
4.client端把這個瀏覽器關掉了 新開一個瀏覽器繼續瀏覽頁面 但是這個瀏覽器不會把session_id傳給server
5.server沒發現session_id 於是server給出一個新的session_id 然後產生一個新的session檔
回到了1.的流程

=============================================================

接著應該可以知道 session_id是很重要的 而且看完上面 應該可以發現
既然client端的瀏覽器常常要把session_id傳給server 那client端應該要儲存session_id才對
沒錯 若是照php.ini的預設 當server給出一個session_id時 client端瀏覽器就會有一個cookie來儲存session_id
但是也可以不要這樣做 例如修改php.ini中的session.use_trans_sid為1
這個設定是告訴server 若是某個瀏覽器不使用cookie
PHP會自動將這個瀏覽器看到的網頁中的連結後面都加上PHPSESSID=xxxxxxx
這樣一樣可以達到瀏覽器瀏覽頁面時將session_id傳遞給server的功能
不過這個方法並不安全 最好不要使用