什么情況下會調用到session_destroy()

https://segmentfault.com/q/1010000000191102

首先 ...?session_destory()?是一個函數 ...

這個函數在任何情況下都不會被 php 引擎自動調用 ... 只能你手工去調用 ...

php 內部存在著清理 session 的機制 ... 但與這個函數完全無關 ...

如果你想問的是什么時候該手工調用這個函數 ...答案就是在你想完全清理掉當前 session 的時候 ...

問題里面提及的幾種情況 ... 不管是關閉網頁也好 ... 關閉瀏覽器也罷 ... 甚至你把瀏覽器刪掉重裝了 ...

都不會影響到已經生成的 session ... 一言以蔽之 ... 所有瀏覽器行為都不會導致 session 被自動銷毀 ...

那么 ... php 到底是如何清理 session 的呢 ..?

仔細去讀?php.ini?... 你可以發現如下幾行 ...

; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using ; gc_probability/gc_divisor. Where session.gc_probability is the numerator ; and gc_divisor is the denominator in the equation. Setting this value to 1 ; when the session.gc_divisor value is 100 will give you approximately a 1% ; chance the gc will run on any give request. ; Default Value: 1 ; Development Value: 1 ; Production Value: 1 ; http://php.net/session.gc-probability session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started ; on every session initialization. The probability is calculated by using ; the following equation: gc_probability/gc_divisor. Where session.gc_probability ; is the numerator and session.gc_divisor is the denominator in the equation. ; Setting this value to 1 when the session.gc_divisor value is 100 will give you ; approximately a 1% chance the gc will run on any give request. Increasing this ; value to 1000 will give you a 0.1% chance the gc will run on any give request. ; For high volume production servers, this is a more efficient approach. ; Default Value: 100 ; Development Value: 1000 ; Production Value: 1000 ; http://php.net/session.gc-divisor session.gc_divisor = 1000 ; After this number of seconds, stored data will be seen as 'garbage' and ; cleaned up by the garbage collection process. ; http://php.net/session.gc-maxlifetime session.gc_maxlifetime = 1440 

其實英文的注釋已經說得很明白了 ... 但如果你不想看 ... 我也可以解釋給你聽 ...

由于 php 的工作機制 ... 它本身不會提供 daemon 來定時掃描 session 信息并判斷其是否失效 ...

當你每次調用?session_start()?時 ...

php 會根據?session.gc_probability?和?session.gc_divisor?來決定是否啟用 Garbage Collector ...

Garbage Collector 顧名思義 ... 被叫做?垃圾回收器?... 也就是俗稱的 GC ...

具體一些講 ... 在我剛剛貼的配置文件里 ...

session.gc_probability = 1
session.gc_divisor = 1000

就是說 php 會有千分之一的概率會啟動垃圾回收 ...

而垃圾回收的工作就是在 session 存儲路徑?session.save_path?下掃描所有存在的 session ...

然后用當前時間減去每個 session 的最后修改時間再跟?session.gc_maxlifetime?參數進行比較 ...

如果某個 session 的生存時間超過了?session.gc_maxlifetime?的設定值就把它銷毀掉 ...

事實上這個過程完全是 php 引擎的行為 ... 和你的程序無關 ... 和用戶做了什么也無關 ...

用戶關閉瀏覽器再開 ... 因為 cookie 失效他會獲得一個新的 session ...

但這并不代表他原來的 session 就被銷毀了 ... 那個 session 依然在服務器上存在 ...

如果他手動把名字等于?session.name?的那個 cookie 的值改回之前的?session_id()?...

還是可以重新獲得之前的那個 session 的 ...

另外一種情況 ... 如果一個用戶獲得 session 之后長時間沒有任何動作 ...

他就可能因為其他用戶觸發了垃圾回收而丟失掉自己的 session ...

大體來說就是如此 ... 更加細節的東西 ... 你可以參考 php 手冊上?關于垃圾回收的章節?...

恩 ... 就是這樣啦 ...

//-------------------------------------------------------------------------------

深入理解session過期機制

首先得明白:session的過期時間由兩方面決定的;?
1存儲在客戶端的$_COOKIE['PHPSESSID']的過期時間(默認cookie名稱為PHPSESSID,可通過php.ini中的session.name修改。)?
2.存儲在服務器端的相對應的session文件(session文件名和上述cookie的值一一對應),默認為1440秒,即24分鐘?

