Board logo

標題: [教學] (PHP+IIS+MsSQL教學第19篇) 資料儲存與檔案管理 上篇 [打印本頁]

作者: 小誌    時間: 2010-5-16 13:19     標題: (PHP+IIS+MsSQL教學第19篇) 資料儲存與檔案管理 上篇

Session記錄物件
Session 物件為紀錄使用者的相關資訊,提供使用者再次對此網頁伺服器要求時作確認,例如使用者帳號與密碼的確認,有 Session 物件的建立,來保留身分認證的結果,則使用者不用於每一頁網頁登錄時都需輸入密碼作確認。

Session 物件是用來記錄『變數』值的, Session 物件是一對一的,對於所有的連線瀏覽者而言,都個別擁有一個『私用』的 Session 物件。

Session為一個陣列形式的記錄物件,在使用Session之前必須先初始它,也就是告知PHP我們要使用Session了:
Sessiont_start 初始函數
  1. bool session_start ( void)
複製代碼
接著,加入Session變數到陣列中成為陣列元素的註標,此字串陣列註標就是Session變數名:
Sessiont_register 註冊函數
  1. bool session_register (mixed name [, mixed ...])
複製代碼
完成Session的變數註冊後才能存取Session變數資料值,例如:
  1. <?
  2. session_register("myname"); //註冊Session變數
  3. $_SESSION["mynam"]="Charles"; //設定Session變數值
  4. echo $_SESSION["mynam"];  //輸出Session變數值
  5. ?>
複製代碼
在上例中,小誌並沒有使用「session_start()」函數告知PHP我們要使用Session陣列,為何能直接使用Session呢?原因在於PHP為我們預設了一個名為「PHPSESSID」的Session陣列了!不過千萬要小心!這麼做的話,在後續的程式敘述中將不能改變Session變數的值,除非您在變動Session變數值之前先行呼叫「session_start()」函數!


在實際應用時並不需要先使用「session_register()」函數先行Session變數註冊,在指定Session變數資料值時也就同時進行了Session變數註冊。


實做學習:
利用Session製作「個人」計數器:
  1. <?
  2. session_start();
  3. if (! session_is_registered("mynum"))
  4.   {
  5.    session_register("mynum");
  6.    $_SESSION["mynum"]=1;
  7.   }
  8. else
  9.   {
  10.    echo "之前人數: " . $_SESSION["mynum"] . "<br>";
  11.    $_SESSION["mynum"]++;
  12.   }
  13. $num=$_SESSION["mynum"];
  14. echo "現在人數:$num";
  15. ?>
複製代碼
當第一次進入網頁時,網頁畫面如下圖:
[attach]442[/attach]


當第一次進入網頁時:程式中的變數num變數值是由Session物件變數「mynum」提取而來,而Session物件變數「mynum」由於是剛建立的,所以我們將其變數值設為1,因此,變數num內的資料值是1。

當第二次進入網頁時:Session物件變數「mynum」已存在,所以可以先將其資料值印出來(之前人數),接著將mynum這個Session變數值加1再回存回去,並將其資料值指定給變數num變數且列印出來,因此網頁畫面如下圖:
[attach]443[/attach]


雖然在表面上看來,這個計數器是OK的,但是,Session 物件現在紀錄的變數資料只與目前瀏覽連線者有關,與其他的瀏覽連線者一點關係都沒有,也就是說目前所讀取的 Session 物件內容是讀取目前瀏覽連線者『私用』的 Session 物件,比較下圖兩瀏覽器畫面,不同瀏覽器執行之前範例,上網者只要按下瀏覽器上的『重新整理』按鈕後,您會發現計數器將會再次的自動加一,其值是不相干的,由此可證明:Session 物件紀錄的變數資料只與目前瀏覽連線者有關,與其他的瀏覽連線者一點關係都沒有。
[attach]444[/attach]


在上例中使用了一個「session_is_registered()」函數,用來判斷Session變數是否已經註冊:
Sessiont_is_registered函數
  1. bool session_is_registered (string name)
複製代碼
如果Session變數已經在Session陣列中註冊過了,則session_is_registered( )函數傳回True值,否則回傳False值。


