0%

  1. 為了做到登入時讓不同的管理者帳號有不同的權限限制,我們先在 back.php 中根據登入的管理者session資料來取得管理員的權限資料。
    back.php

    1
    2
    $admin=$Admin->find(['acc'=>$_SESSION['admin']]);
    $pr=unserialize($admin['pr']);
  2. back.php 的選單中撰寫依據權限來決定是否顯示功能的程式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <div style="min-height:400px;">
    <a href="?do=admin">管理權限設置</a>
    <?php
    echo in_array(1,$pr)?"<a href='?do=th'>商品分類與管理</a>":"";
    echo in_array(2,$pr)?"<a href='?do=order'>訂單管理</a>":"";
    echo in_array(3,$pr)?"<a href='?do=mem'>會員管理</a>":"";
    echo in_array(4,$pr)?"<a href='?do=bot'>頁尾版權管理</a>":"";
    echo in_array(5,$pr)?"<a href='?do=news'>最新消息管理</a>":"";
    ?>
    <a href="./api/logout.php?do=admin" style="color:#f00;">登出</a>
    </div>

  1. ./back/ 目錄中建立 add_admin.php 檔案,並建立新增管理帳號的頁面及表單
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <h2 class="ct">新增管理帳號</h2>
    <!--使用form表單來新增資料-->
    <!-- form:post>table.all>tr*3>td.tt.ct+td.pp>input:text -->
    <form action="./api/save_admin.php" method="post">
    <table class="all">
    <tr>
    <td class="tt ct">帳號</td>
    <td class="pp"><input type="text" name="acc" id="acc"></td>
    </tr>
    <tr>
    <td class="tt ct">密碼</td>
    <td class="pp"><input type="password" name="pw" id="pw"></td>
    </tr>
    <tr>
    <td class="tt ct">權限</td>
    <td class="pp">
    <!--使用陣列來儲存權限資料-->
    <input type="checkbox" name="pr[]" value="1">商品分類與管理<br>
    <input type="checkbox" name="pr[]" value="2">訂單管理<br>
    <input type="checkbox" name="pr[]" value="3">會員管理<br>
    <input type="checkbox" name="pr[]" value="4">頁尾版權區管理<br>
    <input type="checkbox" name="pr[]" value="5">最新消息管理<br>
    </td>
    </tr>
    </table>
    <div class="ct">
    <input type="submit" value="新增">
    <input type="reset" value="重置">
    </div>
    </form>

  1. ./api/ 目錄中建立 save_admin.php 檔案,並撰寫新增/更新管理帳號的程式碼
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    include_once "db.php";

    //使用序列化來儲存權限資料
    $_POST['pr']=serialize($_POST['pr']);

    //將表單資料儲存至資料表中
    $Admin->save($_POST);

    //導回後台管理頁面
    to("../back.php?do=admin");
  2. 複製一份 ./back/add_admin.php 並改名為 edit_admin.php ,然後根據 $_GET['id'] 的值來取出資料
  3. 要記得在 edit_admin.php 中增加一個隱藏欄位把資料的 id 值帶入
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    //取出單筆管理員資料
    $rows=$Admin->find($_GET['id']);

    //使用unserialize來將序列化的權限資料轉回陣列
    $row['pr']=unserialize($row['pr']);
    ?>
    <h2 class="ct">修改管理員權限</h2>
    <!--使用form表單來修改資料-->
    <form action="./api/save_admin.php" method="post">
    <table class="all">
    <tr>
    <td class="tt ct">帳號</td>
    <td class="pp"><input type="text" name="acc" value="<?=$row['acc'];?>"></td>
    </tr>
    <tr>
    <td class="tt ct">密碼</td>
    <td class="pp"><input type="password" name="pw" value="<?=$row['pw'];?>"></td>
    </tr>
    <tr>
    <td class="tt ct">權限</td>
    <td class="pp">
    <!--檢查資料權限,並勾選已獲得的權限-->
    <input type="checkbox" name="pr[]" value="1" <?=(in_array(1,$row['pr']))?'checked':'';?>>商品分類與管理<br>
    <input type="checkbox" name="pr[]" value="2" <?=(in_array(2,$row['pr']))?'checked':'';?>>訂單管理<br>
    <input type="checkbox" name="pr[]" value="3" <?=(in_array(3,$row['pr']))?'checked':'';?>>會員管理<br>
    <input type="checkbox" name="pr[]" value="4" <?=(in_array(4,$row['pr']))?'checked':'';?>>頁尾版權區管理<br>
    <input type="checkbox" name="pr[]" value="5" <?=(in_array(5,$row['pr']))?'checked':'';?>>最新消息管理<br>
    </td>
    </tr>
    </table>
    <div class="ct">
    <!--使用隱藏欄位來傳送資料id-->
    <input type="hidden" name="id" value="<?=$row['id'];?>">
    <input type="submit" value="修改">
    <input type="reset" value="重置">
    </div>
    </form>

