Prepared Statements trong MySQL

Prepared Statement (còn được gọi là câu lệnh được tham số hóa) chỉ đơn giản là một mẫu truy vấn SQL có chứa trình giữ chỗ thay vì các giá trị tham số thực tế.

Trong bài hướng dẫn tự học PHP và MySQL này, bạn sẽ học cách sử dụng Prepared Statements trong MySQL bằng PHP.

Prepared Statement là gì?

Prepared Statement trong MySQL
Prepared Statement trong MySQL

Prepared Statement (còn được gọi là câu lệnh được tham số hóa) chỉ đơn giản là một mẫu truy vấn SQLchứa trình giữ chỗ thay vì các giá trị tham số thực tế.

Các trình giữ chỗ này sẽ được thay thế bằng các giá trị thực tế tại thời điểm thực hiện câu lệnh.

MySQLi hỗ trợ sử dụng trình giữ chỗ vị trí ẩn danh (?), Như được hiển thị bên dưới:

INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?);

Trong khi đó, PDO hỗ trợ cả trình giữ chỗ vị trí ẩn danh (?), Cũng như các trình giữ chỗ được đặt tên.

Một trình giữ chỗ được đặt tên bắt đầu bằng dấu hai chấm (:) theo sau là một mã định danh, như thế này:

INSERT INTO persons (first_name, last_name, email)
VALUES (:first_name, :last_name, :email);

Việc thực hiện Prepared Statement bao gồm hai giai đoạn: Chuẩn bịThực thi.

  • Chuẩn bị: Ở giai đoạn chuẩn bị, một mẫu câu lệnh SQL được tạo và gửi đến máy chủ cơ sở dữ liệu. Máy chủ phân tích mẫu câu lệnh, thực hiện kiểm tra cú pháp và tối ưu hóa truy vấn và lưu trữ nó để sử dụng sau.
  • Thực thi: Trong quá trình thực thi, các giá trị tham số được gửi đến máy chủ. Máy chủ tạo một câu lệnh từ mẫu câu lệnh và sử dụng các giá trị này để thực thi nó.

Prepared Statement rất hữu ích, đặc biệt trong các tình huống khi bạn thực thi một câu lệnh cụ thể nhiều lần với các giá trị khác nhau.

Ví dụ, bạn cần thực hiện một loạt các câu lệnh INSERT. Prepared Statement sẽ giúp bạn tối ưu hóa công việc này.

Phần sau đây mô tả một số lợi ích chính của việc sử dụng Prepared Statement.

Ưu điểm của việc sử dụng Prepared Statement

Prepared Statement có thể thực hiện cùng một câu lệnh lặp đi lặp lại với hiệu quả cao, bởi vì câu lệnh chỉ được phân tích cú pháp một lần, trong khi nó có thể được thực thi nhiều lần.

Nó cũng giảm thiểu việc sử dụng băng thông, vì mỗi lần thực thi, chỉ có các giá trị giữ chỗ cần được truyền đến máy chủ cơ sở dữ liệu thay vì truyền cả câu lệnh SQL hoàn chỉnh.

Prepared Statement cũng cung cấp sự bảo vệ mạnh mẽ chống lại SQL injection (Hành động cố gắng truyền câu lệnh SQL để thao túng CSDL), bởi vì các giá trị tham số không được nhúng trực tiếp bên trong chuỗi truy vấn SQL.

Các giá trị tham số được gửi đến máy chủ cơ sở dữ liệu tách biệt với truy vấn bằng một giao thức khác và do đó không thể can thiệp vào nó.

Máy chủ sử dụng các giá trị này trực tiếp tại điểm thực hiện, sau khi mẫu câu lệnh được phân tích cú pháp.

Đó là lý do tại sao các Prepared Statement ít bị lỗi hơn và do đó được coi là một trong những yếu tố quan trọng nhất trong bảo mật cơ sở dữ liệu.

Ví dụ sau đây sẽ cho bạn thấy Prepared Statement được chuẩn bị thực sự hoạt động như thế nào:

Ví dụ sử dụng Prepared Statement

Cách #1. Sử dụng Prepared Statement bằng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Chuẩn bị câu lệnh INSERT
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)";
 
if($stmt = mysqli_prepare($link, $sql)){
    // Liên kết biến với tham số trong câu lệnh đã chuẩn bị
    mysqli_stmt_bind_param($stmt, "sss", $first_name, $last_name, $email);
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng khác */
    $first_name = "Hermione";
    $last_name = "Granger";
    $email = "hermionegranger@mail.com";
    mysqli_stmt_execute($stmt);
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng */
    $first_name = "Ron";
    $last_name = "Weasley";
    $email = "ronweasley@mail.com";
    mysqli_stmt_execute($stmt);
    
    echo "Chèn bản ghi thành công.";
} else{
    echo "ERROR: Không thể chuẩn bị truy vấn: $sql. " . mysqli_error($link);
}
 
// Đóng câu lệnh
mysqli_stmt_close($stmt);
 
// Đóng kết nối
mysqli_close($link);
?>

Cách #2. Sử dụng Prepared Statement bằng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Chuẩn bị câu lệnh INSERT
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)";
 
if($stmt = $mysqli->prepare($sql)){
    // Liên kết biến với tham số trong câu lệnh đã chuẩn bị
    $stmt->bind_param("sss", $first_name, $last_name, $email);
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng khác */
    $first_name = "Hermione";
    $last_name = "Granger";
    $email = "hermionegranger@mail.com";
    $stmt->execute();
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng */
    $first_name = "Ron";
    $last_name = "Weasley";
    $email = "ronweasley@mail.com";
    $stmt->execute();
    
    echo "Chèn bản ghi thành công.";
} else{
    echo "ERROR: Không thể chuẩn bị truy vấn: $sql. " . $mysqli->error;
}
 
// Đóng câu lệnh
$stmt->close();
 
// Đóng kết nối
$mysqli->close();
?>

Cách #3. Sử dụng Prepared Statement bằng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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 câu lệnh INSERT
try{
    // Chuẩn bị câu lệnh INSERT
    $sql = "INSERT INTO persons (first_name, last_name, email) VALUES (:first_name, :last_name, :email)";
    $stmt = $pdo->prepare($sql);
    
    // Ràng buộc tham số
    $stmt->bindParam(':first_name', $first_name, PDO::PARAM_STR);
    $stmt->bindParam(':last_name', $last_name, PDO::PARAM_STR);
    $stmt->bindParam(':email', $email, PDO::PARAM_STR);
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng khác */
    $first_name = "Hermione";
    $last_name = "Granger";
    $email = "hermionegranger@mail.com";
    $stmt->execute();
    
    /* Thiết lập giá trị tham số và thực thi
    câu lệnh 1 lần nữa để chèn một hàng */
    $first_name = "Ron";
    $last_name = "Weasley";
    $email = "ronweasley@mail.com";
    $stmt->execute();
    
    echo "Chèn bản ghi thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể chuẩn bị / thực thi truy vấn: $sql. " . $e->getMessage());
}
 
// Đóng câu lệnh
unset($stmt);
 
// Đóng kết nối
unset($pdo);
?>

Như bạn có thể thấy trong ví dụ trên, chúng tôi đã chuẩn bị câu lệnh INSERT chỉ một lần nhưng thực hiện nó nhiều lần bằng cách truyền tập hợp các tham số khác nhau.

Giải thích về ví dụ về Prepared Statement (Kiểu thủ tục)

Bên trong câu lệnh SQL INSERT (dòng số 12) của ví dụ trên, các dấu hỏi được sử dụng làm trình giữ chỗ cho các giá trị của trường first_name, last_name, email.

Hàm mysqli_stmt_bind_param() (dòng số 16) liên kết các biến với trình giữ chỗ (?) trong mẫu câu lệnh SQL.

Các phần giữ chỗ (?) Sẽ được thay thế bằng các giá trị thực được giữ trong các biến tại thời điểm thực thi. Chuỗi định nghĩa kiểu được cung cấp ở đối số thứ hai, tức là chuỗi ‘sss‘ chỉ định rằng kiểu dữ liệu của mỗi biến liên kết là chuỗi.

Chuỗi định nghĩa kiểu xác định kiểu dữ liệu của các biến liên kết tương ứng và chứa một hoặc nhiều trong bốn ký tự sau:

  • b — binary (như là hình ảnh, PDF, …)
  • d — double (Số thập phân)
  • i — integer (Số nguyên)
  • s — string (ký tự)

Số lượng biến liên kết và số lượng ký tự trong chuỗi định nghĩa kiểu phải khớp với số lượng giữ chỗ trong câu lệnh SQL mẫu.

Sử dụng Web Form để truyền dữ liệu và sử dụng Prepared Statement

Nếu bạn nhớ từ bài INSERT trong MySQL, chúng ta đã tạo một Form HTML để chèn dữ liệu vào cơ sở dữ liệu.

Ở đây, chúng ta sẽ mở rộng ví dụ đó bằng cách thực hiện Prepared Statement.

Bạn có thể sử dụng cùng một biểu mẫu HTML, nhưng chỉ cần đảm bảo rằng bạn đang sử dụng tên tệp chính xác trong thuộc tính action của biểu mẫu.

Đây là mã PHP được cập nhật để chèn dữ liệu. Nếu bạn xem ví dụ một cách cẩn thận, bạn sẽ thấy chúng tôi đã không sử dụng mysqli_real_escape_opes() để làm sạch dữ liệu đầu vào của người dùng, giống như chúng ta đã làm trong ví dụ chương trước.

Vì trong các câu lệnh đã chuẩn bị, dữ liệu đầu vào vào của người dùng không bao giờ được thay thế trực tiếp vào chuỗi truy vấn, do đó chúng không cần phải được làm sạch.

Hướng dẫn nhận dữ liệu thông qua Form HTML và sử dụng Prepared Statement với MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Chuẩn bị câu lệnh INSERT
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)";
 
if($stmt = mysqli_prepare($link, $sql)){
    // Liên kết biến với tham số trong câu lệnh đã chuẩn bị
    mysqli_stmt_bind_param($stmt, "sss", $first_name, $last_name, $email);
    
    // Thiết lập tham số
    $first_name = $_REQUEST['first_name'];
    $last_name = $_REQUEST['last_name'];
    $email = $_REQUEST['email'];

    // Cố gắng thực hiện câu lệnh đã chuẩn bị
    if(mysqli_stmt_execute($stmt)){
        echo "Chèn bản ghi thành cồng.";
    } else{
        echo "ERROR: Không thể thực thi truy vấn: $sql. " . mysqli_error($link);
    }
} else{
    echo "ERROR: Không thể chuẩn bị truy vấn: $sql. " . mysqli_error($link);
}
 
// Đóng câu lệnh
mysqli_stmt_close($stmt);
 
// Đóng kết nối
mysqli_close($link);
?>

Hướng dẫn nhận dữ liệu thông qua Form HTML và sử dụng Prepared Statement với MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Chuẩn bị câu lệnh INSERT
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES (?, ?, ?)";
 
if($stmt = $mysqli->prepare($sql)){
    // Liên kết biến với tham số trong câu lệnh đã chuẩn bị
    $stmt->bind_param("sss", $first_name, $last_name, $email);
    
    // Thiết lập tham số
    $first_name = $_REQUEST['first_name'];
    $last_name = $_REQUEST['last_name'];
    $email = $_REQUEST['email'];
    
    // Cố gắng thực hiện câu lệnh đã chuẩn bị
    if($stmt->execute()){
        echo "Chèn bản ghi thành công.";
    } else{
        echo "ERROR: Không thể thực thi truy vấn: $sql. " . $mysqli->error;
    }
} else{
    echo "ERROR: Không thể chuẩn bị truy vấn: $sql. " . $mysqli->error;
}
 
// Đóng câu lệnh
$stmt->close();
 
// Đóng kết nối
$mysqli->close();
?>

Lưu ý: Mặc dù làm sạch dữ liệu đầu vào là không bắt buộc trong Prepared Statement, bạn phải luôn xác thực loại và kích thước của dữ liệu nhận được từ các nguồn bên ngoài và thực thi các giới hạn phù hợp để bảo vệ lại các hành động khai thác tài nguyên hệ thống có hại.

Hướng dẫn nhận dữ liệu thông qua Form HTML và sử dụng Prepared Statement với PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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 câu lệnh INSERT
try{
    // Chuẩn bị câu lệnh INSERT
    $sql = "INSERT INTO persons (first_name, last_name, email) VALUES (:first_name, :last_name, :email)";
    $stmt = $pdo->prepare($sql);
    
    // Ràng buộc tham số
   $stmt->bindParam(':first_name', $_REQUEST['first_name'], PDO::PARAM_STR);
    $stmt->bindParam(':last_name', $_REQUEST['last_name'], PDO::PARAM_STR);
    $stmt->bindParam(':email', $_REQUEST['email'], PDO::PARAM_STR);

    // Thực thi câu lệnh đã chuẩn bị
    $stmt->execute();    
    echo "Chèn bản ghi thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể chuẩn bị / thực thi truy vấn: $sql. " . $e->getMessage());
}
 
// Đóng câu lệnh
unset($stmt);
 
// Đóng kết nối
unset($pdo);
?>

Bạn đã hiểu về Prepared Statement chưa?

Việc sử dụng Prepared Statement mang lại cho chúng ta nhiều lợi ích khi lập trình web. Đây là cách thực tế các lập trình viên hay làm để đảm bảo website đạt được sự an toàn và hiệu suất tốt.

Hãy ghi nhớ cách triển khai Prepared Statement bằng cả 3 cách, bạn chắc chắn sẽ cần nhiều đến chúng.

PHPDev

Lệnh INSERT trong MySQL & PHP

Trong bài Hướng dẫn tự học PHP này, bạn sẽ được tìm hiểu cách chèn các bản ghi trong bảng MySQL bằng PHP với lệnh INSERT.

Chèn dữ liệu vào bảng cơ sở dữ liệu MySQL

Qua 2 bài trước, bạn đã hiểu cách tạo cơ sở dữ liệucách tạo bảng trong MySQL. Trong hướng dẫn này, bạn sẽ tìm hiểu cách thực hiện truy vấn SQL để chèn các bản ghi vào bảng.

Câu lệnh INSERT INTO sẽ được sử dụng để chèn các hàng mới trong bảng cơ sở dữ liệu mà chúng ta đã tạo.

Hướng dẫn chèn dữ liệu trong bảng CSDL bằng lệnh INSERT trong MySQL & PHP
Hướng dẫn chèn dữ liệu trong bảng CSDL bằng lệnh INSERT trong MySQL & PHP

Chúng ta hãy tạo một truy vấn SQL bằng cách sử dụng câu lệnh INSERT INTO với các giá trị phù hợp, sau đó chúng ta sẽ thực hiện truy vấn chèn này thông qua việc chuyển nó đến hàm mysqli_query() của PHP để chèn dữ liệu vào bảng.

Dưới đây là một ví dụ, chèn một hàng mới vào bảng person bằng cách chỉ định các giá trị cho các trường First_name, last_nameemail.

3 Cách chèn dữ liệu vào bảng cơ sở dữ liệu sử dụng MySQLi hướng thủ tục, MySQLi OOP và PDO

Ví dụ 1: Chèn dữ liệu bằng cách sử dụng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES ('Peter', 'Parker', 'peterparker@mail.com')";
if(mysqli_query($link, $sql)){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . mysqli_error($link);
}
 
// Đóng kết nối
mysqli_close($link);
?>

Ví dụ 2: Chèn dữ liệu bằng cách sử dụng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES ('Peter', 'Parker', 'peterparker@mail.com')";
if($mysqli->query($sql) === true){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . $mysqli->error;
}
 
// Đóng kết nối
$mysqli->close();
?>

Ví dụ 3: Chèn dữ liệu bằng cách sử dụng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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 câu lệnh insert
try{
    $sql = "INSERT INTO persons (first_name, last_name, email) VALUES ('Peter', 'Parker', 'peterparker@mail.com')";    
    $pdo->exec($sql);
    echo "Thêm bản ghi thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể thực thi $sql. " . $e->getMessage());
}
 
// Đóng kết nôi
unset($pdo);
?>

Nếu bạn nhớ từ bài trước, trường id được đánh dấu là AUTO_INCREMENT. Nó yêu cầu MySQL tự động gán giá trị cho trường này nếu nó không được chỉ định, bằng cách tăng giá trị trước đó lên 1.

3 Cách chèn nhiều hàng vào một bảng trong MySQL với PHP

Bạn cũng có thể chèn nhiều hàng vào một bảng CSDL MySQL với một truy vấn chèn cùng một lúc.

Để thực hiện việc này, trong câu lệnh INSERT INTO chúng ta chỉ cần thêm nhiều giá trị cùng một lúc, trong đó các giá trị của từng cột cho mỗi hàng phải được đặt trong dấu ngoặc đơn và được phân tách bằng dấu phẩy.

Hãy chèn thêm vài hàng vào bảng person, như ví dụ sau:

Ví dụ 4: Chèn nhiều hàng vào một bảng CSDL sử dụng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES             
            ('John', 'Rambo', 'johnrambo@mail.com'),
            ('Clark', 'Kent', 'clarkkent@mail.com'),
            ('John', 'Carter', 'johncarter@mail.com'),
            ('Harry', 'Potter', 'harrypotter@mail.com')";
if(mysqli_query($link, $sql)){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . mysqli_error($link);
}
 
// Đóng kết nối
mysqli_close($link);
?>

Như bạn thấy, chúng ta chỉ cần thay đổi câu lệnh INSERT INTO đi một chút.

Ví dụ 5: Chèn nhiều hàng vào một bảng CSDL sử dụng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES             
            ('John', 'Rambo', 'johnrambo@mail.com'),
            ('Clark', 'Kent', 'clarkkent@mail.com'),
            ('John', 'Carter', 'johncarter@mail.com'),
            ('Harry', 'Potter', 'harrypotter@mail.com')";
if($mysqli->query($sql) === true){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . $mysqli->error;
}
 
// Đóng kết nối
$mysqli->close();
?>

Ví dụ 5: Chèn nhiều hàng vào một bảng CSDL sử dụng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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 câu lệnh insert
try{
    $sql = "INSERT INTO persons (first_name, last_name, email) VALUES 
            ('John', 'Rambo', 'johnrambo@mail.com'),
            ('Clark', 'Kent', 'clarkkent@mail.com'),
            ('John', 'Carter', 'johncarter@mail.com'),
            ('Harry', 'Potter', 'harrypotter@mail.com')";    
    $pdo->exec($sql);
    echo "Thêm bản ghi thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể thực thi $sql. " . $e->getMessage());
}
 
// Đóng kết nôi
unset($pdo);
?>

Bây giờ, hãy truy cập phpMyAdmin (http://localhost/phpmyadmin/) và kiểm tra dữ liệu bảng người trong cơ sở dữ liệu demo. Bạn sẽ tìm thấy giá trị cho cột id được gán tự động bằng cách tăng giá trị của id trước đó lên 1.

Lưu ý: Bất kỳ số lần ngắt dòng nào cũng có thể xảy ra trong một câu lệnh SQL, với điều kiện là bất kỳ ngắt dòng nào sẽ không phá vỡ các từ khóa, giá trị, biểu thức, v.v.

Hướng dẫn chèn dữ liệu vào một bảng CSDL từ một form HTML

Trong phần trước, chúng ta đã học cách chèn dữ liệu vào cơ sở dữ liệu từ tập lệnh PHP. Bây giờ, chúng ta sẽ xem làm thế nào chúng ta có thể chèn dữ liệu vào cơ sở dữ liệu thu được từ một biểu mẫu HTML.

Thực tế, khi lập trình web, để tiện cho việc quản trị website, người quản trị sẽ chỉ làm việc trên các giao diện trực quan chứ không phải thao tác code.

Do đó, để có thể thêm dữ liệu vào bảng, người quản trị web sẽ nhập từ form HTML.

Việc của lập trình viên web chúng ta là,

Tạo một biểu mẫu HTML có thể được sử dụng để chèn các bản ghi mới vào bảng person.

Bước 1: Tạo một form HTML

Đây là một biểu mẫu HTML đơn giản có ba trường nhập văn bản <input> và nút gửi.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form thêm bản ghi</title>
</head>
<body>
<form action="insert.php" method="post">
    <p>
        <label for="firstName">First Name:</label>
        <input type="text" name="first_name" id="firstName">
    </p>
    <p>
        <label for="lastName">Last Name:</label>
        <input type="text" name="last_name" id="lastName">
    </p>
    <p>
        <label for="emailAddress">Email Address:</label>
        <input type="text" name="email" id="emailAddress">
    </p>
    <input type="submit" value="Submit">
</form>
</body>
</html>

Bước 2: Lấy dữ liệu và chèn dữ liệu vào bảng CSDL

Khi người dùng nhấp vào nút gửi của Form thêm bản ghi, trong ví dụ trên, dữ liệu biểu mẫu được gửi đến tệp ‘insert.php’ thông qua phương thức POST trong PHP.

Tệp ‘insert.php‘ sẽ thực hiện kết nối với máy chủ cơ sở dữ liệu MySQL. Chúng ta lấy dữ liệu của các trường bằng biến $_REQUEST của PHP và cuối cùng thực hiện truy vấn chèn để thêm các bản ghi.

Đây là mã hoàn chỉnh của tệp ‘insert.php’ của chúng ta:

Mã Lấy dữ liệu và Chèn dữ liệu sử dụng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Làm sạch dữ liệu đầu vào để đảm bảo an toàn
$first_name = mysqli_real_escape_string($link, $_REQUEST['first_name']);
$last_name = mysqli_real_escape_string($link, $_REQUEST['last_name']);
$email = mysqli_real_escape_string($link, $_REQUEST['email']);
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES ('$first_name', '$last_name', '$email')";
if(mysqli_query($link, $sql)){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . mysqli_error($link);
}
 
// Close connection
mysqli_close($link);
?>

Mã Lấy dữ liệu và Chèn dữ liệu sử dụng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Làm sạch dữ liệu đầu vào để đảm bảo an toàn
$first_name = $mysqli->real_escape_string($_REQUEST['first_name']);
$last_name = $mysqli->real_escape_string($_REQUEST['last_name']);
$email = $mysqli->real_escape_string($_REQUEST['email']);
 
// Cố gắng thực thi câu lệnh insert
$sql = "INSERT INTO persons (first_name, last_name, email) VALUES ('$first_name', '$last_name', '$email')";
if($mysqli->query($sql) === true){
    echo "Thêm bản ghi thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . $mysqli->error;
}
 
// Đóng kết nối
$mysqli->close();
?>

Mã Lấy dữ liệu và Chèn dữ liệu sử dụng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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 câu lệnh insert
try{
    // Chuẩn bị câu lệnh sql
    $sql = "INSERT INTO persons (first_name, last_name, email) VALUES (:first_name, :last_name, :email)";
    $stmt = $pdo->prepare($sql);
    
    // Các tham số ràng buộc
    $stmt->bindParam(':first_name', $_REQUEST['first_name']);
    $stmt->bindParam(':last_name', $_REQUEST['last_name']);
    $stmt->bindParam(':email', $_REQUEST['email']);
    
    // Thực thi câu lệnh đã chuẩn bị
    $stmt->execute();
    echo "Thêm bản ghi thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể thực thi $sql. " . $e->getMessage());
}
 
// Đóng kết nối
unset($pdo);
?>

Trong bài tiếp theo, chúng ta sẽ mở rộng ví dụ truy vấn chèn này và tiến thêm một bước bằng cách triển khai câu lệnh đã chuẩn bị để bảo mật hiệu suất tốt hơn.

Lưu ý: Hàm mysqli_real_escape_string() được sử dụng để loại bỏ các ký tự đặc biệt trong một chuỗi người dùng / quản trị viên nhập vào và tạo một chuỗi SQL hợp lệ để tránh khỏi vấn đề SQL injection.

Bạn đã hiểu cách chèn dữ liệu vào bảng CSLD MySQL bằng PHP chưa?

Đây là ví dụ rất cơ bản về việc chèn dữ liệu biểu mẫu vào bảng cơ sở dữ liệu MySQL. Bạn có thể mở rộng ví dụ này và làm cho nó tương tác hơn bằng cách xác thực dữ liệu người dùng trước khi chèn nó vào các bảng cơ sở dữ liệu.

Vui lòng xem bài Hướng dẫn validate form để tìm hiểu thêm về cách làm sạch và xác thực các dữ liệu đầu vào của người dùng bằng PHP.

PHPDev

3 Cách Tạo bảng trong CSDL MySQL

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ được tìm hiểu về cách tạo bảng trong cơ sở dữ liệu MySQL bằng PHP.

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ được tìm hiểu về cách tạo bảng trong cơ sở dữ liệu MySQL bằng PHP.

Tạo bảng bên trong cơ sở dữ liệu MySQL bằng PHP

Trong bài trước, chúng ta đã học cách tạo cơ sở dữ liệu MySQL. Bây giờ là lúc chúng ta tìm hiểu cách tạo các bảng bên trong cơ sở dữ liệu MySQL vừa tạo để sử dụng chứa dữ liệu.

Một bảng bên trong MySQL chứa dữ liệu được phân chia thành các hàng và cột, trông như thế này:

Ví dụ Bảng CSDL trong MySQL
Ví dụ Bảng CSDL trong MySQL

Chúng ta sẽ sử dụng câu lệnh SQL là CREATE TABLE để tạo bảng trong cơ sở dữ liệu.

Chúng ta hãy thử tạo một truy vấn SQL bằng cách sử dụng câu lệnh CREATE TABLE, sau đó chúng ta sẽ thực hiện truy vấn SQL này thông qua việc chuyển nó đến hàm mysqli_query() của PHP để cuối cùng tạo bảng như chúng ta muốn.

3 Cách tạo bảng CSDL trong MySQL
3 Cách tạo bảng CSDL trong MySQL

Ví dụ tạo Bảng CSDL trong MySQL

1. Tạo bảng CSDL trong MySQL bằng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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());
}
 
// Thực thi tạo bảng CSDL trong MySQL
$sql = "CREATE TABLE persons(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(30) NOT NULL,
    last_name VARCHAR(30) NOT NULL,
    email VARCHAR(70) NOT NULL UNIQUE
)";
if(mysqli_query($link, $sql)){
    echo "Tạo bảng thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . mysqli_error($link);
}
 
// Đóng kết nối
mysqli_close($link);
?>

2. Tạo bảng CSDL trong MySQL bằng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// Thực thi tạo bảng CSDL trong MySQL
$sql = "CREATE TABLE persons(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(30) NOT NULL,
    last_name VARCHAR(30) NOT NULL,
    email VARCHAR(70) NOT NULL UNIQUE
)";
if($mysqli->query($sql) === true){
    echo "Tạo bảng thành công.";
} else{
    echo "ERROR: Không thể thực thi $sql. " . $mysqli->error;
}
 
// Đóng kết nối
$mysqli->close();
?>

3. Tạo bảng CSDL trong MySQL bằng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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 erorr 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());
}
 
// Thực thi tạo bảng CSDL trong MySQL
try{
    $sql = "CREATE TABLE persons(
        id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
        first_name VARCHAR(30) NOT NULL,
        last_name VARCHAR(30) NOT NULL,
        email VARCHAR(70) NOT NULL UNIQUE
    )";    
    $pdo->exec($sql);
    echo "Tạo bảng thành công.";
} catch(PDOException $e){
    die("ERROR: Không thể thực thi $sql. " . $e->getMessage());
}
 
// Đóng kết nối
unset($pdo);
?>

Đoạn code PHP trong ví dụ trên tạo ra một bảng có tên person với bốn cột id, First_name, last_nameemail bên trong cơ sở dữ liệu demo.

Lưu ý rằng mỗi tên trường được theo sau bởi một khai báo kiểu dữ liệu. Khai báo này chỉ định loại dữ liệu mà cột có thể giữ, cho dù là kiểu integer, string, date, v.v.

Có một vài ràng buộc bổ sung (còn được gọi là bổ nghĩa) được chỉ định sau tên cột trong câu lệnh SQL trước đó, như NOT NULL (Không null), PRIMARY KEY (Khóa chính), AUTO_INCREMENT (Tự động tăng), v.v.

Các ràng buộc này xác định các quy tắc liên quan đến các giá trị được cho phép trong các cột.


Lưu ý: Bạn có thể xuống dòng trong khi viết câu lệnh SQL để dễ đọc code hơn, với điều kiện là bất kỳ ngắt dòng nào sẽ không phá vỡ các từ khóa, giá trị, biểu thức, v.v.


Mẹo: Thiết lập thuộc tính PDO::ATTR_ERRMODE thành PDO::ERRMODE_EXCEPTION yêu cầu PDO ném ngoại lệ bất cứ khi nào xảy ra lỗi cơ sở dữ liệu.


Hãy thử tạo Bảng CSDL của bạn trong MySQL

Đến đây bạn đã được hướng dẫn để kết nối CSDL, tạo CSDL trên máy chủ MySQL và tạo bảng CSDL trong CSDL MySQL của mình.

Hãy thử thực hiện lại tất cả các bước này để tạo Bảng CSDL của riêng bạn phục vụ cho một nhu cầu nào đó, ví dụ: Bảng CSDL lưu trữ thông tin sản phẩm, Bảng CSDL thông tin người dùng…

Cố gắng luyện tập và ghi nhớ thật kỹ bạn nhé!

PHPDev

Tạo CSDL MySQL trong PHP

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ tìm hiểu làm thế nào để tạo cơ sở dữ liệu MySQL trong Lập trình Web với PHP theo 3 cách.

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ tìm hiểu làm thế nào để tạo cơ sở dữ liệu MySQL trong Lập trình Web với PHP.

Tạo cơ sở dữ liệu MySQL bằng PHP

Bài trước bạn đã hiểu làm thế nào để mở một kết nối cơ sở dữ liệu MySQL. Trong bài này, bạn sẽ được hướng dẫn cách thực hiện truy vấn SQL để tạo cơ sở dữ liệu (CSDL).

Trước khi lưu hoặc truy cập dữ liệu, trước tiên chúng ta cần tạo cơ sở dữ liệu. Câu lệnh CREATE DATABASE được sử dụng để tạo cơ sở dữ liệu mới trong MySQL.

Chúng ta hãy tạo một truy vấn SQL bằng cách sử dụng câu lệnh CREATE DATABASE, sau đó chúng ta sẽ thực hiện truy vấn SQL này thông qua việc chuyển nó đến hàm mysqli_query() của PHP để cuối cùng tạo ra cơ sở dữ liệu của chúng ta.

Hướng dẫn tạo CSDL MySQL trong lập trình web với PHP
Hướng dẫn tạo CSDL MySQL trong lập trình web với PHP

Ví dụ tạo CSDL MySQL trong lập trình Web với PHP

Chúng ta hoàn toàn có thể thực hiện tạo CSDL theo 3 cách:

  • Sử dụng MySQLi hướng thủ tục
  • Sử dụng MySQLi hướng đối tượng
  • Sử dụng PDO

1. Ví dụ tạo CSDL MySQL bằng MySQLi hướng thủ tục

<?php
/*Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu)*/

$link = mysqli_connect("localhost", "root", "");
 
// Kiểm tra kết nối
if($link === false){
    die("ERROR: Kết nối thất bại. " . mysqli_connect_error());
}
 
// Thực hiện tạo CSDL
$sql = "CREATE DATABASE demo";
if(mysqli_query($link, $sql)){
    echo "Tạo CSDL thành công!";
} else{
    echo "ERROR: Không thể thực thi $sql. " . mysqli_error($link);
}
 
// Đóng kết nối
mysqli_close($link);
?>

2. Ví dụ tạo CSDL MySQL bằng MySQLi hướng đối tượng

<?php
/*Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu)*/
$mysqli = new mysqli("localhost", "root", "");
 
// Kiểm tra kết nối
if($mysqli === false){
    die("ERROR: Kết nối thất bại. " . $mysqli->connect_error);
}
 
// Thực hiện tạo CSDL
$sql = "CREATE DATABASE demo";
if($mysqli->query($sql) === true){
    echo "Tạo CSDL thành công!";
} else{
    echo "ERROR: Không thể thực thi $sql. " . $mysqli->error;
}
 
// Đóng kết nối
$mysqli->close();
?>

3. Ví dụ tạo CSDL MySQL bằng PDO

<?php
/*Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu)*/
try{
    $pdo = new PDO("mysql:host=localhost;", "root", "");
    // Thiết lập PDO error thành Ngoại lệ
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
    die("ERROR: Kết nối thất bại. " . $e->getMessage());
}
 
// Thực hiện tạo CSDL
try{
    $sql = "CREATE DATABASE demo";
    $pdo->exec($sql);
    echo "Tạo CSDL thành công";
} catch(PDOException $e){
    die("ERROR: Không thể thực thi $sql. " . $e->getMessage());
}
 
// Đóng kết nối
unset($pdo);
?>

Hãy ghi nhớ cách tạo CSDL MySQL

Như vậy, qua 2 bài này các bạn đã biết kết nối đến máy chủ MySQltạo CSDL MySQL trên đó.

Đây là những công việc thường xuyên trong lập trình web php. Hãy ghi nhớ thật kỹ nhé.

Bài tiếp theo chúng ta sẽ bắt đầu thực hiện các thao tác cụ thể hơn với CSDL MySQL chúng ta vừa tạo ra.

PHPDev

Hướng dẫn kết nối MySQL trong PHP: MySQLi và PDO

Trong bài hướng dẫn tự học PHP này, bạn sẽ học 3 cách kết nối với máy chủ MySQL bằng PHP với MySQLi và PDO.

Trong bài hướng dẫn tự học PHP này, bạn sẽ học cách kết nối với máy chủ MySQL bằng PHP với MySQLi và PDO.

Các cách kết nối với MySQL bằng PHP

Để lưu trữ hoặc truy cập dữ liệu bên trong cơ sở dữ liệu MySQL, trước tiên bạn cần kết nối với máy chủ cơ sở dữ liệu MySQL.

PHP cung cấp hai công cụ khác nhau để kết nối với máy chủ MySQL:

  • MySQLi (MySQL cải tiến)
  • PDO (PHP Data Object)

PDO thì di động hơn và hỗ trợ hơn 12 cơ sở dữ liệu khác nhau, còn MySQLi tập trung hỗ trợ cơ sở dữ liệu MySQL.

Tuy nhiên, MySQLi cung cấp một cách dễ dàng hơn để kết nốithực hiện các truy vấn trên máy chủ cơ sở dữ liệu MySQL.

Cả PDO và MySQLi đều cung cấp API hướng đối tượng, nhưng MySQLi cũng cung cấp cả API hướng thủ tục tương đối dễ hiểu cho người mới bắt đầu Học lập trình web PHP & MySQL.

Lưu ý 1: MySQLi của PHP cung cấp cả lợi ích về tốc độ và tính năng so với phần mở rộng PDO, vì vậy nó có thể là lựa chọn tốt hơn cho các dự án web dành riêng cho MySQL.

Hướng dẫn kết nối MySQL trong PHP
Hướng dẫn kết nối MySQL trong PHP

Hướng dẫn 3 cách kết nối PHP với MySQL bằng MySQLi và PDO

Trong PHP, bạn có thể dễ dàng thực hiện kết nối đến máy chủ MySQL bằng hàm mysqli_connect().

Tất cả giao tiếp giữa PHP và máy chủ cơ sở dữ liệu MySQL diễn ra thông qua kết nối này.

Dưới đây là các cú pháp cơ bản để kết nối với MySQL bằng các phần mở rộng MySQLi và PDO:

Cách 1: Cú pháp kết nối MySQL sử dụng MySQLi hướng thủ tục

$link = mysqli_connect("hostname", "username", "password", "database");

Ví dụ sử dụng MySQLi hướng thủ tục để kết nối MySQL

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu) */
$link = mysqli_connect("localhost", "root", "");
 
// Kiểm tra kết nối
if($link === false){
    die("ERROR: Không thể kết nối. " . mysqli_connect_error());
}
 
// In thông tin Host
echo "Kết nối thành công. Host: " . mysqli_get_host_info($link);
?>

Cách 2: Cú pháp kết nối MySQL sử dụng MySQLi hướng đối tượng

$mysqli = new mysqli("hostname", "username", "password", "database");

Ví dụ sử dụng MySQLi hướng đối tượng để kết nối MySQL

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// In thông tin Host
echo "Kết nối thành công. Host: " . $mysqli->host_info;
?>

Cách 3: Cú pháp kết nối MySQL sử dụng PDO

$pdo = new PDO("mysql:host=hostname;dbname=database", "username", "password");

Ví dụ sử dụng PDO để kết nối MySQL

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu) */
try{
    $pdo = new PDO("mysql:host=localhost", "root", "");
    
    // Thiết lập PHP erorr thành Ngoại lệ
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // In thông tin Host
    echo "Kết nối thành công. Host: " . 
$pdo->getAttribute(constant("PDO::ATTR_CONNECTION_STATUS"));
} catch(PDOException $e){
    die("ERROR: Không thể kết nối. " . $e->getMessage());
}
?>

Tham số hostname trong cú pháp trên chỉ định tên máy chủ (ví dụ: localhost) hoặc địa chỉ IP của máy chủ MySQL, trong khi tham số usernamepassword chỉ định thông tin đăng nhập để truy cập máy chủ MySQL và tham số database, nếu được cung cấp sẽ chỉ định sơ sở dữ liệu MySQL mặc định được sử dụng khi thực hiện các truy vấn.

Lưu ý 2: Tên user mặc định cho máy chủ cơ sở dữ liệu MySQL là root và không có mật khẩu. Tuy nhiên, để ngăn chặn cơ sở dữ liệu của bạn khỏi sự xâm nhập và truy cập trái phép, bạn nên đặt mật khẩu cho tài khoản MySQL.

Mẹo: Thiế lập thuộc tính PDO::ATTR_ERRMODE thành PDO::ERRMODE_EXCEPTION để yêu cầu PDO ném ngoại lệ bất cứ khi nào xảy ra lỗi cơ sở dữ liệu.

Hướng dẫn đóng kết nối máy chủ cơ sở dữ liệu MySQL theo 3 cách

1. Đóng kết nối MySQL sử dụng MySQLi hướng thủ tục

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu) */
$link = mysqli_connect("localhost", "root", "");
 
// Kiểm tra kết nối
if($link === false){
    die("ERROR: Không thể kết nối. " . mysqli_connect_error());
}
 
// In thông tin Host
echo "Kết nối thành công. Host: " . mysqli_get_host_info($link);

// Đóng kết nối
mysqli_close($link);
?>

2. Đóng kết nối MySQL sử dụng MySQLi hướng đối tượng

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (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);
}
 
// In thông tin Host
echo "Kết nối thành công. Host: " . $mysqli->host_info;

// Đóng kết nối
$mysqli->close();
?>

3. Đóng kết nối MySQL sử dụng PDO

<?php
/* Cố gắng kết nối máy chủ MySQL. Giả sử bạn đang chạy MySQL
Máy chủ có cài đặt mặc định (user là 'root' và không có mật khẩu) */
try{
    $pdo = new PDO("mysql:host=localhost", "root", "");
    
    // Thiết lập PHP erorr thành Ngoại lệ
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // In thông tin Host
    echo "Kết nối thành công. Host: " . 
$pdo->getAttribute(constant("PDO::ATTR_CONNECTION_STATUS"));
} catch(PDOException $e){
    die("ERROR: Không thể kết nối. " . $e->getMessage());
}

// Đóng kết nối
unset($pdo);
?>

Bạn đã biết kết nối MySQL trong PHP chưa?

Trên đây là 3 cách kết nối MySQL trong PHP với MySQLi PDO.

Bất cứ khi nào sử dụng CSDL MySQL thì bạn đều cần mở một kết nối tới máy chủ MySQl. Sau khi sử dụng xong thì cần phải đóng kết nối để đảm bảo an toàn, tăng hiệu năng cho website của bạn.

Hãy luyện tập và ghi nhớ 3 Cách kết nối cơ sở dữ liệu MySQL này nhé.

PHPDev

Giới thiệu về PHP & MySQL

MySQL là hệ thống cơ sở dữ liệu phổ biến nhất được sử dụng với ngôn ngữ PHP. Đây được coi là “Cặp bài trùng” làm mưa làm gió lĩnh vực lập trình Web.

MySQL là hệ thống cơ sở dữ liệu phổ biến nhất được sử dụng với ngôn ngữ PHP. Đây được coi là “Cặp bài trùng” làm mưa làm gió lĩnh vực lập trình Web.

Giới thiệu về PHP & MySQL
Giới thiệu về PHP & MySQL

MySQL là gì?

MySQL là một trong những hệ thống cơ sở dữ liệu quan hệ phổ biến nhất đang được sử dụng trên Web hiện nay. Nó có sẵn, miễn phí và dễ cài đặt, tuy nhiên nếu bạn đã cài đặt Wamperver thì nó đã có sẵn trên máy của bạn.

MySQL database server có một số lợi ích như sau:

  • MySQL rất dễ sử dụng, nhưng cực kỳ mạnh mẽ, nhanh, an toàn và có thể mở rộng.
  • MySQL chạy trên một loạt các hệ điều hành, bao gồm UNIX hoặc Linux, Microsoft Windows, Apple Mac OS X và các hệ điều hành khác.
  • MySQL hỗ trợ SQL chuẩn (Ngôn ngữ truy vấn có cấu trúc).
  • MySQL là giải pháp cơ sở dữ liệu lý tưởng cho cả ứng dụng nhỏ và lớn.
  • MySQL được phát triển và phân phối bởi Tập đoàn Oracle.
  • MySQL bao gồm các lớp bảo mật dữ liệu giúp bảo vệ dữ liệu nhạy cảm của website.

Cơ sở dữ liệu MySQL lưu trữ dữ liệu vào các bảng như các cơ sở dữ liệu quan hệ khác. Trong đó, bảng là tập hợp các dữ liệu liên quan và được chia thành các hàng và cột.

Mỗi hàng trong một bảng biểu thị một bản ghi dữ liệu vốn được kết nối với nhau như thông tin liên quan đến một người cụ thể, trong khi mỗi cột đại diện cho một trường cụ thể như id, First_name, last_name, email, v.v.

Cấu trúc của một bảng MySQL đơn giản chứa thông tin chung của nhan_vien có thể giống như thế này:

Ví dụ về bảng MySQL đơn giản
Ví dụ về bảng MySQL đơn giản
  • Bật mí: Các trang web như Facebook, Twitter, Wikipedia sử dụng MySQL để lưu trữ CSLD. Vì thế, bạn có thể hiểu được khả năng của MySQL chứ?

Nói chuyện với MySQL bằng SQL

Có thể bạn biết chưa biết, SQL Ngôn ngữ truy vấn có cấu trúc, là ngôn ngữ đơn giản, được tiêu chuẩn hóa để giao tiếp với các cơ sở dữ liệu quan hệ như MySQL.

Với SQL, bạn có thể thực hiện bất kỳ tác vụ nào liên quan đến cơ sở dữ liệu, chẳng hạn như tạo cơ sở dữ liệubảng, lưu dữ liệu trong bảng cơ sở dữ liệu, truy vấn cơ sở dữ liệu cho các bản ghi cụ thể, xóa và cập nhật dữ liệu trong cơ sở dữ liệu.

Hãy thử xem truy vấn SQL tiêu chuẩn sau đây sẽ trả về địa chỉ email của một người có tên bằng với “Sênh” trong bảng nhan_vien:

SELECT email FROM nhan_vien WHERE first_name="Sênh"

Nếu bạn thực hiện truy vấn SQL ở trên, chúng ta sẽ nhận được bản ghi như sau:

trieutonsenh@gmail.com

Lời kết

PHP MySQL là một cặp với nhau. Nếu bạn muốn Học lập trình web với PHP thì không có cách nào dễ dàng, hiệu qur hơn để thao tác với cơ sở dữ liệu bằng MySQL.

>> Tham khảo thêm: Lợi ích của Lập trình Web với PHP & MySQL

Xử lý Ngoại lệ trong PHP

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ học xử lý ngoại lệ bằng cách ném (throw) và bắt (catch) trong PHP.

Trong bài hướng dẫn tự học lập trình PHP này, bạn sẽ học xử lý ngoại lệ bằng cách ném (throw) và bắt (catch) trong PHP.

Ngoại lệ là gì?

Một Ngoại lệ (Exception) là một tín hiệu chỉ ra một số loại sự kiện hoặc lỗi đặc biệt đã xảy ra. Các ngoại lệ có thể được gây ra do nhiều lý do,.

Ví dụ: Kết nối cơ sở dữ liệu hoặc truy vấn không thành công, tệp mà bạn đang cố truy cập không tồn tại, v.v.

PHP cung cấp một cơ chế xử lý ngoại lệ mạnh mẽ cho phép bạn xử lý các ngoại lệ một cách đơn giản.

Trái ngược với hệ thống xử lý lỗi trong PHP, xử lý ngoại lệ là phương pháp hướng đối tượng để xử lý lỗi, cung cấp hình thức báo cáo lỗi linh hoạt và có kiểm soát hơn.

Mô hình ngoại lệ được giới thiệu lần đầu tiên trong PHP 5.

Sử dụng Throw và cấu trúc Try…Catch để xử lý ngoại lệ trong PHP

Xử lý ngoại lệ trong PHP
Xử lý ngoại lệ trong PHP

Theo cách tiếp cận này, code chương trình được viết trong một khối try, một ngoại lệ có thể được ném ra bằng cách sử dụng câu lệnh throw.

Khi một sự kiện đặc biệt xảy ra trong quá trình thực thi code trong khối try. Nó sẽ được bắt và giải quyết bằng một hoặc nhiều khối bắt.

Ví dụ sau đây cho thấy cách xử lý ngoại lệ hoạt động trong PHP:

