麻辣家族討論版版's Archiver

小誌 發表於 2010-5-16 13:19

(PHP+IIS+MsSQL教學第19篇) 資料儲存與檔案管理 上篇

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

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

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


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


[color=Magenta][size=4][b]實做學習:[/b][/size][/color]
利用Session製作「個人」計數器:[code]<?
session_start();
if (! session_is_registered("mynum"))
  {
   session_register("mynum");
   $_SESSION["mynum"]=1;
  }
else
  {
   echo "之前人數: " . $_SESSION["mynum"] . "<br>";
   $_SESSION["mynum"]++;
  }
$num=$_SESSION["mynum"];
echo "現在人數:$num";
?>[/code]當第一次進入網頁時,網頁畫面如下圖:
[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函數[code]bool session_is_registered (string name)[/code]如果Session變數已經在Session陣列中註冊過了,則session_is_registered( )函數傳回True值,否則回傳False值。


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

[attach]446[/attach][code]<?
session_start();
if (!session_is_registered("chk") || $_SESSION["chk"]<>"yes")
{
$msg="";
if ($_REQUEST["userid"]<>"charles")
  {
    $msg="登入帳號錯誤";
  }
else if ($_REQUEST["pas"]<>"12345")
  {
    $msg="密碼輸入錯誤";
  }
else if ($_REQUEST["pas"]<>"12345" || $_REQUEST["userid"]<>"charles")
  {
    $msg="密碼輸入錯誤";
  }
else
  {
    $msg="驗證通過,請繼續動作";
    $_SESSION["chk"]="yes";
  }
}
else
{
$msg="已驗證通過,不用驗證了,請繼續動作";
}
?>

<HTML><HEAD>
<TITLE>管理員專區</TITLE>
</HEAD><BODY>
<Center><H2><?=$msg?></H2><HR>
</BODY>
</HTML>[/code]還有一件是要提醒您:「session_start()」函數的呼叫如同header()函數一般,只可用在尚未有任何資料輸出至瀏覽器之前才可呼叫,否則會出現如下圖的錯誤:
[attach]447[/attach]

小誌 發表於 2010-5-16 13:24

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

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


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

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



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

小誌 發表於 2010-5-16 13:32

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


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


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


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



[color=Green][b][size=4]使用Cookie[/size][/b][/color]
要將Cookie寫入使用者端的瀏覽器中,在PHP中是最簡單不過了,只要使用「setcookie()」函數並指定Cookie名稱跟Cookie資料值即可:[code]setcookie(“名稱”, ”資料值”);[/code]而讀取Cookie變數資料則讀取字串註標的COOKIE陣列,如下:[code]$X=$_COOKIE[“名稱”];[/code][color=Magenta][size=4][b]實做學習1:[/b][/size][/color]
證明Cookie物件是儲存在瀏覽連線者的瀏覽器之中與學習Cookie物件的資料存取。
撰寫一含有Cookie的網頁,如下所示:[code]<?
if (! isset($_COOKIE["mynum"]))
  {
   setcookie("mynum",1);
  }
else
  {
   echo "之前來過: " . $_COOKIE["mynum"] . "次<br>";
   $num=$_COOKIE["mynum"]+1;
   setcookie("mynum",$num);
  }
echo "目前次數:" . $_COOKIE["mynum"] . "次";
?>
[/code]執行後會產生卻會產生『Cannot modify header information』的錯誤,如下圖:『已將HTTP標題寫入用戶端瀏覽器』。
[attach]450[/attach]
原因為瀏覽器與伺服端交換 Cookie資料的時機需在伺服器尚未下載資料給瀏覽器之前就進行交換,否則會出現錯誤,解決方法為用緩衝區(Buffer)來裝下載的資料,完整程式如下所示:[code]<?
ob_start();
if (!isset($_COOKIE["mynum"]))
  {
   echo "這是您第1次來";
   setcookie("mynum",1);
  }
else
  {
   $num=$_COOKIE["mynum"];
   $num++;
   echo "這是您第 " . $num . "次來<br>";
   setcookie("mynum",$num);
  }
?>[/code]現在我們來檢驗一下:以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]


[color=Red]提示!![/color]瀏覽器的「快取記憶」只有在「執行瀏覽」時才會生效,若使用「開啟舊檔」的方式觀看網頁(檔案->開啟舊檔),則「快取記憶」是沒有作用的。

小誌 發表於 2010-5-16 13:35

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


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


[color=Red]提示!![/color]所有的Cookie檔案都有一個預設的網域與路徑,只有建立此Cookie的網域與路徑才能存取這個Cookie檔案。

小誌 發表於 2010-5-16 13:41

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


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


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


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



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

頁: [1]

麻辣家族討論版版為 麻辣學園 網站成員  由 昱得資訊工作室 © Since 1993 所提供