iT邦幫忙

1

#更新內容 php篩選資料至網頁上呈現問題(文有點長)

#更新-功能已完成
謝謝留言每個大家的建議
抱歉因後來忙著解決問題所以後面沒有一一回覆
但留言我都有看過了也增長許多新知識 很謝謝大家
至於我想要的功能已經實作出來了
目前也先把連線方式依照大家的建議改成用PDO去連線
剩下還需要改善的地方就慢慢來吧~
專題快截止了我還有一個功能沒做....(扶額)
以下附上程式碼給之後有需要的人可以參考
再次謝謝大家 我會再繼續加油!
P.S 後來發現放置網站的地方有建好資料庫了,所以就沒有GCP的問題了XD

howToPay.php

<?php

require 'Results.php';

// 使用PDO方式連線資料庫
try {
    $pdo = new PDO('mysql:host=localhost;dbname=資料庫名稱;charset=utf8mb4','帳號','密碼');
}
catch(PDOException $e){
    die($e->getMessage());
}

//取得前一頁選擇的選項
$card = $_GET["card"];
$week = $_GET["week"];
$type = $_GET["type"];

//SQL查詢語法
$sql = "SELECT `creditcard`,`payType`,`payment`,`sale` FROM `info` WHERE `creditcard` = '".$card."' AND `week` = '".$week."' AND `type` = '".$type."'";
// echo $sql;
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_CLASS, 'Results');

//列出所有查詢後回傳的資料
// var_dump($results);

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>幫我搭配結果</title>
    <link rel="stylesheet" href="normalize.css">
    <script type = "text/javascript" src="jquery-3.5.1.js"></script>
</head>
<body>
    <nav>
        <img src="img/Howpay-320.png" alt="logo">
    </nav>

    <h2>搭配結果</h2>
    <table>
        <tr>
            <td>卡片</td>
            <td>商家</td>
            <td>支付工具</td>
            <td>優惠訊息</td>
        </tr>
        <?php foreach($results as $results) : ?>
            <?='<tr>';?>
                <?= '<td>'.$results->creditcard.'</td>';?>
                <?= '<td>'.$results->payType.'</td>';?>
                <?= '<td>'.$results->payment.'</td>';?>
                <?= '<td>'.$results->sale.'</td>';?>
            <?='</tr>';?>
        <?php endforeach; ?>
        <?='</table>';?>
    </table>

</body>
</html>

Results.php

<?php

class Results {

    public $creditcard;
    public $payType;
    public $payment;
    public $sale;
}

?>

顯示結果如下
https://ithelp.ithome.com.tw/upload/images/20200916/20130100NrBr2GqlUo.png

(以下舊文)

