PHP và AJAX (Ai rắc) | MySQL & PHP

“Hãy hòa nhã với những kẻ dở hơi. Ai biết được ngày sau bạn có thể phải làm việc cho một kẻ như vậy.”

Bill Gates

Microsoft

Trong bài hướng dẫn tự học PHP này, bạn sẽ tìm hiểu cách tạo một tính năng tìm kiếm trực tiếp (live search) trong cơ sở dữ liệu MySQL bằng PHP và Ajax.

Ví dụ PHP và AJAX
Vúi dụ về PHP và AJAX

Tìm kiếm trực tiếp trong CSDL là gì?

Bạn có thể tạo một chức năng tìm kiếm trực tiếp trong CSDL đơn giản sử dụng Ajax và PHP.

Trong đó kết quả tìm kiếm sẽ được hiển thị khi bạn bắt đầu nhập một số ký tự trong box tìm kiếm.

Trong hướng dẫn này, chúng ta sẽ tạo một box tìm kiếm trực tiếp sẽ tìm kiếm bảng countries và hiển thị kết quả không đồng bộ.

Nhưng, trước hết chúng ta cần tạo bảng CSDL về các quốc gia đã:

Chức năng tìm kiếm trực tiếp bằng PHP và AJAX

Bước 1: Tạo bảng CSDL

Thực hiện truy vấn SQL sau để tạo bảng countries trong cơ sở dữ liệu MySQL của bạn.

CREATE TABLE countries (
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

Sau khi tạo bảng CSDL, bạn cần điền vào đó một số dữ liệu bằng cách sử dụng câu lệnh SQL INSERT.

Ngoài ra, bạn có thể tải xuống bảng countries đã được chuẩn bị trước bằng cách click vào đây và import nó vào cơ sở dữ liệu MySQL của bạn.

Vui lòng xem bài viết hướng dẫn về Cách tạo bảng CSDL MySQL để biết chi tiết về cú pháp tạo bảng trong hệ thống cơ sở dữ liệu MySQL.

Bước 2: Tạo Form tìm kiếm

Bây giờ, hãy tạo một giao diện web đơn giản cho phép người dùng tìm kiếm trực tiếp tên của các quốc gia có sẵn trong bảng countries của chúng ta.

Chức năng này giống như tự động hoàn thành.

Tạo một tệp PHP có tên ‘search-form.php‘ và đặt đoạn mã sau vào trong nó:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chức năng Live Search bằng PHP và AJAX</title>
<style type="text/css">
    body{
        font-family: Arail, sans-serif;
    }
    /* CSS cho search box */
    .search-box{
        width: 300px;
        position: relative;
        display: inline-block;
        font-size: 14px;
    }
    .search-box input[type="text"]{
        height: 32px;
        padding: 5px 10px;
        border: 1px solid #CCCCCC;
        font-size: 14px;
    }
    .result{
        position: absolute;        
        z-index: 999;
        top: 100%;
        left: 0;
    }
    .search-box input[type="text"], .result{
        width: 100%;
        box-sizing: border-box;
    }
    /* CSS cho kết quả */
    .result p{
        margin: 0;
        padding: 7px 10px;
        border: 1px solid #CCCCCC;
        border-top: none;
        cursor: pointer;
    }
    .result p:hover{
        background: #f2f2f2;
    }
</style>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $('.search-box input[type="text"]').on("keyup input", function(){
        /* Lấy giá trị đầu vào khi có thay đổi */
        var inputVal = $(this).val();
        var resultDropdown = $(this).siblings(".result");
        if(inputVal.length){
            $.get("backend-search.php", {term: inputVal}).done(function(data){
                // Hiển thị dữ liệu trả về trong trình duyệt
                resultDropdown.html(data);
            });
        } else{
            resultDropdown.empty();
        }
    });
    
    // Thiết lập giá trị đầu vào khi click vào result
    $(document).on("click", ".result p", function(){
        $(this).parents(".search-box").find('input[type="text"]').val($(this).text());
        $(this).parent(".result").empty();
    });
});
</script>
</head>
<body>
    <div class="search-box">
        <input type="text" autocomplete="off" placeholder="Search country..." />
        <div class="result"></div>
    </div>
</body>
</html>

Mỗi khi nội dung của đầu vào tìm kiếm bị thay đổi hoặc sự kiện keyup xảy ra trên đầu vào tìm kiếm, mã jQuery (dòng no-47 đến 67) đã gửi một yêu cầu Ajax đến tệp ‘backend-search.php‘ để lấy các bản ghi từ bảng countries liên quan đến chuỗi tìm kiếm.

Những bản ghi này sau đó sẽ được jQuery chèn vào một div và hiển thị trên trình duyệt.

Bước 3: Xử lý truy vấn trong Backend

Và đây là mã nguồn của tệp ‘backend-search.php‘ của chúng ta.

Nó sẽ tìm kiếm cơ sở dữ liệu dựa trên chuỗi truy vấn được gửi bởi Ajax và gửi kết quả trở lại trình duyệt.

* Phương pháp hướng thủ tục

<?php
/* Cố gắng kết nối đến MySQL server. Giả sử bạn đang chạy MySQL server mặc đinh (user là 'root' và không có mật khẩu */
$link = mysqli_connect("localhost", "root", "", "demo");
 
// Kiểm tra kết nối
if($link === false){
    die("ERROR: Không thể kết nối. " . mysqli_connect_error());
}
 