ok,現在詳細闡述上述兩者的關系:?當執行session_start()的時候,其實是做了兩件事:?1,檢查客戶端發送過來的的所有cookie(當然也包括$_COOKIE['PHPSESSID'],?如果有的話),根據$_COOKIE['PHPSESSID']的值(這是由apache產生的隨機字符串,如0lkbd2se458r600m2m7o1r4ic5)來訪問?相對應的 session文件(如:sess_0lkbd2se458r600m2m7o1r4ic5,我的默認存儲在‘E:\wamp\tmp’下),這兩者是一 一對應的關系。打個比喻:$_COOKIE['PHPSESSID']就是一把開啟寶盒的鑰匙,而那個寶盒就是session文件,里面存儲著用戶的重要 信息,也就是session的值, 如:$_SESSION['uid']=1,$_SESSION['username']='name',$_SESSION['pwd']='pwd', 當然文件里面的值是經過序列化的。?2,如果客戶端沒有傳來$_COOKIE['PHPSESSID'],就會有服務端產生一個隨機的$_COOKIE['PHPSESSID']并存儲在客戶端。?

明白上面這些,我們可以通過下面的方法修改session的過期時間:?
1.session_set_cookie_params('50');//修改$_COOKIE['PHPSESSID'],的生存時間為50秒?

(或者可以這樣:?setcookie(session_name(),session_id(),time()+50);)?

2.ini_set('session.gc_maxlifetime','50');//設置session文件的有效時間為50秒?

但是,可能有些朋友會做這樣?一個試驗, 在50秒內獲取$_COOKIE['PHPSESSID']的值并記錄下來(如黑客截獲這個cookie),這樣等50秒過后發現原先 的$_COOKIE['PHPSESSID']值確實不存在了,而出現了一個新的$_COOKIE['PHPSESSID'],但是‘E:\wamp \tmp’下的舊session文件卻沒有消失(默認只有1/1000的概率會消失,應該不會碰到吧,呵呵),這是為什么呢?我不是已經設置了.ini_set('session.gc_maxlifetime','50');了 嗎?再做一個實驗:這時你偽造一個$_COOKIE['PHPSESSID'],值為剛才你記錄下的,神奇的事發生了,你依然可以訪問剛才舊的 session文件!!!(雖然他已經過期),只要這個文件沒被刪除,用相對應得$_COOKIE['PHPSESSID']依然可以進行訪問!!!?

那我們設置ini_set('session.gc_maxlifetime', '50');還有什么意義呢?這就涉及的GC(GarbageCollector)的回收機制。?
默 認情況下,session.gc_probability = 1,session.gc_divisor=1000,也就是說有1/1000的可能性會啟動GC。GC的工作,就是掃描所有的session信息,用當 前時間減去session的最后修改時間(modifieddate),同session.gc_maxlifetime參數進行比較,如果生存時間已經 超過gc_maxlifetime,就把該session刪除。只要沒有啟動GC,即使session過期,也仍舊可通過相對應 得$_COOKIE['PHPSESSID']進行訪問!?
???
原文參考:?http://www.jb51.net/article/26890.htm?
?????????????????http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2012/0621/10583.html

轉載于:https://www.cnblogs.com/jukan/p/5431384.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255454.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

對永磁無刷電機的調速過程

考慮了一下對永磁無刷電機的調速過程。 一般把使用永磁轉子、無電刷的電機,根據驅動方式分為永磁同步與直流無刷。其實沒有本質區別。在此稱為永磁無刷。 用永磁無刷電機的分子泵驅動器一向調速做得不太好。這兩年好一些了,但是還是不能完全滿意。李老…

C# / VB.NET合并PDF指定頁

在前面的文章中,我們已經知道如何合并、拆分多個PDF文件,在這篇文章中的合并、拆分PDF文檔主要是以方便文檔管理的目的來操作文檔,在文檔查閱、管理及存儲上很方便實用。但是我們如果想要合并多個文檔中的部分文檔頁的內容,該如何…

高級異常