<?php
function division($dividend, $divisor){
    // Ném ra ngoại lệ chia cho số 0
    if($divisor == 0){
        throw new Exception('Chia cho số 0.');
    } else{
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    // Nếu ngoại lệ được ném ra thì dòng sau không được thực thi
    echo '<p>Tất cả các phép chia thực hiện thành công.</p>';
} catch(Exception $e){
    // Xử lý ngoại lệ
    echo "<p>Ngoại lệ: " . $e->getMessage() . "</p>";
}
 
// Tiếp tục thực thi
echo "<p>Hello World!</p>";
?>

Nếu bạn chưa hiểu đoạn code trên thực hiện như thế nào. Vậy thì, chúng ta hãy đi qua từng phần của đoạn code này để hiểu rõ hơn.

Giải thích về cách xử lý ngoại lệ trong ví dụ trên

Hệ thống xử lý ngoại lệ của PHP về cơ bản có bốn phần: try, throw, catcht và Exception class.

Danh sách sau đây sẽ mô tả chính xác cách mỗi phần hoạt động:

  • Hàm division() trong ví dụ trên kiểm tra xem một ước số có bằng 0 hay không. Nếu đúng như vậy, một ngoại lệ được ném ra thông qua câu lệnh throw của PHP. Nếu không, hàm này thực hiện phép chia bằng các số đã cho và hiển thị kết quả.
  • Sau đó, hàm division() được gọi trong một khối try với các đối số khác nhau. Nếu một ngoại lệ được tạo trong khi thực thi code trong khối try, PHP sẽ dừng thực thi tại điểm đó và cố gắng tìm khối catch tương ứng. Nếu nó được tìm thấy, code trong khối catch đó được thực thi, nếu không, một lỗi nghiêm trọng (fatal error) sẽ được tạo ra.
  • Khối catch thường bắt ngoại lệ được ném trong khối try và tạo một object($e) có chứa thông tin ngoại lệ. Thông báo lỗi từ đối tượng này có thể được truy xuất bằng phương thức getMessage() của Exception class.

Exception class của PHP cũng cung cấp các phương thức khác như getCode(), getFile(), getLine() và getTraceAsString() có thể được sử dụng để truy xuất ra các thông tin cần thiết cho việc gỡ lỗi chi tiết.

<?php
// Tắt báo cáo lỗi mặc định
error_reporting(0);
 
try{
    $file = "somefile.txt";
    
    // Có gắng mở file
    $handle = fopen($file, "r");
    if(!$handle){
        throw new Exception("Không thể mở file!", 5);
    }
    
    // Cố gắng đọc nội dung file
    $content = fread($handle, filesize($file));
    if(!$content){
        throw new Exception("Không thể đọc file!", 10);
    }
    
    // Đóng file
    fclose($handle);
    
    // Hiển thị nội dung
    echo $content;
} catch(Exception $e){
    echo "<h3>Ngoại lệ xảy ra!</h3>";
    echo "<p>Error message: " . $e->getMessage() . "</p>";    
    echo "<p>File: " . $e->getFile() . "</p>";
    echo "<p>Line: " . $e->getLine() . "</p>";
    echo "<p>Error code: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Hàm constructor của Exception nhận một thông báo ngoại lệ và code ngoại lệ. Mặc dù thông báo ngoại lệ thường được sử dụng để hiển thị thông tin chung về những gì đã sai, code ngoại lệ có thể được sử dụng để phân loại lỗi.

Code ngoại lệ được cung cấp có thể được truy xuất sau thông qua phương thức getCode() của Exception class.

Lưu ý: Ngoại lệ chỉ nên được sử dụng để biểu thị các điều kiện đặc biệt. Chúng không nên được sử dụng để kiểm soát luồng ứng dụng thông thường, ví dụ: Nhảy đến một vị trí khác trong tập lệnh tại một điểm cụ thể. Làm như vậy sẽ ảnh hưởng không tốt đến hiệu suất của ứng dụng.

Cách xác định ngoại lệ tùy chỉnh

Bạn thậm chí có thể định nghĩa các trình xử lý ngoại lệ tùy chỉnh của riêng bạn để xử lý các loại ngoại lệ khác nhau theo một cách khác. Nó cho phép bạn sử dụng một khối catch riêng cho từng loại ngoại lệ.

Bạn có thể định nghĩa một ngoại lệ tùy chỉnh bằng cách mở rộng lớp Exception, vì Exception là lớp cơ sở cho tất cả các ngoại lệ.

Lớp ngoại lệ tùy chỉnh kế thừa tất cả các thuộc tính và phương thức từ lớp Exception của PHP.

Bạn cũng có thể thêm các phương thức tùy chỉnh của mình vào lớp ngoại lệ tùy chỉnh., hãy xem ví dụ sau:

<?php
// Mở rộng lớp Exception
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "hello@niithanoi.edu.vn";
 
try{
    // Ném ra ngoại lệ nếu Email trống
    if($email == ""){
        throw new EmptyEmailException("<p>Bạn phải điền Email</p>");
    }
    
    // Ném ra ngoại lệ nếu Email không hợp lệ
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> không hợp lệ!</p>");
    }
    
    // Thông báo thành công nếu email hợp lệ
   echo "<p>CHÚC MỪNG: Xác thực Email thành công.</p>";
} catch(EmptyEmailException $e){
    echo $e->getMessage();
} catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

Trong ví dụ trên, chúng ta đã nhận được hai lớp ngoại lệ mới: EmptyEmailExceptionUnlimitedEmailException từ lớp cơ sở là Exception.

Nhiều khối catch được sử dụng để hiển thị các thông báo lỗi khác nhau, tùy thuộc vào loại ngoại lệ nào được ném ra.

Do các lớp ngoại lệ tùy chỉnh này kế thừa các thuộc tính và phương thức từ lớp Exception, nên chúng ta hoàn toàn có thể sử dụng các phương thức của lớp Exception như getMessage(), getLine(), getFile(), v.v. để lấy thông tin lỗi từ đối tượng ngoại lệ.

Thiết lập Xử lý ngoại lệ toàn cục trong PHP

Như chúng ta đã thảo luận trước đó trong chương này nếu một ngoại lệ không bị bắt, PHP tạo ra Lỗi nghiêm trọng với thông báo ‘Uncaught Exception …’.

Thông báo lỗi này có thể chứa thông tin nhạy cảm như tên file và số dòng nơi xảy ra sự cố. Nếu bạn không muốn để lộ thông tin đó cho người dùng, bạn có thể tạo một hàm tùy chỉnh và đăng ký nó với hàm set_exception_handler() để xử lý tất cả các ngoại lệ chưa được phát hiện.

<?php
function handleUncaughtException($e){
    // Hiển thị thông báo lỗi chung cho người dùng
    echo "Opps! Có lỗi xảy ra. Hãy thử lại hoặc liên hệ với chúng tôi nếu còn lỗi.";
    
    // Lấy thông tin lỗi
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " trong file " . $e->getFile() . " ở dòng " . $e->getLine() . "\n";
    
    // Ghi nhật ký chi tiết lỗi
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
// Đăng ký xử lý ngoại lệ tùy chỉnh
set_exception_handler("handleUncaughtException");
 
// Ném ra một ngoại lệ
throw new Exception("Kiểm tra ngoại lệ!");
?>

Lưu ý: Một ngoại lệ chưa được lưu sẽ luôn dẫn đến việc chấm dứt tập lệnh. Vì thế, nếu bạn muốn tập lệnh tiếp tục thực thi ngoài điểm xảy ra ngoại lệ, bạn phải có ít nhất một khối catch tương ứng cho mỗi khối try.

Bạn đã hiểu về các xử lý ngoại lệ chưa?

Như vậy là trong bài này mình đã hướng dẫn bạn biết cách xử lý ngoại lệ trong PHP với việc sử dụng throw try… catch.

  • Tham khảo Khóa học PHP hoàn thiện từ Front end đến Back end nếu như bạn là người mới bắt đầu.

Nếu có bất cứ thắc mắc nào về vấn đề ngoại lệ trong PHP thì vui lòng để lại câu hỏi trong phần bình luận. Mình sẽ giải thích cho bạn.

Chúc bạn thành công!

Biểu thức chính quy trong PHP – Regular Expressions

Biểu thức chính quy, thường được gọi là ‘regex’ hoặc ‘RegExp’, là một chuỗi văn bản có định dạng đặc biệt được sử dụng để tìm các mẫu trong văn bản.

Trong bài hướng dẫn tự học PHP này, bạn sẽ tìm hiểu cách các biểu thức chính quy hoạt động, cũng như cách sử dụng chúng để thực hiện khớp mẫu trong PHP.

Biểu thức chính quy trong PHP
Biểu thức chính quy trong PHP

Biểu thức chính quy là gì?

Biểu thức chính quy, thường được gọi là ‘regex‘ hoặc ‘RegExp‘, là một chuỗi văn bản có định dạng đặc biệt được sử dụng để tìm các mẫu trong văn bản.

Biểu thức chính quy là một trong những công cụ mạnh nhất hiện nay để xử lý hiệu quả công việc liên quan đến văn bản hiệu.

Ví dụ: Nó có thể được sử dụng để xác minh xem định dạng của dữ liệu như tên, email, số điện thoại, v.v. mà người dùng nhập có chính xác định dạng hay không, xác định mẫu để thay thế chuỗi phù hợp trong nội dung văn bản, v.v.

PHP (phiên bản 5.3 trở lên) hỗ trợ các biểu thức chính quy như ngôn ngữ Perl thông qua hàm preg_.

Tại sao lại giống như Perl?

Bởi vì Perl là ngôn ngữ lập trình chính thống đầu tiên cung cấp sự hỗ trợ tích hợp cho các biểu thức chính quy và Perl được nhiều lâp trình viên biết đến với sự hỗ trợ mạnh mẽ các biểu thức chính quy và khả năng xử lý văn bản đặc biệt hiệu quả của nó.

Chúng ta hãy bắt đầu với một số hàm tích hợp của PHP thường được sử dụng để thực hiện các so khớp các biểu thức chính quy.

HàmTác dụng
preg_match()Thực hiện khớp biểu thức chính quy
preg_match_all()Thực hiện khớp biểu thức chính quy toàn cục
preg_replace()Thực hiện tìm kiếm biểu thức chính quy và thay thế
preg_grep()Trả về các phần tử của mảng đầu vào và khớp mẫu
preg_split()Tách một chuỗi con bằng biểu thức chính quy
preg_quote()Trích dẫn các ký tự biểu thức chính quy được tìm thấy trong một chuỗi

Lưu ý: Hàm preg_match() của PHP ngừng tìm kiếm sau khi nó tìm thấy so khớp đầu tiên, trong khi hàm preg_match_all() tiếp tục tìm kiếm cho đến cuối chuỗi và tìm thấy tất cả các mẫu so khớp có thể thay vì dừng lại ở lần so khớp đúng đầu tiên.

Cú pháp của Biểu thức chính quy

Cú pháp biểu thức chính quy bao gồm việc sử dụng các ký tự đặc biệt (không nên nhầm lẫn với các ký tự đặc biệt HTML).

Các ký tự được cho ý nghĩa đặc biệt trong một biểu thức chính quy là :

. * ? + [ ] () {} ^ $ | \\

Bạn sẽ cần đặt ký tự \ trước các ký tự này bất cứ khi nào bạn muốn sử dụng chúng theo nghĩa đen.

Ví dụ: Nếu bạn muốn khớp ‘.‘, Bạn phải viết \.

Các phần sau đây mô tả các tùy chọn khác nhau có sẵn để xây dựng các mẫu:

Quy tắc xây dựng Biểu thức chính quy trong PHP

Dấu ngoặc vuông bao quanh một mẫu ký tự được gọi là lớp ký tự, ví dụ như: [abc].

Một lớp ký tự luôn khớp một ký tự trong danh sách các ký tự được chỉ định có nghĩa là biểu thức [abc] chỉ khớp với ký tự a, b hoặc c.

Các lớp ký tự phủ định cũng có thể được định nghĩa khớp với bất kỳ ký tự nào ngoại trừ các ký tự có trong ngoặc.

Một lớp ký tự phủ định được xác định bằng cách đặt ký hiệu dấu mũ (^) ngay sau dấu ngoặc mở, như thế này [^ abc].

Bạn cũng có thể xác định một phạm vi các ký tự bằng cách sử dụng ký tự gạch nối (-) bên trong một lớp ký tự, như [0-9]. Hãy xem xét một số ví dụ về các lớp ký tự:

RegExpMô tả
[abc]Khớp với bất kỳ một trong các ký tự a, b hoặc c.
[^abc]Khớp với bất kỳ một ký tự nào ngoại trừ a, b hoặc c.
[a-z]Khớp bất kỳ một ký tự từ chữ thường từ a đến z
[A-Z]Khớp bất kỳ một ký tự từ chữ HOA từ a đến z
[a-Z]Khớp bất kỳ một ký tự từ chữ thường a đến chữ HOA Z
[0-9]Khớp một chữ số duy nhất trong khoảng từ 0 đến 9.
[a-z0-9]Khớp một ký tự đơn giữa a và z hoặc giữa 0 và 9

Ví dụ sau đây sẽ cho bạn thấy cách tìm xem một mẫu có tồn tại trong chuỗi hay không bằng cách sử dụng biểu thức chính quy và hàm preg_match() của PHP:

<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
if(preg_match($pattern, $text)){
    echo "Trùng khớp!";
} else{
    echo "Không tìm thấy.";
}
?>

Tương tự, bạn có thể sử dụng hàm preg_match_all() để tìm tất cả các kết quả khớp trong một chuỗi:

<?php
  $pattern = "/ca[kf]e/";
  $text = "He was eating cake in the cafe.";
  $matches = preg_match_all($pattern, $text, $array);
  echo $matches . " mẫu được tìm thấy.";
?>

Lưu ý: Các biểu thức chính quy không chỉ dành riêng cho PHP. Các ngôn ngữ như Java, Perl, Python, v.v … sử dụng cùng một ký hiệu để tìm các mẫu trong văn bản.

Bộ định lượng trong Biểu thức chính quy

Trong phần trước, chúng ta đã học cách kết hợp một ký tự trong nhiều kiểu khác nhau. Nhưng nếu bạn muốn so khớp ký tự nào đó xuất hiện nhiều lần thì sao?

Ví dụ: Giả sử bạn muốn tìm ra các từ có chứa một hoặc nhiều phiên bản của chữ p hoặc các từ có chứa ít nhất hai chữ p, v.v.

Đây là định lượng phát huy tác dụng. Với các bộ lượng hóa, bạn có thể chỉ định số lần một ký tự trong biểu thức chính quy cần phải so khớp.

Bảng sau liệt kê các cách khác nhau để định lượng một mẫu cụ thể:

RegExpMô tả
p+Khớp với một hoặc nhiều lần xuất hiện của chữ p
p*Khớp 0 hoặc nhiều lần xuất hiện của chữ p.
p?Khớp 0 hoặc một lần xuất hiện của chữ p.
p{2}Khớp chính xác hai lần xuất hiện của chữ p
p{2,3}Khớp ít nhất hai lần xuất hiện của chữ p, nhưng không quá ba lần xuất hiện của chữ p.
p{2,}Khớp hai hoặc nhiều lần xuất hiện của chữ p
p{,3} Khớp nhiều nhất ba lần xuất hiện của chữ p

Biểu thức chính quy trong ví dụ sau sẽ phân tách chuỗi theo dấu phẩy, chuỗi dấu phẩy, khoảng trắng hoặc kết hợp của nó bằng cách sử dụng hàm preg_split() của PHP:

<?php
  $pattern = "/[\s,]+/";
  $text = "My favourite colors are red, green and blue";
  $parts = preg_split($pattern, $text);
 
  // Loop through parts array and display substrings
  foreach($parts as $part){
    echo $part . "<br>";
  }
?>

So khớp dựa theo vị trí trong biểu thức chính quy

Có một số tình huống mà bạn muốn so khớp ở đầu hoặc cuối của một dòng, từ hoặc một chuỗi. Để làm điều này, bạn có thể sử dụng neo vị trí.

Hai vị trí neo phổ biến là:

  • Dấu mũ (^) đại diện cho phần bắt đầu của chuỗi
  • Ký hiệu đô la ($) đại diện cho phần cuối của chuỗi.
RegExpMô tả
^pSo khớp với chữ p ở đầu dòng
p$So khớp với chữ p ở cuối dòng

Biểu thức chính quy trong ví dụ sau sẽ chỉ hiển thị các tên bắt đầu bằng chữ “J” từ một mảng tên bằng cách sử dụng hàm preg_grep() của PHP:

<?php
  $pattern = "/^J/";
  $names = array("Jhon Carter", "Clark Kent", "John Rambo");
  $matches = preg_grep($pattern, $names);
 
  // lặp qua các matches và hiển thị chúng
  foreach($matches as $match){
    echo $match . "<br>";
  }
?>

Sửa đổi Pattern trong Biểu thức chính Quy

Công cụ sửa đổi pattern cho phép bạn kiểm soát cách xử lý khớp mẫu. Công cụ sửa đổi mẫu được đặt trực tiếp sau biểu thức chính quy.

Ví dụ: Nếu bạn muốn tìm kiếm mẫu theo cách không phân biệt chữ hoa chữ thường, bạn có thể sử dụng công cụ sửa đổi i, như sau: / pattern / i.

Bảng sau liệt kê một số công cụ sửa đổi mẫu được sử dụng phổ biến nhất:

ModifierMô tả
iKhông phân biệt chữ HOA – chữ thường
mThay đổi hành vi của ^ và $ để khớp với ranh giới dòng mới (nghĩa là bắt đầu hoặc kết thúc mỗi dòng trong một chuỗi nhiều dòng), thay vì ranh giới chuỗi.
gThực hiện khớp toàn cục, tìm thấy tất cả các lần xuất hiện
oĐánh giá biểu thức chỉ một lần.
sThay đổi hành vi của. (dấu chấm) để khớp với tất cả các ký tự, bao gồm cả dòng mới.
xCho phép bạn sử dụng khoảng trắng và comment trong một biểu thức chính quy cho rõ ràng.

Ví dụ sau đây sẽ cho bạn thấy cách thực hiện tìm kiếm không phân biệt chữ hoa chữ thường bằng cách sử dụng công cụ sửa đổi i và hàm preg_match_all() của PHP:

<?php
  $pattern = "/color/i";
  $text = "Color red is more visible than color blue in daylight.";
  $matches = preg_match_all($pattern, $text, $array);
  echo $matches . " matches were found.";
?>

Tương tự, ví dụ sau đây cho thấy cách so khớp ở đầu mỗi dòng trong chuỗi nhiều dòng bằng cách sử dụng neo vị trí đầu với ký tự mũ (^) và (m) với hàm preg_match_all() của PHP:

<?php
  $pattern = "/^color/im";
  $text = "Color red is more visible than \ncolor blue in daylight.";
  $matches = preg_match_all($pattern, $text, $array);
  echo $matches . " matches were found.";
?>

Ranh giới các từ trong Biểu thức chính quy

Một ký tự ranh giới từ (\b) giúp bạn tìm kiếm các từ bắt đầu và / hoặc kết thúc bằng một mẫu.

Ví dụ: Mẫu /\bcar/ khớp với các từ bắt đầu bằng mẫu car và sẽ khớp với cart, carot hoặc cartoon, nhưng sẽ không khớp với từ oscar.

Tương tự, Mẫu /car\b/ khớp với các từ kết thúc bằng mẫu xe và sẽ khớp với car, oscar hoặc supercar, nhưng sẽ không khớp với cart, cartoon, carot.

Tương tự, /\bcar\b/ so khớp với các từ bắt đầu và kết thúc với từ car. Do đó nó sẽ chỉ khớp với từ car

Ví dụ sau đây sẽ làm nổi bật các từ bắt đầu bằng car in đậm:

<?php
  $pattern = '/\bcar\w*/';
  $replacement = '<b>$0</b>';
  $text = 'Words begining with car: cart, carrot, cartoon. Words ending 
  with car: scar, oscar, supercar.';
  echo preg_replace($pattern, $replacement, $text);
?>

Tham khảo PHP Cheat Sheet

PHP Cheat Sheet

Lời Kết

Mình hy vọng bạn đã hiểu những điều cơ bản của Biểu thức chính quy trong PHP. Để tìm hiểu cách xác thực dữ liệu biểu mẫu bằng biểu thức chính quy, bạn có thể xem lại bài hướng dẫn về Xác thực biểu mẫu với PHP.

Lưu ý, đôi khi để gia tăng trải nghiệm người dùng, bạn không cần so khớp quá chính xác.

JSON Parsing: Phân giải dữ liệu JSON với PHP

Trong bài hướng dẫn tự học Lập trình PHP này, bạn sẽ dược học cách mã hóa (endcode) và giải mã (decode) dữ liệu JSON trong PHP.

Trong bài hướng dẫn tự học Lập trình PHP này, bạn sẽ dược học cách mã hóa (endcode)giải mã (decode) dữ liệu JSON với PHP.

Vậy,

JSON là gì?

JSON là từ viết tắt của Javascript Object Notation. JSON là một định dạng tiêu chuẩn trong trao đổi dữ liệu nhẹ, nhanh chóng và dễ dàng tạo (generate) và phân tích (parse).

JSON, giống như XML, là một định dạng dựa trên văn bản, dễ viết và dễ hiểu cho cả con người và máy tính.

Nhưng không giống như XML, các cấu trúc dữ liệu JSON chiếm ít băng thông hơn các phiên bản XML của chúng.

Dữ liệu kiểu JSON dựa trên hai cấu trúc cơ bản:

  • Object: Được định nghĩa là một tập hợp các cặp key / value (nghĩa là key: value). Mỗi đối tượng bắt đầu bằng dấu ngoặc nhọn trái { và kết thúc bằng dấu ngoặc nhọn phải }. Có nhiều cặp key / value được phân tách bằng dấu phẩy , .
  • Array: Được định nghĩa là một danh sách các giá trị được sắp xếp. Một mảng bắt đầu bằng dấu ngoặc vuông trái [ và kết thúc bằng dấu ngoặc vuông phải ]. Các giá trị được phân tách bằng dấu phẩy , .

Trong JSON, các key luôn là các string, trong khi giá trị có thể là một string, number, true hoặc false, null, thậm chí là một Object hoặc một Array.

Các string phải được đặt trong dấu ngoặc kép “” và có thể chứa các ký tự thoát như \n, \t và \.

Một đối tượng JSON có thể trông như thế này:

Ví dụ về JSON Object theo cấu trúc Object

{
    "book": {
        "Tên": "Lập trình viên PHP",
        "Chữ ký": "PHP Dev",
        "Năm": 2019,
        "Loại": "Công nghệ",
        "Nổi tiếng": true
    }
}

Ví dụ về JSON Object theo cấu trúc Array

{
    "Danh mục": [
        "PHP Cơ Bản",
        "PHP Nâng Cao",
        "PHP & MySQL",
        "Ví dụ thực tế"
    ]
}

Ghi chú:

Định dạng data-interchange là định dạng văn bản được sử dụng để trao đổi hoặc hoán đổi dữ liệu giữa các nền tảng và hệ điều hành khác nhau. JSON là định dạng trao đổi dữ liệu nhẹ và phổ biến nhất cho các ứng dụng web.

Hướng dẫn phân giải dữ liệu JSON với PHP
Hướng dẫn phân giải dữ liệu JSON với PHP

Phân giải JSON với PHP (JSON Parsing)

Cấu trúc dữ liệu JSON rất giống với mảng của PHP. PHP có các hàm dựng sẵn để encode và decode dữ liệu JSON.

Các hàm này lần lượt là json_encode()json_decode(). Cả hai chức năng chỉ hoạt động với dữ liệu chuỗi được mã hóa theo chuẩn UTF-8.

Endcoding dữ liệu JSON bằng PHP

Trong PHP, chúng ta sử dụng hàm json_encode() được sử dụng để mã hóa một giá trị thành định dạng JSON.

Giá trị được mã hóa có thể là bất kỳ loại dữ liệu PHP nào ngoại trừ tài nguyên như cơ sở dữ liệu hoặc liên quan đến xử lý tệp.

Ví dụ dưới đây trình bày cách mã hóa một mảng kết hợp PHP thành một đối tượng JSON:

<?php
// Một mảng kết hợp
$tuoiNhanVien = array("Khánh"=>27, "Đức"=>32, "Huyền"=>35, "Thúy"=>30);
 
echo json_encode($tuoiNhanVien);
?>

Kết quả nhận được như sau:

{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}

Tương tự…

Bạn có thể mã hóa mảng chỉ số trong PHP thành một mảng JSON, như thế này:

<?php
// Mảng chỉ số
$mauSac= array("Đỏ", "Xanh", "Vàng", "Lục", "Lam");
 
echo json_encode($colors);
?>

Kết quả nhận được là:

["Đỏ","Xanh","Vàng","Lục","Lam"]

Bạn cũng có thể buộc hàm json_encode() trả về một mảng chỉ số trong PHP dưới dạng đối tượng JSON bằng cách sử dụng tùy chọn JSON_FORCE_OBJECT, như trong ví dụ dưới đây:

<?php
// Mảng chỉ số
// Mảng chỉ số
$mauSac= array("Đỏ", "Xanh", "Vàng", "Lục", "Lam");
 
echo json_encode($colors, JSON_FORCE_OBJECT);
?>

Kết quả nhận được là:

{"Đỏ","Xanh","Vàng","Lục","Lam"}

Như bạn có thể thấy trong các ví dụ trên, một mảng không kết hợp có thể được mã hóa thành mảng hoặc đối tượng. Tuy nhiên, một mảng kết hợp luôn được mã hóa dưới dạng đối tượng.

Decoding dữ liệu JSON bằng PHP

Decoding dữ liệu JSON đơn giản như Endcoding nó. Bạn có thể sử dụng hàm json_decode() của PHP để chuyển đổi chuỗi được mã hóa JSON thành kiểu dữ liệu PHP phù hợp.

Ví dụ sau minh họa cách decoding hoặc chuyển đổi một đối tượng JSON thành đối tượng trong PHP.

<?php
// Lưu dữ liệu JSON trong biến
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
var_dump(json_decode($json));
?>

Kết quả của ví dụ trên sẽ trông giống như thế này:

object(stdClass)#1 (4) { ["Khánh"]=> int(27) ["Đức"]=> int(32) ["Huyền"]=> int(35) ["Thúy"]=> int(30) }

Theo mặc định, hàm json_decode() trả về một đối tượng. Tuy nhiên, bạn có thể tùy ý chỉ định tham số thứ hai $assoc chấp nhận giá trị boolean mà khi:

  • Được thiết lập là true => các đối tượng JSON thực được decoding thành các mảng kết hợp.
  • Còn mặc định là false

Đây là ví dụ:

<?php
// Lưu dữ liệu JSON trong biến
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
var_dump(json_decode($json, true));
?>

Kết quả nhận được:

array(4) { ["Khánh"]=> int(27) ["Đức"]=> int(32) ["Huyền"]=> int(35) ["Thúy"]=> int(30) }

Tiếp theo, hãy xem một ví dụ sẽ chỉ cho bạn cách decoding JSON data và cách truy cập các phần tử riêng lẻ của đối tượng JSON hoặc mảng trong PHP.

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
// Truy cập giá trị của mảng kết hợp
echo $arr["Khánh"];  // Output: 27
echo $arr["Đức"];  // Output: 32
echo $arr["Huyền"];   // Output: 35
echo $arr["Thúy"];  // Output: 30
 
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
// Truy cập dữ liệu từ đối tượng được trả về
echo $obj->Khánh;   // Output: 65
echo $obj->Đức;   // Output: 80
echo $obj->Huyền;    // Output: 78
echo $obj->Thúy;   // Output: 90
?>

Bạn cũng có thể lặp qua dữ liệu được decoding bằng vòng lặp foreach(), như thế này:

<?php
// Gán chuỗi được mã hóa JSON cho một biến PHP
$json = '{"Khánh":27,"Đức":32,"Huyền":35,"Thúy":30}';
 
// Decode JSON data thành mảng kết hợp trong PHP
$arr = json_decode($json, true);
 
// Lặp qua mảng Kết hợp
foreach($arr as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
echo "<hr>";
// Decode JSON data thành đối tượng trong PHP
$obj = json_decode($json);
 
// Lặp qua đối tượng
foreach($obj as $key=>$value){
    echo $key . "=>" . $value . "<br>";
}
?>

Hướng dẫn trích xuất các giá trị từ dữ liệu JSON lồng nhau trong PHP

Trong khi làm việc với JSON, các đối tượng và mảng JSON cũng có thể được lồng nhau. Một đối tượng JSON có thể tùy ý chứa các đối tượng JSON, mảng, mảng lồng nhau, mảng đối tượng JSON, v.v.

Ví dụ sau sẽ chỉ cho bạn cách giải mã một đối tượng JSON lồng nhau và in tất cả các giá trị của nó trong PHP .

<?php
// Khai báo hàm đệ quy để trích xuất các giá trị lồng nhau
function printValues($arr) {
    global $count;
    global $values;
    
    // Kiểm tra đầu vào của một mảng
    if(!is_array($arr)){
        die("ERROR: Đầu vào không phải một mảng");
    }
    
    /*
    *Lặp qua một mảng
    *Nếu giá trị tự nó là một mảng thì gọi hàm đệ quy
    *Nếu không thì thêm giá trị tìm thấy vào mảng đầu ra
    *Tăng bộ đếm lên 1 đơn vị
    */
    foreach($arr as $key=>$value){
        if(is_array($value)){
            printValues($value);
        } else{
            $values[] = $value;
            $count++;
        }
    }
    
    // Trả về tổng số giá trị được tìm thấy trong Mảng
    return array('total' => $count, 'values' => $values);
}
 
// Gán chuỗi JSON được mã hóa cho một biến PHP
$json = '{
    "book": {
        "name": "Harry Potter and the Goblet of Fire",
        "author": "J. K. Rowling",
        "year": 2000,
        "characters": ["Harry Potter", "Hermione Granger", "Ron Weasley"],
        "genre": "Fantasy Fiction",
        "price": {
            "paperback": "$10.40", "hardcover": "$20.32", "kindle": "4.11"
        }
    }
}';
// Decode Dữ liệu JSON thành định dạng mảng kết hợp
$arr = json_decode($json, true);
 
// Gọi hàm và in tất cả các giá trị
$result = printValues($arr);
echo "<h3>" . $result["total"] . " value(s) found: </h3>";
echo implode("<br>", $result["values"]);
 
echo "<hr>";
 
// In giá trị riêng lẻ
echo $arr["book"]["author"] . "<br>";  // Output: J. K. Rowling
echo $arr["book"]["characters"][0] . "<br>";  // Output: Harry Potter
echo $arr["book"]["price"]["hardcover"];  // Output: $20.32
?>

Tổng kết

Như vậy là qua bài này bạn đã được học về cách endcode decode dữ liệu JSON trong PHP.

Đây là một dạng dữ liệu trao đổi giữa các nền tảng rất phổ biến. Hãy thực hành lại các ví dụ để chắc chắn bạn đã hiểu và nắm được các thao tác với dữ liệu JSON bằng PHP.

PHPDev

Bài 31: Tìm hiểu Class và Object trong PHP

Trong bài hướng dẫn này, bạn sẽ được học cách lập trình theo kiểu hướng đối tượng (OOP) trong PHP. Tìm hiểu về cách khai báo Class, Object và truy cập thuộc tính, phương thức của chúng…

Trong bài hướng dẫn này, bạn sẽ được học cách lập trình theo kiểu hướng đối tượng (OOP) trong PHP. Tìm hiểu về cách khai báo Class, Object và truy cập thuộc tính, phương thức của chúng…

Tìm hiểu về Class và Object trong PHP
Tìm hiểu về Class và Object trong PHP

Lập trình hướng đối tượng là gì

Lập trình hướng đối tượng (OOP) là một mô hình lập trình dựa trên khái niệm về các lớp và các đối tượng.

Trái ngược với lập trình thủ tục trong đó trọng tâm là viết các thủ tục hoặc hàm thực hiện các thao tác trên dữ liệu. Trong lập trình hướng đối tượng, trọng tâm là tạo các đối tượng chứa cả dữ liệu và hàm cùng nhau.

Lập trình hướng đối tượng có một số lợi thế so với phong cách lập trình thông thường hoặc theo thủ tục. Những cái quan trọng nhất được liệt kê dưới đây:

  • Hướng đối tượng cung cấp một cấu trúc mô-đun rõ ràng cho chương trình
  • Nó giúp bạn tuân thủ nguyên tắc ‘không lặp lại chính mình’ (DRY) và do đó làm cho mã của bạn dễ dàng hơn nhiều để duy trì, sửa đổi và gỡ lỗi
  • Nó có thể tạo ra hành vi phức tạp hơn với ít mã hơn và thời gian phát triển ngắn hơn và mức độ tái sử dụng cao

Các phần sau đây sẽ mô tả cách các lớp và các đối tượng hoạt động trong PHP.

Mẹo nhanh: Ý tưởng đằng sau nguyên tắc Đừng lặp lại chính mình (DRY) là giảm việc lặp lại code bằng cách trừu tượng hóa các đoạn code tương tự, phổ biến cho ứng dụng và đặt chúng tại một nơi duy nhất và sử dụng lại chúng thay vì viết đi viết lại nhiều lần.

Hiểu về Lớp và Đối tượng trong PHP

Các Lớp (Class) và các Đối tượng (Object) là hai khía cạnh chính của Lập trình hướng đối tượng.

Một lớp là một container tập hợp các biến và hàm độc lập, hoạt động cùng nhau để thực hiện một hoặc nhiều tác vụ cụ thể, trong khi các đối tượng là các thể hiện riêng lẻ của một lớp.

Một lớp hoạt động như một khuôn mẫu hoặc bản thiết kế mà từ đó có thể tạo ra rất nhiều đối tượng riêng lẻ.

Khi các đối tượng riêng lẻ được tạo, chúng kế thừa các thuộc tínhhành vi chung giống nhau, mặc dù mỗi đối tượng có thể có các giá trị khác nhau cho các thuộc tính nhất định.

Ví dụ, hãy nghĩ về một lớp học như một bản thiết kế cho một ngôi nhà. Bản thân bản thiết kế chi tiết không phải là một ngôi nhà, mà là một kế hoạch chi tiết để xây dựng ngôi nhà.

Chúng ta có thể xây dựng một số ngôi nhà giống hệt nhau từ cùng một bản thiết kế, nhưng mỗi ngôi nhà có thể có màu sơn khác nhau, nội thất và gia đình khác nhau bên trong, như trong hình minh họa dưới đây.

Minh họa Class và Object
Minh họa Class và Object

Một lớp có thể được khai báo bằng từ khóa class, theo sau là tên của lớp và một cặp dấu ngoặc nhọn ({}), như trong ví dụ sau.

Chúng ta hãy tạo một tệp PHP có tên là Rectangle.php và đặt code ví dụ sau vào bên trong. Chúng ta tách chúng khỏi phần còn lại của chương trình. Sau đó, chúng ta có thể sử dụng nó bất cứ nơi nào cần thiết bằng cách bao include tệp Rectangle.php

<?php
class Rectangle
{
    // Khai báo thuộc tính
    public $length = 0;
    public $width = 0;
    
    // Phương thức tính chu vi
    public function getPerimeter(){
        return (2 * ($this->length + $this->width));
    }
    
    // Phương thức tính diện tích
    public function getArea(){
        return ($this->length * $this->width);
    }
}
?>

Từ khóa public trước các thuộc tính và phương thức trong ví dụ trên, là một cách để điều chỉnh cấp độ truy cập, nó cho biết thuộc tính hoặc phương thức này có thể truy cập được từ mọi nơi.

Chúng ta sẽ tìm hiểu thêm về các cấp độ truy cập trong các bài học sau này.

Lưu ý: Về mặt cú pháp, các biến trong một lớp được gọi là các thuộc tính, trong khi các hàm được gọi là các phương thức. Ngoài ra, các tên lớp theo quy ước được viết bằng PascalCase, tức là mỗi từ được ghép bắt đầu bằng một chữ cái viết hoa (ví dụ: MyClass).

Khi một lớp đã được xác định, các đối tượng có thể được tạo từ lớp với từ khóa new. Các phương thức và thuộc tính lớp có thể được truy cập trực tiếp thông qua thể hiện đối tượng này.

Tạo một tệp PHP tên là test.php khác và đặt đoạn mã sau vào bên trong nó.

<?php
// Include Lớp Rectangle
require "Rectangle.php";
 
// Tạo một đối tượng mới từ class Rectangle
$obj = new Rectangle;
 
// Lấy các giá trị thuộc tính của đối tượng
echo $obj->length; // 0utput: 0
echo $obj->width; // 0utput: 0
 
// Thiết lập giá trị thuộc tính
$obj->length = 30;
$obj->width = 20;
 
/* Đọc các giá trị thuộc tính đối tượng một lần nữa để hiển thị sự thay đổi*/
echo $obj->length; // 0utput: 30
echo $obj->width; // 0utput: 20
 
 
// Gọi phương thức của đối tượng
echo $obj->getPerimeter(); // 0utput: 100
echo $obj->getArea(); // Output: 600
?>

Ký hiệu mũi tên (->) là cấu trúc OOP được sử dụng để truy cập các thuộc tính và phương thức chứa của một đối tượng nhất định. Trong khi đó, biến giả $this cung cấp một tham chiếu đến đối tượng gọi tức là đối tượng mà phương thức thuộc về.

Sức mạnh thực sự của lập trình hướng đối tượng trở nên rõ ràng khi sử dụng nhiều phiên bản của cùng một lớp, như trong ví dụ sau:

<?php
// Include lớp Rectangle
require "Rectangle.php";
 
// Tạo nhiều đối tượng mới từ Lớp Rectangle
$obj1 = new Rectangle;
$obj2 = new Rectangle;
 
// Tính diện tích của cả 2 đối tượng
echo $obj1->getArea(); // Output: 0
echo $obj2->getArea(); // Output: 0
 
// Thiết lập thuộc tính cho đối tượng $obj1
$obj1->length = 30;
$obj1->width = 20;
 
// Thiết lập thuộc tính cho đối tượng $obj2
$obj2->length = 35;
$obj2->width = 50;
 
// Gọi phương thức tính diện tích của cả 2 đối tượng 1 lần nữa
echo $obj1->getArea(); // Output: 600
echo $obj2->getArea(); // Output: 1750
?>

Như bạn có thể thấy trong ví dụ trên, việc gọi phương thức getArea() trên các đối tượng khác nhau khiến phương thức đó hoạt động trên một tập hợp dữ liệu khác nhau.

Mỗi đối tượng là hoàn toàn độc lập, với các thuộc tính và phương thức riêng của nó và do đó có thể được thao tác độc lập, ngay cả khi chúng cùng loại.

Sử dụng Constructors và Destructors

Để làm cho việc lập trình hướng đối tượng trở nên dễ dàng hơn, PHP cung cấp một số phương thức được thực thi tự động khi một số hành động nhất định xảy ra trong một đối tượng.

Ví dụ, phương thức __construct() (được gọi là hàm tạo / hàm khởi tạo) được thực thi tự động bất cứ khi nào một đối tượng mới được tạo.

Tương tự, phương thức __destruct() (được gọi là hàm hủy) được thực thi tự động khi đối tượng bị hủy. Hàm hủy diệt sẽ dọn sạch mọi tài nguyên được phân bổ cho một đối tượng sau khi đối tượng bị hủy.

<?php
class MyClass
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
    
    // Destructor
    public function __destruct(){
        echo 'Lớp "' . __CLASS__ . '" đã được phá hủy.<br>';
    }
}
 
// Tạo một đối tượng mới
$obj = new MyClass;
 
// Xuất một in nhắn ở cuối file
echo "Kết thúc tập tin.";
?>

Chạy đoạn code PHP trên chúng ta sẽ nhận được kết quả sau:

Lớp MyClass đã được khởi tạo!
Kết thúc tập tin.
Lớp MyClass đã được phá hủy.

Hàm hủy được gọi tự động khi tập lệnh kết thúc. Tuy nhiên, để kích hoạt rõ ràng hàm hủy, bạn có thể hủy đối tượng bằng hàm unset() của PHP, như sau:

<?php
class MyClass
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
    
    // Destructor
    public function __destruct(){
        echo 'Lớp "' . __CLASS__ . '" đã được phá hủy.<br>';
    }
}
 
