程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP會話控制

PHP會話控制

編輯:關於PHP編程

會話控制的思想是指能夠在網站中根據一個會話跟蹤用戶。 1 cookie 1.1 什麼是cookie Set-Cookie: NAME = VALUE; [expires = DATE;] [path = PATH;] [domain = DOMAIN_NAME;] [secure]   :如果失效日期不設置,cookie將永遠有效,如果不手動將其刪除的話)。path和domain域合起來指定URL或與cookie相關的URL。secure關鍵字的意思是在普通的HTTP鏈接中不發送cookie。   1.2 通過PHP設置cookie 使用setcookie()函數在PHP中手動設置cookie。函數原型如下: bool setcookie(string name [, string value [, int expire [, string path [, string domain [, int secure]]]]])   :cookie標題頭必須,否則就無效(這是cookie的限制,而不是PHP的限制)。   1.3 在會話中使用cookie 1.4 存儲會話ID 2 實現簡單的會話 2.1 開始一個會話 2.2 注冊一個會話變量 2.3 使用會話變量 2.4 注銷變量與銷毀會話 ID。   3一個簡單的會話(實例)   auto-main.php <?php session_start();   if(isset ($_POST['userid' ]) && isset($_POST['password'])){       $userid = $_POST[ 'userid'];       $password = $_POST[ 'password'];              $db_conn = new mysqli('localhost' , 'root' , '' , 'test' );              if(mysqli_connect_error()){              echo "Connection to database failed:" . mysqli_connect_errno();              exit();       }              $query = "select * from authorized_users" . " where name = '$userid'" . "and password = ' $password'" ;         $result = $db_conn -> query($query);              if($result -> num_rows > 0){             $_SESSION[ 'valid_user'] = $userid;       }       $db_conn -> close(); }   ?> <html>       <body >              <h1 >Home Page </h1 >              <?php                    ifisset($_SESSION[ 'valid_user'])){                          echo 'You are logged in as: ' . $_SESSION['valid_user'] . '<br />' ;                          echo '<a href="logout.php">Log out</a><br />';                   } else {                          ifisset($userid)){ //失敗                                echo 'Could not log you in.<br />';                         } else {                                echo 'You are not logged in.<br />';                         }                   }                                       echo '<form method="post" action="auto-main.php">                               <table>                                     <tr>                                           <td>Userid:</td>                                           <td><input type="text" name="userid"></td>                                     </tr>                                     <tr>                                           <td>Password:</td>                                           <td><input type="password" name="password"></td>                                     </tr>                                     <tr>                                           <td colspan="2" align="center"><input type="submit" value="Log in"></td>                                     </tr>                               </table>                         </form>' ;              ?>              <br />              <a href ="members-only.php"> Members section</ a>       </body > </html>   3.2 members_only.php <?php session_start();   echo "<h1>Members only</h1>";   if(isset ($_SESSION['valid_user' ])){       echo "<p>You are logged in as " . $_SESSION['valid_user' ] . "</p>";       echo "<p>Member only content goes here </p>" ; } else {       echo "<p>You are not logged in.</p>" ; }   echo "<a href='auto-main.php'>Back to main page</p>"; ?>   3.3 logout.php <?php session_start();   $old_user = $_SESSION['valid_user']; unset($old_user);   session_destroy();   ?> <html>       <body >              <h1 >Log out </h1 >              <?php                    if(! empty($old_user)){                          echo 'Logged out.<br />';                   } else {                          echo 'You were not logged in, and so have not been logged out.<br />';                   }              ?>              <a href ="auto-main.php"> Back to main page</ a>       </body > </html>   4 session 4.1 影響session數據的PHP函數或事件

session_start() 初始化session,生命周期的開始。

     session初始化操作,聲明一個全局數組$_SESSION,映射寄存在內存的session數據。如果session文件已經存在,並且保存有session數據,session_start()則會讀取session數據,填入$_SESSION中,開始一個新的session生命周期。 (2) $_SESSION       在session生命周期內,使用全局變量名稱將注全局變量注冊到當前session中。所謂注冊,就是將變量填入$_SESSION中,值為NULL。它不會對session文件進行任何IO操作,只是影響$_SESSION變量。注意,它的正確寫法是session_register(‘varname’),而不是session_register($varname) (4) session_unregister()       與session_register操作正好相反,即在session生命周期,從當前session注銷指定變量。同樣只影響$_SESSION,並不進行任何IO操作。 (5) session_unset()       在session生命周期,從當前session中注銷全部session數據,讓$_SESSION成為一個空數組。它與unset($_SESSION)的區別在於:unset直接刪除$_SESSION變量,釋放內存資源;另一個區別在於,session_unset()僅在session生命周期能夠操作$_SESSION數組,而unset()則在整個頁面(page)生命周期都能操作$_SESSION數組。session_unset()同樣不進行任何IO操作,只影響$_SESSION數組。 (6) session_destroy()       如果說session_start()初始化一個session的話,而它則注銷一個session。意味著session生命周期結束了。在session生命周期結整後,session_register, session_unset, session_register都將不能操作$_SESSION數組,而$_SESSION數組依然可以被unset()等函數操作。這時,session意味著是未定義的,而$_SESSION依然是一個全局變量,他們脫離了關映射關系。 通過session_destroy()注銷session,除了結束session生命周期外,它還會刪除sesion文件,但不會影響當前$_SESSION變量。即它會產生一個IO操作。 (7) session_regenerate_id()       調用它,會給當前用戶重新分配一個新的session id。並且在結束當前頁面生命周期的時候,將當前session數據寫入session文件。前提是,調用此函數之前,當前session生命周期沒有被終止(參考第9點)。它會產生一個IO操作,創建一個新的session文件,創建新的session文件的是在session結束之前,而不是調用此函數就立即創建新的session文件。 (8) session_commit()       session_commit()函數是session_write_close()函數的別名。它會結束當前session的生命周期,並且將session數據立即強制寫入session文件。不推薦通過session_commit()來手工寫入session數據,因為PHP會在頁面生命周期結束的時候,自動結束當前沒有終止的session生命周期。它會產生一個IO寫操作 (9) end session       結束session,默認是在頁面生命周期結束的之前,PHP會自動結束當前沒有終止的session。但是還可以通過session_commit()與session_destroy()二個函數提前結束session。不管是哪種方式,結束session都會產生IO操作,分別不一樣。默認情況,產生一個IO寫操作,將當前session數據寫回session文件。session_commit()則是調用該函數那刻,產生一個IO寫操作,將session數據寫回session文件。而session_destroy()不一樣在於,它不會將數據寫回session文件,而是直接刪除當前session文件。有趣的是,不管是session_commit(),還是session_destroy()都不會清空$_SESSION數組,更不會刪除$_SESSION數組,只是所有session_*函數不能再操作session數據,因為當前的session生命周期終止了,即不能操作一個未定義對象。   4.2總結 1, 用戶注銷web應用系統,最好的調用方式依次是 session_unset();  session_destroy();  unset($_SESSION); 2, 盡量將鍵與值填入$_SESSION,而不推薦使用session_register()。同樣,盡量使用unset($_SESSION[‘var’]),而不使用session_unregister()。 3, 對於可能產生大量session的WEB應用,推薦使用的session.save_path的格式是session.save_path=”N:/path”。注意:這些目錄需要手工創建,並且有httpd守護進程屬主寫權限。這樣做可以獲得更好的性能 4, 如果調用了session_regenerate_id()給用戶分配了新的session id。該函數並不會主動刪除舊的session文件,需要定時清理舊的session文件,這樣更優化。 5, 盡量不要使用session_commit()提交sessioin數據,因為它同時會結束當前session,PHP默認會在頁面生命周期的時候提交session數據到session文件        session終究是因為管理用戶狀態信息才存在的。我們曾探討過session id的意義:每個來訪問用戶都會被分配一個唯一的session id,用於區分其它用戶的session數據。換句話說,session id是用戶表明身份的一種標識,就像入場券一樣。用戶一旦從被分配了session id之後的每次訪問(http請求)都會攜帶這個session id給服務端,用於加載該用戶的session數據。那麼,通過什麼方式傳給服務端?這是我們這節探討的內容。      用戶端與服務端的web通信協議是http。而PHP通過http取得用戶數據慣用的三種方法分別是:POST方法、GET方法還有Cookie。而PHP默認傳遞方法正是Cookie,也是最佳方法。只有在客戶端不支持Cookie的時候(浏覽器禁用了Cookie功能)才會通過GET方法來傳遞session_id,即通過在URL的query_string部分傳遞session id。      確定了傳遞方法,我們還有必要清楚一下session id的傳遞過程。用戶通過浏覽器訪問網頁,將URL輸入地址欄回車,浏覽器發出請求,在調用sockect send之前浏覽器引擎會搜索有效的Cookies記錄封裝在http請求頭的Cookie字段,一同發送出去。服務端器接收到請求後,交給PHP處理。這時,session初始化函數如果在$_COOKIE中沒有找到以session_name()作為鍵值存儲的生素(值為session id),則會以為用戶是第一次訪問web。作為第一次訪問的用戶,session初始化函數總會隨機生成一個session_id並且通過setcookie()函數調用將新生成的session_id以”sesseson_name = session_id”的格式填入http響應頭Set-Cookie字段,發送給客戶端(這樣接下來的請求,http請求頭Cookie字段都會攜帶該Cookie記錄給web服務器)。如果初始化函數發現用戶端Cookies中已定義了存在$_COOKIE[‘sess_name’],則會加載與$_COOKIE[‘sess_name’]相對應的session文件($_COOKIE[‘sess_name’]就是session ID)。如果用戶Cookie記錄過期,則會被浏覽器刪除。之後的下一次請求,服務器會以為用戶又是第一次訪問,如此循環。   4.4 Session回收 4.5 總結 1, PHP使用Cookie的方法傳遞session id。盡量不要使用GET方法傳遞session id,因為這樣很不安全。 2, 可以通過setcookie()的方法,將客戶端的session id的Cookie記錄刪除。 3, PHP GC進程由session初始化啟動。但不是每一次用戶請求都會被啟動,它的啟動概率默認是1/1000。過於頻繁訪問的網站,並發量大的網站,可減小PHP GC的啟動頻率。PHP GC回收session會降低php的執行效率。 參考:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved