本篇為網乙解析系列之題組三,難度算是最高的,題目動作與資料庫少,但大量依賴前端 JSJQ 進行視覺與動態資料操作占用時間,步驟不熟悉一旦卡住某小節設計,整題後續都將無法完成,若題目沒有特別要求的視覺操作盡可能不要花時間求媲美於示意圖。本篇之前置作業 (lib.php 與 MySQL 規劃)不再進行說明。
No.3 主選單 (15%) 調整 index.php 選單的有效連接,以及規劃好帳號登入功能。
主選單的有效連結 先修正正確的檔案名稱之超連結,在三個素材版型內找到
修改 index.php & order.php & admin.php index.php & order.php & admin.php <div id ="top2" > <a href ="03P01.htm" > 首頁</a > <a href ="03P02.htm" > 線上訂票</a > <a href ="#" > 會員系統</a > <a href ="03P03.htm" > 管理系統</a > </div >
修改為
index.php & order.php & admin.php <div id ="top2" > <a href ="index.php" > 首頁</a > <a href ="order.php" > 線上訂票</a > <a href ="#" > 會員系統</a > <a href ="admin.php" > 管理系統</a > </div >
另外先插入各頁首連接 lib.php
,方便之後任何 PHP 與 SQL 處理。
index.php & order.php & admin.php <?php include "lib.php" ;?>
前台首頁的內容切換 這裡會有三組切換,包含預設畫面、內容細節、登入畫面。所以設計一個內容切換。把 div.mm 的內容都抽取出來
修改 index.php main.php <div class ="half" style ="vertical-align:top;" > <h1 > 預告片介紹</h1 > <div class ="rb tab" style ="width:95%;" > <div id ="abgne-block-20111227" > <ul class ="lists" > </ul > <ul class ="controls" > </ul > </div > </div > </div > <div class ="half" > <h1 > 院線片清單</h1 > <div class ="rb tab" style ="width:95%;" > <table > <tbody > <tr > </tr > </tbody > </table > <div class ="ct" > </div > </div > </div >
取代為下列代碼,上列代碼另存為 main.php
index.php <?php include $main .".php" ?>
以及開頭記得做判斷
index.php $main = (empty ($_GET ['do' ])) ? "main" : $_GET ['do' ];
後台選單的超連結簡化 在後台設計上大部分都是 do=admin&redo=XX。順手將 redo 拿掉只留一個變數就好。
修改 admin.php admin.php <div class ="ct a rb" style ="position:relative; width:101.5%; left:-1%; padding:3px; top:-9px;" > <a href ="?do=admin&redo=tit" > 網站標題管理</a > | <a href ="?do=admin&redo=go" > 動態文字管理</a > | <a href ="?do=admin&redo=rr" > 預告片海報管理</a > | <a href ="?do=admin&redo=vv" > 院線片管理</a > | <a href ="?do=admin&redo=order" > 電影訂票管理</a > </div >
更改為
admin.php <div class ="ct a rb" style ="position:relative; width:101.5%; left:-1%; padding:3px; top:-9px;" > <a href ="?do=tit" > 網站標題管理</a > | <a href ="?do=go" > 動態文字管理</a > | <a href ="?do=rr" > 預告片海報管理</a > | <a href ="?do=vv" > 院線片管理</a > | <a href ="?do=orderlist" > 電影訂票管理</a > </div >
後台選單的內容切換 抽取後台選單對應的主內容,拿來做對應的分割區域。並另存為 admain.php ,連結回 admin 首頁
修改 admin.php 將下面代抽出來另存為admain.php
admain.php <h2 class ="ct ">請選擇所需功能</h2 >
改為
index.php <?php include $admain . ".php" ?>
後台管理也有自己的選單內容,所以我們要做個選單內容服務。寫入到最上面的 php
index.php $admain =(empty ($_GET ['do' ]))?"admain" :$_GET ['do' ];
判斷是否登入 如果沒有偵測到 SESSION[‘admin’] 存在,就踢到前台的登入畫面。
增添 admin.php 在頁首處增加以下代碼
admin.php if (empty ($_SESSION ['admin' ])) plo ("index.php?do=login" );
建立 login.php 設計 login 表單並提交到 api.php,同時順便設計之後有登入過就直接轉回 admin.php 不用到登入面
login.php <form action="api.php?do=login" method="post" > 帳號:<input type="text" name="acc" id="" ><br><br> 密碼:<input type="text" name="pwd" id="" ><br><br> <input type="submit" value="送出" > </form>
建立 api.php 規劃 switch,並開始做 login 的提交處理
api.php <?php include "lib.php" ;switch ($_GET ['do' ]) { case 'login' : if ($_POST ['acc' ] == "admin" && $_POST ['pwd' ] == "1234" ) { $_SESSION ['admin' ] = true ; plo ("admin.php" ); } else echo "<script>alert('輸入錯誤');window.history.back()</script>" ; break ; } ?>
題目沒要求,這裡不一定需要設計登出功能,因為前後台都能同存操作。
No.5 後台之預告片海報管理 (25%) 跟第四題同一組,這裡先做第五題的後台新增修改刪除,最後才再回設計第四題之前台設計。
這題先做出大概版型 -> 做好新增 -> 修改刪除 -> 前台顯示
所有的 form 都提交到 api 處理
規劃版型 我們先設計列表,同時先預訂進行以下設計:
所有的異動處理,直接大表單一併提交到 api.php?do=rrmdy
進行資料處理
資料顯示部分使用 input:checkbox[name=dpy[ID]],value 為 0 與 1(先全部為 0,需要的靠覆蓋特性為 1)
資料刪除部分使用 input:checkbox[name=del[]],value 為 ID
沒有內容修改要求,唯一修改的是資料排序,為了減省時間使用數字做處理, input[name=odr[ID]]
,value 為排序值
建立 rr.php rr.php <h3 class ="ct" > 預告片清單</h3 > <form action ="api.php?do=rrmdy" method ="post" class ="ct" > <table width ="100%" > <tr > <td > 預告片海報</td > <td > 預告片片名</td > <td > 播放順序</td > <td > 操作</td > </tr > <?php $re = select("q3t5_img", "1 order by odr"); foreach ($re as $ro) { ?> <tr > <td > <img width =100 src ="img/<?= $ro['img'] ?>" alt ="" > </td > <td > <?= $ro['text'] ?></td > <td > <input type ="text" name ="odr[<?= $ro['id'] ?>]" value ="<?= $ro['odr'] ?>" > </td > <td > <input type ="hidden" name ="dpy[<?= $ro['id'] ?>]" value =0 > <input type ="checkbox" name ="dpy[<?= $ro['id'] ?>]" value ="1" <?= ($ro[ 'dpy ']) ? "checked " : "" ?> >顯示 <input type ="checkbox" name ="del[]" value ="<?= $ro['id'] ?>" > 刪除 </td > </tr > <?php } ?> </table > <div class ="ct" > <input type ="submit" value ="編輯" > </div > </form >
規劃新增功能
參考示意圖,在版面最底下另外獨立表單且彼此用 hr 分開,我們先做新增方便之後的修改刪除測試。
注意 form 需要宣告 enctpye。並提交到 api.php?do=rradd
處理
新增時沒有指定 odr 值,預設將會是 0。而 dpy 值亦同。
增添 rr.php rr.php <hr > <h3 class ="ct" > 新增預告片</h3 > <form action ="api.php?do=rradd" method ="post" enctype ="multipart/form-data" class ="ct" > 預告片海報<input type ="file" name ="img" id ="" > 預告片片名<input type ="text" name ="text" id ="" > <br > <br > <input type ="submit" value ="新增" > </form >
增添 api.php api.php case 'rradd' : $_POST ['img' ] = addfile ($_FILES ['img' ]); insert ($_POST , "q3t5_img" ); plo ("admin.php?do=rr" ); break ;
試著增添幾筆,檢查 sql 以及 img 資料夾有無新成功。
做修改刪除 題目要求很簡單只有新增刪除而已。且修改只要求顯示與排序。為了考試節省時間,用 Input 數字來處理排序就好。在版型設計時已完成,這裡接著處理提交行為:
增添 api.php api.php case 'rrmdy' : update ($_POST , "q3t5_img" ); delete ($_POST , "q3t5_img" ); plo ("admin.php?do=rr" ); break ;
轉場特效選項 題目還要求要給前端的轉場特效,參考示意圖可跟之前的 form 表單做在一起,在 from 與 table 標籤之間加入一個 select 表單。
增添 rr.php rr.php <form action ="api.php?do=rrmdy" method ="post" class ="ct" > <select name ="eft" > <?php $re = select("q3t5_effect", 1); $ro = $re[0]; ?> <option value ="1" <?= ($ro[ 'once '] == 1) ? "selected " : "" ?> >淡入</option > <option value ="2" <?= ($ro[ 'once '] == 2) ? "selected " : "" ?> >縮放</option > <option value ="3" <?= ($ro[ 'once '] == 3) ? "selected " : "" ?> >移出</option > </select > <hr > <table >
修改 api.php 到剛剛的 api.php 添加調整一下。
將 once 這個欄位抽取出來另存為 $post 陣列進行 update 到 q3t5_effect
舊的陣列可清可不清除,不存在的 field 被 update 到 q3t5_img 並不會被受理。
此外這裡的陣列規劃 $post['field name']['num id']=data value
符合函式結構進行處理
api.php case 'rrmdy' : $gg ['once' ][1 ] = $_POST ['eft' ]; update ($gg , "q3t5_effect" ); update ($_POST , "q3t5_img" ); delete ($_POST , "q3t5_img" ); plo ("admin.php?do=rr" ); break ;
先處理資料庫的 CRUD 四部曲為止,實際的 effect 設計在接下來的前台著手設計。
No.4 前台之預告片海報導覽 (30%) 做好第五題時已經擁有一些資料。便可以開始設計前台。需要一些 css animate 以及第一題的按鈕互動。
按鈕列設計 第五題完成後才處理第四題關於前台的 slider 素材,可以去偷取第一題的 img 箭頭以及 JS 來改寫。箭頭利用 windows 檔案總管右鍵快速旋轉並用小畫家儲存為 left.jpg 跟 right.jpg。將圖片放到 img 內待用。
從 web01 取得的 JavaScript 為
var nowpage=0 ,num=0 ;function pp (x ){ var s,t;if (x==1 &&nowpage-1 >=0 ){nowpage--;} if (x==2 &&(nowpage+1 )*3 <=num*1 +3 ){nowpage++;} $(".im" ).hide () for (s=0 ;s<=2 ;s++){ t=s*1 +nowpage*1 ; $("#ssaa" +t).show () } pp (1 )
已知的關鍵是
.im 會自隱藏,#ssaa 會自顯示
nowpage 是初始狀態,num 是總圖數
pp(1) 跟 pp(2) 分別是方向鍵
if(x==2&&(nowpage+1)3<=num 1+3) 算式有誤,要調整。
修改 main.php 多利用 chrome 慢慢調整 style,開始設計版型位於
main.php <ul class ="controls" > </ul >
設計為(條件有顯示與排序大小)
main.php <ul class ="controls" style ="height:100px" > <img src ="img/left.jpg" style ="padding:40px 0" onclick ="pp(1)" > <?php $re = select("q3t5_img", "dpy=1 order by odr"); $num = count($re); foreach ($re as $key => $ro) echo '<img class="im" id="ssaa' . $key . '" onclick="ani(' . $key . ')" style="height:100%" src="img/' . $ro['img'] . '" alt="' . $ro['text'] . '">'; ?> <img src ="img/right.jpg" style ="padding:40px 0" onclick ="pp(2)" > </ul >
目前為全顯示出來且溢位,需要透過以持有的 JavaScript 素材進行指定四張顯示以及左右按鈕的切換:
這裡需要偷塞個文字標題到 alt 內,方便之後 jQuery 時抓取為標題區。
同時預留 img 的 onclick=ani 帶參數,做之後點選時的 JavaScript 動作
讓點選左右鍵可以正常反應
num 總數可透過前面 PHP 算過的$num 來用
加入 JavaScript:
main.php <script > var nowpage = 0 , num = <?= $num ?>; function pp (x ) { var s, t; if (x == 1 && nowpage - 1 >= 0 ) nowpage--; if (x == 2 && (nowpage + 1 ) <= num - 4 ) nowpage++; $(".im" ).hide (); for (s = 0 ; s <= 3 ; s++) { t = s * 1 + nowpage * 1 ; $("#ssaa" + t).show () } } pp (); </script >
海報展示區 繼續設計海報主題區域。試著任意一張假圖片與標題文字為版型的調整試作。多利用 chrome 慢慢調整 style,開始設計版型。同時多了 flex 容器方便做效果使用。
修改 main.php main.php
更改為
main.php <div style ="display:flex;justify-content:center;height:300px" > <ul class ="lists" style ="transform:scale(1); transition:transform 0.5s;" > <img id =simg src ="img/03A07.jpg" style ="height:90%;width:auto" > <div id =stxt class =ct > 1234</div > </ul > </div >
點選播放 點選過後的 JavaScript 處理動作為:
取得新替換的文字與圖片
根據特效設定決定不同的效果轉場,先轉出,替換,再轉入
取得目前替換的 ID 為何,之後讓自動播放可以知道下一張該換誰
修改 main.php main.php function ani (id ) { img = $("#ssaa" + id).attr ("src" ); txt = $("#ssaa" + id).attr ("alt" ); <?php $re = select ("q3t5_effect" , 1 ); $eft = $re[0 ]['once' ]; ?> switch (<?= $eft ?>) { case 1 : $(".lists" ).fadeToggle (() => { $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).fadeToggle (); }); break ; case 2 : $(".lists" ).css ('transform' , 'scale(0)' ); setTimeout (() => { $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).css ('transform' , 'scale(1)' ); }, 500 ); break ; case 3 : $(".lists" ).animate ({ left : "-400px" }, () => { $(".lists" ).css ("left" , "400px" ); $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).animate ({ left : "0" }); }); break ; } run = id; }
自動播放 當點選效果都能正常動畫時,設計一個自動會去執行 ani(參數),最後一張的 ID 最大是多少記得回到第一張輪播
修改 main.php main.php function auto ( ) { run = (run == (num - 1 )) ? 0 : run + 1 ; ani (run); } setInterval (auto, 3000 );ani (0 );
ani(0) 是讓畫面載入時先跑第一張
以下為 main.php
完整代碼
main.php <div class ="half" style ="vertical-align:top;" > <h1 > 預告片介紹</h1 > <div class ="rb tab" style ="width:95%;" > <div id ="abgne-block-20111227" > <div style ="display:flex;justify-content:center;height:300px" > <ul class ="lists" style ="transform:scale(1); transition:transform 0.5s;" > <img id =simg src ="img/03A07.jpg" style ="height:90%;width:auto" > <div id =stxt class =ct > 1234</div > </ul > </div > <ul class ="controls" style ="height:100px" > <img src ="img/left.jpg" style ="padding:40px 0" onclick ="pp(1)" > <?php $re = select("q3t5_img", "dpy=1 order by odr"); $num = count($re); foreach ($re as $key => $ro) echo '<img class="im" id="ssaa' . $key . '" onclick="ani(' . $key . ')" style="height:100%" src="img/' . $ro['img'] . '" alt="' . $ro['text'] . '">'; ?> <img src ="img/right.jpg" style ="padding:40px 0" onclick ="pp(2)" > </ul > <script > var nowpage = 0 , num = <?= $num ?>; function pp (x ) { var s, t; if (x == 1 && nowpage - 1 >= 0 ) nowpage--; if (x == 2 && (nowpage + 1 ) <= num - 4 ) nowpage++; $(".im" ).hide (); for (s = 0 ; s <= 3 ; s++) { t = s * 1 + nowpage * 1 ; $("#ssaa" + t).show () } } pp (); function ani (id ) { img = $("#ssaa" + id).attr ("src" ); txt = $("#ssaa" + id).attr ("alt" ); <?php $re = select ("q3t5_effect" , 1 ); $eft = $re[0 ]['once' ]; ?> switch (<?= $eft ?>) { case 1 : $(".lists" ).fadeToggle (() => { $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).fadeToggle (); }); break ; case 2 : $(".lists" ).css ('transform' , 'scale(0)' ); setTimeout (() => { $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).css ('transform' , 'scale(1)' ); }, 500 ); break ; case 3 : $(".lists" ).animate ({ left : "-400px" }, () => { $(".lists" ).css ("left" , "400px" ); $("#simg" ).attr ("src" , img); $("#stxt" ).text (txt); $(".lists" ).animate ({ left : "0" }); }); break ; } run = id; } function auto ( ) { run = (run == (num - 1 )) ? 0 : run + 1 ; ani (run); } setInterval (auto, 3000 ); ani (0 ); </script > </div > </div > </div > <div class ="half" > <h1 > 院線片清單</h1 > <div class ="rb tab" style ="width:95%;" > <table > <tbody > <tr > </tr > </tbody > </table > <div class ="ct" > </div > </div > </div >
No.7 後台院線片清單管理 (25%) 版型可從第五題開始複製調整,步驟應先設計版型、新增、修改刪除、單獨修改。因版型來自複製修改,程度夠可以連同版型一口氣弄好修改刪除功能之初階段,之後可新增時再做驗證測試。
顯示+修改+排序+刪除的版型 跟第五題不同的是欄位較多,版型不用太配合,只要該顯示資訊該有功能使用即可。
新增電影的連接按鈕放到上面,帶到 do=vvadd 之頁面
單修改的連結按鈕到 api.php?do=vvchg 之處理
單一刪除的連結則是 vvdel,利用 GET 抓 ID
批次修改排序的連結則是 vvmdy
因 update 會拆成一筆筆,所以每一個欄位都需要利用格數當作 id 索引。
排序效果跟第五題一樣,透過數字來控制就好。
影片分級的圖片記得命名為 1.2.3.4(跟資料庫內的命名相同)
建立 vv.php(參考 rr.php) vv.php <h3 class ="ct" > 電影清單</h3 > <input type ="button" value ="新增電影" onclick ="<?= jlo(" ?do =vvadd ") ?> "><hr > <form action ="api.php?do=vvmdy" method ="post" class ="ct" > <table width =100% > <?php $re = select("q3t7_movie", "1 order by odr"); foreach ($re as $ro) { ?> <tr > <td rowspan =3 > <img width =100 src ="img/<?= $ro['img'] ?>" alt ="" > </td > <td rowspan =3 valign ="center" > 分級:<img src ="img/<?= $ro['cls'] ?>.png" alt ="" > </td > <td > 片名:<?= $ro['title'] ?> 片長:<?= $ro['length'] ?> 上映日期:<?= $ro['date'] ?> </td > </tr > <tr > <td > 排序:<input type ="text" name ="odr[<?= $ro['id'] ?>]" value ="<?= $ro['odr'] ?>" > <input type ="button" value ="編輯電影" onclick ="<?= jlo(" ?do =vvchg&id =" . $ro['id']) ?>" > <input type ="button" value ="刪除電影" onclick ="<?= jlo(" api.php ?do =vvdel&id =" . $ro['id']) ?>" > </td > </tr > <tr > <td > 劇情介紹:<?= $ro['text'] ?></td > </tr > <tr > <td colspan =3 > <hr > </td > </tr > <?php } ?> </table > <div class ="ct" > <input type ="submit" value ="編輯排序" > </div > </form >
修改排序與單一刪除處理 修改排序直接丟函式就好,反而刪除部分要利用 GET 產生一個陣列處理刪除部分
增建 api.php api.php case 'vvmdy' : update ($_POST , "q3t7_movie" ); plo ("admin.php?do=vv" ); break ; case 'vvdel' : $_POST ['del' ][] = $_GET ['id' ]; delete ($_POST , "q3t7_movie" ); plo ("admin.php?do=vv" ); break ;
新增單筆電影 欄位較多,求快可以直接 br 處理而不用 table。日期依題目要求分三欄。之後提交 api 再另行合併。
建立 vvadd.php vvadd.php <form action ="api.php?do=vvadd" method ="post" enctype ="multipart/form-data" > 影片資料 <hr > 片名:<input type ="text" name ="title" id ="" > <br > <br > 分級: <select name ="cls" id ="" > <option value ="1" > 普遍級</option > <option value ="2" > 保護級</option > <option value ="3" > 輔導級</option > <option value ="4" > 限制級</option > </select > <br > <br > 片長:<input type ="text" name ="length" id ="" > <br > <br > 上映日期: <select name ="yy" id ="" > <option value ="" > 西元年</option > <?php for ($i = date("Y"); $i < date("Y") + 2; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <select name ="mm" id ="" > <option value ="" > 月份</option > <?php for ($i = 1; $i < 13; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <select name ="dd" id ="" > <option value ="" > 日期</option > <?php for ($i = 1; $i < 32; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <br > <br > 發行商:<input type ="text" name ="corp" id ="" > <br > <br > 導演:<input type ="text" name ="corp" id ="" > <br > <br > 預告影片:<input type ="file" name ="video" id ="" > <br > <br > 電影海報:<input type ="file" name ="img" id ="" > <br > <br > 劇情簡介 <hr > <textarea name ="text" id ="" cols ="30" rows ="10" > </textarea > <br > <br > <input type ="submit" value ="新增" > </form >
增添 api.php 日期需要合併成一個 POST 欄位方便且合併完後要清除掉,insert 才能與 SQL 對應作業。檔案都需要拆開,一次只能丟一筆到 addfile() 並取得黨名。所以有的檔案都會被放置到 upload 且已被更名。
api.php case 'vvadd' : $_POST ['img' ] = addfile ($_FILES ['img' ]); $_POST ['video' ] = addfile ($_FILES ['video' ]); $_POST ['date' ] = $_POST ['yy' ] . "-" . $_POST ['mm' ] . "-" . $_POST ['dd' ]; unset ($_POST ['yy' ], $_POST ['mm' ], $_POST ['dd' ]); insert ($_POST , "q3t7_movie" ); plo ("admin.php?do=vv" ); break ;
修改單筆電影 兩者欄位與版型相同,建議求快就不需帶預設值。時間投資太大除了每個欄位都要設定舊值 value,select 也要判斷 selected 處,檔案上傳也是要在後端處理判斷是否有上傳,有才進行 file copy & update。建議直接就題目動作 提供修改功能 進行敷衍(才五分)。
新增 vvchg.php(參考 vvadd.php) vvchg.php <h3 class ="ct" > 修改電影資料</h3 > <form action ="api.php?do=vvchg&id=<?= $_GET['id'] ?>" method ="post" enctype ="multipart/form-data" > 影片資料 <hr > 片名:<input type ="text" name ="title[<?= $_GET['id'] ?>]" id ="" > <br > <br > 分級: <select name ="cls[<?= $_GET['id'] ?>]" id ="" > <option value ="1" > 普遍級</option > <option value ="2" > 保護級</option > <option value ="3" > 輔導級</option > <option value ="4" > 限制級</option > </select > <br > <br > 片長:<input type ="text" name ="length[<?= $_GET['id'] ?>]" id ="" > <br > <br > 上映日期: <select name ="yy" id ="" > <option value ="" > 年</option > <?php for ($i = date("Y"); $i < date("Y") + 2; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <select name ="mm" id ="" > <option value ="" > 年</option > <?php for ($i = 1; $i < 13; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <select name ="dd" id ="" > <option value ="" > 年</option > <?php for ($i = 1; $i < 32; $i++) echo '<option value="' . $i . '">' . $i . '</option>'; ?> </select > <br > <br > 發行商:<input type ="text" name ="corp[<?= $_GET['id'] ?>]" id ="" > <br > <br > 導演:<input type ="text" name ="corp[<?= $_GET['id'] ?>]" id ="" > <br > <br > 預告影片:<input type ="file" name ="video" id ="" > <br > <br > 電影海報:<input type ="file" name ="img" id ="" > <br > <br > 劇情簡介 <hr > <textarea name ="text[<?= $_GET['id'] ?>]" id ="" cols ="30" rows ="10" > </textarea > <br > <br > <input type ="submit" value ="修改" > </form >
增添 api.php 不考慮是否有抓到檔案,都直接做更新,沒有輸入或檔案就是會變空的內容。
api.php case 'vvchg' : $_POST ['img' ][$_GET ['id' ]] = addfile ($_FILES ['img' ]); $_POST ['video' ][$_GET ['id' ]] = addfile ($_FILES ['video' ]); $_POST ['date' ][$_GET ['id' ]] = $_POST ['yy' ] . "-" . $_POST ['mm' ] . "-" . $_POST ['dd' ]; unset ($_POST ['yy' ], $_POST ['mm' ], $_POST ['dd' ]); update ($_POST , "q3t7_movie" ); plo ("admin.php?do=vv" ); break ;
No.6 院線片清單 (40%) 做好第七題,你已經擁有一些資料。便可以開始設計前台。
設計院線片顯示區域 一開始需要設定一個有效時間差異三天(含當天),所以是今天,昨天,前天的上映日期為有效。則就是今天日期減兩天等於前天。設定好此時間差異做之後的判斷
增添 lib.php lib.php $minday =date ("Y-m-d" ,strtotime ("-2days" ));$today =date ("Y-m-d" );
修改 main.php 預設給的寫入位置<tr></tr>
,在內部建立四組 td。透過 td 指定寬度並設定 float:left,能製造出 2X2 的排版效果。先以假資訊模擬出適合的版型。示意圖的設計不符合比例,不用特別雷同只要有題目動作的操作與文字項目即可。
main.php <div class ="half" > <h1 > 院線片清單</h1 > <div class ="rb tab" style ="width:95%;" > <table width ="100%" style ="font-size:0.8rem" > <tr > <td width =210 style ="float:left;padding:20px 0" > <img src ="img/03B01.png" style ="float:left;width:50px;padding:10px" > AAA<br > 分級:<img src ="img/1.png" style ="height:1em" > <br > 上映日期:2020-05-22<br > <div style ="clear:both;text-align:center" > <input type ="button" value ="劇情簡介" onclick ="<?= jlo(" ?do =info&id =x ") ?> "> <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =x ") ?> "> </div > </td > <td width =210 style ="float:left;padding:20px 0" > <img src ="img/03B01.png" style ="float:left;width:50px;padding:10px" > AAA<br > 分級:<img src ="img/1.png" style ="height:1em" > <br > 上映日期:2020-05-22<br > <div style ="clear:both;text-align:center" > <input type ="button" value ="劇情簡介" onclick ="<?= jlo(" ?do =info&id =x ") ?> "> <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =x ") ?> "> </div > </td > <td width =210 style ="float:left;padding:20px 0" > <img src ="img/03B01.png" style ="float:left;width:50px;padding:10px" > AAA<br > 分級:<img src ="img/1.png" style ="height:1em" > <br > 上映日期:2020-05-22<br > <div style ="clear:both;text-align:center" > <input type ="button" value ="劇情簡介" onclick ="<?= jlo(" ?do =info&id =x ") ?> "> <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =x ") ?> "> </div > </td > <td width =210 style ="float:left;padding:20px 0" > <img src ="img/03B01.png" style ="float:left;width:50px;padding:10px" > AAA<br > 分級:<img src ="img/1.png" style ="height:1em" > <br > 上映日期:2019-04-21<br > <div style ="clear:both;text-align:center" > <input type ="button" value ="劇情簡介" onclick ="<?= jlo(" ?do =info&id =x ") ?> "> <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =x ") ?> "> </div > </td > </tr > </table > <div class ="ct" > </div > </div > </div >
接著在前置作業進行 select limit 每次四筆。規劃迴圈並指定好超連結。並注意題目要求上映有效為三天含當日。所以需要特別去計算:期限日≦上映日期≦今天。
main.php <div class ="half" > <h1 > 院線片清單</h1 > <div class ="rb tab" style ="width:95%;" > <table width ="100%" style ="font-size:0.8rem" > <tr > <?php $nw = (empty($_GET['page'])) ? 1 : $_GET['page']; $ba = ($nw - 1) * 4; $re = select("q3t7_movie", "'" . $minday . "'<=date and date<='" . $today . "' order by odr limit " . $ba . ",4"); foreach ($re as $ro) { ?> <td width =210 style ="float:left;padding:20px 0" > <img src ="img/<?= $ro['img'] ?>" style ="float:left;width:50px;padding:10px" > <?= $ro['title'] ?><br > 分級:<img src ="img/<?= $ro['cls'] ?>.png" style ="height:1em" > <br > 上映日期:<?= $ro['date'] ?><br > <div style ="clear:both;text-align:center" > <input type ="button" value ="劇情簡介" onclick ="<?= jlo(" ?do =info&id =" . $ro['id']) ?>" > <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =" . $ro['id']) ?>" > </div > </td > <?php } ?> </tr > </table > <div class ="ct" > </div > </div > </div >
規劃分頁導覽 使用函式庫設計的 navpage(table,sql,range,page) 回傳陣列,並轉為連接網址。找到
修改 main.php
為
main.php <div class ="ct" > <?php $pg = navpage("q3t7_movie", "'" . $minday . "'<=date and date<='" . $today . "' order by odr", 4, $nw); foreach ($pg as $key => $value) echo '<a href="?page=' . $value . '">' . $key . '</a>'; ?> </div >
劇情簡介版面 素材有提供劇情簡介版面,先前被放在 order.php 內而跟 order.php 內容無關,找到以下代碼存到 info.php 內 (被 div#mm 所包覆)
新增 info.php(抽取自 order.php) info.php <div style="background:#FFF; width:100%; color:#333; text-align:left" > <video src="movie/03B20v.avi" width="300px" height="250px" controls="" style="float:right;" ></video> <font style="font-size:24px" > <img src="Profile page_files/03B20.png" width="200px" height="250px" style="margin:10px; float:left" > <p style="margin:3px" >影片名稱 : <input type="button" value="線上訂票" onclick="lof('?do=order&id=4')" style="margin-left:50px; padding:2px 4px" class ="b2_btu "> </p > <p style ="margin :3px ">影片分級 : <img src ="Profile page_files /03C04 .png " style ="display :inline -block ;">限制級 </p > <p style ="margin :3px ">影片片長 : 時/分</p > <p style ="margin :3px ">上映日期 2014/02/14</p > <p style ="margin :3px ">發行商 : </p > <p style ="margin :3px ">導演 : </p > <br > <p style ="margin :10px 3px 3px 3px ; word -break :break -all "> 劇情簡介:<br > </p > </font > <table width ="100%" border ="0"> <tbody > <tr > <td align ="center "><input type ="button " value ="院線片清單" onclick ="lof ('?')"></td > </tr > </tbody > </table > </div >
並加入 select,調整為正確的內容顯示。ID 為透過 GET 取得該資訊。按鈕導向到 order.php?do=step1&id=xx.
info.php <?php $re = select("q3t7_movie", "id=" . $_GET['id']); $ro = $re[0]; ?> <div style ="background:#FFF; width:100%; color:#333; text-align:left" > <video src ="img/03B20v.avi" width ="300px" height ="250px" controls ="" style ="float:right;" > </video > <font style ="font-size:24px" > <img src ="img/<?= $ro['img'] ?>" width ="200px" height ="250px" style ="margin:10px; float:left" > <p style ="margin:3px" > 影片名稱 :<?= $ro['title'] ?> <input type ="button" value ="線上訂票" onclick ="<?= jlo(" order.php ?do =step1&id =" . $_GET['id']) ?>" style ="margin-left:50px; padding:2px 4px" class ="b2_btu" > </p > <p style ="margin:3px" > 影片分級 : <img src ="img/<?= $ro['cls'] ?>.png" style ="display:inline-block;" > </p > <p style ="margin:3px" > 影片片長 : <?= $ro['length'] ?></p > <p style ="margin:3px" > 上映日期 : <?= $ro['date'] ?></p > <p style ="margin:3px" > 發行商 : <?= $ro['corp'] ?></p > <p style ="margin:3px" > 導演 : <?= $ro['maker'] ?></p > <br > <p style ="margin:10px 3px 3px 3px; word-break:break-all" > 劇情簡介:<br > <?= $ro['text'] ?> </p > </font > <table width ="100%" border ="0" > <tbody > <tr > <td align ="center" > <input type ="button" value ="院線片清單" onclick ="<?= jlo('index.php') ?>" > </td > </tr > </tbody > </table > </div >
導向到 Order 的畫面於第八題時設計,記住要設計會有 GET[id] 能提供給 order 做自動選取電影。第八題會有 step1,step2,step3 等不同的動作。
No.8 前台線上訂票 (35%) 題目要求有三個步驟:選取電影場次、選取座位、結果顯示。因此你會需要設計 URL 轉址參數。
電影場次的下拉選單透過 ajax api 進行查詢回傳。同時去搜索 table.seat 座位(陣列以字串儲存,取出時轉回陣列並計算列數)
選取座位有條件選擇,透過 JQ 去控制超過四筆不顯示。以及資料 select 時,有資料不提供 checkbox
結果顯示的流水號使用日期+索引組合即可,題目要求沒有很明確流水號的方式。
table.q3t8_book 的欄位只需要索引,電影 ID, 訂購日,場次,座位陣列 (string) 即可,訂購數可透過座位陣列算得。
先設計好 URL 轉址參數 之前已被抽取過主內容給 info.php,這裡直接改主內容區部分,找到
修改 order.php order.php <div id ="mm" > <div class ="tab rb" style ="width:87%;" > </div > </div >
改成
order.php <div id ="mm" > <div class ="tab rb" style ="width:87%;" > <?php include $main . ".php"; ?> </div > </div >
並在頁首 PHP 段落塞入參數
$main = (empty ($_GET ['do' ])) ? "step1" : $_GET ['do' ];
STEP1 訂票選單
依據題目初始有 已知 movie id 跟 沒有選擇 兩種來源。接著每次點選需對應相對的其次欄位內容。
這裡需要 JQ 搭配 AJAX 來完成下拉選單的內值。根據前一項 select 標籤的變化去做 ajax 出後一項的內容。
select 標籤的影響為 電影=> 影響有效日期(在 api.php 處理),日期=> 影響是否今日有效時段(在 JS 內提供一個參數是否為今日,在 php 內做顯示從幾筆開始輸出)
同時注意只能撈取顯示有效期限的電影。提交到 step2.php 建議採用 target=”_blank” 利於回到本頁面仍有舊選項之要求。
建立 step1.php step1.php <form action ="?do=step2" method ="post" target ="_blank" > 電影:<select name ="mm" id ="sm" onchange ="gd()" > <?php $re = select("q3t7_movie", "'" . $minday . "'<=date and date<='" . $today . "'"); foreach ($re as $ro) echo '<option value="' . $ro['title'] . '" ' . ((!empty($_GET['id']) && $_GET['id'] == $ro['id']) ? "selected" : "") . '>' . $ro['title'] . '</option>'; ?> </select > 日期:<select name ="dd" id ="sd" onchange ="gt()" > </select > 場次:<select name ="tt" id ="st" > </select > <br > <br > <input type ="submit" value ="確定" > <input type ="reset" value ="重置" > </form >
JS 部分,透過 AJAX 提交到 api.php 處理回傳
當選擇電影有變化時,自動呼叫 gd() 去算出有效日期的選項。
若一開始就有帶 MOVE ID 參數,也會自動去跑 getdate()
當選擇日期時,呼叫 getime() 算出時間場次。
執行 getimeg 時,當日期等於今天時,today 成立,否則為不。
最後都由 api.php 進行 SQL 分析與輸出處理。
此時 JS 規劃為
step1.php <script > if ($("#sm" ).length >0 ) gd ();function gd ( ){ title=$("#sm" ).val (); $.post ("api.php?do=gd" ,{title},(re )=> { $("#sd" ).html (re); gt (); }); } function gt ( ){ title=$("#sm" ).val (); date=$("#sd" ).val (); $.post ("api.php?do=gt" ,{title,date},(re )=> { $("#st" ).html (re); }); } </script >
增添 api.php AJAX 提交動作的處理
api.php case 'gd' : $re = select ("q3t7_movie" , "title='" . $_POST ['title' ] . "'" ); $ro = $re [0 ]; $num = (strtotime ($ro ['date' ]) - strtotime ($minday )) / 3600 / 24 ; for ($i = 0 ; $i <= $num ; $i ++) echo '<option value="' . date ("Y-m-d" , strtotime ("+" . $i . "days" )) . '">' . date ("Y-m-d" , strtotime ("+" . $i . "days" )) . '</option>' ; break ; case 'gt' : $re = select ("q3t8_book" , "movie='" . $_POST ['title' ] . "' and date='" . $_POST ['date' ] . "'" ); $ary = array (0 , 0 , 0 , 0 , 0 ); foreach ($re as $ro ) $ary [$ro ['time' ]] += count (unserialize ($ro ['seat' ])); $now = (date ("H" ) >= 14 && $today == $_POST ['date' ]) ? floor (date ("H" ) / 2 - 6 ) : 0 ; for ($i = $now ; $i < 5 ; $i ++) echo '<option value="' . $i . '">' . $seat [$i ] . ' 剩餘座位 ' . (20 - $ary [$i ]) . '</option>' ; break ;
增添 lib.php 這裡加一段座位的代碼到公用 PHP 表內,後面會重複用到
$seat [0 ]="14:00~16:00" ;$seat [1 ]="16:00~18:00" ;$seat [2 ]="18:00~20:00" ;$seat [3 ]="20:00~22:00" ;$seat [4 ]="22:00~24:00" ;
STEP2 選位功能
取得 step1.php 得來的資料進行版面規劃,並還要再包一次到 input:hidden。才能在 step3.php 真正做總資料處理。
算位置時利用迴圈去跑,同時每五筆斷行。同時負責 seat 的資料為字串化陣列,需轉回陣列格式 (unserialize)
訂單多筆有多筆不一樣的陣列。需要一個新陣列每次加入合併這些 foreachf 取的單陣列。
JS 部分要記錄點選 checkbox 數量並阻止超過選擇數
最後送出到 api.php,進行 order 作業
建立 step2.php step2.php <form action ="api.php?do=order" method ="post" > <?php $re = select("q3t8_book", "movie='" . $_POST['mm'] . "' and date='" . $_POST['dd'] . "' and time=" . $_POST['tt']); $set = array(); foreach ($re as $row) $set = array_merge($set, unserialize($row['seat'])); //將所有該時段的多筆座位陣列都倒入到一個新陣列 for ($i = 1; $i < 21; $i++) { if (in_array($i, $set)) echo '<img src="img/03D03.png" style="padding-right:30px">'; else echo ' <img src="img/03D02.png" alt=""> <input class="seat" type="checkbox" name="ss[]" value="' . $i . '"> '; if ($i % 5 == 0) echo '<br>'; } ?> <hr > <input type ="hidden" name ="movie" value ="<?= $_POST['mm'] ?>" > <input type ="hidden" name ="date" value ="<?= $_POST['dd'] ?>" > <input type ="hidden" name ="time" value ="<?= $_POST['tt'] ?>" > 您選擇的電影是:<?= $_POST['mm'] ?><br > 您選擇的時刻是:<?= $_POST['dd'] ?> <?= $seat[$_POST['tt']] ?><br > 您勾選了<span id =nn > 0</span > 張票,最多可購買 4 張票<br > <input type ="button" value ="上一步" onclick ="window.close()" > <input type ="submit" value ="確定" > </form >
JS 部分,從 0 開始數,每一次被 check 打勾時,如果還沒超過 4 就繼續數,否則把打勾取消。反之被取消打勾就記數少一
step2.php num = 0 ; $(".seat" ).click (function ( ) { if (this .checked ) (num < 4 ) ? num++ : this .checked = false ; else num--; $("#nn" ).text (num); });
增添 api.php 進行資料上傳,並先將 seat 陣列給字串化。這樣一筆訂單就是一筆 DATA,方便訂單管理。
api.php case 'order' : $_POST ['seat' ] = serialize ($_POST ['ss' ]); $_POST ['buydate' ] = date ("Y-m-d" ); unset ($_POST ['ss' ]); $id = insert ($_POST , "q3t8_book" ); plo ("order.php?do=step3&id=" . $id ); break ;
STEP3 檢視訂票結果 很簡單的做撈取動作,訂單編號部分利用日期與 ID 合併即可,不需要特地在設計該 SQL 欄位。
建立 step3.php step3.php <?php $re = select("q3t8_book", "id=" . $_GET['id']); $ro = $re[0]; $seq = date("Ymd0000", strtotime($ro['buydate'])) + $ro['id']; $ss = unserialize($ro['seat']); ?> 訂單資訊:<?= $seq ?> <hr > 您選擇的電影是:<?= $ro['movie'] ?><br > 您選擇的時刻是:<?= $ro['date'] ?> <?= $seat[$ro['time']] ?><br > 您勾選的座位是:<br > <?php foreach ($ss as $value) echo $value . '號<br>'; ?>
No.9 後台電影票訂單管理 (25%) 先試著在前台新增多筆訂單,接著在進行後台設計。主要重點在於刪除功能,分為單筆刪除與批次刪除。難度不高,只需記得單筆刪除直接使用 onclick 帶 GET 網址到 api 處理即可。至於批次刪除利用 form 表單搭配 input typey 到 api 處理。處理批次只需對 where 描述正確即可。
清單檢視版型 這題不適合參考任何前面的版型,重新畫一個 table 會比較快。
建立 orderlist.php orderlist.php <table width ="100%" > <tr > <td > 訂單編號</td > <td > 電影名稱</td > <td > 觀看日期</td > <td > 場次時間</td > <td > 訂購數量</td > <td > 訂購位置</td > <td > 操作</td > </tr > <?php $re = select("q3t8_book", "1 order by id desc"); foreach ($re as $ro) { $seq = date("Ymd0000", strtotime($ro['buydate'])) + $ro['id']; $ss = unserialize($ro['seat']); ?> <tr > <td > <?= $seq ?></td > <td > <?= $ro['movie'] ?></td > <td > <?= $ro['date'] ?></td > <td > <?= $seat[$ro['time']] ?></td > <td > <?= count($ss) ?></td > <td > <?php foreach ($ss as $value) echo $value . '號<br>'; ?> </td > <td > <input type ="button" value ="刪除" onclick ="<?= jlo(" api.php ?do =orderdel&id =" . $ro['id']) ?>" > </td > </tr > <?php } ?> </table >
單獨刪除功能 取得訂單 ID 針對該訂單刪除
增添 api.php api.php case 'orderdel' : $_POST ['del' ][] = $_GET ['id' ]; delete ($_POST , "q3t8_book" ); plo ("admin.php?do=orderlist" ); break ;
快速刪除之版型 題目要求需要快速刪除前有提示,所以 from 多個 onsubmit 的 JS 動作。radio 咬個 required 比較不會被亂搞。
修改 orderlist.php orderlist <h3 class ="ct" > 訂單清單</h3 > <hr > <form action ="api.php?do=orderfast" method ="post" onsubmit ="return confirm('幹你確定嗎?')" > <input type ="radio" name ="sw" value ="1" required > 依日期 <input type ="date" name ="date" > <input type ="radio" name ="sw" value ="2" > 電影名稱 <select name ="movie" > <?php $re = select("q3t7_movie", 1); foreach ($re as $ro) echo '<option value="' . $ro['title'] . '">' . $ro['title'] . '</option>'; ?> </select > <input type ="submit" value ="快速刪除" > </form > <hr >
增添 api.php 判斷何種刪除法,做對應刪除之條件
api.php case 'orderfast' : switch ($_POST ["sw" ]) { case 1 : $post ['delat' ] = "date='" . $_POST ['date' ] . "'" ; break ; case 2 : $post ['delat' ] = "movie='" . $_POST ['movie' ] . "'" ; break ; } delete ($post , "q3t8_book" ); plo ("admin.php?do=orderlist" ); break ;
END 調整版面 (5%) 這題動作如果來不及做可以放棄,元素材差異性下有可能不會被考官所注意到。
修改 index.php & admin.php & order.php 找到主區域的 div 修改為
index.php & admin.php & order.php <div id ="main" style ="overflow-y: scroll;width: 1024px;height: 768px;margin: 10px auto;border: 0;" >
修改 main.php 院線片清單版型有被擠壓到跑版,對 main.php 的這部分調整一下到 100%
main.php <div class ="rb tab" style ="width:100%;" >
修改 admin.php 雖然題目未提及,如果有空則消除無效的連結
admin.php <div class ="ct a rb" style ="position:relative; width:101.5%; left:-1%; padding:3px; top:-9px;" > <a href ="#" > 網站標題管理</a > | <a href ="#" > 動態文字管理</a > | <a href ="?do=rr" > 預告片海報管理</a > | <a href ="?do=vv" > 院線片管理</a > | <a href ="?do=orderlist" > 電影訂票管理</a > </div >
透過 Chrome 遊覽器檢查可以得到 1024*768 且上下左右 10px 並垂直至中的動作要求。