管理登入功能和會員登入功能幾乎一樣,差別在於管理登入的資料表中有一個權限的欄位我們採用序列化的字串來儲存。

  1. ./front/login.php 中的程式碼複製一份到 ./front/admin.php,並調整內容以符合題目要求。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <h2>管理員登入</h2>
    <!-- table.all>tr*3>td.tt.ct+td.pp>input:text -->
    <table class="all">
    <tr>
    <td class="tt">帳號</td>
    <td class="pp"><input type="text" name="acc" id="acc"></td>
    </tr>
    <tr>
    <td class="tt">密碼</td>
    <td class="pp"><input type="password" name="pw" id="pw"></td>
    </tr>
    <tr>
    <td class="tt">驗證碼</td>
    <td class="pp">
    <?php
    $a=rand(10,99);
    $b=rand(10,99);
    $_SESSION['ans']=$a+$b;
    echo $a . " + " .$b . " =";
    ?>
    <input type="text" name="ans" id="ans"></td>
    </tr>
    </table>
    <div class="ct">
    <button onclick="login('admin')">確認</button>
    </div>
  2. 由於函式login()已經寫在 ./front/login.php 中了,因此只要複製過來改一下參數就可以了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //建立登入函式,並傳入table參數
    function login(table){
    //使用ajax呼叫api/chk_ans.php,並傳入ans參數
    $.get('./api/chk_ans.php',{ans:$("#ans").val()},(chk)=>{
    //判斷回傳值是否為0
    if(parseInt(chk)==0){
    //回傳值為0,顯示警告訊息
    alert("驗證碼錯誤,請重新輸入")
    }else{
    //回傳值不為0,使用ajax呼叫api/chk_pw.php,並傳入table、acc、pw參數
    $.post("./api/chk_pw.php",
    {table,
    acc:$("#acc").val(),
    pw:$("#pw").val()},
    (res)=>{
    //判斷回傳值是否為0
    if(parseInt(res)==0){
    //回傳值為0,顯示警告訊息
    alert("帳號或密碼錯誤,請重新輸入")
    }else{
    //回傳值不為0,導向後台管理頁面
    location.href='back.php';
    }
    })
    }
    })
    }

補充

如果要測試管理者帳號的話,可以先手動在資料表中塞一筆資料,而權限的字串我們可以先做一個測試用的php來產生這個序列化的字串,並寫入到資料表中

1
2
3
4
5
6
7
//手動產生一筆管理者資料進db
$admin["admin"]="admin";
$admin["pw"]="1234";
$admin["pr"]=serialize([1,2,3,4,5]);

$Admin->save($admin);

  1. login.php 中建立驗證碼程式,這裏我們採session的方式來建立驗證碼,將答案存在session中,然後登入時先使用ajax去確認答案是否正確,如果正確則繼續下一步,如果錯誤則出現錯誤提示
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <tr>
    <td class="tt ct">驗證碼</td>
    <td class="pp">
    <?php
    //使用亂數取得兩個變數
    $a=rand(10,99);
    $b=rand(10,99);
    //將答案存入session
    $_SESSION['ans']=$a+$b;
    //顯示驗證碼字串在頁面上
    echo "{$a} + {$b} = ";
    ?>
    <input type="text" name="ans" id="ans"></td>
    </tr>

  1. ./api/ 目錄中建立 chk_ans.php 檔案,並撰寫檢查驗證碼的功能

    1
    2
    3
    session_start();

    echo ($_SESSION['ans']==$_GET['ans'])?1:0;
  2. ./js/js.js 中建立檢查驗證碼的js程式碼,在外部js檔中建立這支函式,並增加帶入資料表物件名稱的參數,這會讓這支函式同時也可以適用於管理登入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //建立登入函式,並傳入table參數
    function login(table){
    //使用ajax呼叫api/chk_ans.php,並傳入ans參數
    $.get('./api/chk_ans.php',{ans:$("#ans").val()},(chk)=>{
    //判斷回傳值是否為0
    if(parseInt(chk)==0){
    //回傳值為0,顯示警告訊息
    alert("驗證碼錯誤,請重新輸入")
    }else{
    //回傳值不為0,使用ajax呼叫api/chk_pw.php,並傳入table、acc、pw參數
    $.post("./api/chk_pw.php",
    {table,
    acc:$("#acc").val(),
    pw:$("#pw").val()},
    (res)=>{
    //判斷回傳值是否為0
    if(parseInt(res)==0){
    //回傳值為0,顯示警告訊息
    alert("帳號或密碼錯誤,請重新輸入")
    }else{
    //回傳值不為0,導向首頁
    location.href='index.php';
    }
    })
    }
    })
    }
  3. ./api/ 目錄中建立 chk_pw.php 檔案,利用可變變數的方式來建立對應的資料表物件,這讓這支程式可以同時被會員登入和管理登入使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    include_once 'db.php';
    //取得table參數
    $table=$_POST['table'];
    //移除$_POST表單資料中的table參數
    unset($_POST['table']);
    //建立DB物件,並傳入table參數
    $db=new DB($table);
    //呼叫DB物件的count方法,並傳入$_POST表單資料
    $chk=$db->count($_POST);
    //判斷回傳值是否為1
    if($chk){
    //回傳值為1,將acc欄位的值寫入$_SESSION[$table]變數
    echo $chk;
    $_SESSION[$table]=$_POST['acc'];
    }else{
    //回傳值不為1,顯示0
    echo $chk;
    }

項目三提到的內容大多都是後面的功能有做完就會有的,但反過來說,如果後面的相關功能沒完成的話,這邊會再多扣五分,而題組四中有些功能是和資料庫無關的,因此我們會先在這步驟把這些相較之下可以快速完成的功能先做完。

閱讀全文 »