PHP開(kāi)發中(zhōng)session應用詳解

發布時間:2007年01月24日      浏覽次數:2983 次
Session指的就是用戶在浏覽某個網站時,從進入網站到浏覽器關閉所經過的這段時間,也就是用戶浏覽這個網站所花費(fèi)的時間。從上述的定義中(zhōng)我(wǒ)(wǒ)們可以看到,Session實際上是一(yī)個特定的時間概念。
  一(yī)般來說,在網站上某一(yī)個頁面中(zhōng)的變量(指服務器端變量,下(xià)同)是不能在下(xià)一(yī)頁中(zhōng)用的,有了session就好辦了。session中(zhōng)注冊的變量可以作爲全局變量使用。這樣我(wǒ)(wǒ)們就可以将session用于用戶身份認證,程序狀态記錄,頁面之間參數傳遞。
  在PHP3版本中(zhōng)是如何實現session的?
  php3本身是沒有實現session功能的,我(wǒ)(wǒ)們隻有用其他的方法來實現,這其中(zhōng)最有名的要算phplib了。phplib最基本的功能包括用戶認證、Session管理、權限及數據庫的抽象化。下(xià)面我(wǒ)(wǒ)們就講述一(yī)下(xià)如何用phplib實現session。
  1、首先安裝phplib(環境爲win2000+php3.0.16+Apache1.3.12+phplib7.2c+mysql3.23.21 for win32)
  首先将phplib解開(kāi),裏面有一(yī)個"php"目錄,将這個目錄拷貝到Apache的安裝目錄下(xià)。例如:Apache安裝在d:\Apache 目錄下(xià),那麽就将"php"目錄拷貝到d:\Apache,并将phplib目錄的pages目錄下(xià)(不包括目錄本身)的文件和目錄一(yī)起拷貝到d:\Apache\htdocs下(xià)。
  phplib的類庫需要根據系統進行初始化,可能需要修改local.inc文件,其中(zhōng)包含着一(yī)些基本參數,可以根據自己機器的實際情況來進行修改。
  将d:\Apache\php\prepend.php文件中(zhōng)的一(yī)段程序改爲如下(xià)樣子:
if (!isset($_PHPLIB) or !is_array($_PHPLIB)) {
  $_PHPLIB["libdir"] = "d:/Apache/php/"; //放(fàng)phplib下(xià)php目錄的路徑
}
  修改d:\Apache\php\local.inc文件:
class DB_Example extends DB_Sql {
  var $Host = "localhost"; //mysql數據庫所在主機名
  var $Database = "test"; //數據庫名
  var $User = "root"; //數據庫用戶名
  var $Password = "1234567"; //數據庫用戶密碼
}
  最後根據phplib目錄下(xià)的stuff子目錄中(zhōng)的create_database.mysql文件生(shēng)成初始表。
  由于每一(yī)個使用phplib的頁面首先必須可以找到運行phplib所必需的類庫文件,我(wǒ)(wǒ)們可以在php.ini中(zhōng)設置auto_prepend變量來支持,phplib中(zhōng)包含一(yī)個prepend.php文件,并将auto_prepend指定爲"d:/Apache/php/prepend.php"(帶引号)後,各頁面就會自動包含phplib類庫,我(wǒ)(wǒ)們還可以将phplib類庫所在目錄加進include變量中(zhōng),以便可以找到這些文件。 2、調用page_open()函數
  在每一(yī)個使用phplib的頁面中(zhōng),必須首先調用page_open函數進行初始化,例如:
<?php
  page_open(array("sess" => "Test_Session"));