// Tạo một đối tượng mới
$obj = new MyClass;

// Phá hủy đối tượng
unset($obj);
 
// Xuất một in nhắn ở cuối file
echo "Kết thúc tập tin.";
?>

Bây giờ, chạy tập tin trên và nhận được kết quả:

Lớp MyClass đã được khởi tạo!
Lớp MyClass đã được phá hủy.
Kết thúc tập tin.

Mẹo nhanh: PHP tự động dọn sạch tất cả các tài nguyên được phân bổ trong khi thực thi khi tập lệnh kết thúc, ví dụ: Đóng kết nối cơ sở dữ liệu, phá hủy các đối tượng, vv

Lưu ý: __CLASS__ là hằng số chứa tên của lớp mà nó xảy ra. Nó trống rỗng, nếu nó xảy ra bên ngoài lớp học.

Mở rộng (Extend) Lớp thông qua Kế thừa (Inheritance)

Các lớp có thể kế thừa các thuộc tínhphương thức của một lớp khác bằng cách sử dụng từ khóa extends. Quá trình mở rộng này được gọi là thừa kế.

Đây có lẽ là lý do việc sử dụng mô hình lập trình hướng đối tượng phổ biến như thế.

<?php
// Include lớp Rectangle
require "Rectangle.php";
 