實做學習:
利用Session製作「登入驗證」:
[attach]445[/attach]
  1. <HTML><HEAD>
  2. <TITLE>登入驗證</TITLE>
  3. </HEAD><BODY>
  4. <Center><H2>管理員登入</H2><HR>
  5. <form action="login_chk.php" method="Post">
  6. 帳號:<input type="Text" name="userid"><BR>
  7. 密碼:<input type="Password" name="pas"><BR>
  8. <input type="Submit">
  9. </form>
  10. </BODY>
  11. </HTML>
複製代碼
驗證方式很簡單,在login.php中輸入帳號與密碼,輸入的資料送交login_chk.php驗證,只要帳號密碼正確就可通過驗證,就出現「驗證通過,請繼續動作」訊息文字,否則就出現警告訊息,若已經驗證過,而再次連結login_chk.php,則出現「已驗證通過,不用驗證了,請繼續動作」訊息文字。

[attach]446[/attach]
  1. <?
  2. session_start();
  3. if (!session_is_registered("chk") || $_SESSION["chk"]<>"yes")
  4. {
  5. $msg="";
  6. if ($_REQUEST["userid"]<>"charles")
  7.   {
  8.     $msg="登入帳號錯誤";
  9.   }
  10. else if ($_REQUEST["pas"]<>"12345")
  11.   {
  12.     $msg="密碼輸入錯誤";
  13.   }
  14. else if ($_REQUEST["pas"]<>"12345" || $_REQUEST["userid"]<>"charles")
  15.   {
  16.     $msg="密碼輸入錯誤";
  17.   }
  18. else
  19.   {
  20.     $msg="驗證通過,請繼續動作";
  21.     $_SESSION["chk"]="yes";
  22.   }
  23. }
  24. else
  25. {
  26. $msg="已驗證通過,不用驗證了,請繼續動作";
  27. }
  28. ?>

  29. <HTML><HEAD>
  30. <TITLE>管理員專區</TITLE>
  31. </HEAD><BODY>
  32. <Center><H2><?=$msg?></H2><HR>
  33. </BODY>
  34. </HTML>
複製代碼
還有一件是要提醒您:「session_start()」函數的呼叫如同header()函數一般,只可用在尚未有任何資料輸出至瀏覽器之前才可呼叫,否則會出現如下圖的錯誤:
[attach]447[/attach]
作者: 小誌    時間: 2010-5-16 13:24

延長Session物件的生命
Session 物件的生命週期起始於瀏覽器第一次與伺服器連線時。終止於瀏覽器結束執行時或瀏覽器一段時間(預設為24分鐘)沒有向伺服器要求任何網頁時。

要延長Session物件的生命時間有兩種方式,第一種是透過「ini_set()函數」變更「session.gc_maxlifetime」屬性設定:
  1. ini_set("session.gc_maxlifetime","N");
複製代碼
上式中的N就是設定Session物件的存在時間,單位為秒。
另一種設定Session物件存在時間的方法是直接修改PHP.ini組態設定檔,此檔案的位置在「\windows\php.ini」,利用記事本打開此檔案,尋找「[Session]」組態設定區段,此區段為設定PHP的Session屬性,找到「session.gc_maxlifetime = 1440」敘述,將預設的Session存活時間1440秒改成您希望的時間即可,單位為「秒」:
[attach]448[/attach]


Session的存放位置
完蛋了啦!我剛剛用我的網際網路真實IP來看範例卻出現錯誤畫面了啦!
[attach]449[/attach]

別緊張!因為我們尚未建立存放Session物件檔的資料夾啦!預設的Session物件檔將會放置在磁碟根目錄下的「tmp」目錄下,您先檢查一下磁碟根目錄下有沒有「tmp」這個子目錄,若沒有,把這「tmp」子目錄建立出來就行了!



其他Session函數
session_unregistered():消滅一個已註冊的Session變數。
  1. bool session_unregister ( string name)
複製代碼
session_destroy():消滅全部已註冊的Session變數。
  1. bool session_destroy ( void)
複製代碼
session_save_path():取得或設定Session變數的存放路徑。
  1. string session_save_path ( [string path])
複製代碼
session_decode():從字串中解碼Session變數。
  1. bool session_decode ( string data)
複製代碼
session_encode():將Session變數資料編碼。
  1. string session_encode ( void)
複製代碼

作者: 小誌    時間: 2010-5-16 13:32

Cookie記錄物件
什麼是「Cookie」?Cookie就是吃的小餅乾ㄚ!不是啦!Cookie是網站(網頁)在使用者端(client),也就是您的硬碟中所儲存的一小段資訊!它可以記錄您瀏覽網站時的一些資訊,使網站變聰明,當您再度光臨網站時,或許您會發現網站竟然知道您是誰、叫什麼名字、住在哪裡…!現在,很多的網站都已經利用這種Cookie技術來記住訪客的瀏覽習慣。


Session物件將資訊記錄在Server端,而Cookie物件會藉由瀏覽器所提供之Cookie功能,將資訊記錄在客戶端,也就是說:Cookie 物件是儲存在瀏覽連線者的瀏覽器之中!


我們可用Cookies物件的紀錄來判斷某個使用者是否曾經進入本網站。奇怪!雖然Session物件將資訊記錄在Server端,但是它也會個別紀錄連線瀏覽者是否曾經進入本網站啊!但是Session 物件的生存期限是很短的,當瀏覽連線者的瀏覽器在設定時間內(預設為24分鐘)沒有向伺服器要求任何資料的話,伺服器就會將Session物件中的資料全數消除,而 Cookie物件是存在於瀏覽連線者的瀏覽器中的,即使是瀏覽者離線了,Cookie 物件的資料記錄依然存在!


提示!!
一個Cookie檔案能儲存近300個Cookies,而每個Cookies約可儲存4000個位元組的資料。



使用Cookie
要將Cookie寫入使用者端的瀏覽器中,在PHP中是最簡單不過了,只要使用「setcookie()」函數並指定Cookie名稱跟Cookie資料值即可:
  1. setcookie(“名稱”, ”資料值”);
複製代碼
而讀取Cookie變數資料則讀取字串註標的COOKIE陣列,如下:
  1. $X=$_COOKIE[“名稱”];
複製代碼
實做學習1:
證明Cookie物件是儲存在瀏覽連線者的瀏覽器之中與學習Cookie物件的資料存取。
撰寫一含有Cookie的網頁,如下所示:
  1. <?
  2. if (! isset($_COOKIE["mynum"]))
  3.   {
  4.    setcookie("mynum",1);
  5.   }
  6. else
  7.   {
  8.    echo "之前來過: " . $_COOKIE["mynum"] . "次<br>";
  9.    $num=$_COOKIE["mynum"]+1;
  10.    setcookie("mynum",$num);
  11.   }
  12. echo "目前次數:" . $_COOKIE["mynum"] . "次";
  13. ?>
複製代碼
執行後會產生卻會產生『Cannot modify header information』的錯誤,如下圖:『已將HTTP標題寫入用戶端瀏覽器』。
[attach]450[/attach]
原因為瀏覽器與伺服端交換 Cookie資料的時機需在伺服器尚未下載資料給瀏覽器之前就進行交換,否則會出現錯誤,解決方法為用緩衝區(Buffer)來裝下載的資料,完整程式如下所示:
  1. <?
  2. ob_start();
  3. if (!isset($_COOKIE["mynum"]))
  4.   {
  5.    echo "這是您第1次來";
  6.    setcookie("mynum",1);
  7.   }
  8. else
  9.   {
  10.    $num=$_COOKIE["mynum"];
  11.    $num++;
  12.    echo "這是您第 " . $num . "次來<br>";
  13.    setcookie("mynum",$num);
  14.   }
  15. ?>
複製代碼
現在我們來檢驗一下:以IE 6(Window XP)為例,建立在瀏覽器中的Cookies物件將會放置在『C:\Documents and Settings\XXX\ Local Settings\Temporary Internet Files』目錄中,我們先將目錄中的所有資料檔案清除乾淨。

接著啟動瀏覽器,開始瀏覽ex6_5.php,此時我們將會發現在『C:\Documents and Settings\XXX\Local Settings\Temporary Internet Files』目錄中的快取記憶中只有我們的程式網頁暫存檔,並沒有多出Cookies 的物件檔案!這是因為我們沒有設定Cookie物件的到期日,因此該Cookies物件並不會存在於瀏覽器中。
[attach]451[/attach]


提示!!瀏覽器的「快取記憶」只有在「執行瀏覽」時才會生效,若使用「開啟舊檔」的方式觀看網頁(檔案->開啟舊檔),則「快取記憶」是沒有作用的。
作者: 小誌    時間: 2010-5-16 13:35

