session問題集錦
對於PHP的session功能,始終找不到合適的答案,尤其是一些錯誤,還有一些沒有錯誤的結果,最可怕的就是後者,一直為許多的初學者為難。就連有些老手,有時都被搞得莫名其妙。本文,將這些問題,做一個簡單的匯總,以便大家查閱。
1.
錯誤提示
Warning: Cannot send session cookie - headers already sent
Warning: Cannot send session cache limiter - headers already sent
分析及解決辦法
這一類問題,的原因是你在程式中使用session_start()時,之前已經有實際的html內容輸出了。或許你說,我沒有啊,我只不過是echo或print一條訊息了。很抱歉,你的echo或print語句所產生的輸出,就是實際的html內容輸出。解決此類問題的辦法是,將你的session_start()調到程式的第一行。
2.
錯誤提示
Warning: open(F:/689phpsessiondatasess_66a39376b873f4daecf239891edc98b5, O_RDWR) failed
分析及解決方案
出現這樣的錯誤語句一般是因為你的php.ini中關於session.save_path一項沒有設定好,解決的方法是將session.save_path和session.cookie_path 設定置為
session_save_path = c: emp
session.cookie_path = c: emp
然後在c:目錄下建立一個temp目錄,即可
3.
錯誤提示
Warning: Trying to destroy uninitialized session in
分析及解決方案
出類這樣的提示,一般情況都是你直接調session_destroy()函數造成的。很多的朋友認為session_destroy()函數可以獨立的運行,其實不然。解決的方法是在你調session_destroy()函數之前,要用session_start()開啟session的功能。
4.問題:怎麼獲得當前session的id值呢?
最簡單的方法是:
echo SID;
你會發現的。
5.問題:我的程式,在調用header函數之前沒有任何的輸出,雖然我include了一個config.php檔案,但在config.php檔案中也沒有任何的輸出,為什麼session還是會報出與問題1同樣的錯誤呢,是不是因為我在header之前用了session_start()的緣故呢?
答:或許你確實認真的檢查了你的php程式,在引用header()之前確實也沒有任何的輸出,並且在你的include檔案中也沒有任何的輸出!但是你是否用游標鍵在?>這個PHP代碼結束語句後移動檢查呢?那麼你會發現在?>這個後面,有一個空行或幾個空格,你刪除了這幾個空行或空格,那麼問題就解決了。
註:此問題,會出PHP4.1.2中,更高版本,沒有測試過。
6.問:用session做登入首頁面後,其它頁面怎麼用session限制登入。。。
答:最簡單的方法是
session_start();
if(!session_registered('login') ││ $login != true) {
echo "你沒有登陸";
exit;
}
7.問:我用session_register()註冊了session變數,可是當我用header或用javascript的重新導向語句,那麼在一下頁面中,我卻訪問不到session所註冊的變數值。請問如何解決?
問題的程式片段:
session_start();
$ok = 'love you';
session_register('ok');
header("location : next.php");
?>
next.php
session_start();
echo $ok;
?>
解決的方法:
當你用header函數或window.location這樣的功能後,你上一個頁面所註冊的session變數,就會容易的丟失,關於這個問題的原因,至今仍沒有一個詳細的回答。
不過有解決的方法。如下所示
header("Location: next.php" ."?" . SID);
在跳轉到下一頁面的時候,將session的當前id做為一個參數,傳到後一個頁面。
8.session如何傳數組
session_register('data');
$data=array(1,2,3,4);
方法是先註冊後賦值
9.問題9:我是不是可以用像$HTTP_GET_VARS['**']方式來訪問session值呢?
回答:可以,你可以使用如下global數組來訪問session,以加強網頁的安全性
$HTTP_SESSION_VARS
$_SESSION
常式:
session_start();
$username = 'stangly.wrong';
session_register('username');
echo $HTTP_SESSION_VARS['username'];
echo '
';
echo $_SESSION['username'];
?>
請參照此常式修改符合您自己的程式。
問題10:session_unregister() 和 session_destroy() 有何區別?
session_unregister()函數主要作用是注消當前的一sion.(譯自於php.net)
常式:
if(isset($_COOKIE[session_name()])) {
session_start();
session_destroy();
unset($_COOKIE[session_name()]);
}
以上,所述是一些新手經常遇到的問題。或許是詳述不清,難免有誤所在,請高手指點批評。
php中的session的配置
今天偵錯工具遇到了session的設定問題,網上這篇文章比較好,共拿來學習,並供大家參考。
轉載自旅行論壇 http://www/lvxing.net
首先開啟php.ini檔案,找到session的部分:(分號後面的是注釋)
[Session]
; Handler used to store/retrieve data.
session.save_handler = files ; 這個是session的方式,預設的files就可以了,代表用檔案儲存
; Argument passed to save_handler. In the case of files, this is the path where data files are stored.
session.save_path = /tmp ; 這個是session的儲存路徑,比如你是c盤,那麼預設就是c:/tmp, 所以如果出現“Warning: open(/tmpsess_cc8b04f146a1e0494bc464305da92ea1, O_RDWR) failed”這樣子的錯誤,你可以修改這個路徑,或者在根目錄下面建立一個tmp的檔案夾
; Whether to use cookies.
session.use_cookies = 1 ; sessionid的傳遞方式,預設是cookie,推薦使用
; Name of the session (used as cookie name).
session.name = PHPSESSID ; sessionid的名稱,儲存在cookie裡面的,要避免同名
; Initialize session on request startup.
session.auto_start = 0 ; 是否自動啟動session,預設為不是,不需要修改
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
session.cookie_lifetime = 0 ; sessionid的cookie存留時間,0代表知道瀏覽器關閉
; The path for which the cookie is valid.
session.cookie_path = / ; sessionid的cookie路徑,不需要修改
; The domain for which the cookie is valid.
session.cookie_domain = ; ;sessionid的cookie網域名稱,不需要修改
; Handler used to serialize data. php is the standard serializer of PHP.
session.serialize_handler = php ; 儲存data的預設檔案名稱尾碼,不需要修改
; Percentual probability that the 'garbage collection' process is started on every session initialization.
session.gc_probability = 1
; After this number of seconds, stored data will be seen as 'garbage' and cleaned up by the garbage collection process.
session.gc_maxlifetime = 1440 ; session檔案的儲存時間
; Check HTTP Referer to invalidate externally stored URLs containing ids.
session.referer_check = ; How many bytes to read from the file.
session.entropy_length = 0 ; Specified here to create the session id.
session.entropy_file = ;session.entropy_length = 16 ;session.entropy_file = /dev/urandom
; Set to {nocache,private,public} to determine HTTP caching aspects.
session.cache_limiter = nocache ; Document expires after n minutes.
session.cache_expire = 180 ; use transient sid support if enabled by compiling with --enable-trans-sid.
session.use_trans_sid = 1 url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ======================================================================
session 的生命週期是多長
1 瀏覽器結束時其生命週期也同時結束,但是檔案仍然存在於 /tmp/(sess_???)
2 下次重新開瀏覽器時會重新分配 sessionID,如果你使用 session_id() 把以前的 ID 帶回來,
則會去讀取殘存在 /tmp 處的 sess_???, 取回你之前所有已經設定的參數
3 可以在 php.ini 裡修改 session 檔案殘存的時間 session.gc_maxlifetime = 1440 ; after this number of seconds, stored
; data will be seen as 'garbage' and
; cleaned up by the gc process 預設是 1440 秒,24分鐘
=========================================================================
使用無限生命期Session的方法
在PHP4.0中加入了對Session的支援,方便了我們很多程式,比如購物車等等!
在很多論壇中,Session也用於處理使用者的登陸,記錄下使用者名稱和密碼,使得使用者不必每次都輸入自己的使用者名稱和密碼!但是一般的Session的生命期有限,如果使用者關閉了瀏覽器,就不能儲存Session的變數了!那麼怎麼樣可以實現Session的永久生命期呢?
大家知道,Session儲存在伺服器端,根據用戶端提供的SessionID來得到這個使用者的檔案,然後讀取檔案,取得變數的值,SessionID可以使用用戶端的Cookie或者Http1.1協議的Query_String(就是訪問的URL的“?”後面的部分)來傳送給伺服器,然後伺服器讀取Session的目錄……
要實現Session的永久生命期,首先需要瞭解一下php.ini關於Session的相關設定(開啟php.ini檔案,在“[Session]”部分):
1、session.use_cookies:預設的值是“1”,代表SessionID使用Cookie來傳遞,反之就是使用Query_String來傳遞;
2、session.name:這個就是SessionID儲存的變數名稱,可能是Cookie,也可能是Query_String來傳遞,預設值“PHPSESSID”;
3、session.cookie_lifetime:這個代表SessionID在用戶端Cookie儲存的時間,預設是0,代表瀏覽器一關閉SessionID就作廢……就是因為這個所以Session不能永久使用!
4、session.gc_maxlifetime:這個是Session資料在伺服器端儲存的時間,如果超過這個時間,那麼Session資料就自動刪除!
還有很多的設定,不過和本文相關的就是這些了,下面開始講使用永久Session的原理和步驟。
前面說過,伺服器通過SessionID來讀取Session的資料,但是一般瀏覽器傳送的SessionID在瀏覽器關閉後就沒有了,那麼我們只需要人為的設定SessionID並且儲存下來,不就可以……
如果你擁有伺服器的操作許可權,那麼設定這個非常非常的簡單,只是需要進行如下的步驟:
1、把“session.use_cookies”設定為1,開啟Cookie儲存SessionID,不過預設就是1,一般不用修改;
2、把“session.cookie_lifetime”改為正無窮(當然沒有正無窮的參數,不過999999999和正無窮也沒有什麼區別);
3、把“session.gc_maxlifetime”設定為和“session.cookie_lifetime”一樣的時間;
設定完畢後,開啟編輯器,輸入如下的代碼:
------------------------------------------------------------------------------------
<?php session_start();
session_register('count');
$count++;
echo $count;
?>
------------------------------------------------------------------------------------
然後儲存為“session_check.php”,用瀏覽器開啟“session_check.php”,看看顯示的是不是“1”,再關閉瀏覽器,然後再開啟瀏覽器訪問“session_check.php”,如果顯示“2”,那麼恭喜了,你已經成功;如果失敗的話,請檢查你前面的設定。
但是如果你沒有伺服器的操作許可權,那就比較麻煩了,你需要通過PHP程式改寫SessionID來實現永久的Session資料儲存。查查php.net的函數手冊,可以見到有“session_id”這個函數:如果沒有設定參數,那麼將返回當前的SessionID,如果設定了參數,就會將當前的SessionID設定為給出的值……
只要利用永久性的Cookie加上“session_id”函數,就可以實現永久Session資料儲存了!
但是為了方便,我們需要知道伺服器設定的“session.name”,但是一般使用者都沒有許可權查看伺服器的php.ini設定,不過PHP提供了一個非常好的函數“phpinfo”,利用這個可以查看幾乎所有的PHP資訊!
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
開啟編輯器,輸入上面的代碼,然後在瀏覽器中運行這個程式,會見到PHP的相關資訊(1所示)。其中有一項“session.name”的參數(圖中已經標出),這個就是我們需要的伺服器“session.name”,一般是“PHPSESSID”。
記下了SessionID的名稱後,我們就可以實現永久的Session資料儲存了!
開啟編輯器,輸入下面的代碼:
------------------------------------------------------------------------------------
session_start(); // 啟動Session
session_register('count'); // 註冊Session變數Count
if(isset($PHPSESSID)) {
session_id($PHPSESSID);
} // 如果設定了$PHPSESSID,就將SessionID賦值為$PHPSESSID,否則產生SessionID
$PHPSESSID = session_id(); // 取得當前的SessionID
$count++; // 變數count加1
setcookie('PHPSESSID', $PHPSESSID, time()+3156000); // 儲存SessionID到Cookie中
echo $count; // 顯示Session變數count的值
?>
------------------------------------------------------------------------------------
儲存之後,利用和剛才擁有伺服器許可權時候的檢測一樣的方法,檢測是否成功的儲存了SessionID。
後記:
其實真正的永久儲存是不可能的,因為Cookie的儲存時間有限,而伺服器的空間也有限……
但是對於一些需要儲存時間比較長的網站,以上方法就已經足夠了!關於Session的其他應用,可
以參見zphp.com的文章。
最後,筆者的調試環境:Windows98DigExt(SE)+Apache+PHP 4.04