if(isset($_REQUEST["term"])){
    // Chuẩn bị câu lệnh SQL SELECT
    $sql = "SELECT * FROM countries WHERE name LIKE ?";
    
    if($stmt = mysqli_prepare($link, $sql)){
        // Liên kết biến đến câu lệnh đã chuẩn bị như là tham số
        mysqli_stmt_bind_param($stmt, "s", $param_term);
        
        // Thiết lập các tham số
        $param_term = $_REQUEST["term"] . '%';
        
        // Cố gắng thực thi câu lệnh đã chuẩn bị
        if(mysqli_stmt_execute($stmt)){
            $result = mysqli_stmt_get_result($stmt);
            
            // Kiểm tra số lượng row trong kết quả
            if(mysqli_num_rows($result) > 0){
                // Tìm nạp các hàng kết quả dưới dạng mảng kết hợp
                while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
                    echo "<p>" . $row["name"] . "</p>";
                }
            } else{
                echo "<p>Không tìm thấy kết quả nào</p>";
            }
        } else{
            echo "ERROR: Không thể thực thi câu lệnh $sql. " . mysqli_error($link);
        }
    }
     
    // Đóng câu lệnh
    mysqli_stmt_close($stmt);
}
 
// Đóng kết nối
mysqli_close($link);
?>

* Phương pháp hướng đối tượng

<?php
/* Cố gắng kết nối đến MySQL server. Giả sử bạn đang chạy MySQL server mặc đinh (user là 'root' và không có mật khẩu */
$mysqli = new mysqli("localhost", "root", "", "demo");
 
// Kiểm tra kết nối
if($mysqli === false){
    die("ERROR: Không thể kết nối. " . $mysqli->connect_error);
}
 
if(isset($_REQUEST["term"])){
    // Chuẩn bị câu lệnh SQL SELECT
    $sql = "SELECT * FROM countries WHERE name LIKE ?";
    
    if($stmt = $mysqli->prepare($sql)){
        // Liên kết biến đến câu lệnh đã chuẩn bị như là tham số
        $stmt->bind_param("s", $param_term);
        
        // Thiết lập các tham số
        $param_term = $_REQUEST["term"] . '%';
        
        // Cố gắng thực thi câu lệnh đã chuẩn bị
        if($stmt->execute()){
            $result = $stmt->get_result();
            
            // Kiểm tra số lượng row trong kết quả
            if($result->num_rows > 0){
                // Tìm nạp các hàng kết quả dưới dạng mảng kết hợp
                while($row = $result->fetch_array(MYSQLI_ASSOC)){
                    echo "<p>" . $row["name"] . "</p>";
                }
            } else{
                echo "<p>Không tìm thấy kết quả nào</p>";
            }
        } else{
            echo "ERROR: Không thể thực thi câu lệnh $sql. " . mysqli_error($link);
        }
    }
     
    // Đóng câu lệnh
    $stmt->close();
}
 
// Đóng kết nối
$mysqli->close();
?>

* Sử dụng PDO

<?php
/* Cố gắng kết nối đến MySQL server. Giả sử bạn đang chạy MySQL server mặc đinh (user là 'root' và không có mật khẩu */
try{
    $pdo = new PDO("mysql:host=localhost;dbname=demo", "root", "");
    // Thiết lập PDO error mode thành ngoại lệ
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
    die("ERROR: Không thể kết nối. " . $e->getMessage());
}
 
// Cố gắng thực thi truy vấn
try{
    if(isset($_REQUEST["term"])){
        // Chuẩn bị câu lệnh
        $sql = "SELECT * FROM countries WHERE name LIKE :term";
        $stmt = $pdo->prepare($sql);
        $term = $_REQUEST["term"] . '%';
        // Liên kết các tham số đến câu lệnh
        $stmt->bindParam(":term", $term);
        // Thực thi câu lệnh đã chuẩn bị
        $stmt->execute();
        if($stmt->rowCount() > 0){
            while($row = $stmt->fetch()){
                echo "<p>" . $row["name"] . "</p>";
            }
        } else{
            echo "<p>Không tìm thấy kết quả nào</p>";
        }
    }  
} catch(PDOException $e){
    die("ERROR: Không thể thực thi câu lệnh $sql. " . $e->getMessage());
}
 
// Đóng câu lệnh
unset($stmt);
 
// Đóng kết nối
unset($pdo);
?>

Câu lệnh SQL SELECT được sử dụng kết hợp với toán tử LIKE (dòng số 16) để tìm các bản ghi khớp trong bảng cơ sở dữ liệu countries.

Chúng ta đã triển khai câu lệnh đã chuẩn bị (Prepared Statements trong PHP) để có hiệu suất tìm kiếm tốt hơn cũng như để ngăn chặn các cuộc tấn công SQL injection.

Lưu ý: Luôn lọc và xác thực đầu vào của người dùng trước khi sử dụng nó trong câu lệnh SQL. Bạn cũng có thể sử dụng hàm mysqli_real_escape_string() của PHP để loại bỏ các ký tự đặc biệt trong đầu vào của người dùng và tạo một chuỗi SQL hợp lệ để chống lại tấn công SQL injection.

Bạn đã tạo thành công chức năng live search với PHP và AJAX.

Trong bài viết này, mình đã hướng dẫn bạn tạo thành công chức năng live search bằng cách sử dụng PHP và AJAX, nó có 4 bước:

  • Tạo bảng CSDL
  • Tạo form (tạo box search) và chỗ hiển thị kết quả tìm kiếm
  • Xử lý truy vấn với PHP (Hướng thủ tục, hướng đối tượng, PDO

Chức năng này rất hữu ích trong website cũng như cho bạn thấy cách sử dụng PHP và AJAX.

>. Tham gia ngay Khóa học PHP tại Hà Nội để nhanh chóng nhận cơ hội việc làm thu nhập cao.

Chúc bạn học lập trình PHP hiệu quả.

PHP DEV

Có thể bạn muốn xem

Leave a reply

Please enter your comment!
Please enter your name here