DANH MỤC: PHP&MYSQL

Bài 9: Xây dựng lớp database xử lý truy vấn


Tiếp tục với series, bài này chúng ta sẽ cùng nhau xây dựng một lớp(class) database đơn giản để xử lý truy vấn trong dự án. Để có thể hiểu được series này thì bạn cần phải có kiến thức của series PHP& MySqlPHP hướng đối tượng.

DOWNLOAD SOURCE

1, Class Database.

-Trong bộ source dưới đây mình đã giải thích từng thuộc tính, phương thức có nhiệm vụ gì rồi, còn về phần code thì toàn bộ nhưng code này trên website của mình đã có nên mình sẽ không giải thích, để cho mọi người ôn lại kiến thức cũ luôn.

<?php
/**
 * @package TOIDICODEDB
 * @author  Toidicode Team
 * @copyright   Copyright (c) 2017, toidicode.com
 * @link    https://toidicode.com
 * @since   Version 1.0
 */
class Database
{
    /**
     * $host Chứa thông tin host
     * @var string
     */
    private $host = 'localhost';
    /**
     * $username Tài khoản truy cập mysql
     * @var string
     */
    private $username = 'root';
    /**
     * $password Mật khẩu truy cập sql
     * @var string
     */
    private $password = '';
    /**
     * $databaseName Tên Database các bạn muốn kết nối
     * @var string
     */
    private $databaseName = 'vtt_may';
    /**
     * $charset Dạng ký tự
     * @var string
     */
    private $charset = 'utf8';
    /**
     * $conn Lưu trữ lớp kết nối
     * @var [objetc]
     */
    private $conn;
    /**
     * __construct Hàm khởi tạo
     * @return void;
     */
    public function __construct()
    {
        $this->connect();
    }
    /**
     * connect Kết nối
     * @return void
     */
    public function connect()
    {
        if(!$this->conn){
            $this->conn = mysqli_connect($this->host,$this->username,$this->password,$this->databaseName);
            if (mysqli_connect_errno()) {
                echo 'Failed: '. mysqli_connect_error();
                die();
            }
            mysqli_set_charset($this->conn,$this->charset);
        }
    }
    /**
     * disConnect Ngắt kết nối
     * @return void
     */
    public function disConnect()
    {
        if($this->conn)
            mysqli_close($this->conn);
    }
    /**
     * error Hiển thị lỗi
     * @return string
     */
    public function error()
    {
        if($this->conn)
            return mysqli_error($this->conn);
        else
            return false;
    }
    /**
     * insert thêm dữ liẹu
     * @param string $table tên bảng muốn thêm, array $data dữ liệu cần thêm
     * @return boolean
     */
    public function insert($table = '', $data = [])
    {
        $keys = '';
        $values= '';
        foreach ($data as $key => $value) {
            $keys .= ',' . $key;
            $values .= ',"' . mysqli_real_escape_string($this->conn,$value).'"';
        }
        $sql = 'INSERT INTO ' .$table . '(' . trim($keys,',') . ') VALUES (' . trim($values,',') . ')';
        return mysqli_query($this->conn,$sql);
    }
    /**
     * update sửa dữ liệu
     * @param string $table tên bảng muốn sửa, array $data dữ liệu cần sửa, array|int $id điều kiện
     * @return boolean
     */
    public function update($table = '',$data = [], $id =[])
    {
        $content = '';
        if(is_integer($id))
            $where = 'id = '.$id;
        else if(is_array($id) && count($id)==1){
            $listKey = array_keys($id);
            $where = $listKey[0].'='.$id[$listKey[0]];
        }
        else
            die('Không thể có nhiều hơn 1 khóa chính và id truyền vào phải là số');
        foreach ($data as $key => $value) {
            $content .= ','. $key . '="' . mysqli_real_escape_string($this->conn,$value).'"';
        }
        $sql = 'UPDATE ' .$table .' SET '.trim($content,',') . ' WHERE ' . $where ;
        return mysqli_query($this->conn,$sql);
    }
    /**
     * delete xóa dữ liệu
     * @param string $table tên bảng muốn xóa, array|int điều kiện
     * @return boolean
     */
    public function delete($table= '', $id = [])
    {
        $content = '';
        if(is_integer($id))
            $where = 'id = '.$id;
        else if(is_array($id) && count($id)==1){
            $listKey = array_keys($id);
            $where = $listKey[0].'='.$id[$listKey[0]];
        }
        else
            die('Không thể có nhiều hơn 1 khóa chính và id truyền vào phải là số');
        $sql = 'DELETE FROM ' . $table . ' WHERE '. $where;
        return mysqli_query($this->conn,$sql);
    }
    /**
     * getObject lấy hết dữ liệu trong bảng trả về mảng đối tượng
     * @param string $table tên bảng muốn lấy ra dữ liệu
     * @return array objetc
     */
    public function getObject($table = '')
    {
        $sql = 'SELECT * FROM '. $table;
        $data = null;
        if($result = mysqli_query($this->conn,$sql)){
            while($row = mysqli_fetch_object($result)){
                $data[] = $row;
            }
            mysqli_free_result($result);
            return $data;
        }
        return false;
    }
    /**
     * getObject lấy hết dữ liệu trong bảng trả về mảng dữ liệu
     * @param string $table tên bảng muốn lấy dữ liệu
     * @return array
     */
    public function getArray($table = '')
    {
        $sql = 'SELECT * FROM '. $table;
        $data = null;
        if($result = mysqli_query($this->conn,$sql)){
            while($row = mysqli_fetch_array($result)){
                $data[] = $row;
            }
            mysqli_free_result($result);
            return $data;
        }
        else
            return false;
    }
    /**
     * getRowObject lấy một dòng dữ liệu trong bảng trả về mảng dữ liệu
     * @param string $table tên bảng muốn lấy dữ liệu, array|int $id điều kiện
     * @return object
     */
    public function getRowObject($table = '', $id = [])
    {
        if(is_integer($id))
            $where = 'id = '.$id;
        else if(is_array($id) && count($id)==1){
            $listKey = array_keys($id);
            $where = $listKey[0].'='.$id[$listKey[0]];
        }
        else
            die('Không thể có nhiều hơn 1 khóa chính và id truyền vào phải là số');
        $sql = 'SELECT * FROM '. $table . ' WHERE '. $where;
        
        if($result = mysqli_query($this->conn,$sql)){
            $data = mysqli_fetch_object($result);
            mysqli_free_result($result);
            return $data;
        }
        else
            return false;
    }
    /**
     * getRowArray lấy một dòng dữ liệu trong bảng trả về mảng dữ liệu
     * @param string $table tên bảng muốn lấy dữ liệu, array|int $id điều kiện
     * @return array
     */
    public function getRowArray($table = '', $id = [])
    {
        if(is_integer($id))
            $where = 'id = '.$id;
        else if(is_array($id) && count($id)==1){
            $listKey = array_keys($id);
            $where = $listKey[0].'='.$id[$listKey[0]];
        }
        else
            die('Không thể có nhiều hơn 1 khóa chính và id truyền vào phải là số');
        $sql = 'SELECT * FROM '. $table . ' WHERE '. $where;
        
        if($result = mysqli_query($this->conn,$sql)){
            $data = mysqli_fetch_array($result);
            mysqli_free_result($result);
            return $data;
        }
        else
            return false;
    }
    /**
     * query thực hiện query
     * @param string $sql
     * @return boolean|array
     */
    public function query($sql ='', $return = true)
    {
        if($result = mysqli_query($this->conn,$sql))
        {
            if($return === true){
                while ($row = mysqli_fetch_array($result)) {
                    $data[] = $row;
                }
                mysqli_free_result($result);
                return $data;
            }
            else
                return true;
        }
        else
            return false;
    }
    /**
     * __destruct hàm hủy
     * @param none
     * @return void
     */
    public function __destruct()
    {
        $this->disConnect();
    }
}

