iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 17
1
tags: 2019鐵人賽 PHP 會員登入 PHP session 用法

前言

昨天跟大家介紹了 session 的一些概念,今天就用 session + CRUD 來製作一個簡單的會員登入系統。

這次開發一樣會設計一個簡單頁面來測試,但是切版的細節我就不介紹,把重點放在咱們的 session 上面。

PHP session 的使用方法

要使用 PHP session ,必須在操作之前以 session_start() 啟動頁面的 session 功能。要注意的是,每支檔案如果要使用 session 功能,都要在程式開始之前加上 session_start()

儲存並取得 session 資料

啟動 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 的儲存路徑

透過 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

刪除 session

  • 刪除指定 session
    unset($_SESSION['userName']);

  • 刪除全部 session
    session_unset();
    釋放當前記憶體中已經創建的所有 $_SESSION 變數,但不刪除session 檔案以及不釋放對應的 session ID

    session_destroy();
    刪除當前用戶對應的 session 檔案以及釋放 session ID,內存中的 $_SESSION 變數內容依然保留。

會員登入系統

資料表的建制

欄位設定如下

Create

我們一樣設計一個表格用來儲放我們的網路請求

<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>

接著跟前天的做法一樣,但是我們這次多了兩個步驟

  1. 要利用 session 把使用者資料儲存起來。
  2. 利用 password_hash() 將使用者輸入的 password 雜湊。
    ps:hash = 雜湊,是一個加密的方法。大家可以自己上網查查。
<?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');
}
?>

Read

我們來建立一個歡迎頁面,如果使用者成功登入就顯示 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

在 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 '密碼確認有誤';
        }
}

Delete

我這邊是用 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');
}

上一篇
Day 16 - 什麼是 Session?
下一篇
Day 18 - shell 是什麼?
系列文
新手後端工程師的學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言