?>
  數組變量(sess)用來初始化一(yī)些狀态保存對象,這裏應該注意:必須使用phplib内置名(sess),這些内置名是在local.inc中(zhōng)所定義的.。
  因爲phplib使用了Cookies來保存狀态信息,所以page_open()函數必須在頁面内容輸出到浏覽器之前被調用。php腳本最後應以page_close()結束,這将會将有關狀态數據寫回到數據庫中(zhōng),否則變量會丢失。
  3、具體(tǐ)使用。
  注冊一(yī)個變量後即可在随後的頁面中(zhōng)使用它,直至session結束。方法:
  <?php $sess->register( "varname"); ?>
  注意,這裏的varname不是變量值,而是變量名,可以先指定變量名,随後再賦值。你在某個頁面中(zhōng)可以改變變量的值,随後的頁面訪問該變量時會得到改變後的值。變量的類型是多樣的,可以是一(yī)個字符串,一(yī)個數字,一(yī)個數組。舉例來說明:
  第一(yī)頁:
<?php
 page_open(array("sess" => "Test _Session"));
 $sess->register( "welcome"); //注冊變量$welcome,注意不需要加$
 $welcome="Hello,PHP world!";
 ……
 page_close();
?>
  第二頁:
<?php
 page_open();//開(kāi)始session
 echo $welcome;//顯示第一(yī)頁中(zhōng)定義的$welcome
 page_close();//保存狀态信息
?>
  注冊完一(yī)個變量,當頁面最後調用page_close()函數後,各個session變量會被寫回到數據庫中(zhōng)。如果忘記調用page_close()函數的話(huà),變量就不會被寫回數據庫,這樣将出現不可預知(zhī)的後果。當變量被使用完畢,不再需要用到時,可以調用以下(xià)函數将變量删除:
<?php
 page_open(array("sess" => "Test _Session"));
 ……
 $sess->unregister( "variable_name");
 ……
 page_close();
?>
  在PHP4版本中(zhōng)是如何實現session的?
  php4的session也靠cookies保存session id,用文件系統保存變量(默認情況下(xià)),因此,它的session變量不能保存對象。當然也可以将session保存在數據庫中(zhōng)。
  在php4中(zhōng)有關session的函數很多(詳見php.ini配置一(yī)文),通常情況下(xià)我(wǒ)(wǒ)們隻需要調用三個函數即可:sesssion_start()、session_register()、session_is_registered()。
  在需要用到session的每一(yī)頁的最開(kāi)始處調用session_start()函數, 例如:
<?session_start()?>
<html><body>
<?
 $welcome="hello world !";
 session_register("welcome");//注冊$welcome變量,注意沒有$符号
 if(session_is_registered("welcome"))//檢查$welcome變量是否注冊
  echo "welcome變量已經注冊了!";
 else
  echo "welcome變量還沒有注冊!";
?>
</body></html>
  php4中(zhōng)session處理的定制
  我(wǒ)(wǒ)們需要擴充6個函數:
  ·sess_open($sess_path, $session_name);
    這個函數被session處理程序調用來作初始化工(gōng)作。
    參數$sess_path對應php.ini文件中(zhōng)的session.save_path選項
    參數$session_name對應php.ini中(zhōng)的session.name 選項。
  ·sess_close();
    這個函數在頁面結束執行并且session處理程序需要關閉時被調用
  ·sess_read($key);
    這個函數在session處理程序讀取指定session鍵值($key)時,檢索并返回标識爲$key的session數據.(注意:序列化是将變量或對象在程序結束或需要時保存在文件中(zhōng),在下(xià)次程序運行或需要時再調入内存的技術,有别于隻保存數據的方法。)
  ·sess_write($key, $val);
    這個函數據在session處理程序需要将數據保存時調用,這種情況經常在程序結束時發生(shēng)。它負責将數據保存在下(xià)次能用sess_read($key)函數檢索的地方。
  ·sess_destroy($key);
    這個函數在需要消毀session時。它負責删除session并且清除環境。
  ·sess_gc($maxlifetime);
    這個函數負責清理碎片。在這種情況下(xià),它負責删除過時的session數據。session處理程序會偶爾調用它們。
  定制程序可以用mysql數據庫或DBM文件保存session數據,視具體(tǐ)的情況而定。如果使用mysql作支持,那還需要進行以下(xià)的步驟:
  首先在mysql中(zhōng)創建一(yī)個sessions數據庫,并且創建一(yī)個sessions表:
mysql> CREATE DATABASE sessions;
mysql> GRANT select, insert, update, delete ON sessions.* TO phpsession@localhost
  -> IDENTIFIED BY 'phpsession';
mysql> CREATE TABLE sessions (
  -> sesskey char(32) not null,
  -> expiry int(11) unsigned not null,
  -> value text not null,
  -> PRIMARY KEY (sesskey)
  -> );
  下(xià)一(yī)步,修改session_mysql.php文件的$SESS_DB* 變量使其匹配你機器上的數據庫設置:
<?
$SESS_DBHOST = "localhost"; /* 數據庫主機名 */
$SESS_DBNAME = "sessions"; /* 數據庫名 */
$SESS_DBUSER = "phpsession"; /* 數據庫用戶名 */
$SESS_DBPASS = "phpsession"; /* 數據庫密碼 */
$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
……//定制函數
session_set_save_handler( "sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
?>
  定制使用dbm文件時的接口 :
<?
$SESS_DBM = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
……//定制函數
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
?>
  session定制的測試代碼:
<?php
……
if ($handler == "dbm") include("session_dbm.php");//使用何種接口
elseif ($handler == "mysql") include("session_mysql.php");
else ……
session_start();
session_register("count");
……
?>
  在身份驗證中(zhōng),怎樣應用Session?
  Session可以用于用戶認證 :
  驗證用戶是否合法:
<?
 session_start();
 ……//驗證過程
 session_register("reguser");
?>
  在另一(yī)頁面中(zhōng)檢查用戶是否登錄
<?
 session_start();
 if(isset($reguser)&&$reguser!=""){//如果已經登錄
  echo "親愛的用戶,歡迎你";
 }else{//如果沒有登錄
  echo "請先注冊!";
 }
?>
  用戶退出登錄:
<?
 session_destroy();
 ……
?>
  如何實現多session并發運行?
  問題提出:我(wǒ)(wǒ)在爲所在單位編寫一(yī)個進銷存系統中(zhōng)發現需要讓多個用戶可以同時進入一(yī)個php應用程序。原來設計的靜态的唯一(yī)的session ID導緻數據混亂。這樣,動态生(shēng)成一(yī)個唯一(yī)的session ID成爲當務之急。
  解決辦法很簡單:我(wǒ)(wǒ)用了php文件名+時間戳爲唯一(yī)的session ID,這樣在我(wǒ)(wǒ)的程序中(zhōng)的每個session就各就各位,不再混亂了。
  下(xià)面把我(wǒ)(wǒ)的源代碼公布,方便也有同樣的問題的朋友多一(yī)個解決方法。
//Start a PHP session to preserve variables.
  if ( empty($mysessionname) ) {
     $micro = microtime();
     $micro = str_replace(" ","",$micro); // strip out the blanks
     $micro = str_replace(".","",$micro); // strip out the periods
     $mysessionname = "po_maint" . $micro;
  }
  session_name($mysessionname);
  session_start();
  程序注釋:
  用mysessionname爲頁面間唯一(yī)的sessionname傳遞變量,如果你也用到這個名字必須把上述程序做個小(xiǎo)小(xiǎo)的改動。Mysessionname不能爲session的内部變量名,因爲他在session開(kāi)始之前就已經存在了。Mysessionname也不能用cookie方式存放(fàng),因爲多個session肯定會覆蓋掉原先的cookie文件。你可以用隐含表單的域來保存它。這樣就不會有問題。
文章來源:http://programmer.blog.hexun.com/1765048_d.html
免責聲明:本站相關技術文章信息部分(fēn)來自網絡,目的主要是傳播更多信息,如果您認爲本站的某些信息侵犯了您的版權,請與我(wǒ)(wǒ)們聯系,我(wǒ)(wǒ)們會即時妥善的處理,謝謝合作!