KT客棧

Web程式交流 & 聊幹畫 / 心情手札

【MySQL】AJAX實作(javascript)-站內搜尋

*MySQL  AJAX實作(javascript)-站內搜尋





AJAX實作(javascript)-站內搜尋
講解的這個範例算是頗實用的(棧長是參考W3C再進行改寫的),在前端頁搭配javascript的方式來撈取後端MySQL資料達成AJAX非同步處理的效果(網路上也有人是使用jquery的方式來達成)。


該效果應用面算是很廣,包含像是臉書的搜尋朋友、google的翻譯等等都是透過AJAX方式達成,亦即當我們在鍵盤上打字當手離開鍵盤時(onkeyup事件),前端會傳值給後端,而後端也會將取出的資料庫內容送回前端把資料秀出來。

下圖中,還未輸入文字時,會出現我的大頭照,之後我在左邊欄位內輸入"陳",就會立即透過AJAX呼叫後端的資料秀在右邊(這次就不用SHE當範例😆)。



在phpmyadmin當中請建立一個ktmysqlclass資料庫,編碼使用utf8_unicode_ci(基於相容性很多人都開始用utf8mb4_unicode_ci,不過這裡僅為作範例講解,就使用utf8_unicode_ci)。
建立一個名為score的資料表,設7個欄位,型態如下圖所示:
名字、資料等可以自己隨意取名來新增


建立好之後,就是重點了,我們需要兩個頁面,一個是前端頁取名為index.php,一個是後端頁取名為ajax.php。來達到非同步處理的效果。
這邊我有用到boostrap4第三方框架,所以是有自適應rwd的,格子我是採用左邊5(col-md-5 col-sm-12)、右邊7
(col-md-7 col-sm-12)
*boostrap4的格子系統(連結)


#前端頁index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AJAX-站內搜尋</title>
<style>
  h1, h2, h3, h4{ font-family: '微軟正黑體';}
  table {
    border-collapse: collapse;
    text-align: center;
    margin: 20px 0 0 0px; /*外距:上右下左*/
    box-shadow: 0px 15px 22px rgba(0, 0, 0, 0.2);
    width: 100%;
  }
  th {
    background-color: #f7c24a;
    border : 2px solid black;
    padding: 5px;
  }
  td {
    color: #5b3202;
    border : 3px solid black;
    padding: 5px;
  }
  .section-1 {
  padding-top:  50px;
  }
  .box1{
    height: 400px;
    width: 100%;
    position: absolute; /*絕對位置*/
    border: 4px solid #ab0303;
    border-radius: 5px;
  }
  .panel1{
    background-color: #fffebd;
    padding-top: 120px;
  }
  .panel2{
    padding-top: 30px;
  }
</style>
<script>
function showSite(str)
{
    if (str == "")
    {
        //收集輸入字段的值,其id為“txtHint”。
        document.getElementById("txtHint").innerHTML="";
        return;
    }
    if (window.XMLHttpRequest)
    {
        // IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行碼(建立物件)
        xmlhttp = new XMLHttpRequest();
    }
    else
    {
        // IE6, IE5 瀏覽器執行碼(建立物件)
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //'onreadystatechange'是XMLHttpRequest物件的屬性,只要'readyState'屬性發生更改,就會調用該屬性。 我們將其分配給下一個要宣告的函數。
    xmlhttp.onreadystatechange=function()
    {
        //檢查'readyState'屬性的值是否為4,以及結果代碼200表明對請求的響應是成功的。。
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            //設置要在div中顯示的字符串的值,其id為'txtHint',作為XMLHttpRequest物件的'responseText'屬性。 'responseText'是對文本請求的響應。
            document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
        }
    }
    //此方法傳遞了三個參數。 'GET'確定httprequest的類型。 'ajax.php'設置後端文件,並設置第三個參數'true'表示異步處理請求。
    xmlhttp.open("GET", "ajax.php?name="+str, true);
    xmlhttp.send();
}
</script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
</head>
<body align="center">
<section class="section-1">
  <div class="container alert text-center">
    <div class="row box1">
      <div class="col-md-5 col-sm-12 panel1">
        <h4 style="color:black;">AJAX-站內搜尋</h4>
          <input name="name" onkeyup="showSite(this.value)">
          <p>請輸入您要查詢的名字</p>
      </div>
      <div class="col-md-7 col-sm-12 panel2">
        <div class="text-center">
          <div id="txtHint">
            <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUUQkj6NwE1eHB_c4e15DF3-XVDJ8zSV_0MEVjfjm-q-Jp5FlQOWZ7Y7kxteky6NoC8yOyVXPqZ3sqXqCUSreexsK3RjioAaCFOooThTXW1JNy577JG6i4aHi5lE6sXtvdtUV-B3IwgWaA/s1600/%25E8%25B3%25BD%25E4%25BA%259E%25E4%25BA%25BA%25E5%2598%259F%25E5%2598%25B4.jpg">
            <br>
            <b>查詢結果會秀出在這邊呦~~棧友們</b>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src="https://code.jquery.com/jquery-3.4.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>


