XEM MỤC LỤC CÁC BÀI VIẾT PHP
Các câu truy vấn soạn sẵn rất hữu dụng dùng chống lại nguy
cơ SQL injections.
Câu truy vấn soạn sẵn và tham số ràng buộc
Câu truy vấn soạn sẵn
là tính năng dùng để thực thi các câu truy vấn SQL giống nhau (hoặc tương tự) lặp
đi lặp lại với hiệu suất cao.
Câu truy vấn soạn sẵn
về cơ bản hoạt động như sau:
- Chuẩn bị: 01 khuôn mẫu truy vấn SQL được tạo và gửi đến cơ sở dữ liệu. Các giá trị bất kỳ không xác định rõ được gọi là tham số (với ký tự đại diện là dấu "?"). Ví dụ: INSERT INTO MyGuests VALUES(?, ?, ?)
- Cơ sở dữ liệu phân tích , biên dịch, và thực hiện tối ưu hoá truy vấn dựa trên câu truy vấn SQL mẫu, và lưu kết quả nhưng chưa thực thi nó.
- Thực thi: 01 khoảng thời gian sau đó, ứng dụng gắn các giá trị vào các tham số, và cơ sở dữ liệu thực thi các câu lệnh. Lúc này ứng dụng có thể thực thi câu lệnh bao nhiêu lần mà nó muốn với các giá trị khác nhau.
So với việc thực thi
các câu lệnh truy vấn SQL trực tiếp, các câu lệnh soạn sẵn có 03 ưu điểm chính
sau:
- Câu lệnh soạn sẵn rút ngắn thời gian phân tích khi chuẩn bị để câu truy vấn được thực hiện chỉ 01 lần (mặc dù câu lệnh được thực thi nhiều lần)
- Việc truyền tham số giúp tối thiểu hóa băng thông đến máy chủ khi bạn chỉ cần gửi tham số mỗi lần kết nối thay vì nguyên cả câu truy vấn.
- Câu truy vấn soạn sẵn rất hữu dụng để chống SQL injections, do các giá trị tham số được truyền đi sau sẽ sử dụng 01 giao thức khác , không cần truyền đầy đủ gói. Nếu câu lệnh truy vấn khuôn mẫu gốc không bị lộ ra khi truyền đi, SQL injection không thể có.
Câu truy vấn soạn sẵn trong MySQLi
Ví dụ sau sử dụng các
câu truy vấn soạn sẵn và các tham số truyền vào với MySQLi:
Ví dụ (MySQLi truy vấn soạn sẵn)
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";
// Tạo kết nối
$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die("Kết nối thất bại: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// thiết lập tham số và thực thi
$firstname = "Nguyễn";
$lastname = "Du";
$email = "nguyendu@example.com";
$stmt->execute();
$firstname = "Nguyễn";
$lastname = "Khuyến";
$email = "nguyenkhuyen@example.com";
$stmt->execute();
$firstname = "Trần Hưng";
$lastname = "Đạo";
$email = "tranhungdao@example.com";
$stmt->execute();
echo "Thêm mới các bản ghi thành công!";
$stmt->close();
$conn->close();
?>
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";
// Tạo kết nối
$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die("Kết nối thất bại: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);
// thiết lập tham số và thực thi
$firstname = "Nguyễn";
$lastname = "Du";
$email = "nguyendu@example.com";
$stmt->execute();
$firstname = "Nguyễn";
$lastname = "Khuyến";
$email = "nguyenkhuyen@example.com";
$stmt->execute();
$firstname = "Trần Hưng";
$lastname = "Đạo";
$email = "tranhungdao@example.com";
$stmt->execute();
echo "Thêm mới các bản ghi thành công!";
$stmt->close();
$conn->close();
?>
Giải thích các dòng
mã ví dụ trên như sau:
"INSERT
INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
Trong các câu truy
vấn SQL, ta chèn dấu hỏi (?) nơi chúng ta muốn để giá trị là 01 số nguyên, chuỗi,
số thực double hoặc blob.
Sau đó, ta nhìn vào
hàm bind_param()
$stmt->bind_param("sss",
$firstname, $lastname, $email);
Hàm này truyền tham
số vào câu truy vấn SQL và nói với cơ sở dữ liệu đây là các tham số. Cú pháp
"sss" liệt kê các loại dữ
liệu của tham số . Chữ s báo cho
mysql rằng tham số này là 01 chuỗi.
Tham số có thể là 01
trong 04 dạng sau:
- i - integer
- d - double
- s - string
- b – BLOB ()
BLOB: dùng
cho dữ liệu lớn ở dạng nhị phân (binary large object) không có cấu trúc
như tập tin ảnh, text, phim.
Dữ liệu của chúng ta
bắt buộc phải là 01 trong các dạng trên.
Việc báo cho mysql kiểu
dữ liệu mà bạn mong muốn giúp giảm thiểu nguy cơ SQL injections.
Ghi chú: nếu chúng ta muốn chèn bất kỳ
dữ liệu nào từ bên ngoài (Ví dụ: từ người dùng nhập vào) , nhất thiết phải “làm
sạch” và kiểm tra nó trước.
Câu truy vấn soạn sẵn trong PDO
Ví dụ sau sử dụng câu truy vấn soạn sẵn và các tham số truyền vào
với PDO:
Ví dụ (PDO truy vấn soạn sẵn)
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// thiết lập PDO chế độ xử lý lỗi bằng ngoại lệ
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// thiết lập câu truy vấn sql và truyền tham số
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
// chèn 01 dòng
$firstname = "Nguyễn";
$lastname = "Du";
$email = "nguyendu@example.com";
$stmt->execute();
// chèn thêm dòng khác
$firstname = "Nguyễn";
$lastname = "Khuyến";
$email = "nguyenkhuyen@example.com";
$stmt->execute();
// chèn thêm dòng khác
$firstname = "Trần Hưng";
$lastname = "Đạo";
$email = "tranhungdao@example.com";
$stmt->execute();
echo "Thêm mới các bản ghi thành công!";
}
catch(PDOException $e)
{
echo "Lỗi: " . $e->getMessage();
}
$conn = null;
?>
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// thiết lập PDO chế độ xử lý lỗi bằng ngoại lệ
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// thiết lập câu truy vấn sql và truyền tham số
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname', $lastname);
$stmt->bindParam(':email', $email);
// chèn 01 dòng
$firstname = "Nguyễn";
$lastname = "Du";
$email = "nguyendu@example.com";
$stmt->execute();
// chèn thêm dòng khác
$firstname = "Nguyễn";
$lastname = "Khuyến";
$email = "nguyenkhuyen@example.com";
$stmt->execute();
// chèn thêm dòng khác
$firstname = "Trần Hưng";
$lastname = "Đạo";
$email = "tranhungdao@example.com";
$stmt->execute();
echo "Thêm mới các bản ghi thành công!";
}
catch(PDOException $e)
{
echo "Lỗi: " . $e->getMessage();
}
$conn = null;
?>
Ghi
chú: các bạn nên
chèn thêm đoạn mã xử lý unicode như trong các bài trước để hiển thị Tiếng Việt
chính xác.
Nếu vẫn
chưa rõ các bạn xem them video clip sau:
XEM MỤC LỤC CÁC BÀI VIẾT PHP
By #tiensim
Nguồn:
sưu tầm
Không có nhận xét nào:
Đăng nhận xét