0%

我們使用到了物件導向來宣告了一個類別DB,這個類別足夠可以處理題組一大多數的功能,為了更好的在解題是可以快速的應用到這個類別的功能,因為我們建立一個共用函式檔,將整個題組都會用到的變數及函式都集中放到這個檔案中,再透過include的方式將檔案匯入到最主要的index.php及back.php,由於這兩個檔案會再include各個子頁面,因此相當於所有的頁面都可以使用到這個共用函式檔的變數。

同時我們也把一些好用的小函式集中放在一個檔案中,透過include的方式讓各個頁面都能使用到這些類別及函式。

建立題組專用共用函式檔

/db.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
31
32
33
34
35
36
37
38
39
40
session_start();       //啟用session功能
date_default_timezone_set("Asia/Taipei"); //設定網站的時區為亞洲台北

//簡易的自訂函式
/**
* 用來顯示陣列內容-除錯時使用
*/
function dd($array){
echo "<pre>";
print_r($array);
echo "</pre>";
}

/**
* 簡化header('location:')的使用
* 將請求導向其他檔案或頁面
*/
function to($url){
header("location:".$url);
}

/**
* 用來處理較複雜的sql語句,比如子查詢或聯表查詢
* 預設回傳的資料是2維陣列
*/
function q($sql){
$pdo=new PDO("mysql:host=localhost;charset=utf8;dbname={your db name}",'root','');
return $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}

//宣告各個類別的物件變數
$Title=new DB('titles');
$Total=new DB('total');
$Bottom=new DB('bottom');
$Ad=new DB('ad');
$Mvim=new DB('mvim');
$Image=new DB('image');
$News=new DB('news');
$Admin=new DB('admin');
$Menu=new DB('menu');

接著將這個檔案引入到 index.phpbackend.php 中:

/index.php

1
2
3
4
5
<?php include_once "db.php";?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

/back.php

1
2
3
4
5
<?php include_once "db.php";?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

每個題組依狀況不同,在這一步有不同的做法,視自己對題目的熟悉程度來做應變,可以一次把全部資料表建完,也可以視解題的進度來逐步建立或修改資料表。
這裏我們採用的做法是利用phpmyadmin的複製資料表功能,快速的複製五張欄位雷同的資料表(title,ad,mvim,image,news),
,依據需要再去修改欄位的內容,也可以不用改,五張類似的資料表並不是所有的欄位都會用得上。

閱讀全文 »

  1. 開立./css, ./js, ./img, ./icon, ./api, ./front, ./back,等常用目錄以利檔案分類及管理
  2. 將素材檔中的.css, .js, 及icon圖檔複製到相應的目錄下
  3. 更改版型素材的相關檔名,以符合解題的需要
    • 01P01.html => login.php
    • 01P02.html => index.php
    • 01P03.html => back.php
    • 01P04.html => news.php
      閱讀全文 »

API串接過程中,並非每次都能順利進行,尤其是當問題來自提供API的那一方時,常見的問題如下:

  • CORS問題
  • 資料數量過大
  • 資料格式為json以外的文字檔案(.txt,.csv,.xml…)

我提供幾個自己的經驗,做為遇到以上問題時的基本排除原則,具體做法還是要看API的狀況來決定。

閱讀全文 »