接著後端頁取名為ajax.php,這邊資料庫連線是採用mysqli建立資料庫物件,傳統的mysql則較不建議再用。或是更建議您採用PDO搭配stmt預備語法的方式,它在預防SQL injection會更完善(這邊有接觸過ASP.NET的棧友們是不是有聯想到了ADO.NET了,ASP.NET若是直接用datasource精靈連線是存有一定風險,但透過後置程式碼於C#使用ADO.NET較能有效預防SQL injection)
資料庫連線的起手式 : 連線->撈資料->倒出資料->關閉資料庫
#後端頁ajax.php
<?php
$host = "localhost"; //本機端
$username = "root"; //mysql帳號
$passwd = "1234";   //mysql密碼
$database = "ktmysqlclass"; //mysql資料庫

//建立資料庫物件
$kt_conn = new mysqli($host, $username, $passwd, $database);
if ($kt_conn -> connect_error){
  echo "連結mysql資料庫失敗";
}
else{
  $kt_conn -> query("SET NAMES 'utf8'");
  //echo "連結mysql資料庫成功,語系設為utf8";
}

//接收從前端傳來的內容,撈取資料後透過ajax丟回前端
if($_GET['name'] != "") {
  @$n = $_GET['name'];
  /*從score資料表,撈取所有欄位(用*米字號),當所傳來的值是字首、中、尾有符合(LIKE)資料name欄位的名字,
    就會呼叫出來,並且透過id欄位來設定為升序(ASC是升序(小跑到大)、DESC是降序(大跑到小))*/
  $sql = "SELECT * FROM score WHERE name LIKE '%$n%' ORDER BY id ASC";
  $score_result = mysqli_query($kt_conn,$sql);
}
echo "<table border='1'>
      <tr>
        <th>編號</th>
        <th>姓名</th>
        <th>國文</th>
        <th>英文</th>
        <th>數學</th>
        <th>電子信箱</th>
      </tr>";

while($row = mysqli_fetch_array($score_result))
{
    echo "<tr>";
    echo "<td>" . $row['id'] . "</td>";
    echo "<td>" . $row['name'] . "</td>";
    echo "<td>" . $row['chinese'] . "</td>";
    echo "<td>" . $row['english'] . "</td>";
    echo "<td>" . $row['math'] . "</td>";
    echo "<td>" . $row['email'] . "</td>";
    echo "</tr>";
}
echo "</table>";

//關閉資料庫
mysqli_close($kt_conn);
?>





5 則留言:

  1. 你好 我想請問
    如果我全部語法複製貼上了
    然後資料庫裡也有東西
    但是輸入後還是沒有抓到資料
    可能是哪裡出了問題

    回覆刪除
  2. JD你好,資料抓不到建議你從兩方向著手檢查,
    第1是javascript的部分>
    檢查html中是否有抓到上方js語法的function(也就是onkeyup事件),
    上方js語法的getElementById("txtHint"),是否下方有確實填上div id="txtHint"
    注意js語法的xmlhttp.open("GET", "ajax.php?name="+str, true),其中ajax.php名字必須要對應你撈資料的檔案。
    第2是mysql撈資料的部分(ajax.php)>
    *帳號、密碼是否有誤
    *連線是否正常,未必要用資料庫物件,也可用mysqli
    *SQL語法是否有誤
    --------------------------------
    可以參考w3school這個網站有介紹>
    https://www.w3school.com.cn/js/js_ajax_database.asp

    PS.您也可以參考我寫的另一篇用jQuery方式去做ajax,都是達到相同效果

    回覆刪除
  3. 可以參考這篇是採用jQuery方式來呈現的。
    AJAX實作(jQuery)-站內搜尋(二)
    https://reurl.cc/oD2aMg

    回覆刪除
  4. 不好意思 我會一直遇到在
    if($_GET['author_name'] != "") {
    @$n = $_GET['author_name'];

    這邊會一直說我的author不存在
    Notice: Undefined index: author_name
    可以問一下是為甚麼嗎

    回覆刪除
    回覆
    1. 你的前端要讓ajax.php檔獲取資料,讓他根據這個資料去搜尋表,通常是id,前端網址後面要有php?id=123,可以搜尋如何獲取網址參數~

      刪除

@templatesyard