2, Cách sử dụng.

Gỉa sử chúng ta sẽ có một bảng dữ liệu có cấu trúc như sau:

cấu trúc bảng

 

-Giờ chúng ta sẽ sử dụng cấu trúc đó để sử dụng cho lớp DB.

Khởi tạo class

-Để sử dụng được lớp đương nhiên chúng ta phải khởi tạo nó rồi.

$db= new Database();

Hiển thị lỗi

-Để hiển thị lỗi trong khi thực hiện các bạn sử dụn cú pháp:

$db->error();

Thêm dữ liệu

-Để thêm dữ liệu chúng ta dùng cú pháp:

$db->insert($table, $data);

Trong đó

  • $table là bảng dữ liệu các bạn muốn thêm.
  • $data là mảng dữ liệu các bạn muốn thêm. Với key là tên trường và value là giá trị của trường dữ liệu đó.

VD: Mình sẽ thêm dữ liệu vào bảng tbl_news ở trên.

$data= [
    'title'   => 'Bài viết 1',
    'slug'    => 'bai-viet-1',
    'content' => 'Nội dung 1'
];
$db = new Database();
if($db->insert('tbl_news', $data)){
    echo 'Thêm thành công';
}else {
    echo "Lỗi: " .$db->error();
}

Sửa dữ liệu

