Session
Session
2019/10/20 (增補內容)
簡介
上週我們學到利用query string及$_GET來傳資料。
login.php
<?php
$message = isset($_GET["msg"])? "帳號密碼錯誤</br>" : "";
?>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form action="login_process.php" method="post">
<?=$message?>
帳號: <input type="text" name="account"><br>
密碼: <input type="password" name="password"><br>
<input type="submit" value="登入">
</form>
</body>
</html>
我們在login_process.php利用query string把
<?php
if ($_POST["account"] == "root" && $_POST["password"] == "password" ) {
header("Location: success.php?account=root");
}
else {
header("Location: login.php?msg=error");
}
?>
success.php
<?php
echo "welcome, ".$_GET["account"]."!<p>";
echo "<a href='login.php'>login.php</a>"
?>
不過,這會有一個問題: 萬一success.php一定要被驗證過,那我們要如何處理? 第一個想到的解決方法是在success.php加入檢查機制:
<?php
if (isset($_GET["account"])){
echo "welcome, ".$_GET["account"]."!<p>";
echo "<a href='login.php'>login.php</a>";
}
else {
header("Location: login.php");
}
?>
可是,萬一要是被發現是利用?account=root,使用者是可以在瀏覽器直接打:
http://localhost/web/success.php?account=root
就會發生沒有通過登入也可以進入系統的問題了!! 那怎麼辦呢?!
Session
- 當我們登入系統之後,系統記得我們是誰,主要就是靠session。sessions所儲存的就是個人化的資料內容,例如,帳號。session所儲存的內容會一直保留到瀏覽器關閉為止。session的內容是個人化的,不同人登入會使用不同的session。
- PHP 7 Sessions
我們來試試看,改寫原本的登入頁面,當登入成功之後,就利用$_SESSION["account"]記住帳號。這樣做還有另一個好處,在其他頁面也可以取得session的資料。
login_process.php
<?php
if ($_POST["account"] == "root" && $_POST["password"] == "password" ) {
session_start();
$_SESSION["account"] = $_POST["account"];
header("Location: success.php");
}
else {
header("Location: login.php?msg=error");
}
?>
如果我們希望如果沒有透過登入就無法進入這個頁面,那就要多一些檢查
success.php
<?php
session_start();
if (isset($_SESSION["account"])){
echo "welcome, ".$_SESSION["account"]."!<p>";
echo "<a href='login.php'>login.php</a><p>";
echo "<a href='success2.php'>success2.php</a>";
}
else {
header("Location: login.php");
}
?>
這樣還有另一個好處,就是其他頁面也可以取得session的內容。
success2.php
<?php
session_start();
if (isset($_SESSION["account"])){
echo "welcome, ".$_SESSION["account"]."!<p>";
echo "<a href='login.php'>login.php</a><p>";
echo "<a href='success.php'>success.php</a>";
}
else {
header("Location: login.php");
}
?>
萬一使用者把頁面關了,下個使用者可以直接打網址也就可以不用登入就直接進入系統,所以,一定還要加個登出的頁面:
logout.php
<?php
session_start();
unset($_SESSION["account"]);
header("Location: login.php");
?>
也可以使用session_unset()或session_destroy() (詳參: 基於session_unset與session_destroy的區別詳解)
logout.php
<?php
session_start();
session_destroy();
header("Location: login.php");
?>
修改一下success.php
<?php
session_start();
if ($_SESSION["account"]){
echo "welcome!".$_SESSION["account"]."<p>";
echo "<a href='logout.php'>Logout</a><p>";
echo "<a href='login.php'>login.php</a>";
echo "<a href='success2.php'>success2.php</a>";
}
else {
header("Location: login.php");
}
?>
session是屬於個人的,可以試著去連別人的程式,就會發現,不同人執行同一個程式,互相是不會干擾的。
該如何找到我電腦的IP位址 (Windows XP, Vista, 7, 8,10, Mac)?
- For Windows 10
- 方式1
- 步驟1:按Windows鍵+R,然後會出現執行框,輸入控制台(control panel)並按Enter鍵。
- 步驟2:點選網路和網際網路(若沒找到可跳過此項)>網路和共用中心>變更介面卡設定。
- 步驟3:右鍵點選您的區域連線(乙太網路)圖示狀態,選取詳細資料您將會看到電腦的IP位址。
- 方式2
- 步驟1:右鍵點選螢幕右下角電腦圖示的開啟網路和網際網路設定。
- 步驟2:點選乙太網路,並選取畫面右側的變更介面卡選項。
- 步驟3:右鍵點選您的區域連線(乙太網路)圖示狀態,選取詳細資料您將會看到電腦的IP位址。
儲存form的輸入值
可以利用session將$_POST內容(從register.php傳過來的內容)儲存起來:
register_process.php
<?php
session_start();
$_SESSION["post"] = $_POST ?? [];
?>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<a href="register_clear.php">重新填寫</a><br>
<a href="register.php">修改</a>
</body>
</html>
回到register.php就可以將內容取出,為避免第一次進入時的錯誤訊息,加了一些檢查邏輯。radio的做法比較複雜一點,不是單純的把值放進去,而是要判斷何時要有"checked"。
<?php
session_start();
$postData = $_SESSION["post"] ?? [];
$name = $postData["name"] ?? "";
$email = $postData["email"] ?? "";
$website = $postData["website"] ?? "";
$comment = $postData["comment"] ?? "";
$gender = $postData["gender"] ?? "";
$maleChecked = ($gender=="male")?"checked":"";
$femaleChecked = ($gender=="female")?"checked":"";
$otherChecked = ($gender=="other")?"checked":"";
?>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form action="register_process.php" method="post">
Name: <input type="text" name="name" value="<?= $name?>"><br>
E-mail: <input type="text" name="email" value="<?= $email?>"><br><br>
Website: <input type="text" name="website" value="<?= $website?>"><br>
Comment: <textarea name="comment" rows="5" cols="40"><?= $comment?></textarea><br>
Gender:
<input type="radio" name="gender" <?=$femaleChecked?> value="female">Female
<input type="radio" name="gender" <?=$maleChecked?> value="male">Male
<input type="radio" name="gender" <?=$otherChecked?> value="other">Other
<br>
<input type="submit" value="送出">
</form>
</body>
</html>
清除內容
<?php
session_start();
unset($_SESSION["post"]);
header("Location: register.php");
?>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<a href="register.php">重新輸入</a>
</body>
</html>
** 作業 **
- 更改第三週的作業,利用session暫存使用者的姓名,而不是使用URL及$_GET傳變數,也請確保沒有登入成功是無法進入下一頁,也加一個登出的功能。
- 讓使用者可以回頭修改是否要繳會費以及想參加的活動,要利用session記住使用者所輸入的內容,並且要正確的顯示在介面上。 (挑戰題)
$_GET、$_POST、$_SESSION的比較
在php裡,不同的php頁面跟頁面之間的變數是無法共用的,所以,必須要靠$_GET、$_POST或$_SESSION。
$_GET跟$_POST主要是利用HTTP GET及HTTP POST傳遞變數。
HTTP POST一般而言是透過HTML form,傳送資料,HTTP GET可以利用url query string也可以利用HTML form。
$_GET
http://localhost/welcome_get.php?name=ben&email=benwu@im.fju.edu.tw
在welcome_get.php裡,利用$_GET取得資料。
<html>
<body>
Welcome <?php echo $_GET["name"]; ?><br>
Your email address is: <?php echo $_GET["email"]; ?>
</body>
</html>
當我們使用html form的時候,當method設定為get,或沒有寫method時,就是將form的內容透過HTTP GET送到welcome_get.php,雖然一般不會這麼用,但萬一忘了寫method時,就會被預設為GET了。
welcome_get.html
<html>
<body>
<form action="welcome_get.php" method="get">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>
或者,沒有指定method。
<html>
<body>
<form action="welcome_get.php">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>
在welcome_get.php裡,利用$_GET取得資料。
<html>
<body>
Welcome <?php echo $_GET["name"]; ?><br>
Your email address is: <?php echo $_GET["email"]; ?>
</body>
</html>
$_POST
如果是使用post
welcome_post.html
<html>
<body>
<form action="welcome_post.php" method="post">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
</body>
</html>
在welcome_post.php裡,利用$_POST取得資料。
<html>
<body>
Welcome <?php echo $_POST["name"]; ?><br>
Your email address is: <?php echo $_POST["email"]; ?>
</body>
</html>
$_SESSION
$_SESSION的運作原理跟HTTP GET及HTTP POST是完全不同的,HTTP GET及HTTP POST是從資料把browser端送到server端,但是,$_SESSION則一直是儲存在server端,另一個差別是,$_GET及$_POST只在接收頁有效,到下一頁就無效了。但是$_SESSION只要被設定了,除非是時間到了或者是被清除了,否則就一直可以取得 (詳參: PHP 7 Sessions)。
設定$_SESSION變數
session_start();
$_SESSION["account"] = $_POST["account"];
取得$_SESSION變數
session_start();
$account = $_SESSION["account"];
清除特定session內容:
session_start();
unset($_SESSION["account"]);
清除session內所有的內容:
// remove all session variables
session_unset();
刪除整個session:
// destroy the session
session_destroy();