設定Cookies物件的使用期限
若只指定Cookie物件名稱來寫入資料,而沒有在指定Cookies物件的有效期限,則Cookie物件將只存在於瀏覽器之中,當瀏覽器關閉後Cookie物件就消滅了。


Cookie物件的生命週期起始於瀏覽器被執行時。終止於瀏覽器結束執行時。那如果我們要延長Cookies 物件的生命週期呢?若要延長Cookie 物件的生命週期我們可另用『Expires』參數來設定Cookies的生命週期(Expires表失效),如下所示:
  1. setcookie(“名稱”, ”資料值”,”存活期限”);"
複製代碼
例如:使用time()函數取得時間戳記(自01/01/1970日起到目前的日期時間秒數)加上Cookie 物件的可存活秒數:
  1. //在10分鐘(600秒)後消滅
  2. setcookie("myname","charles",time()+600);
  3. //在3600秒後消滅
  4. setcookie("myname","charles",time()+3600);
複製代碼
要讓Cookie在特定的日期時間消滅,這時可改用mktime()函數來做,mktime()函數格式如下:
mktime() 函數格式
  1. int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]])
複製代碼
使用mktime()函數設定Cookie到期時間:
  1. //在2004年1月1日消滅
  2. setcookie("myname","charles",mktime(0,0,0,1,1,2004));
  3. //在2003年10月5日上午10點消滅
  4. setcookie("myname","charles",mktime(10,0,0,10,5,2003));
複製代碼
實做學習2:
延續實做學習1,為Cookies 物件建立使用期限,證明Cookies 物件確實是儲存在瀏覽連線者的瀏覽器之中。
ex6_6.php
  1. <?
  2. ob_start();
  3. if (!isset($_COOKIE["mynum"]))
  4.   {
  5.    echo "這是您第1次來";
  6.    $life = mktime(10,0,0,10,5,2003);
  7.    setcookie("mynum",1,$life);
  8.   }
  9. else
  10.   {
  11.    $num=$_COOKIE["mynum"];
  12.    $num++;
  13.    echo "這是您第 " . $num . "次來<br>";
  14.    $life = mktime(10,0,0,10,5,2003);
  15.    setcookie("mynum",$num,$life);
  16.   }
  17. ?>
複製代碼
啟動瀏覽器,開始瀏覽ex6_6.php,此時我們將會發現在『C:\Documents and Settings\XXX\ Local Settings\Temporary Internet Files』目錄中的快取記憶中不但有範例ex6_9的程式網頁暫存檔,同時還多出Cookie 的物件檔案!這次因為我們有設定Cookie物件的到期日為Cookie物件使用後到失效期限內內都有效,因此,該Cookie物件會以一個文字檔案的格式存在於瀏覽器中。
[attach]452[/attach]


提示!!所有的Cookie檔案都有一個預設的網域與路徑,只有建立此Cookie的網域與路徑才能存取這個Cookie檔案。
作者: 小誌    時間: 2010-5-16 13:41

瀏覽器的Cookies設定
當我們使用瀏覽器瀏覽網站,有時您會發現在瀏覽器狀態列中出現了一個奇怪的圖示:
[attach]454[/attach]


那是因為我們瀏覽的網頁使用了Cookies物件的存取,而我們所使用的隱私層級訂的太高了,無法使用Cookies的功能,當我們雙擊那怪怪的「Cookies功能限制」圖示,就會出現如下圖的「隱私權報告視窗」視窗:
[attach]455[/attach]


基本上,要讓Cookie發揮功能,隱私的權限等級必須設定在「中高」以下,所以要讓您撰寫的程式(含有Cookie的使用)正確運行,就必須開啟瀏覽器的Cookie功能。那要如何設定Cookie的隱私權限呢?
首先,點選瀏覽器「工具」功能項目中的「網際網路選項」:
[attach]456[/attach]


在「網際網路選項」視窗中選取『隱私』頁面標籤,在『隱私』頁面標籤中的「設定」區塊中,將隱私等級調整為中高以下即可:
[attach]457[/attach]



      提示!!
瀏覽器的隱私權限等級只與「網際網路」有關,與「內部網路」無關,因此,不管您如何的調整瀏覽器的隱私權限,只要您是瀏覽單機內網頁或區域網路內的網頁伺服器網頁,Cookies物件皆可正確使用。




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)