-Để sửa dữ liệu các bạn sử dụng cú pháp sau:

$db->update($table, $data, $id);

Trong đó

  • $table là bảng dữ liệu các bạn muốn sửa.
  • $data là mảng dữ liệu các bạn muốn thêm. Với key là tên trường và value là giá trị của trường dữ liệu đó.
  • $id là khóa chính của bảng. Nếu khóa chính của bạn là id thì truyền vào là giá trị của id, nếu khóa chính của bạn không phải là id thì truyền vào là mảng với key là khóa chính và value là giá trị của khóa chính.

VD: Mình sẽ sửa dữ liệu dòng có id=1 của bảng tbl_news.

$data= [
    'title'   => 'Bài viết mới',
    'slug'    => 'bai-viet-moi',
    'content' => 'Nội dung mới'
];
$id = 1;
$db = new Database();
if($db->update('tbl_news', $data, $id)){
    echo 'Sửa thành công';
}else {
    echo "Lỗi: " .$db->error();
}

Xóa dữ liệu.

-Để xóa dữ liệu trong bảng các bạn sử dụng cú pháp:

$db->delete($table, $id);

Trong đó

  • $table là bảng dữ liệu các bạn muốn xóa.
  • $id là khóa chính của bảng. Nếu khóa chính của bạn là id thì truyền vào là giá trị của id, nếu khóa chính của bạn không phải là id thì truyền vào là mảng với key là khóa chính và value là giá trị của khóa chính.

VD: Xóa dữ liệu dòng có id=1 trong bảng tbl_news.

$id = 1;
$db = new Database();
if($db->delete('tbl_news', $id)){
    echo 'Xóa thành công';
}else {
    echo "Lỗi: " .$db->error();
}

Select all dữ liệu

-Để select list dữ liệu thì chúng ta sẽ có 2 cách:

+Cách 1: Trả về mảng object.

Đối với cách này các bạn sử dụng cú pháp:

$db->getObject($table);

VD: Lấy hết dữ liệu của bảng tbl_news và trả về mảng đối tượng.

$db = new Database();
$data = $db->getObject('tbl_news');
foreach ($data as $value) {
    echo '____________________________________________ <br/>';
    echo 'ID: ' . $value->id . '<br>';
    echo 'Slug: ' . $value->slug . '<br>';
    echo 'Title: ' .  $value->title . '<br>';
    echo 'Content: ' . $value->content . '<br>';
}

+Cách 2: Trả về mảng.

Đối với cách này các bạn sử dụng cú pháp:

$db->getArray($table);

VD: Lấy hết dữ liệu của bảng tbl_news và trả về mảng.