一、什么是異常 解析:異常就是在程序的運行過程中所發生的不正常事件 二、Java異常處理是通過5個關鍵字來解決的:try、catch、finally、(前三個是捕獲異常)throw(手動拋出異常)、throws(聲明異常…

【糾錯】——錯誤:PermissionError: [WinError 32] 另一個程序正在使用此文件,進程無法訪問。“+解決方案

目錄 問題出現場景 原因 解決方案 問題出現場景 先打開pdf文件,獲取pdf文件內容后,利用os.remove()來刪除文件,這時候出現錯誤 os.remove(source_path)PermissionError: [WinError 32] 另一個程序正在使用此文件,進程無法訪問。…

Eclipse中自動添加注釋

方法一:Eclipse中設置在創建新類時自動生成注釋 windows-->preference   Java-->Code Style-->Code Templates     code-->new Java files 編輯它 ${filecomment} ${package_declaration} /** * Author fufu* Time ${date} ${time} * Version 1.…

使用rancher創建負載均衡服務

2019獨角獸企業重金招聘Python工程師標準>>> 2臺主機,一個server包含2個容器進程(可以是多個),一個負載均衡容器(貌似是依賴haproxy的) 1,創建一個鏡像,編輯Dockerfile 創…

Six Basic Functional Areas of Spring

轉載于:https://www.cnblogs.com/Brake/p/5440738.html

【pyqt5學習】——登錄界面跳轉到主界面,登錄界面關閉的情況下從主界面跳轉回登錄界面

目錄 一、登錄界面長下面這樣,由qt designer設計 login.py 二、登錄界面 邏輯代碼loginLogic.py 三、主界面comsumeType.py 四、主界面邏輯代碼comsumeTypeLogic.py 五、登錄界面跳轉至主界面 六、主界面回到登錄界面 一、登錄界面長下面這樣,由qt d…

關于問題vxworks與linux區別

vxWorks Linux 內核 結構 微內核, 內核只提供 了基本的服 務,如:任 務管理,內 存管理,中 斷處理等 宏內核, 除了基本的 服務,內核…

【python學習】——獲取桌面路徑,獲取系統盤符,獲取電腦用戶名,獲取軟件自啟動存放目錄

目錄 1、獲取桌面路徑 法一:利用winshell庫 法二:利用winreg庫 2、獲取系統盤符 3、獲取電腦用戶名 4、獲取軟件自啟動存放目錄 1、獲取桌面路徑 法一:利用winshell庫 import winshell print(winshell.desktop()) 法二:利…

團隊項目:個人工作總結10

團隊項目:個人工作總結10 一.昨天干了什么改進現有的成果二.今天準備干什么做最后的調試分析改進整合。三.遇到的困難任務還是沒有完成轉載于:https://www.cnblogs.com/kongyuhang/p/5442714.html

WPF ClickOnce應用程序IIS部署發布攻略

WPF程序非常適合公司內網使用,唯一缺點就是客戶端要安裝.net框架4.0。優勢也很明顯,在客戶端運行的是一個WinForm程序,自動下載,可以充分利用客戶機的性能,而且是以當前的Windows用戶權限運行,避免了權限帶…

文件傳輸協議

文件傳輸協議(英文:File Transfer Protocol,簡稱為FTP)是用于在網絡上進行文件傳輸的一套標準協議。它屬于網絡傳輸協議的應用層。 FTP是一個8位的客戶端-服務器協議,能操作任何類型的文件而不需要進一步處理&#xff…

36.LEN() 函數

LEN() 函數 LEN 函數返回文本字段中值的長度。 SQL LEN() 語法 SELECT LEN(column_name) FROM table_name SQL LEN() 實例 我們擁有下面這個 "Persons" 表: IdLastNameFirstNameAddressCity1AdamsJohnOxford StreetLondon2BushGeorgeFifth AvenueNew York…

【python學習】——為exe軟件創建快捷方式;實現軟件自啟動

目錄 1、為exe創建快捷方式 2、實現軟件自啟動 3、完整代碼 4、結果展示 1、為exe創建快捷方式 利用winshell庫的CreateShortCut函數進行創建 【python學習】——獲取桌面路徑,獲取系統盤符,獲取電腦用戶名,獲取軟件自啟動存放目錄_有情懷…

dedecms如何調用當前欄目的子欄目及子欄目文章

前面ytkah談到了 dedecms調用當前欄目的子欄目怎么操作,有的朋友會問如果再增加一個調用子欄目文章的需求,即調用當前欄目的子欄目及子欄目文章,這個有辦法實現嗎?這時就要涉及到另外兩個標簽的調用了,dede:channelart…

控制面板項 .cpl 文件說明

控制面板項 .cpl 文件說明appwiz.cpl 程序和功能、卸載或更改程序bthprops.cpl 藍牙控制面板desk.cpl 屏幕分辨率Firewall.cpl WINDOWS防火墻hdwwiz.cpl 設備管理器igfxcpl.cpl 英特爾圖形和…

vxWorks下常用的幾種延時方法

在應用編程的時候,通常會碰到需要一個任務在特定的延時之后執行一個指定的動作,如等待外設以確保數據可靠,控制揚聲器發聲時間以及串口通信超時重發等。這就需要利用定時器機制來計量特定長度的時間段。 vxWorks作為實時嵌入式系統&#xff0…

【pyqt5學習】——窗口最小化至托盤、取消任務欄圖標

目錄 1、最小化至托盤 1)重寫系統托盤類,設置托盤圖標等屬性 2)將具體的窗口放入托盤 2、取消任務欄界面圖標 3、問題匯總 1)退出后托盤圖標還是存在,沒有消失 2)最小化后左下角會出現 窗口 3&#…

標準庫類型String,Vector

string對象中每個字符的處理&#xff1a; 要用到 for(聲明:表達式) 語句 比如簡單的打印string str中每一個字符 --- string str("hello world!!!"); for(auto c: str)cout<<c<<endl; (ps:這里auto 的意思是讓編譯器自己來決定c變量的類型) --- 再舉一…