// Xác định một lớp mới dựa trên một lớp hiện có
class Square extends Rectangle
{   
    /* Phương pháp kiểm tra xem hình chữ nhật có phải là hình vuông không */
    public function isSquare(){
        if($this->length == $this->width){
            return true; // Hình Vuông
        } else{
            return false; // Hình Chữ Nhật
        }
    }
}
 
// Tạo một đối tượng mới từ Lớp Square
$obj = new Square;
 
// Thiết lập giá trị thuộc tính đối tượng
$obj->length = 20;
$obj->width = 20;
 
// Gọi phương thức
if($obj->isSquare()){
    echo "Diện tích hình Vuông là ";
} else{
    echo "Diện tích hình Chữ Nhật là ";
};
echo $obj->getArea();
?>

Đoạn mã PHP trong ví dụ trên sẽ cho ra kết quả như sau:

Diện tích hình Vuông là 400

Như bạn có thể thấy trong ví dụ trên, mặc dù định nghĩa lớp của Square không rõ ràng chứa phương thức getArea() cũng như thuộc tính $length và $width, các thể hiện của lớp Square vẫn có thể sử dụng chúng, vì chúng được kế thừa từ Lớp cha của nó là Rectangle.

Mẹo nhanh: Vì một lớp con có nguồn gốc từ một lớp cha, nên nó cũng được gọi là lớp dẫn xuất và lớp cha của nó được gọi là lớp cơ sở.

