進階 WWW 程式設計 -- PHP Regular Expression 靜宜大學資訊管理學系 蔡奇偉副教授 2004 2018/11/28 進階 WWW 程式設計 在網頁間傳遞資訊 靜宜大學資訊管理學系 蔡奇偉副教授 2004 靜宜大學資管系 蔡奇偉編撰 版權所有 2003
內容大綱 前言 表單隱藏欄 URL 查詢字串 Cookies PHP Session-tracking
前言 WWW 採用的 HTTP 是一種「無記憶性」的通訊協定,換句話說,當 WWW 伺服器回傳客戶端所要求的網頁或檔案後,即切斷和客戶端間的連繫,也不保留連線時的任何狀態資料。這樣的作法可減輕 WWW 伺服器與網路線路的負擔,使得 WWW 系統能有較高的效率。 不過,如此的設計卻不適合某些需要記錄瀏覽行為的應用,譬如,購物網站需要記錄瀏覽者在不同網頁上所選購的商品,才能在最後的結帳網頁中計算出正確的購買金額。
在這一章中,我們探討底下四個克服 HTTP 無記憶性的技巧與其優缺點。 表單隱藏欄 URL 查詢字串 Cookies PHP Session-tracking
表單隱藏欄 我們可以用表單的隱藏欄(hidden field)把資料從一張表單網頁傳遞給下一張網頁。隱藏欄是用底下 HTML 的表單元件來指定: <input type="hidden" name=name_of_field value=value_of_field> 目前網頁 下一張網頁 取得或修改需要傳遞的資料,然後將資料擺入下一張網頁的表單隱藏欄中。 產生 隱藏欄
範例 <html> <head> http://bryce.cs.pu.edu.tw/course/AdvWebProg/examples/hidden01.php <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <title>Hidden Ex01</title> </head> <body> <form name="myform" method="post" action="hidden01.php"> <?php if (!isset($_POST["submit"])) { ?> <input type="hidden" name="currentValue" value="1"> 最初值:1 }
else { $newValue = $_POST['currentValue']+1; ?> <input type="hidden" name="currentValue" value=<?= $newValue?>> 目前值:<?= $newValue?> <?php } <input name="submit" type="submit" value=" 加一 "> </form> </body> </html>
<form name="myform" method="post" action="hidden01.php"> <input type="hidden" name="currentValue" value="1"> 最初值:1 <input name="submit" type="submit" value=" 加一 "> </form>
<form name="myform" method="post" action="hidden01.php"> <input type="hidden" name="currentValue" value=2> 目前值:2 <input name="submit" type="submit" value=" 加一 "> </form>
<form name="myform" method="post" action="hidden01.php"> <input type="hidden" name="currentValue" value=3> 目前值:3 <input name="submit" type="submit" value=" 加一 "> </form>
如果傳遞的資料不只一項,你可以用多個隱藏欄。譬如: <input type="hidden" name="lastName" value="Jordon"> <input type="hidden" name="firstName" value="Michael"> 然後在表單處理程式中透過變數 $_POST(或 $_GET)來取得各項的值。譬如:上面的隱藏欄使得 $_POST["lastName"] 和 $_POST["firstName"] 的值分別為 "Jordon" 和 "Michael"。 你也可以用特殊的格式把多項資料存在一個隱藏欄中。譬如: <input type="hidden" name=“name" value="Jordon:Michael"> 然後用字串裂解函式取出各項資料。譬如: list($firstName, $lastName) = explode(':', $_POST["name"]);
缺點 只能包裝在表單中,因此不適用於非表單類的網頁。 只能在連續的網頁中傳遞。 資料只能在同一瀏覽段(session)中傳遞,而無法保存得更長久。 註:在同一個瀏覽器視窗中,瀏覽某一個固定網站稱為一個瀏覽段(session)
URL 查詢字串 URL 網頁路徑之後的查詢字串(query string)是以字元 ? 開頭的一連串資料欄設定,欄與欄之間是以字元 & 隔開,每一資料欄的格式為「欄名=欄值」。譬如: http://books.pu.edu.tw/choose.php?book=1234&chap=3 其中的查詢字串包含 book=1234 和 chap=3 兩個資料欄。 我們可以在 URL 目標網頁中,用 PHP 的 $_GET 變數取得查詢字串中的資料值。譬如:在上述的 choose.php 中,$_GET["book"] 的值將是 1234 以及 $_GET["chap"] 的值將是 3。
Cookies cookies 是儲存在客戶端電腦上關於某張網頁或某個網站的資訊。適當地運用 cookies,我們可以在多張網頁間傳遞相關的資訊。譬如:購物網站可以把瀏覽者選購的商品存在 cookies 中,然後在結帳網頁讀取 cookies 來列出瀏覽者所有的採購項目。 我們可以用下一頁所述的 setcookie() 函式來設定 cookie 值,然後用變數 $_COOKIE 來讀取 cookie 值。 由於 cookie 是包裝在 HTTP 的表頭欄(header)中傳送,因此 cookie 的設定與讀取程式碼必須寫在 <html> 標籤之前。
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, int secure]]]]] ) 傳送一個 cookie 至客戶端。若成功則傳回值為 TRUE,否為則為 FALSE。以下是各參數的意義: name cookie 的名稱。 value cookie 的值。 expire cookie 的有效期限。採用 Unix timestamp 的格式,譬如:若設為算式 time()+60*60*24*30,則有效期限為 30 天。若不設定此參數,則瀏覽段結束後,cookie 即失效。
path 設定可讀取 cookie 的最上層目錄。 在預設的隱私性規則下,cookie 只能被設定網頁的目錄與其子目錄中的其他網頁所讀取。譬如:假定網頁 http://www.pu.edu.tw/csim/course/login.html 建立了一個 cookie,則此 cookie 可以被 http://www.pu.edu.tw/csim/course/mail.html 或 http://www.pu.edu.tw/csim/course/webprog/list.html 所讀取,但不能被 http://www.pu.edu.tw/csim/department/info.html 所讀取。換句話說,在這例子中,可讀取此 cookie 的最上層目錄為 /csim/course。 如果上述的規則不符合所需,我們可以設定 path 項目來變更可讀取的最上層目錄。以前述的例子而言,若設定 path=/csim,則網頁 http://www.pu.edu.tw/csim/department/info.html 就可以讀取此 cookie。若設定 path=/,則網站 http://www.pu.edu.tw 裏的所有網頁均可以讀取此 cookie。
domain secure 設定可讀取 cookie 的網域。 在預設的隱私性規則下,cookie 只能被設定網頁所在的站台讀取。設定 domain 可以改變這個限制。譬如:假定網頁 http://www.pu.edu.tw/csim/course/login.html 建立了一個 cookie,同時把 path 設為 / 以及把 domain 設為 pu.edu.tw,則所有在 pu.edu.tw 網域的 WWW 站台(如 register.pu.edu.tw)都可以讀取此 cookie。 secure 設定是否用加密的方式來傳輸 cookie。可代入 0 或 1 。 在預設的隱私性規則下,cookie 是用無加密的 HTTP 通訊協定在 WWW 伺服器和瀏覽器之間傳輸。加入 secure 這一設定項後,則 cookie 的傳輸會改用 HTTPS 或其他加密型的通訊協定。
範例 <?php $value = 'something from somewhere'; setcookie ("TestCookie", $value); setcookie ("TestCookie", $value,time()+3600); /* expire in 1 hour */ setcookie ("TestCookie", $value,time()+3600, "/~rasmus/", ".example.com", 1); ?>
範例 <form name="myform" method="post" action="setcookie.php"> 姓名: http://bryce.cs.pu.edu.tw/course/AdvWebProg/examples/cookie01.html <form name="myform" method="post" action="setcookie.php"> 姓名: <input name="name" type="text" id="name" size="10"> <input type="submit" name="Submit" value="送出"> </form>
setcookie("username", $_POST["name"]); setcookie("pgvisit", "0"); <?php setcookie("username", $_POST["name"]); setcookie("pgvisit", "0"); ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <title>Set Cookie</title> </head> <body> <p><?= $_POST[“name”] ?> 同學,cookies 已經設定完成,請跳至 <a href="showcookie.php">下一頁</a>來測試。</p> </body> </html>
$page_visit = $_COOKIE["pgvisit"]; <?php $page_visit = $_COOKIE["pgvisit"]; setcookie("pgvisit", ++$page_visit); ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <title>無標題文件</title> </head> <body> <p><?= $_COOKIE[“username"] ?> 同學,你已經拜訪本頁 <?= $page_visit ?> 次。</p> <p><a href="showcookie.php">再連結本頁</a></p> </body> </html>
優點 缺點 可以設定比較長的有效期限,使得資料傳遞不侷限在同一個瀏覽段內。 瀏覽器通常對 cookie 的數量和容量有所限制,譬如:Netscape 4.x 最多只儲存 300 個 cookies,每個站台最多只能設定 20 個 cookies,每個 cookie 的長度不得超過 4 KB。 此外,某些瀏覽器並不具有 cookie 的機制。就算是瀏覽器有 cookie 的功能,使用者為了安全上的考量仍可以關閉 cookie 功能,而造成你的 cookie 網頁執行失敗。
PHP Session-tracking PHP 提供一些瀏覽段資料追蹤(session-tracking)的函式,用來儲存一些讓多張網頁共用的變數。這個技術可以讓你容易地製作出多網頁的表單設計(如購物車)、在多張網頁中檢驗使用者的驗証資訊、或儲存瀏覽者的使用偏好設定、…、等等。 使用這項技術時,第一次拜訪網站的瀏覽者會被分配一個瀏覽段識別碼(session ID)。這個識別碼通常會以 cookie 的方式存在客戶端(名稱為 PHPSESSID)。若瀏覽器不支援或關閉 cookie 功能,則識別碼自動改以 URL 查詢字串的格式在網頁間傳遞。 每一個瀏覽段在伺服器中會被指定一個資料區(data store)。你可以把網頁共用的變數以註冊的方式存入資料區。
要在一張網頁中啟動瀏覽段追蹤的功能,你必須在網頁開頭的地方呼叫 session_start() 函式。譬如: <?php session_start() ?> <html> … </html> session_start() 會指定一個瀏覽段識別碼(若它尚不存在),然後載入資料區中的共用變數。 函式 session_register() 用來註冊瀏覽段變數(session variable)的名稱。譬如: <?php session_start(); session_register(“pgvisit”); ++$pgvisit; ?>
瀏覽段變數會被 session_start() 函式載入對照陣列 $_SESSION。你可以用瀏覽段變數的名稱從這個對照陣列中取出變數值。譬如: $_SESSION[“pgvisit”]。 函式 session_unregister() 用來刪除瀏覽段變數。譬如: session_unregister(“pgvisit”); 函式 sesseion_destroy() 用來終止目前的瀏覽段,它會清除資料區中的所有瀏覽段變數,但不會移除客戶端的瀏覽段識別碼 cookie。
範例 <form name="myform" method="post" action="setsession.php"> http://bryce.cs.pu.edu.tw/course/AdvWebProg/examples/session01.html <form name="myform" method="post" action="setsession.php"> 姓名: <input name="name" type="text" id="name" size="10"> <input type="submit" name="Submit" value="送出"> </form>
session_register("username"); session_register("pgvisit"); <?php session_start(); session_register("username"); session_register("pgvisit"); $username = $_POST["name"]; $pgvisit = 0; ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <title>Set Cookie</title> </head> <body> <p><?= $username ?> 同學,cookies 已經設定完成,請跳至 <a href="showsession.php">下一頁</a>來測試。</p> </body> </html>
session_start(); $_SESSION[“pgvist"]++; <?php ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <title>無標題文件</title> </head> <body> <p><?= $_SESSION[“username”] ?> 同學,你已經拜訪本頁 <?= $_SESSION[“pgvist"]?> 次。</p> <p><a href="showsession.php">再連結本頁</a></p> </body> </html>