Bài 07: MySQL prepared câu lệnh select với PHP(Tiếp)

PHP & MySQL 17/03/2030 07:00 938
Trong bài viết ngắn này mình sẽ bổ sung thêm về câu lệnh prepared với truy vấn SELECT trong MySQLi. Như mình đã nói trước với việc sử dụng prepared sẽ giúp bạn tránh được nguy cơ bị tấn công SQL Injection.

Bài 07: MySQL prepared với PHP

Trong bài viết này mình sẽ giới thiệu tới các bạn tính năng prepared câu lệnh SQL trong PHP. Bằng việc sử dụng prepared sẽ làm tăng hiệu quả của câu lệnh SQL.

Trong bài viết trước mình đã trình bày về câu lệnh Prepared trong MySQL với PHP. Thì trong bài viết này mình muốn bổ sung thêm với các bạn về câu lệnh SELECT sử dụng lệnh prepared với PHP.

Có bạn hỏi mình rằng anh ơi tại sao em làm theo các ví dụ hướng dẫn trên mạng, hay thực tế làm theo y hệt như trên trang php.net nó lại báo lỗi. Thì mình cũng trả lời luôn các bạn rằng khi các bạn làm việc với Prepared thì bản thân nó sẽ phát sinh hàng nghàn lỗi khác nhau. Và theo mình nó chỉ dơi vào một trong hai trường hợp sau.

  • Là phiên bản MySQL của bạn nó không hỗ trợ mố số hàm get_result(), fetch_all().
  • Bạn đang viết sai cú pháp.

Hiện tại thì mình cũng đã quen với việc sử dụng thư viện ADODB. Thì trong ADODB cũng cung cấp cho chúng ta hàm để làm việc với Prepared. Nếu bạn cũng đang dùng ADODB thì bạn có thể thao khảo ở liên kết này Prepare($sql )

Như mình đã nói ở trên nếu các bạn khi sử dụng Prepared mà bị lỗi thì hãy bật error bug nên và tìm nguyên nhân. Theo mình biết thì khá nhiều do version của bạn không gọi được một số các hàm.

Ví dụ:

Trong bài viết này mình sẽ viết một đoạn code nhỏ nhỏ sử dụng prepared với câu lệnh SELECT. Mình sẽ sử dụng bảng employees trong CSDL mẫu.

Mình sẽ SELECT những trường employeeNumber, firstName, Names, email, jobTitle. Và điều kiện của mình là mình sẽ lấy những người nào có officeCode=1

SELECT *
FROM employees 
ORDER BY employeeNumber ASC

Try In Out

1. File dbconfig.php

File này sẽ chứa thông tin dùng để kết nối tới CSDL.

define("DB_HOST", "localhost");
/** The name of the database demo */
define("DB_NAME", "demo_db");
/** MySQL database username */
define("DB_USER", "root");
/** MySQL database password */
define("DB_PASS", "");

// Kết nối tới CSDL
$dbconn = new mysqli(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if($dbconn->connect_error){
	die("Cound\'t connect the database ".$dbconn->connect_error);
}

2. File index.php

<?php 
	ini_set('display_errors',0);
	error_reporting(E_ALL ^ ~E_STRICT);
	
	require_once(dirname(__FILE__).'/dbconfig.php');
	$officeCode = 1;
	$sql = "SELECT employeeNumber,Names,firstName,email,jobTitle FROM employees WHERE officeCode=? ORDER BY employeeNumber ASC";
	// Khởi tạo một prepared
	if($stmt = $dbconn->prepare($sql)){
		// Ràng buộc các tham số
		$stmt->bind_param('i',$officeCode);
		// Thực thị truy vấn
		$stmt->execute();
		// Chuyển kết quả sau lệnh thực thi
		$stmt->store_result();
		// Ràng buộc các biến kết quả
		$stmt->bind_result($employeeNumber,$Names, $firstName, $email, $jobTitle);
		// Kiểm tra dữ liệu
		if($stmt->num_rows > 0){ ?>
			<div class="alert alert-danger">
				<?php echo $sql; ?>
			</div>
			<table class="tbl-grid" cellpadding="0" cellspacing="0" width="100%">
				<thead>
					<th class="gridheader">employeeNumber</th>
					<th class="gridheader">Names</th>
					<th class="gridheader">FirstName</th>
					<th class="gridheader">Email</th>
					<th class="gridheader">JobTitle</th>
				</thead>
				<?php 
				// Lấy giá trị
				while($stmt->fetch()){ ?>
				<tr>
					<td align="center"><?php echo $employeeNumber ?></td>
					<td><?php echo $Names ?></td>
					<td><?php echo $firstName ?></td>
					<td><?php echo $email ?></td>
					<td><?php echo $jobTitle ?></td>
				</tr>	
				<?php } ?>
			</table>
		<?php }
		// Ngắt prepared
		$stmt->close();
	}
	// Ngắt kết nối
	$dbconn->close();
?>

Tuy bạn có khá nhiều lựa chọn hàm sau khi thực thi câu lệnh execute() như ví dụ dưới đây.

// Ràng buộc các tham số
$stmt->bind_param('i',$officeCode);
// Thực thị truy vấn
$stmt->execute();
// Lấy về kết quả
$result = $stmt->get_result();

Tuy nhiên từ đây nó cũng suất phát một số lỗi mà lỗi phổ biến nhất là lỗi. Call to undefined method mysqli_stmt::get_result(). Có nghĩa là nó không xác định được hàm get_result() đó.

Mình thường sử dụng như thế này.

// Ràng buộc các tham số
$stmt->bind_param('i',$officeCode);
// Thực thị truy vấn
$stmt->execute();
// Chuyển kết quả sau lệnh thực thi
$stmt->store_result();
// Ràng buộc các biến kết quả
$stmt->bind_result($employeeNumber,$Names, $firstName, $email, $jobTitle);

Điểm yếu của việc bind_result($variable,[$variable1..]) là bạn phải chi rõ danh sách các field mà bạn cần lấy trong câu truy vấn của bạn.

SELECT employeeNumber,Names,firstName,email,jobTitle FROM employees 
WHERE officeCode=? ORDER BY employeeNumber ASC

Kết quả là từ đó tới giờ mình vẫn quen sử dụng thế này vì dù sao nó cũng đáp ứng được yêu cầu công việc. Vả các bạn có thể optimize để cho câu lệnh của bạn tốt hơn.

Tổng kết.

Trên đây mình đã bổ sung thêm cách sử dụng prepared câu lệnh SELECT với MySQLi và PHP. Tuy có khá nhiều cách viết khác nhau mỗi người chọn một cách. Nhưng chúng ta đều hướng tới giải quết được vấn đề. Hy vọng bài viết nhỏ nhỏ này sẽ hữu ích với các bạn.

Xem Thêm

Profile photo of adminTheHalfHeart

B.V.T

Sinh ra và lớn nên ở Bắc Giang. Hiện tại thì tôi đang là một lập trình viên tại VietISO. Tôi lập website này với mục đích là bookmark những gì tôi đã đọc qua và mong muốn chia sẻ những gì tôi biết.