2019鐵人賽
PHP
會員登入
PHP session 用法
昨天跟大家介紹了 session 的一些概念,今天就用 session + CRUD 來製作一個簡單的會員登入系統。
這次開發一樣會設計一個簡單頁面來測試,但是切版的細節我就不介紹,把重點放在咱們的 session 上面。
要使用 PHP session ,必須在操作之前以 session_start()
啟動頁面的 session 功能。要注意的是,每支檔案如果要使用 session 功能,都要在程式開始之前加上 session_start()
啟動 session 後,我們就可以透過 $_SESSION
這個變數去存取,而$_SESSION
本身是一個 array 格式,所以存取方式也就比照 array。
<?php
session_start();
$_SESSION['userName'] = "Kao";
echo $_SESSION['userName'];
接著我們把程式改成
<?php
session_start();
//$_SESSION['userName'] = "Kao";
echo $_SESSION['userName'];
結果還是得到一樣的結果,事實證明,伺服器已經把 session 儲存下來
透過 session_save_path()
可以指定 session 的儲存路徑,如果為空,則自動依照 php.ini 設定檔中設定的路徑儲存。
設定方法如下
<?php
session_save_path('/tmp');
session_start();
?>
請注意,如果要自定義儲存路徑,一定要寫在session_start()
之前,否則 session_start()
會只會讀取 php.ini 設定檔的設定。
現在我們在原程式上面加上兩行
<?php
session_start();
//$_SESSION['userName'] = "Kao";
echo $_SESSION['userName'];
echo '</br>';
echo session_save_path();
結果如下
接著我們進到那個資料夾,果然找到一個名為 sess_ 開頭的檔案,這個檔案就是我們的 session
刪除指定 sessionunset($_SESSION['userName']);
刪除全部 sessionsession_unset();
釋放當前記憶體中已經創建的所有 $_SESSION 變數,但不刪除session 檔案以及不釋放對應的 session ID
session_destroy();
刪除當前用戶對應的 session 檔案以及釋放 session ID,內存中的 $_SESSION 變數內容依然保留。
欄位設定如下
我們一樣設計一個表格用來儲放我們的網路請求
<form id="update" name="update" method="post" action="">
<table width="300" border="0" align="center" cellpadding="5" cellspacing="0" bgcolor="#F2F2F2">
<tr>
<div class="content">
<td colspan="2" align="center" bgcolor="#CCCCCC"><font color="#000000">會員資料</font></td>
</tr>
<tr>
<td width="80" align="center" valign="baseline">帳號</td>
<td valign="baseline">
<input type="text" name="username" id="username" value=""></td>
</tr>
<tr>
<td width="80" align="center" valign="baseline">密碼</td>
<td valign="baseline">
<input type="text" name="password" id="password" value=""></td>
</tr>
<tr>
<td width="80" align="center" valign="baseline">名字</td>
<td valign="baseline">
<input type="name" name="name" id="name" value=""></td>
</tr>
<tr>
<td width="80" align="center" valign="baseline">電話</td>
<td valign="baseline">
<input type="phone" name="phone" id="phone"></td>
</tr>
<tr>
<td colspan="2" align="center" bgcolor="#CCCCCC">
<input type="hidden" name="action" value="store">
<input type="submit" name="button" id="button" value="註冊"></td>
<!-- <input type="reset" name="button2" id="button2" value="重設" ></td>-->
</tr>
</table>
</form>
接著跟前天的做法一樣,但是我們這次多了兩個步驟
password_hash()
將使用者輸入的 password 雜湊。<?php
if (! (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['name']) || empty($_POST['phone']))) {
include('connectMySQL.php');
$username = $_POST['username'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$name = $_POST['name'];
$phone = $_POST['phone'];
$sql_query = "INSERT INTO nativeUsers (username, password, name, phone) VALUES ('$username', '$password', '$name', '$phone')";
mysqli_query($db_link, $sql_query);
$sql_findID = "SELECT * FROM nativeUsers WHERE username = '".$_POST['username']."'";
$data = mysqli_query($db_link, $sql_findID);
$user = mysqli_fetch_assoc($data);
session_start();
$_SESSION['id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['password'] = $user['password'];
$_SESSION['name'] = $user['name'];
$_SESSION['phone'] = $user['phone'];
header('Location: welcome.php');
}
?>
我們來建立一個歡迎頁面,如果使用者成功登入就顯示 Hello, username!
進入這個頁面之前,我們可以先檢查看看 $_SESSION['userName']
是否存在,若不存在表是使用者還沒登入,直接跳轉回首頁
if(! isset($_SESSION['name'])) {
header('Location: index.php');
}
若存在,就顯示 Hello, userName
<div class="title m-b-md">
Hello, <?php echo $_SESSION['name'] ?>
</div>
效果如下
在 update 的時候,我嘗試讓使用者一併變更密碼,變更密碼除了要輸入舊密碼、新密碼,還要對新密碼做 double check,所以在請求驗證上面就要多花點心思。像是資料不可為空,密碼是否正確。
PS:這邊我先沒考慮資料格式是否正確,例如電話如果輸入英文、國字也不會報錯,這在實作上當然不允許,但是這會延伸另外一個問題 - "正規表示法式",有興趣的可以先去找找。我再看看後面有沒有機會來補充。
if (isset($_POST['currentPassword']) && $_POST['currentPassword'] != "" && password_verify($_POST['currentPassword'] ,$_SESSION['password'])) {
if ($_POST['newPassword'] == $_POST['confirmPassword'] && $_POST['newPassword'] != "") {
require('connectMySQL.php');
$hash_password = password_hash($_POST['newPassword'], PASSWORD_DEFAULT);
$query = "UPDATE nativeUsers SET name = '" . $_POST['name'] . "' ,password = '" . $hash_password . "' ,phone = '" . $_POST['phone'] . "' WHERE id = " . $_SESSION['id'];
$result = mysqli_query($db_link, $query);
$_SESSION['password'] = password_hash($_POST['newPassword'], PASSWORD_DEFAULT);
unset($_POST['currentPassword']);
header('Location: welcome.php');
} else {
echo '密碼確認有誤';
}
}
我這邊是用 form 把請求送出
<form name="delete" method="post" action="">
<input type="hidden" name="delete" value="">
<input type="submit" name="delete" style="width:120px;font-size:20px;" value="刪除帳號">
</form>
確認請求是 delete 之後,除了刪除資料,也要記得刪除 session
if(isset($_POST['delete'])) {
require ('connectMySQL.php');
$deleteQuery = "DELETE FROM nativeUsers WHERE id = ".$_SESSION['id'];
mysqli_query($db_link, $deleteQuery);
session_destroy();
header('refresh:0;url=index.php');
}