Kiểm soát mức độ hiển thị của các thuộc tính và phương thức

Khi làm việc với các lớp, bạn có thể hạn chế quyền truy cập vào các thuộc tính và phương thức của nó bằng cách sử dụng các từ khóa hiển thị để kiểm soát tốt hơn.

Có ba từ khóa hiển thị (từ dễ thấy nhất đến ít nhìn thấy nhất): public, protected, private.

Từ đó các thuộc tính và phương thức có thể được kiểm soát mức độ truy cập và sửa đổi.

  • public: Một thuộc tính hoặc phương thức công khai có thể được truy cập ở bất cứ đâu, từ trong lớp đến bên ngoài lớp. Đây là khả năng hiển thị mặc định cho tất cả các thành viên lớp trong PHP.
  • protected: Một thuộc tính hoặc phương thức được bảo vệ chỉ có thể được truy cập từ bên trong chính lớp đó hoặc trong các lớp con hoặc các lớp được kế thừa, tức là các lớp mở rộng lớp đó.
  • private: Một thuộc tính hoặc phương thức riêng tư chỉ có thể truy cập được từ bên trong lớp định nghĩa nó. Ngay cả các lớp con hoặc lớp thừa kế cũng không thể truy cập các thuộc tính hoặc phương thức private.

Ví dụ sau đây sẽ cho bạn thấy khả năng hiển thị / mức độ truy cập này thực sự hoạt động như thế nào.

<?php
// Định nghĩa class
class Automobile
{
    // Khai báo thuộc tính
    public $fuel;
    protected $engine;
    private $transmission;
}
class Car extends Automobile
{
    // Constructor
    public function __construct(){
        echo 'Lớp "' . __CLASS__ . '" đã được khởi tạo!<br>';
    }
}
 
// Tạo một đối tượng từ lớp Automobile
$automobile = new Automobile;
 
// Thiết lập thuộc tính cho đối tượng $automobile
$automobile->fuel = 'Petrol'; // ok
$automobile->engine = '1500 cc'; // fatal error
$automobile->transmission = 'Manual'; // fatal error
 
// Tạo một đối tượng từ Lớp Car
$car = new Car;
 
// Thiết lập thuộc tính cho đối tượng $car
$car->fuel = 'Diesel'; // ok
$car->engine = '2200 cc'; // fatal error
$car->transmission = 'Automatic'; // undefined
?>

Phương thức static và thuộc tính stactic

Ngoài khả năng hiển thị trên, các thuộc tính và phương thức cũng có thể được khai báo là static, điều này làm cho chúng có thể truy cập được mà không cần phải khởi tạo lớp.

Các thuộc tính và phương thức tĩnh có thể được truy cập bằng toán tử phân giải phạm vi (: :), như thế này: ClassName::$property và ClassName::method().

Một thuộc tính được khai báo là static không thể được truy cập thông qua đối tượng của lớp đó mặc dù có thể là một phương thức tĩnh, như được minh họa trong ví dụ sau:

<?php
// Định nghĩa Lớp
class HelloClass
{
    // Khai báo thuộc tính static
    public static $greeting = "Hello World!";
    
    // Khai báo phương thức static
    public static function sayHello(){
        echo self::$greeting;
    }
}
// Cố gắng truy cập vào thuộc tính và phương thức static
echo HelloClass::$greeting; // Output: Hello World!
HelloClass::sayHello(); // Output: Hello World!
 
// Cố gắng truy cập thuộc tính và phương thức tĩnh thông qua đối tượng
$hello = new HelloClass;
echo $hello->greeting; // Strict Warning
$hello->sayHello(); // Output: Hello World!
?>

Từ khóa self trong ví dụ trên có nghĩa là ‘lớp hiện tại’. Nó không bao giờ đi trước ký hiệu đô la ($) và luôn được theo sau bởi toán tử :: (ví dụ: self::$name).

Từ khóa self khác với từ khóa this có nghĩa là ‘đối tượng hiện tại’ hoặc ‘thể hiện hiện tại của một lớp’. Từ khóa this luôn đi trước ký hiệu đô la ($) và theo sau là toán tử -> (ví dụ: $this -> name).

Lưu ý: Vì các phương thức static có thể được gọi mà không có phiên bản của một lớp (tức là đối tượng), biến giả $this không có sẵn bên trong phương thức được khai báo là static.

Lời kết

Chúng tôi hy vọng bạn đã hiểu các khái niệm cơ bản về lập trình hướng đối tượng. Bạn sẽ tìm thấy nhiều ví dụ về OOP trong phần cơ sở dữ liệu PHP và MySQL.