本篇為網乙解析系列之題組四,難度算是次高的,資料處理觀念要熟悉且欄位很多而對應處理要準確。本篇之前置作業 (lib.php 與 MySQL 規劃)不再進行說明。
No.3 前台首頁標題 (35%)
修正指定之網頁有效連結
選單的有效連結
大部分的選單都已有預設值,我們不特別修改。只需調整首頁連結,以及 URL 轉換能有效執行便可
修改 index.php
調整主區域,找到
改為
index.php<div id="right"> <?php include $main.".php";?> </div>
|
在頁首加入
index.php<?php include "lib.php"; $main = (empty($_GET['do'])) ? "main" : $_GET['do']; ?>
|
另外 do=admin 會直接嵌入後台,所以也要改
index.php<a href="?do=admin">管理登入</a>
|
改為
index.php<a href="admin.php">管理登入</a>
|
購物流程的圖片顯示
這部分很容易遺忘掉,其他的選單都在之後的題目動作會完成。所以這裡記得先做掉。
建立 look.php
No.4 前台商品分類 (25%)
偷取 admin 的選單作為前台選單。
先規劃前台選單
- 偷取 admin 的選單作為前台選單。並透過 SQL 去產生對應的選單標題與連結。
- 先找 fa 再找 son。同時先把 son 隱藏起來(顏色可改一下)。
- 之後再透過 JQ 去控制是否顯示。同時全部商品同為首頁,所以不帶參數。
修改 index.php
index.php<div style="min-height:400px;"> </div>
|
改為
index.php<div style="min-height:400px;"> <?php $num = count(select("q4t5_product", 1)); echo '<a href="index.php">全部商品 (' . $num . ')</a>'; $re = select("q4t4_class", "parent=0"); foreach ($re as $ro) { $num = count(select("q4t5_product", "fa=" . $ro['id'])); echo '<a onmouseover="show(' . $ro['id'] . ')" href="?do=main&fa=' . $ro['id'] . '">' . $ro['title'] . '(' . $num . ')</a>';
$re2 = select("q4t4_class", "parent=" . $ro['id']); foreach ($re2 as $ro2) { $num = count(select("q4t5_product", "son=" . $ro2['id'])); echo '<a class="son fa' . $ro['id'] . '" href="?do=main&fa=' . $ro['id'] . '&son=' . $ro2['id'] . '" style="background: #fce2c4">' . $ro2['title'] . '(' . $num . ')</a>'; } } ?> </div>
|
注意這裡會先安排一些 class 方便之後控制,並在每個 father 上面規劃 onmouseover=show(id);
子選單滑入顯示
第四題版型沒有提供 JQ,故去偷第三題的 JQ 來用,除了複製該路徑檔案,在 head 標籤內插入以下行
修改 index.php
index.php<script src="scripts/jquery-1.9.1.min.js"></script>
|
進行動作為
index.php<script> $(".son").hide();
function show(id) { $(".son").hide(); $(".fa" + id).show(); } </script>
|
選單對應的內容
- 父選單與子選單所撈取的範圍會不同。透過取得的 GET 來進行不同的撈取動作。
- 題目自改版後,新要求內容區要有對應的分類母子標題,所以利用 GET 變數做判斷。
- 利用
$who
來做不同的塞選條件,譬如如果是全部商品 $who
會是空的,如果是指定 fa 或 son 會對應適合的塞選條件
- “縮圖”需能連接到產品細節,網址 do=info& 帶 ID 參數
- “我要購買”題目沒要求連接到哪,故也一併連接到 do=info 省得麻煩。
建立 main.php
設計為
main.php<h2> <?php if (empty($_GET['do'])) echo "全部商品"; else { echo select("q4t4_class", "id=" . $_GET['fa'])[0]['title']; if (!empty($_GET['son'])) echo ">" . select("q4t4_class", "id=" . $_GET['son'])[0]['title']; } ?> </h2> <table> <?php $who = ""; if (!empty($_GET['fa'])) $who .= " and fa=" . $_GET['fa']; if (!empty($_GET['son'])) $who .= " and son=" . $_GET['son']; $re = select("q4t5_product", "dpy=1" . $who); foreach ($re as $ro) { ?> <tr> <td rowspan=4><a href="?do=info&id=<?= $ro['id'] ?>"><img src="img/<?= $ro['img'] ?>" width="200"></a></td> <td><?= $ro['title'] ?></td> </tr> <tr> <td>價錢:<?= $ro['price'] ?> <a href="?do=info&id=<?= $ro['id'] ?>"><img src="img/0402.jpg" alt=""></a></td> </tr> <tr> <td>規格:<?= $ro['spec'] ?></td> </tr> <tr> <td>簡介:<?= $ro['text'] ?></td> </tr> <?php } ?> </table>
|
產品細節
- 從 ID 去取得出該商品的大分類與中分類。
- 分類顯示參考 main.php 的做法,只是這裡從產品 id 去推算出來
- 題目自改版後,新要求產品編號顯示(來自素材且固定之隨機碼),這裡指的是編號不是產品 ID
- 規劃 form 收集 ID、數量。利用 image 做成 submit 功能 (alt=submit)
- 利用 from 送到 api.php 去先判別是否已登入再加入購物車的 SESSION
建立 info.php
info.php<?php $re = select("q4t5_product", "id=" . $_GET['id']); $ro = $re[0]; ?> <form action="api.php?do=want&id=<?= $_GET['id'] ?>" method="post"> <h3 class="ct"><?= $ro['title'] ?></h3> <table> <tr> <td rowspan=5><img width=400 src="img/<?= $ro['img'] ?>" alt=""></td> <td>分類: <?php echo select("q4t4_class", "id=" . $ro['fa'])[0]['title']; echo ">".select("q4t4_class", "id=" . $ro['son'])[0]['title']; ?> </td> </tr> <tr> <td>編號:<?= $ro['seq'] ?></td> </tr> <tr> <td>價錢:<?= $ro['price'] ?></td> </tr> <tr> <td>詳細說明:<br><?= $ro['text'] ?></td> </tr> <tr> <td>庫存量:<?= $ro['num'] ?></td> </tr> <tr> <td colspan=2>購買數量<input type="text" name="num" id=""> <input type="image" src="img/0402.jpg" alt="submit"> <input type="button" value="返回" onclick="window.history.back()"> </td> </tr> </table> </form>
|
步驟到此,api.php 的寫法留至第七題解。接下來準備處理後台商品管理,但你需要先設計第十題的管理登入。
No.10 管理登入 (35%)
先設計登入功能,方便你做其他題目後台的設計。本題重點分為列表、新增、修改、刪除四組 SQL 連接。後三者以送往 api.php 處理為主。
判斷是否登入
- 登入頁面有分 user 登入跟 admin 登入,所以這裡用 adlogin.php
- 如果沒有偵測到 SESSION[‘admin’] 存在,就踢到前台的管理登入畫面。在 admin.php 頁首插入代碼
修改 admin.php
admin.php<?php include "lib.php"; if (empty($_SESSION['admin'])) plo("index.php?do=adlogin"); ?>
|
登入畫面的版面設計
- 題目沒有提供素材風格,所以我們不太需要講究 table 格式。簡單用 p 與 br 標籤完成。
- 題目有要求驗證動作,在 form 上面多個 onsubmit 做 JQ 的提交前處理。
建立 adlogin.php
adlogin.php<form action="api.php?do=adlogin" method="post" onsubmit="return check()"> 帳號:<input type="text" name="acc" id=""><br> 密碼:<input type="text" name="pwd" id=""><br> 驗證碼<?= $a1 ?>+<?= $a2 ?>= <input type="text" name="ans" id=""> <input type="submit" value="登入"> </form>
|
補上 jq 語法反應
adlogin.phpfunction check() { if ($("input[name=ans]").val() != <?= $ans ?>) { alert("對不起,您輸入的驗證碼有誤請您重新輸入"); return false; } }
|
增添 lib.php
由於其他題目也會有此設計,將隨機碼答案放在 lib.php
lib.php $a1 = rand(11, 99); $a2 = rand(11, 99); $ans = $a1 + $a2;
|
建立 api.php
這裡是第一次做,所以要規劃 switch case。登入成功就咬一個 SESSION
api.php<?php include "lib.php"; switch ($_GET['do']) { case 'adlogin': $re = select("q4t10_admin", "acc='" . $_POST['acc'] . "' and pwd='" . $_POST['pwd'] . "'"); if ($re != null) { $_SESSION['admin'] = $_POST['acc']; plo("admin.php"); } else echo "<script>alert('輸入錯誤');window.history.back()</script>"; break; } ?>
|
登出功能
題目沒有要求登出,但有寫到有個返回按鈕可以回到前台首頁。因此這裡用文字遊戲讓他符合
修改 admin.php
admin.php<a href="?do=admin&redo=logout" style="color:#f00;">登出</a>
|
修改為
admin.php<a href="api.php?do=adlogout" style="color:#f00;">返回</a>
|
增添 api.php
對登出提交動作處理
api.phpcase 'adlogout': unset($_SESSION['admin']); plo("index.php"); break;
|
權限選單與正確連接
- 每個管理者有不同的選單權限,因此需根據不同的權限做選單顯現。
- 增添到頁首的 PHP 區域。這裡取得的權限資訊為字串型陣列,先轉成陣列後待使用。
- 先寫好選單與內容的切換
修改 admin.php
admin.php$re = select("q4t10_admin", "acc='" . $_SESSION['admin'] . "'"); $access = unserialize($re[0]['access']); $main = (empty($_GET['redo'])) ? "admain" : $_GET['redo'];
|
此時修改選單為,只有值為 1 時成立輸出該 html 行。順便修正簡化超連結為?redo=XX 就夠了
admin.php<div style="min-height:400px;"> <a href="?redo=admain">管理權限設置</a> <?= ($access[0]) ? '<a href="?redo=th">商品分類與管理</a>' : '' ?> <?= ($access[1]) ? '<a href="?redo=order">訂單管理</a>' : '' ?> <?= ($access[2]) ? '<a href="?redo=mem">會員管理</a>' : '' ?> <?= ($access[3]) ? '<a href="?redo=bot">頁尾版權管理</a>' : '' ?> <?= ($access[4]) ? '<a href="#">最新消息管理</a>' : '' ?> <a href="api.php?do=adlogout" style="color:#f00;">返回</a> </div>
|
同時找到內容區
更改為
admin.php<div id="right"> <?php include $main . ".php"; ?> </div>
|
此時登入登出的畫面與可用服務都算告一段落。
管理者列表
做好列出所有列表,同時 admin 不可修改,題目需求不周全,因此這裡可以寫假資料代替。select 時跳過 id=1(admin) 即可。規劃新增修改刪除的作業與 api 提交。
建立 admain.php
admain.php<input type="button" value="新增管理員" onclick="<?= jlo('?redo=adminadd') ?>"> <table> <tr> <td>帳號</td> <td>密碼</td> <td>操作</td> </tr> <tr> <td>admin</td> <td>****</td> <td>此帳號為最高權限</td> </tr> <?php $re = select("q4t10_admin", "id!=1"); foreach ($re as $ro) { ?> <tr> <td><?= $ro['acc'] ?></td> <td><?= $ro['pwd'] ?></td> <td> <input type="button" value="修改" onclick="<?= jlo('?redo=adminmdy&id=' . $ro['id']) ?>"> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=admindel&id=' . $ro['id']) ?>"> </td> </tr> <?php } ?> </table>
|
建立管理者
這裡比較需要說明的是權限,先用陣列與值代表各權限。最快是這裡先整理好 0 與 1 的 access 陣列
建立 adminadd.php
adminadd.php<h3 class="ct">新增管理者帳號</h3> <form action="api.php?do=adminadd" method="post"> 帳號:<input type="text" name="acc" id=""><br> 密碼:<input type="text" name="pwd" id=""><br> 權限:<br> <input type="hidden" name="access[0]" value="0"> <input type="hidden" name="access[1]" value="0"> <input type="hidden" name="access[2]" value="0"> <input type="hidden" name="access[3]" value="0"> <input type="hidden" name="access[4]" value="0"> <input type="checkbox" name="access[0]" value="1">商品分類與管理<br> <input type="checkbox" name="access[1]" value="1">訂單管理<br> <input type="checkbox" name="access[2]" value="1">會員管理<br> <input type="checkbox" name="access[3]" value="1">頁尾版權管理<br> <input type="checkbox" name="access[4]" value="1">最新消息管理<br> <input type="submit" value="新增"> </form>
|
增添 api.php
- access 陣列最後轉乘字串化陣列塞回 $_POST 。
api.phpcase 'adminadd': $_POST['access'] = serialize($_POST['access']); insert($_POST, "q4t10_admin"); plo("admin.php"); break;
|
修改管理者
- 可以參考新增的版面複製修改,由於到時候會送往 API 處理。
- 這裡為了考試速度不特別帶預設值,節省了資料帶出的處理。
建立 adminmdy.php
adminmdy.php<h3 class="ct">修改管理者帳號</h3> <form action="api.php?do=adminmdy&id=<?= $_GET['id'] ?>" method="post"> 帳號:<input type="text" name="acc[<?= $_GET['id'] ?>]" id=""><br> 密碼:<input type="text" name="pwd[<?= $_GET['id'] ?>]" id=""><br> 權限:<br> <input type="hidden" name="cc[0]" value="0"> <input type="hidden" name="cc[1]" value="0"> <input type="hidden" name="cc[2]" value="0"> <input type="hidden" name="cc[3]" value="0"> <input type="hidden" name="cc[4]" value="0"> <input type="checkbox" name="cc[0]" value="1">商品分類與管理<br> <input type="checkbox" name="cc[1]" value="1">訂單管理<br> <input type="checkbox" name="cc[2]" value="1">會員管理<br> <input type="checkbox" name="cc[3]" value="1">頁尾版權管理<br> <input type="checkbox" name="cc[4]" value="1">最新消息管理<br> <input type="submit" value="修改"> </form>
|
增添 api.php
先建立 array 將 value0 或 1 整理好,最後轉成字串化陣列到指定 array 位置、(視為 ID),當然一樣 unset 不需要的值
api.phpcase 'adminmdy': $_POST['access'][$_GET['id']] = serialize($_POST['cc']); unset($_POST['cc']); update($_POST, "q4t10_admin"); plo("admin.php"); break;
|
刪除管理者
這裡就直接提交 api.php 處理了,不用再設計版型。
增添 api.php
api.phpcase 'admindel': $post['del'][] = $_GET['id']; delete($post, "q4t10_admin"); plo("admin.php"); break;
|
No.5 商品介紹 (55%)
事實上這裡分為兩個主題被歸類在同一題目,分別是分類管理與商品管理。所以除了原本指定好的路徑建立 th.php,再另外建立為 tp.php,兩者之間再建立連結做為切換。
分類管理之版型
- 規劃切換選單於 h3 內並放在起頭
- 參考 main.php 取得多重迴圈,主要邏輯在搜尋大類,分類之內容。
- 設計兩個獨立 form 表單分開進行大類新增與中類新增
- 修改另外到 admin_mdyth 做修改再到 api.php
- 刪除直接到 api.php 處理
建立 th.php(參考 main.php)
th.php<h3>商品分類 | <a href="?redo=tp">商品管理</a></h3> <form action="api.php?do=thadd" method="post"> <p>新增大類 <input type="text" name="title"> <input type="hidden" name="parent" value=0> <input type="submit" value="新增"> </p> </form> <form action="api.php?do=thadd" method="post"> <p>新增中類 <select name="parent"> <?php $re = select("q4t4_class", "parent=0"); foreach ($re as $ro) echo '<option value="' . $ro['id'] . '">' . $ro['title'] . '</option>'; ?> </select> <input type="text" name="title"> <input type="submit" value="新增"> </p> </form> <table> <?php foreach ($re as $ro) { ?> <tr bgcolor=#ffc> <td><?= $ro['title'] ?></td> <td> <input type="button" value="修改" onclick="<?= jlo('?redo=thmdy&id=' . $ro['id']) ?>"> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=thdel&id=' . $ro['id']) ?>"> </td> </tr> <?php $re2 = select("q4t4_class", "parent=" . $ro['id']); foreach ($re2 as $ro2) { ?> <tr bgcolor=#ffe> <td><?= $ro2['title'] ?></td> <td> <input type="button" value="修改" onclick="<?= jlo('?redo=thmdy&id=' . $ro2['id']) ?>"> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=thdel&id=' . $ro2['id']) ?>"> </td> </tr> <?php } } ?> </table>
|
分類管理之新增
增添 api.php
api.phpcase 'thadd': insert($_POST, "q4t4_class"); plo("admin.php?redo=th"); break;
|
分類管理之修改
修改使用 function update,因故要塞入 id 到陣列之 key 內,新增 admin_mdyth.php,寫下
建立 thmdy.php
thmdy.php<form action="api.php?do=thmdy" method="post"> 名稱:<input type="text" name="title[<?= $_GET['id'] ?>]" id=""><br> <input type="submit" value="修改"> </form>
|
增添 api.php
api.phpcase 'thmdy': update($_POST, "q4t4_class"); plo("admin.php?redo=th"); break;
|
D. 分類管理之刪除
直接連結到 api 作處理動作,記得規劃成 function del 之可接受格式。
增添 api.php
api.phpcase 'thdel': $post['del'][] = $_GET['id']; delete($post, "q4t4_class"); plo("admin.php?redo=th"); break;
|
商品管理之版型
- 重點同樣在列表新增修改刪除。列表與修改部分較複雜些
- 新增導向另一個 URL 參數 do=admin&redo=tpadd
- 修改導向另一個 URL 參數 do=admin&redo=tpmdy
- 刪除與上下架導向到 api 直接處理
建立 tp.php(參考 th.php )
tp.php<h3><a href="?redo=th">商品分類</a> | 商品管理</h3> <input type="button" value="新增商品" onclick="<?= jlo('?redo=tpadd') ?>"> <table> <tr> <td>編號</td> <td>商品名稱</td> <td>庫存量</td> <td>狀況</td> <td>操作</td> </tr> <?php $re = select("q4t5_product", 1); foreach ($re as $ro) { ?> <tr bgcolor= <td><?= $ro['id'] ?></td> <td><?= $ro['title'] ?></td> <td><?= $ro['num'] ?></td> <td><?= ($ro['dpy']) ? "販售中" : "已下架"; ?></td> <td> <input type="button" value="修改" onclick="<?= jlo('?redo=tpmdy&id=' . $ro['id']) ?>"> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=tpdel&id=' . $ro['id']) ?>"> <input type="button" value="上架" onclick="<?= jlo('api.php?do=tpon&id=' . $ro['id']) ?>"> <input type="button" value="下架" onclick="<?= jlo('api.php?do=tpoff&id=' . $ro['id']) ?>"> </td> </tr> <?php } ?> </table>
|
商品管理之新增
- 複雜的地方在於下拉選單的關聯切換,需要透過 JQ 去完成替換
- 由 JQ 去判別大類之值為何,送 ajax 取得新的 HTML 打印輸出
- 重置與返回題目沒有示意圖有,可以不做不會被扣分
建立 tpadd.php
tpadd.php<h3 class="ct">新增商品</h3> <form action="api.php?do=tpadd" method="post" enctype="multipart/form-data"> 所屬大類: <select name="fa" id="" onchange="getson()"> <option value="">請選擇</option> <?php $re = select("q4t4_class", "parent=0"); foreach ($re as $ro) echo '<option value="' . $ro['id'] . '">' . $ro['title'] . '</option>'; ?> </select><br> 所屬中類: <select name="son" id=""> </select><br> 商品編號:系統自動生成<br> 商品名稱:<input type="text" name="title" id=""><br> 商品價格:<input type="text" name="price" id=""><br> 規格:<input type="text" name="spec" id=""><br> 庫存量:<input type="text" name="num" id=""><br> 商品圖片:<input type="file" name="img" id=""><br> 商品介紹:<textarea name="text" id="" cols="30" rows="10"></textarea> <input type="submit" value="新增"> </form>
|
此時要利用 JQ 去處理 AJAX
tpadd.php<script> function getson() { id = $("select[name=fa]").val(); $.post("api.php?do=getson", { id }, function(re) { $("select[name=son]").html(re); }); } </script>
|
增添 admin.php
記得 head 標籤要宣告 JQ 位置,才能運作 JQ
admin.php<script src="scripts/jquery-1.9.1.min.js"></script>
|
增添 api.php
api.phpcase 'getson': $re = select("q4t4_class", "parent=" . $_POST['id']); foreach ($re as $ro) echo '<option value="' . $ro['id'] . '">' . $ro['title'] . '</option>'; break;
|
此時可以正常帶子選單了,最後設計提交到 api 的行為處理。
- 這裡因為題目改版,需要額外做一個 seq 當作編號(應考人自訂),簡單規則是 100000 與 ID 之和。
api.phpcase 'tpadd': $_POST['img'] = addfile($_FILES['img']); $newid = insert($_POST, "q4t5_product"); $post['seq'][$newid] = $newid + 100000; update($post, "q4t5_product"); plo("admin.php?redo=tp"); break;
|
商品管理之單一修改
- 版型與新增差不多,同樣複雜在預設值,考慮考試速度這裡都不特地設計帶入
- 重置跟返回功能題目沒有示意圖有,可以考慮不用寫。
- 更新的做法,必須每個欄位採用 array 並多夾帶 ID。才能在 function update 運作
建立 tpmdy.php(參考 tpadd.php)
tpmdy.php<h3 class="ct">修改商品</h3> <form action="api.php?do=tpmdy&id=<?= $_GET['id'] ?>" method="post" enctype="multipart/form-data"> 所屬大類: <select id=fa name="fa[<?= $_GET['id'] ?>]" id="" onchange="getson()"> <option value="">請選擇</option> <?php $re = select("t4_class", "parent=0"); foreach ($re as $ro) echo '<option value="' . $ro['id'] . '">' . $ro['text'] . '</option>'; ?> </select><br> 所屬中類: <select id=son name="son[<?= $_GET['id'] ?>]" id=""> </select><br> 商品編號:<?= $_GET['id'] ?><br> 商品名稱:<input type="text" name="title[<?= $_GET['id'] ?>]" id=""><br> 商品價格:<input type="text" name="price[<?= $_GET['id'] ?>]" id=""><br> 規格:<input type="text" name="spec[<?= $_GET['id'] ?>]" id=""><br> 庫存量:<input type="text" name="num[<?= $_GET['id'] ?>]" id=""><br> 商品圖片:<input type="file" name="img" id=""><br> 商品介紹:<textarea name="text[<?= $_GET['id'] ?>]" id="" cols="30" rows="10"></textarea> <input type="submit" value="修改"> </form> <script> function getson() { id = $("#fa").val(); $.post("api.php?do=getson", { id }, function(re) { $("#son").html(re); }); } </script>
|
增添 api.php
api.phpcase 'tpmdy': $_POST['img'][$_GET['id']] = addfile($_FILES['img']); update($_POST, "q4t5_product"); plo("admin.php?redo=tp"); break;
|
商品管理之刪除、上下架
直接在 api.php 處理,注意需額外整理 delete 與 update 的 display,為 function 所能接受格式。
增添 api.php
api.phpcase 'tpon': $_POST['dpy'][$_GET['id']] = 1; update($_POST, "q4t5_product"); plo("admin.php?redo=tp"); break; case 'tpoff': $_POST['dpy'][$_GET['id']] = 0; update($_POST, "q4t5_product"); plo("admin.php?redo=tp"); break; case 'tpdel': $post['del'][] = $_GET['id']; delete($post, "q4t5_product"); plo("admin.php?redo=tp"); break;
|
No.6 最新消息 (10%)
分為做跑馬燈以及最新消息文章顯示。後者的說明較不齊全完整,要求沒有指定從資料庫處理,所以直接都由 HTML 處理掉。
跑馬燈效果
這裡比較簡單,就是撈取然後顯示為 marquee,找到該靜態文字
修改 index.php
index.php情人節特惠活動 為了慶祝七夕情人節,將舉辦情人兩人到現場有七七折之特惠活動~
|
取代為
index.php<marquee behavior="" direction="">情人節特惠活動 為了慶祝七夕情人節,將舉辦情人兩人到現場有七七折之特惠活動~</marquee>
|
文章顯示
示意圖多一步驟是可以點選查看內文。這是題目動作沒有的,只需要做標題即可。
建立 news.php
news.php<h3 class="ct">最新消息</h3> <table bgcolor=#fff width=100%> <tr bgcolor=#ff5> <td>標題</td> </tr> <tr bgcolor=#ffc> <td>年終特賣會開跑了</td> </tr> <tr bgcolor=#ffc> <td>情人節特惠活動</td> </tr> </table>
|
另外題目沒有設計後台的最新消息管理功能,所以記得後台的選單路徑要改為 # 作為無反應。
No.7 購物功能 (45%)
這題被塞了兩個單元,分別是前台的會員註冊登入與會員服務(購物)。
操作流程與設計方針為:
- 讓註冊或登入與購物之兩者程式獨立。
- 不管有無登入按下”我要購買”就把購買資訊存在 SESSION,接著檢查到未登入就帶去註冊或登入。
- 只要不登出情況下,查看購物車就是查看 session cart。
因此
- 先完成前台的會員登入與註冊,再來完成按下購物可以將資訊塞入購物車。
- 設計技巧採用新訪客的流程登入,模擬新使用者的操作,會碰到登入版型、新註冊、登入帳號、查看購物車
規劃購物車
之前第四題做到按下我要購買會送往 api 處理並加入 cart。這裡分兩動作,第一先記下來買了什麼,第二是確認登入了沒。(否則往登入頁面)。為了記錄商品 ID,寫在 SESSION 的 key 上。
增添 api.php
api.pgpcase 'want': $_SESSION['buy'][$_GET['id']] = $_POST['num']; if (empty($_SESSION['user'])) plo("index.php?do=login"); else plo("index.php?do=buycart"); break;
|
登入版型
- 版型差不多只需記得導向的位置不同。
- 一樣透過 onsumit 去觸發處理驗證。
- 會員註冊導向到 reg 處理。
建立 login.php(參考 adlogin.php)
login.php<h3>第一次登入</h3> <a href="?do=reg"><img src="img/0413.jpg" alt=""></a> <h3>會員登入</h3> <form action="api.php?do=login" method="post" onsubmit="return check()"> 帳號:<input type="text" name="acc" id=""><br> 密碼:<input type="text" name="pwd" id=""><br> 驗證碼<?= $a1 ?>+<?= $a2 ?>= <input type="text" name="ans" id=""> <input type="submit" value="登入"> </form> <script> function check() { if ($("input[name=ans]").val() != <?= $ans ?>) { alert("對不起,您輸入的驗證碼有務請您重新輸入"); return false; } } </script>
|
會員註冊
- 這裡需要考量新帳號的同名驗證,所以靠 JQ 來處理 api 傳遞。
- 比較周全的除了帳號驗證,表單送出也需檢查,因為 ajax 為簡易模式會並行執行,所以兩者要用 flag 去分前後任務,一個是檢查,一個是要使用者去檢查。
建立 reg.php
reg.php<h3 class="ct">會員註冊</h3> <form action="api.php?do=reg" method="post" onsubmit="return checkflag()"> 姓名:<input type="text" name="name" id=""><br> 帳號:<input type="text" name="acc" id=""><input type="button" value="檢測帳號" onclick="check()"><br> 密碼:<input type="text" name="pwd" id=""><br> 電話:<input type="text" name="tel" id=""><br> 地址:<input type="text" name="addr" id=""><br> 電子信箱:<input type="text" name="mail" id=""><br> <input type="submit" value="確認"> </form> <script> flag = 1; function check() { if ($("input[name=acc]").val() == 'admin') alert("不可使用 admin"); else { id = $("input[name=acc]").val(); $.post("api.php?do=checkuser", {id}, function(re) { alert(re); if (re == "可使用此帳號") flag = 0; else flag = 1; }); } } function checkflag() { if (flag) { alert("請先驗證帳號"); return false; } } </script>
|
增建 api.php
api 這裡要處理帳號重複的驗證,以及註冊帳號的處理並導向到登入畫面,讓使用者再登入一次(順便讓考官確認可正常登入新帳號)
api.phpcase 'checkuser': $re = select("q4t9_user", "acc='" . $_POST['id'] . "'"); if ($re != null) echo "帳號重複"; else echo "可使用此帳號"; break; case 'reg': $_POST['date'] = date("Y-m-d"); insert($_POST, "q4t9_user"); plo("index.php?do=login"); break;
|
登入帳號
前面已經完成登入介面,試著使用帳號登入,接著 api 來作帳密登入,登入成功就咬住名字跟帳號
增建 api.php
api.phpcase 'login': $re = select("q4t9_user", "acc='" . $_POST['acc'] . "' and pwd='" . $_POST['pwd'] . "'"); if ($re != null) { $_SESSION['user'] = $_POST['acc']; $_SESSION['id'] = $re[0]['id']; plo("index.php"); } else echo "<script>alert('輸入錯誤');window.history.back()</script>"; break;
|
登出按鈕
雖然題目沒要求此功能但程式碼不多,做此功能能幫助你快速驗證相關功能。找到選單連接加入運算子
修改 index.php
index.php<a href="?do=login">會員登入</a>
|
更改為
index.php<?= (empty($_SESSION['user'])) ? '<a href="?do=login">會員登入</a>' : '<a href="api.php?do=logout">會員登出</a>' ?> |
|
增添 api.php
api.phpcase 'logout': unset($_SESSION['user']); plo("index.php"); break;
|
如此一來你能正常登入登出並請試著功能正常性。
查看購物車
- buycart 只是單純地將 SESSION 輸出並撈取該商品資訊,只需清楚 SESSION 的陣列結構即可。
- 題目改版新要求,另外刪除該項時,委託 api 去 unset 該資訊(藉由 ID)。
- 真正建立訂單導向另一頁 order.php。另外避免操作不當,空購物車時就不提供結帳按鈕。
- 示意圖上要求呈現數量,但示意圖為可修改 [數量]。斟酌此項。
- 提交 POST 並記錄 ID 與 NUM。再另一畫面重新打回 SESSION 的 NUM
建立 buycart.php
buycart.php<?php $who = (empty($_SESSION['user'])) ? "訪客(請先登入)" : $_SESSION['user']; ?> <h3 class="ct"><?= $who ?>的購物車</h3> <table> <tr> <td>編號</td> <td>商品名稱</td> <td>數量</td> <td>庫存量</td> <td>單價</td> <td>小計</td> <td>刪除</td> </tr> <?php $total = 0; if (!empty($_SESSION['buy'])) foreach ($_SESSION['buy'] as $id => $num) { $re = select("q4t5_product", "id=" . $id); $ro = $re[0]; ?> <tr bgcolor=#ffc> <td><?= $ro['seq'] ?></td> <td><?= $ro['title'] ?></td> <td><?= $num ?></td> <td><?= $ro['num'] ?></td> <td><?= $ro['price'] ?></td> <td><?= $ro['price'] * $num ?></td> <td><input type="button" value="刪除" onclick="<?= jlo('api.php?do=cartdel&id=' . $id) ?>"></td> </tr> <?php $total += $ro['price'] * $num; } ?> </table> <a href="index.php"><img src="img/0411.jpg" alt=""></a> <a href="?do=pay"><img src="img/0412.jpg" alt=""></a>
|
增添 api.php
api.phpcase 'cartdel': unset($_SESSION['buy'][$_GET['id']]); plo("index.php?do=buycart"); break;
|
建立 pay.php(參考 buycart.php)
事實上這裡不需要使用者做任何 input,而真正建立資料庫是這裡步驟之後,我們只需要 total 值帶去後端 api 且下步驟還會再分析一次 session
- 一開始先透過目前的登入者抓取用戶資訊。
- 分析購物車內的 session 抓出產品 ID 與購買數規劃成表單準備輸出,同時去計算總價(新題目已調整要求該資訊)
- 版型可以從 buycart.php 那裏取得餐搞。
pay.php<h3 class="ct">確認資料</h3> <?php $re = select("q4t9_user", "id=" . $_SESSION['id']); $ro = $re[0]; ?> 姓名:<?= $ro['name'] ?><br> 帳號:<?= $ro['acc'] ?><br> 電話:<?= $ro['tel'] ?><br> 地址:<?= $ro['addr'] ?><br> 電子信箱:<?= $ro['mail'] ?> <hr> <table> <tr> <td>編號</td> <td>商品名稱</td> <td>數量</td> <td>庫存量</td> <td>單價</td> <td>小計</td> </tr> <?php $total = 0; if (!empty($_SESSION['buy'])) foreach ($_SESSION['buy'] as $id => $num) { $re = select("q4t5_product", "id=" . $id); $ro = $re[0]; ?> <tr bgcolor=#ffc> <td><?= $ro['seq'] ?></td> <td><?= $ro['title'] ?></td> <td><?= $num ?></td> <td><?= $ro['num'] ?></td> <td><?= $ro['price'] ?></td> <td><?= $ro['price'] * $num ?></td> </tr> <?php $total += $ro['price'] * $num; } ?> <tr> <td colspan="6">總價:<?= $total ?></td> </tr> </table> <hr> <input type="button" value="確定送出" onclick="<?= jlo('api.php?do=pay&total=' . $total) ?>"> <input type="button" value="返回修改訂單" onclick="window.history.back()">
|
增添 api.php
SESSION 直接打包成字串並清除購物車 (SESSION),acc 跟 date 以及將用戶資訊也要塞入 $_POST 內一併上傳,方便後台上的直接讀取。另外題目要求有提示 alert,所以轉址要用 JS 不能用 PHP 否則還沒跑 JS 就被 PHP 轉走。
api.phpcase 'pay': $re = select("q4t9_user", "id=" . $_SESSION['id']); $ro = $re[0]; $_POST['acc'] = $ro['acc']; $_POST['name'] = $ro['name']; $_POST['tel'] = $ro['tel']; $_POST['addr'] = $ro['addr']; $_POST['mail'] = $ro['mail']; $_POST['total'] = $_GET['total']; $_POST['date'] = date("Y-m-d"); $_POST['buy'] = serialize($_SESSION['buy']); unset($_SESSION['buy']); insert($_POST, "q4t8_order"); echo "<script>alert('訂購成功感謝您的參與');" . jlo("index.php") . "</script>"; break;
|
No.8 訂單管理 (20%)
這裡只有兩個版型要規劃,分別是列表與細節。透過第七題先隨意建立幾筆訂單。
訂單列表
之前都已經先將必要資訊都已建立起來,只需取得 sql table order。刪除則由 API 來處理。注意 delete function 之格式。至於細節則導向到 do=admin&redo=orderdetial 並夾帶 ID
建立 order.php(參考 buycart.php)
order.php<h3>訂單管理</h3> <table> <tr> <td>訂單編號</td> <td>金額</td> <td>會員帳號</td> <td>姓名</td> <td>下單時間</td> </tr> <?php $re = select("q4t8_order", 1); foreach ($re as $ro) { $seq = date("Ymd000000", strtotime($ro['date'])) + $ro['id']; ?> <tr bgcolor=#ffc> <td><a href="?redo=item&id=<?= $ro['id'] ?>"><?= $seq ?></a></td> <td><?= $ro['total'] ?></td> <td><?= $ro['acc'] ?></td> <td><?= $ro['name'] ?></td> <td><?= $ro['date'] ?></td> <td> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=odrdel&id=' . $ro['id']) ?>"> </td> </tr> <?php } ?> </table>
|
訂票細節
這裡要抓取 order 與 product 商品(藉由 GET ID)
建立 item.php(參考 order.php)
item.php<?php $re = select("q4t8_order", "id=" . $_GET['id']); $ro = $re[0]; $seq = date("Ymd000000", strtotime($ro['date'])) + $ro['id']; ?> <h3>訂單編號<?= $seq ?>的詳細資料</h3> 姓名:<?= $ro['name'] ?><br> 帳號:<?= $ro['acc'] ?><br> 電話:<?= $ro['tel'] ?><br> 地址:<?= $ro['addr'] ?><br> 電子信箱:<?= $ro['mail'] ?> <hr> <table> <tr> <td>商品名稱</td> <td>編號</td> <td>數量</td> <td>單價</td> <td>小計</td> </tr> <?php $ary = unserialize($ro['buy']); foreach ($ary as $key => $value) { $re = select("q4t5_product", "id=" . $key); $x = $re[0]; ?> <tr bgcolor=#ffc> <td><?= $x['title'] ?></td> <td><?= $key ?></td> <td><?= $value ?></td> <td><?= $x['price'] ?></td> <td><?= $x['price'] * $value ?></td> </tr> <?php } ?> <tr> <td colspan=5>總價:<?= $ro['total'] ?></td> </tr> </table> <hr> <input type="button" value="返回" onclick="window.history.back()">
|
訂單刪除
題目要求可以刪除訂單,由 api 來處理
增添 api.pgp
api.phpcase 'odrdel': $post['del'][] = $_GET['id']; delete($post, "q4t8_order"); plo("admin.php?redo=order"); break;
|
No.9 會員管理 (15%)
第七題已經設計出可新增會員,這裡只需做列表與修改刪除。
清單檢視版型
取得相近的 HTML table 版型做設計
建立 mem.php(參考 order.php)
mem.php<h3>會員管理</h3> <table> <tr> <td>姓名</td> <td>會員帳號</td> <td>註冊日期</td> <td>操作</td> </tr> <?php $re = select("q4t9_user", 1); foreach ($re as $ro) { ?> <tr bgcolor=#ffc> <td><?= $ro['id'] ?></a></td> <td><?= $ro['acc'] ?></td> <td><?= $ro['date'] ?></td> <td> <input type="button" value="修改" onclick="<?= jlo('?redo=memmdy&id=' . $ro['id']) ?>"> <input type="button" value="刪除" onclick="<?= jlo('api.php?do=memdel&id=' . $ro['id']) ?>"> </td> </tr> <?php } ?> </table>
|
修改功能
參考 HTML Table 版型規劃。題目只要求可指定修改四個資料,這裡考試速度不帶預設值,修改需夾帶 ID 在各 name 內。
建立 memmdy.php(參考 item.php)
memmdy.php<h3 class="ct">編輯會員</h3> <form action="api.php?do=memmdy" method="post" onsubmit="return check()"> 姓名:<input type="text" name="name[<?= $_GET['id'] ?>]" id=""><br> 電話:<input type="text" name="tel[<?= $_GET['id'] ?>]" id=""><br> 地址:<input type="text" name="addr[<?= $_GET['id'] ?>]" id=""><br> 電子信箱:<input type="text" name="mail[<?= $_GET['id'] ?>]" id=""><br> <input type="submit" value="確認"> </form>
|
增添 api.php
api.phpcase 'memmdy': update($_POST, "q4t9_user"); plo('admin.php?do=admin&redo=mem'); break;
|
這裡後台會看不到修改後的差異,驗收的時候請考官去看前台的新訂單動作下的資料。
刪除功能
廢話不多說
增添 api.php
api.phpcase 'memdel': $post['del'][] = $_GET['id']; delete($post, "q4t9_user"); plo("admin.php?redo=mem"); break;
|
No.11 頁尾版權 (25%)
這題後台有改沒提示。找個最簡單相近的 HTML 版型來使用。
頁尾編輯
- 我們指定一下 id,陣列為 text[1]
- 注意要帶舊值,且重置紐不是一般的作法
建立 bot.php(參考 thmdy.php)
bot.php<h3 class="ct">編輯頁尾版權區</h3> <form action="api.php?do=bot" method="post"> <input id="vall" type="text" name="text[1]" value="<?= select("q4t11_footer", 1)[0]['text'] ?>"> <input type="submit" value="修改"> <input type="button" value="重置" onclick="$('#vall').val('')"> </form>
|
增添 api.php
api.phpcase 'bot': update($_POST, "q4t11_footer"); plo("admin.php?redo=bot"); break;
|
B. 前後台顯示
這裡同時要給兩個版型用,所以 sql 查詢部分就放在 lib.php 內
增添 sql.php
$re=select("q4t11_footer",1); $bot=$re[0]['text'];
|
修改 index.php 與 admin.php
找到頁尾部分
<div id="bottom" style="line-height:70px; color:#FFF; background:url(icon/bot.png);" class="ct"> 頁尾版權 : </div>
|
改成下列
<div id="bottom" style="line-height:70px; color:#FFF; background:url(icon/bot.png);" class="ct"> <?=$bot?> </div>
|
END 調整版面 (5%)
這題動作一定要做!!,因為題目有明確表示因產品過多一定要做分頁或是滾輪。
修改 index.php & admin.php
找到主區域的 div 修改為
index.php & admin.php<div id="main" style="width: 1024px;height: 768px;overflow-y:scroll; padding:0; margin:10px auto; border: 0;">
|
後台的頁首圖片有跑掉,跟著修改兩張圖片為 69%跟 30%
修改 admin.php
admin.php<a href="?"> <img src="./Manage Page_files/0416.jpg" style="width:69%"> </a> <img src="./Manage Page_files/0417.jpg" style="width:30%">
|
透過 Chrome 遊覽器檢查可以得到 1024*768 且上下左右 10px 並垂直至中的動作要求。