PHP Session codeIgniter Session 愛恨糾葛

  PHP Session從開始接觸PHP以後就一直是一個方便好用但是不容易理解的東西,如今開始使用Framework以後,內部擴充或外部擴充的library提供的額外功能又必須讓自己更瞭解Session運作的原理以後才能瞭解他,並且擴充他,否則會時常遇到莫名的session消失,令人苦惱。

  codeIgniter內建的session library實在不是太好用(在1.7.1版時),所以在網路上東找西找,找到的還可以接受的就是KNDB Session了。
  已經忘記比較的基礎跟找了哪些進行比較了,這篇主要不是要提這個,但比較時大略是觀察可否支援資料庫,是否與原生函式相容等等條件,http://bootleq.blogspot.com/2008/04/codeigniter-session-libs.html 主要是參考這篇文章的內容進行比較。
  而KNDB就是相容於$_SESSION也可擴充於資料庫等等的原因,實際跟其他使用起來感覺最順就選用了,只是印象好像在flash的部份有些bug有額外找資料修正,不曉得官方wiki版本是否修正了。

  接下來想要紀錄一下關於Session存活的一些參數,於KNDB中的參數內關於逾時的參數有兩個,觀察說明或原始碼後可以發現他們的意義:

sess_expiration:生存時間(LifeTime),Session最後存取時間超過此生存時間則會死亡。
sess_time_to_update:多久需要重新生成一次session_id,代表重送一次cookie 內的session_id,可以參考http://php.net/manual/en/function.session-regenerate-id.php內的說明。

  要真正瞭解這兩個參數需要從整個session運作的流程與方法才會完全理解。在下面試著做簡短又完整的說明:

  當瀏覽器一被session_start以後 php 會產生一個id 並於伺服器端建立一個檔案,然後將這id紀錄於使用者的cookie中,以確保使用者能在瀏覽區間內都可以與session檔案取得關聯以取得變數,在紀錄cookie的時後會有幾個參數發生作用
session.name:要用什麼名稱存於cookie中。
session.cookie_lifetime:這個cookie要存在瀏覽器多久的時間。
  接著使用者不停的在瀏覽器間換頁,直到發生了幾個事件,
session.gc_maxlifetime,session自從建立後假設超出了此時間,此session將會被視為垃圾,有一定機率被回收,回收機率則是 session.gc_probability / session.gc_divisor 這兩個參數所控制。
  或者是cookie超出session.cookie_lifetime的生存時間,則他的session_id就算還沒被回收,瀏覽器也會忘記他自己的session_id是什麼。

  如果瞭解這個流程之後,就可以搭配Session Library的參數進行瞭解,sess_time_to_update則是幫助你延遲cookie的lieftime,幫助你重新建立,而sess_expiration就是額外於原始php session中不可調整session存取時間與生存時間的擴充參數,但假設你的session.gc_maxlifetime沒有足夠長的時間,則不小心就被回收的話,這些參數就會變的無效用囉。

  所以可以透過於index.php中設置這些參數來調整,做更完整的session生存掌控。

ini_set(‘session.name’, ‘pissession’); // session值使用名稱
ini_set(‘session.gc_probability’, 5); // 回收處理分子項
ini_set(‘session.gc_divisor’, 100); // 回收處理分母項
ini_set(‘session.gc_maxlifetime’, 3600); // 清除以目前時間差中失效的過期session
ini_set(‘session.cookie_lifetime’, 0); // Cookie的SID存在時間

  最好是讓’session.gc_maxlifetime’與sess_time_to_update的時間有相對應的長度,否則sess_time_to_update有可能來不及重新產生session_id 就被回收掉囉。

  主要是這個運作的流程需要花費比較多時間去網路蒐集資料或閱讀數本書來了解,這篇就大略整理一下我對PHP Session目前的理解。