$db = new Database();
$data = $db->getArray('tbl_news');
foreach ($data as $value) {
    echo '____________________________________________ <br/>';
    echo 'ID: ' . $value['id'] . '<br>';
    echo 'Slug: ' . $value['slug'] . '<br>';
    echo 'Title: ' .  $value['title'] . '<br>';
    echo 'Content: ' . $value['content'] . '<br>';
}

Select dòng dữ liệu

-Để lấy ra một dòng dữ liệu chúng ta cũng có 2 cách là trả đối tương và mảng.

+Cách 1: Trả về đối tượng.

Cách này các bạn sử dụng cú pháp như sau:

$db->getRowObject($table, $id)

Trong đó: 

  • $table là bẳng dữ liệu các bạn muốn lấy.
  • $id là khóa chính của bảng. Nếu khóa chính của bạn là id thì truyền vào là giá trị của id, nếu khóa chính của bạn không phải là id thì truyền vào là mảng với key là khóa chính và value là giá trị của khóa chính.

VD:

$db = new Database();
$value = $db->getRowObject('tbl_news', 14);
if($value){
    echo '____________________________________________ <br/>';
    echo 'ID: ' . $value->id . '<br>';
    echo 'Slug: ' . $value->slug . '<br>';
    echo 'Title: ' .  $value->title . '<br>';
    echo 'Content: ' . $value->content . '<br>';
}else {
    echo 'Lỗi: ' . $db->error(); 
}

+Cách 2: Trả về mảng.

Cách này các bạn sử dụng cú pháp như sau:

$db->getRowArray($table, $id)

Trong đó: 

  • $table là bẳng dữ liệu các bạn muốn lấy.
  • $id là khóa chính của bảng. Nếu khóa chính của bạn là id thì truyền vào là giá trị của id, nếu khóa chính của bạn không phải là id thì truyền vào là mảng với key là khóa chính và value là giá trị của khóa chính.

VD:

$db = new Database();
$value = $db->getRowArray('tbl_news', 14);
if($value){
    echo '____________________________________________ <br/>';
    echo 'ID: ' . $value['id'] . '<br>';
    echo 'Slug: ' . $value['slug'] . '<br>';
    echo 'Title: ' .  $value['title'] . '<br>';
    echo 'Content: ' . $value['content'] . '<br>';
}else {
    echo 'Lỗi: ' . $db->error(); 
}

Query

-Để có thể chèn câu truy vấn của bạn vào trong đối tượng các bạn sử dụng cú pháp:

$db->query($sql, $option);

Trong đó:

  • $sql là câu truy vấn của bạn.
  • $option là tùy biến dữ liệu trả về. Nếu option bằng true hoặc để trống thì có trả về dữ liệu và ngược lại bằng false nếu không muốn trả về dữ liệu.

VD: Truy vấn có trả về dữ liệu.

$db = new Database();
$sql = 'SELECT * FROM tbl_news LIMIT 0,10';
if($data = $db->query($sql))
    print_r($data);
else
    echo 'Lỗi: '.$db->error();

VD: Truy vấn không trả về dữ liệu.

$db = new Database();
$sql = 'UPDATE tbl_news SET title= "Học Lập Trình" WHERE id=35555';
if($db->query($sql,false))
    echo 'Sửa thành công';
else
    echo 'Thất bại: '. $db->error();

Chú ý

- Luôn bật chế độ debug để xem lỗi và tắt đi khi phát hành ứng dụng.

3, Lời Kết.

-Như vậy mình đã xây dựng xong lớp Database cơ bản, hạn chế được các lỗi mysql injection và một số lỗi cơ bản khác. Các bạn hoàn toàn có thể viết thêm chức năng cho nó sao cho phù hợp với dự án của bạn.  

Nguồn: Toidicode.com

Thông tin tác giả

Vũ Thanh Tài

Vũ Thanh Tài

Biển học vô biên, quay đầu là dại!

Hãy tham gia group facebook để cùng giao lưu chia sẻ kiến thức! Tham Gia