結帳櫃台功能

  1. 建立 ./view/front/checkout.php 檔案,並先把畫面需要的html碼建立出來,可以分別從 buycart.phpreg.php中複製程式碼過來修改
    收件人表單可從reg.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
    31
    32
    33
    34
    <h2 class="ct">填寫資料</h2>
    <?php $user=$User->find(['acc'=>$_SESSION['user']]);?>
    <table class="all">
    <tr>
    <td class="tt ct">帳號</td>
    <td class="pp">
    <?=$user['acc'];?>
    </td>
    </tr>
    <tr>
    <td class="tt ct">姓名</td>
    <td class="pp">
    <input type="text" name="name" id="name" value="<?=$user['name'];?>">
    </td>
    </tr>
    <tr>
    <td class="tt ct">電話</td>
    <td class="pp">
    <input type="text" name="tel" id="tel" value="<?=$user['tel'];?>">
    </td>
    </tr>
    <tr>
    <td class="tt ct">住址</td>
    <td class="pp">
    <input type="text" name="addr" id="addr" value="<?=$user['addr'];?>">
    </td>
    </tr>
    <tr>
    <td class="tt ct">電子信箱</td>
    <td class="pp">
    <input type="text" name="email" id="email" value="<?=$user['email'];?>">
    </td>
    </tr>
    </table>

    商品小計可以從buycart.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
    31
    32
    33
    34
    <table class="all">
    <tr class="tt ct">
    <td>商品名稱</td>
    <td>編號</td>
    <td>數量</td>
    <td>單價</td>
    <td>小計</td>
    </tr>
    <?php
    $sum=0; //宣告一個變數來計算總計
    foreach($_SESSION['cart'] as $id => $qt){
    $row=$Goods->find($id);
    ?>
    <tr class="pp ct">
    <td><?=$row['name'];?></td>
    <td><?=$row['no'];?></td>
    <td><?=$qt;?></td>
    <td><?=$row['price'];?></td>
    <td><?=$row['price']*$qt;?></td>

    </tr>
    <?php
    //迴圈每跑完一個商品就計算一次總計
    $sum += $row['price']*$qt;
    }
    ?>
    </table>
    <div class="all tt ct">總價:<?=$sum;?></div>
    <div class="ct">
    <input type="hidden" name="sum" id="sum" value="<?=$sum?>">
    <input type="button" value="確定送出" onclick="checkout()">
    <input type="button" value="返回修改訂單" onclick="location.href='?do=buycart'">
    </div>

  2. 在傳送訂單資料方面我們採用ajax的方式來傳送表單的內容,這樣在處理彈出視窗訊息時會比較單純一些。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function checkout(){
    let user={};
    user.name=$("#name").val();
    user.tel=$("#tel").val();
    user.addr=$("#addr").val();
    user.email=$("#email").val();
    user.total=$("#sum").val();

    $.post("./api/checkout.php",user,()=>{
    alert("訂購完成\n感謝您的選購")
    location.href='index.php';
    })
    }
  3. 建立 /api/checkout.php 來接收訂單資訊並寫入訂單資料表中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    include_once "../base.php";

    //依據題意產生訂單編號,後六碼我們使用亂數來產生即可
    $_POST['no']=date("Ymd").rand(100000,999999);

    $_POST['acc']=$_SESSION['user'];

    $_POST['orderdate']=date("Y-m-d");

    //將購物實陣列轉為字串
    $_POST['cart']=serialize($_SESSION['cart']);

    $Order->save($_POST);
  4. 另外一個題目沒提到的細節是在送出訂單後的購物車及會員登入狀態要怎麼處理?如果檢定時只照題目的流程走一遍,那做到寫入訂單就可以了,但是當要操作第二筆訂單時,就會發生原有的購物車內容還有上一筆訂單的資料在的狀況,所以這邊建議如果時間上來得及,同時也已經做到這一步了,可以把一些細節補上,這樣在評分時會減少一些爭議。

  5. 我的做法是在ajax傳送表單資料後彈出感謝訊息的視窗,然後把使用者導回首頁去;而此同時,在後端的api除了收集ajax傳來的內容並寫入資料表外,也會同時清除購物車的session內容,這樣使用者就有一台空的購物車可以進行第二筆訂單。
    /api/checkout.php

    1
    2
    3
    //刪除購物車(檢定可不做)
    unset($_SESSION['cart']);

補充

…headers already sent by… 錯誤,這個問題是在 sessionheader() 相關的函式使用時會發生的問題,一般來說這些指令的前面不能有任何的輸出,如果發生了,可以使用函式來開啟緩衝解決;或是直接修改 php.ini 中的輸出緩衝設定也可以

1
2
3
output_buffering=4096
or
output_buffering=on