各位安安~~
小的最近在畢專製作過程中遇到很大的問題
這是我第一次寫網頁所以很多概念語法都是最近上網看很多教學惡補的
懇請各位高手幫忙QQ
我想要做的功能如下:

  1. 使用者在這一頁選擇篩選條件
    (網頁在這:https://howpay.nde.tw/howToPay.html
    程式碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>幫我搭配</title>
    <link rel="stylesheet" href="normalize.css">
</head>
<body>
    
    <nav>
        <img src="img/Howpay-320.png" alt="logo">
    </nav>
    <form action="howToPay.php" method="GET" target="_self">
        <p>選擇信用卡</p>
        <select id="card" name="card">
            <option value="大戶卡">大戶卡</option>
            <option value="LINEPAY信用卡">Line Pay信用卡</option>
            <option value="GOGO卡">GOGO卡</option>
            <option value="UBear卡">Ubear卡</option>
            <option value="Costco聯名卡">Costco聯名卡</option>
            <option value="Pi聯名卡">Pi聯名卡</option>
            <option value="街口聯名卡">街口聯名卡</option>
            <option value="賴點卡">賴點卡</option>
            <option value="饗樂生活卡">饗樂生活卡</option>
        </select>
        <p>選擇消費星期</p>
        <select id="week" name="week">
            <option value="7">星期日</option>
            <option value="1">星期一</option>
            <option value="2">星期二</option>
            <option value="3">星期三</option>
            <option value="4">星期四</option>
            <option value="5">星期五</option>
            <option value="6">星期六</option>
        </select>
        <p>選擇消費類型</p>
        <select id="type" name="type">
            <option value="日常用品">日常用品</option>
            <option value="購物網站">購物網站</option>
            <option value="美妝保養">美妝保養</option>
            <option value="美容美髮服務業">美容美髮服務業</option>
            <option value="餐飲業">餐飲業</option>
            <option value="服飾包鞋">服飾包鞋</option>
            <option value="3C產品">3C產品</option>
            <option value="休閒娛樂">休閒娛樂</option>
            <option value="文教育樂用品">文教育樂用品</option>
            <option value="教育學習">教育學習</option>
            <option value="百貨公司">百貨公司</option>
            <option value="旅館飯店業">旅館飯店業</option>
            <option value="眼鏡行">眼鏡行</option>
            <option value="醫藥零售">醫藥零售</option>
            <option value="寵物用品及美容">寵物用品及美容</option>
            <option value="加油站">加油站</option>
            <option value="叫車服務">叫車服務</option>
            <option value="外送服務">外送服務</option>
            <option value="租車服務">租車服務</option>
            <option value="航空業">航空業</option>
        </select>
        <p>
            <input type="submit" value="確定">
        </p>
        
    </form>
    
</body>
</html>
  1. 按下確定鈕後如上所示程式碼跳轉到howToPay.php
    理想狀況是依照前一頁選擇的條件到資料庫去做篩選後回傳結果
    並且以表格的方式呈現
    程式碼如下:(資料庫帳密已做隱藏處理,下面三行echo只是想確認有沒有抓到前一頁選擇的值,之後確定沒問題會刪掉)
    P.S資料庫目前放在GCP上,連線速度不知道為什麼超級慢....有人能順便解答嗎QQ
<?php
$servername = "35.229.234.152";
$username = "xxxxx";
$password = "xxxxx";

// Create connection
$conn = new mysqli($servername, $username, $password);

if ($connect->connect_error) {
    die("連線失敗: " . $connect->connect_error);
} else {
    echo "連線成功";
}



$card = $_GET["card"];
$week = $_GET["week"];
$type = $_GET["type"];

$sql = "SELECT creditcard, payType, payment, sale FROM info WHERE creditcard = '$card' and week = '$week' and type = '$type'";

$result = $conn->query($sql);

// header("Location: howToPayResult.html");
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>幫我搭配結果</title>
    <link rel="stylesheet" href="normalize.css">
    <script type = "text/javascript" src="jquery-3.5.1.js"></script>
</head>
<body>
    <nav>
        <img src="img/Howpay-320.png" alt="logo">
    </nav>
    <h2>搭配結果</h2>
    <table>
        <tr>
            <td>卡片</td>
            <td>商家</td>
            <td>支付工具</td>
            <td>優惠訊息</td>
        </tr>
        <?php
        while($row = mysqli_fetch_row($result)) {
            echo "<tr>";
            for($i=0;$i<mysqli_num_fields($result);$i++){
                echo "<td>",$row[$i],"</td>";
            }
            echo "</tr>";
        }
        ?>
    </table>
    <?php echo $card?>
    <?php echo $week?>
    <?php echo $type?>
</body>
</html>

以上程式跑出來的結果會長這樣
https://ithelp.ithome.com.tw/upload/images/20200915/201301005Oxr4gDWkI.png
沒辦法將我要的功能做出來
不確定是哪邊出問題或是我有少做什麼步驟
SQL語法也有先在資料庫內下Query確認過沒問題
請求大家幫忙QAQ

1
海綿寶寶
iT邦大神 1 級 ‧ 2020-09-15 11:41:38

先把

$conn = new mysqli($servername, $username, $password);

if ($connect->connect_error) {
    die("連線失敗: " . $connect->connect_error);
} else {
    echo "連線成功";
}

改成

$conn = new mysqli($servername, $username, $password);

if ($conn -> connect_errno) {
    die("連線失敗: " . $conn -> connect_error);
} else {
    echo "連線成功";
}

試看看

參考資料來源

看更多先前的回應...收起先前的回應...
listennn08 iT邦研究生 1 級 ‧ 2020-09-15 11:44:45 檢舉

這沒有幫助也按太快了/images/emoticon/emoticon38.gif

Pulin iT邦新手 5 級 ‧ 2020-09-15 11:47:03 檢舉

我剛剛改完後就變這樣了...
請問是資料庫根本沒有連接成功嗎?
https://ithelp.ithome.com.tw/upload/images/20200915/20130100OWgd40QGIq.png

Pulin iT邦新手 5 級 ‧ 2020-09-15 11:47:42 檢舉

啊啊澄清一下
沒有幫助不是我按的QQ

兩個問題(無顯示資料、回應時間很長),同一個原因
資料庫連接失敗

Pulin iT邦新手 5 級 ‧ 2020-09-15 11:57:58 檢舉

了解~
我想了一下,不確定是不是我在GCP的設定有問題
我晚點改成把資料庫建在老師提供的電腦試看看
或是請問有什麼其他可能的解決辦法嗎?

問題只有兩個可能:程式、GCP
兩個都是你做的
自己加油
祝你好運

Pulin iT邦新手 5 級 ‧ 2020-09-15 12:13:40 檢舉

好的瞭解了~
非常謝謝你的回答!
我會再加油試看看

1
ckp6250
iT邦研究生 4 級 ‧ 2020-09-15 11:46:56

資料庫目前放在GCP上,連線速度不知道為什麼超級慢....有人能順便解答嗎QQ

我有租用 GCP 好幾年了 , 就回答最簡單的這個吧。

GCP 是很快哦,至少比我公司租用固定IP的 40M/100M 快很多很多,所以,慢不是 GCP 的問題。

$conn = new mysqli($servername, $username, $password);

改用 pdo 去個連線吧,既然您是初學,就學新的吧。

google 一下 pdo , 和 mysqli 大同小異。

Pulin iT邦新手 5 級 ‧ 2020-09-15 11:48:38 檢舉

好的感謝你的回答~
那可能就是我程式碼有問題了QQ

Pulin iT邦新手 5 級 ‧ 2020-09-15 12:14:18 檢舉

好的~
我會再試著把它改成pdo
謝謝你的建議!

2

程式乍看之下沒什麼問題,先講 T-SQL 語法部分,有根據自己需要的資訊而去 SELECT 指定欄位,而不是濫用 * 來把資料通通倒出來,值得讚賞。

不過有些眉眉角角的地方如果改進,會讓你的應用程式在資料搜尋這部分更加快速,首先會建議對欄位前加入資料表名稱。

SELECT
	`info`.`creditcard` AS 'creditcard',
	`info`.`payType` AS 'payType',
	`info`.`payment` AS 'payment',
	`info`.`sale` AS 'sale'
FROM
	`info`
WHERE
	`info`.`creditcard` = '$card' 
AND
	`info`.`week` = '$week' 
AND
	`info`.`type` = '$type'

再來大量資料建議做分頁,因為不確定資料有多少筆,如果有幾十萬筆商品資料,那就會因為資料量龐大的問題,而所有時間都浪費在這點上,導致 Response timeout 的問題發生,為了避免這個問題,建議在最後加上 LIMIT 去限制搜尋範圍。

SELECT
	`info`.`creditcard` AS 'creditcard',
	`info`.`payType` AS 'payType',
	`info`.`payment` AS 'payment',
	`info`.`sale` AS 'sale'
FROM
	`info`
WHERE
	`info`.`creditcard` = '$card' 
AND
	`info`.`week` = '$week' 
AND
	`info`.`type` = '$type'
LIMIT
	0, 25

最後,不建議直接在網頁應用程式上直接使用 T-SQL 語法,應用程式與資料庫之間,應該使用 ORM(Object Relational Mapping) 來做連結,目前你的做法是 Server-side Render,無論是取資料、畫面繪製,通通都壓在伺服器端處理,會導致回傳時間拉更長,因此建議資料呈現上改為以 API 的形式來吐資料,畫面以 Client-side Render 的方式來顯示,這樣可以有效降低伺服器的負擔。

以上淺見。

看更多先前的回應...收起先前的回應...

補充一下,建議使用 ORM 的方式是降低被 SQL injection 的風險。

Pulin iT邦新手 5 級 ‧ 2020-09-15 12:11:58 檢舉

感謝你的回答與肯定~
我會再照你的建議來做修正
資料量因為只有700多筆資料所以當初沒有想太多只希望先求有再求好
至於建議中提到的ORM以及用API方式吐資料等我會再去查資料看要怎麼實作
非常感謝!!

淺水員 iT邦研究生 4 級 ‧ 2020-09-15 12:43:34 檢舉

補充一下比較基礎的

SQL Injection 部分,最早是用 escape 的方式,讓一些含有特殊字元的字串無法攻擊成功。

後來一些資料庫有支援 prepare 的方式,這可以避免 SQL Injection

mysqli 是 PHP 與資料庫互動的一組 API,其實 mysqli 有支援 prepare 的方式。(可以參考:w3c 的教學)如果要把前端的資料送到欄位中,會建議用 prepare 的方式。

在 mysqli 之後,其實現在大多數都改用 pdo 了,有位前輩拍過教學影片,有空可以參考。PHP PDO基礎介紹(影片版)

至於 ORM 是第三方所寫的函式庫,大部分也是 PHP 寫的,說穿了就是一組包裝後的 API。是否要使用是看個人或公司的選擇。除了避免 SQL Injection 之外,方便轉換不同的資料庫也是一個特點。不過有時候有些特殊需求還是會需要自己寫原生的 SQL 命令。

Pulin iT邦新手 5 級 ‧ 2020-09-15 13:12:41 檢舉

好的~非常感謝你的補充
我會再去找相關資料來看
謝謝你!

1
浩瀚星空
iT邦超人 1 級 ‧ 2020-09-15 13:28:16

上面都說完了,我只補充重點

1.一定要換pdo,雖然已經有人說了,但那太重要了,所以我要再強調一次。
2.從input下手,所謂的input就是指get或是post這些。嚴格點的需要指定變數類型。
常用的手法是將get或post的經過整理後放到一個物件變數內取用。

第二點的變數資料格式請求。我將我早期自已想的規則給你。雖然現在我大多已經都是直接用input物件來處理了。

數值型態的倒是不用太在意。只要能做數值轉換,一般不太可能能從這下手注入。比較麻煩的就是字串型態。
一般字串型態我會再區分str跟text。
str的處理,會先排除空白跟引號的部份。然後再做escape處理
text則比較沒辦法。只能先做 escape 處理。
早期我曾經用過html編碼轉換處理。但後來放棄,因為容量會增加很大。
也有過一次採用加密文處理。不過這招倒不是為了注入。有特殊需要做的。

做escape處理儲存到資料庫,再早期常用的如下

serialize
addslashes

後期則會依照性質搭配

json_encode
htmlspecialchars 

以上提供參考。

Pulin iT邦新手 5 級 ‧ 2020-09-16 15:58:08 檢舉

非常謝謝你的建議!

ke11vin30 iT邦新手 5 級 ‧ 2020-09-16 17:27:42 檢舉

浩瀚星空想額外請教個問題:目前我使用php oci8來連接oracle,想請問為甚麼會比較建議使用PDO的方式連線?安全性嗎?還是目前市場上PDO居多?/images/emoticon/emoticon41.gif

會問「目前市場上PDO居多?」這個,代表你對pdo真的不是很了解。
pdo本身並不是資料庫。認真來說,它算是一種資料庫的庫應用。
要拿來連接oracle也是可以的。

用他除了你說的安全性。它有針對sql語法有做了庫應用處理。只要你不直接用它的query就行了。

另外一種就是多驅動性。同樣的專案可各自支援不同的資料庫引擎。
不會再被限制一定要mysql或是oracle還是mssql。

1
小魚
iT邦大師 1 級 ‧ 2020-09-15 13:35:48

大問題很難找,
要先把問題拆解,
因為你又有GCP又有網頁,
你也不知道問題出在哪裡,
所以首先要先確定資料庫是沒問題的,
先找個資料庫連線軟體(如:HeidiSQL),
確定資料庫運作是正常的,
再來拆解程式的部分,
學會拆解就會比較容易找出問題所在,
找出問題所在就會比較好解決問題了.

Pulin iT邦新手 5 級 ‧ 2020-09-16 15:59:23 檢舉

謝謝你的建議!
之後再遇到問題我會試看看你的方法~

1
dragonH
iT邦超人 6 級 ‧ 2020-09-15 13:54:57

如果你是一台 database server + 一台 webserver

先確認你有辦法從webserver 的那台機器連到mysql

我懷疑是 port 或者是 ip

甚至是 gcp 有某些類似 aws security group 的東西

你沒有設定好

Pulin iT邦新手 5 級 ‧ 2020-09-16 16:00:20 檢舉

謝謝你的建議~後來沒有用GCP了所以就排除掉這個問題了

我要發表回答

立即登入回答