Khilàm việc với PDO bạn sẽ không cần phải viết các câu lệnh SQL cụ thể mà chỉ sửdụng các phương thức mà PDO cung cấp, giúp tiết kiệm thời gian và làm cho việcchuyển đổi Hệ quản trị cơ sở
Trang 1Bài 1: Lập trình website theo mô hình MVC
1 Giới thiệu mô hình MVC
MVC là từ viết tắt bởi 3 từ Model – View – Controller Đây là mô hình thiết kế
sử dụng trong kỹ thuật phần mềm Mô hình source code thành 3 phần, tương ứngmỗi từ Mỗi từ tương ứng với một hoạt động tách biệt trong một mô hình
Để hiểu rõ hơn, sau đây chúng ta sẽ cùng đi phân tích từng thành phần:
Mô hình MVC và các thành phần bên trong của MVC
Model (M):
Là bộ phận có chức năng lưu trữ toàn bộ dữ liệu của ứng dụng Bộ phận này
là một cầu nối giữa 2 thành phần bên dưới là View và Controller Model thể hiệndưới hình thức là một cơ sở dữ liệu hoặc có khi chỉ đơn giản là một file XML bìnhthường Model thể hiện rõ các thao tác với cơ sở dữ liệu như cho phép xem, truyxuất, xử lý dữ liệu,…
Trang 2View (V):
Đây là phần giao diện (theme) dành cho người sử dụng Nơi mà người dùng
có thể lấy được thông tin dữ liệu của MVC thông qua các thao tác truy vấn như tìmkiếm hoặc sử dụng thông qua các website
Thông thường, các ứng dụng web sử dụng MVC View như một phần của hệthống, nơi các thành phần HTML được tạo ra Bên cạnh đó, View cũng có chứcnăng ghi nhận hoạt động của người dùng để tương tác với Controller Tuy nhiên,View không có mối quan hệ trực tiếp với Controller, cũng không được lấy dữ liệu
từ Controller mà chỉ hiển thị yêu cầu chuyển cho Controller mà thôi
Ví dụ: Nút “delete” được tạo bởi View khi người dùng nhấn vào nút đó sẽ cómột hành động trong Controller
Controller (C):
Bộ phận có nhiệm vụ xử lý các yêu cầu người dùng đưa đến thông qua view
Từ đó, C đưa ra dữ liệu phù hợp với người dùng Bên cạnh đó, Controller còn cóchức năng kết nối với model
Trang 3Luồng tương tác giữa các thành phần trong MVC.
Ví dụ: Chức năng thêm bài viết mới trong trang quản trị website Nơi đây có 2trường nhập về tiêu đề và nội dung bài viết, thì trong đó:
• View sẽ hiển thị ra phần nhập form tiêu đề và nội dung
• Controller lấy dữ liệu từ 2 trường và gửi tới Model
• Model lúc này sẽ nhận dữ liệu từ Controller để lưu trữ trong cơ sở dữ liệu
Mỗi bộ phận thực hiện chức năng nhất định, nhưng chúng có sự thống nhất, liênkết với nhau tạo nên mô hình MVC Mô hình này tương đối nhẹ Nó có thể tíchhợp được nhiều tính năng có trong ASP.NET hiện giờ Ví dụ như authentication(quá trình xác thực)
Luồng đi trong mô hình MVC như thế nào?
Chúng ta có thể hình dung, khi một yêu cầu từ máy client gửi tới server,Controller sẽ thực hiện nhiệm vụ của mình đó là tiếp nhận và xử lý yêu cầu Trongtrường hợp cần thiết, nó có thể liên hệ Model – bộ phận làm việc với database để
hỗ trợ
Trang 4Khi xử lý xong yêu cầu, kết quả sẽ được trả về View Tại View sẽ tạo mãHTML thành giao diện và trả về hiển thị trên trình duyệt.
Ưu điểm của mô hình MVC
Nhẹ, tiết kiệm băng thông: MVC không sử dụng viewstate nên khá tiết kiệmdiện tích băng thông Khi sử dụng, người dùng có thể sử dụng ứng dụng trên webcần tương tác gửi và nhận dữ liệu một cách liên tục Do đó, việc giảm băng thônggiúp cho website hoạt động tốt và ổn định hơn
• Kiểm tra dễ dàng: Với MVC, bạn có thể dễ dàng kiểm tra, rà soát lỗi phầnmềm trước khi tới tay người tiêu dùng, đảm bảo chất lượng và độ uy tín caohơn
• Chức năng control: Trên các nền website thì ngôn ngữ lập trình như CSS,HTML, Javascript có một vai trò vô cùng quan trọng Việc sử dụng mô hìnhMVC sẽ giúp bạn có một bộ control ưu việt trên nền tảng các ngôn ngữ hiệnđại với nhiều hình thức khác nhau
• View và size: View sẽ là nơi lưu trữ các dữ liệu Càng nhiều yêu cầu đượcthực hiện thì kích thước càng tệp càng lớn Khi đó, đường truyền mạng
Trang 5cũng giảm tốc độ load Việc sử dụng mô hình MVC sẽ giúp bạn tiết kiệmđược diện tích băng thông một cách tối ưu.
• Chức năng Soc (Separation of Concern): Chức năng này cho phép bạn phântách rõ ràng các phần như Model, giao diện, data, nghiệp vụ
• Tính kết hợp: Việc tích hợp ở mô hình MVC cho phép bạn thoải mái viếtcode trên nền tảng website Khi đó, server của bạn sẽ được giảm tải khánhiều
• Đơn giản: Đây là một mô hình với kết cấu tương đối đơn giản Dù bạnkhông có quá nhiều chuyên môn cũng có thể sử dụng được
Nhược điểm của mô hình MVC
MVC thường được sử dụng vào những dự án lớn Do đó, với các dự án nhỏ,
mô hình MVC có thể gây cồng kềnh, tốn thời gian trong quá trình phát triển cũngnhư thời gian trung chuyển dữ liệu
2 Ứng dụng mô hình MVC vào lập trình
Mô hình MVC được ứng dụng trong nhiều ngôn ngữ lập trình khác nhau,nhưng phổ biến nhất là ứng dụng ASP.NET MVC hay PHP MVC
Trang 6MVC đang là mô hình được ứng dụng rất nhiều trong lập trình.
Hệ thống MVC phát triển tốt sẽ cho phép phát triển front – end, back – endcùng trên hệ thống mà không có sự can thiệp, chia sẻ, chỉnh sửa các tập tin trongkhi một hoặc hai bên vẫn đang làm việc
Việc sử dụng mô hình tương đối đơn giản Chỉ cần hiểu rõ quy trình vận hành,nắm được các chức năng của từng bộ phận thì việc triển khai mô hình MVC tươngđối dễ dàng
Xây dựng chức năng đăng nhập bằng MVC
Phần này hướng dẫn tạo chức năng đăng nhập theo mô hình MVC
Bước 1: Tạo một thư mục mới Trong thư mục mới này, tạo 3 thư mục mới khác
với tên controller, model, view tương ứng và cũng tạo một trang PHP với tênindex.php
Trang 7if($reslt == ‘login’) {
include ‘view/Afterlogin.php’;
} else {
include ‘view/login.php’;
} }
Trang 8return ‘invalid user’;
} }
} }
?>
Bước 4: Trong thư mục view, tạo hai trang PHP với tên lần lượt là login.php,
Afterlogin.php và viết đoạn mã sau:
Trang 9<input id=”password” name=”password”
Bài 2: Các kỹ thuật lập trình MySQL với PHP nâng cao
1 Kết nối và truy vấn cơ sở dữ liệu sử dụng PDO
Giới thiệu PDO - PHP Data Objects
Trang 10PHP Data Objects (PDO) là một lớp truy xuất cơ sở dữ liệu cung cấp mộtphương pháp thống nhất để làm việc với nhiều loại cơ sở dữ liệu khác nhau Khilàm việc với PDO bạn sẽ không cần phải viết các câu lệnh SQL cụ thể mà chỉ sửdụng các phương thức mà PDO cung cấp, giúp tiết kiệm thời gian và làm cho việcchuyển đổi Hệ quản trị cơ sở dữ liệu trở nên dễ dàng hơn, chỉ đơn giản là thay đổiConnection String (chuỗi kết nối CSDL).
Chúng ta chỉ cần nắm rõ API mà PDO cung cấp là có thể làm việc được vớinhiều Hệ quản trị cơ sở dữ liệu khác nhau như MySQL, SQLite, PostgreSQL,Microsoft SQL Server, và có thể dễ dàng chuyển đổi chúng
Các Hệ quản trị cơ sở dữ liệu (Database Management System) mà PDO hỗtrợ gồm có:
PDO_OCI Oracle Call Interface
PDO_ODBC ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
PDO_SQLITE SQLite 3 and SQLite 2
PDO_SQLSRV Microsoft SQL Server / SQL Azure
Trang 11Kết nối cơ sở dữ liệu
Mỗi DBMS sẽ có các phương thức kết nối khác nhau (có loại cần Username,Password, đường dẫn đới Database, Port, có loại không) Connection String của cácDBMS phổ biến hầu hết đều có dạng như sau:
$conn = new PDO('mysql:host=localhost;dbname=izlearn', $username,
$password);
Với mysql là tên của DBMS, localhost có ý nghĩa database được đặt trêncùng server, izlearn là tên của database $username và $password là 2 biến chứathông tin xác thực
Đối với SQLite, DBMS này không có cơ chế xác thực bằng Username vàPassword mà chỉ đơn giản là đường dẫn tới file dữ liệu:
$conn =newPDO("sqlite:your/database/path/izlearn.db");
Đế ngắt kết nối khi không cần thao tác với database nữa, chúng ta chỉ cần sétbiến $conn về null;
$conn = null;
Insert và Update
Thêm mới (insert) và cập nhật (update) dữ liệu là những hoạt động cơ bản khithao tác với database Với PDO, mỗi hoạt động insert hay update được thực hiệnqua 3 quá trình sử dụng cơ chế Prepared Statement
• Prepare statement: Chuẩn bị một câu lệnh SQL làm khung/mẫu được gọi làPrepared Statement với các Placeholder (có thể hiểu placeholder đóng vaitrò như tham số của các phương thức khi bạn khai báo hàm)
Trang 12• Bind params: Gắn giá trị thực vào các placeholder (tương tự như khi bạntruyền giá trị vào các tham số của phương thức)
• Execute: Thực thi câu lệnh
Prepared Statement
Có 2 loại Placeholder trong Prepared Statement là Placeholder không địnhdanh (Unnamed Placeholder) và Placeholder định danh (Named Placeholder) như ví
dụ sau:
$stmt = $conn->prepare('INSERT INTO users (name, email, age) values (?, ?, ?)');
$stmt = $conn->prepare('INSERT INTO users (name, email, age) values(:name, :mail, :age)');
Dòng lệnh thứ nhất sử dụng Placeholder không định danh là các dấu hỏi - ?.Dòng lệnh thứ 2 sử dụng Placeholder định danh: :name, :mail, :age (lưu ý dấu haichấm và placeholder không nhất thiết phải giống tên column) Sau đây là toàn bộquá trình Insert và Update sử dụng 2 loại Placeholder nêu trên
Trang 13//Gán những giá trị khác và tiếp tục thực thi
$name = "Nguyen Van A";
$mail = "nva@live.com";
$age = 23;
$stmt->execute();
Như chúng ta thấy ta chỉ cần khởi tạo Prepared Statement một lần và có thể
sử dụng lại nhiều lần Với mỗi column - placeholder ta phải thực hiện gán tham sốmột lần, điều này sẽ không sao với những table có ít column như ví dụ trên, nhưng
sẽ rất bất tiện nếu bảng có nhiều table, rất may mắn ta có cách khác để làm việc này,
đó là lưu toàn bộ giá trị vào trong một mảng và truyền mảng này vào phương thứcexecute(), cụ thể như sau:
$stmt = $conn -> prepare ( 'INSERT INTO users (name, email, age)
$data = array ( 'Vu Hoang Lam' , 'lamvh@live.com' , 22 );
//Phương thức execute() dưới đây sẽ gán lần lượt giá trị trong mảng vào các Placeholder theo thứ tự
$stmt -> execute ($data);
Named Placeholder
Đối với Named Placeholder, cách thực hiện cũng khá tương đồng vớiUnnamed Placeholder, chỉ khác là chúng ta không dùng thứ tự placeholder để gángiá trị (bind) mà dùng chính tên của placeholder:
//Khởi tạo Prepared Statement từ biến $conn ở phần trước
Trang 14$stmt = $conn->prepare('INSERT INTO users (name, email, age) values(:name, :mail, :age)');
//Gán các biến (lúc này chưa mang giá trị) vào các placeholder theo tên của chúng
$stmt->bindParam(':name', $name);
$stmt->bindParam(':mail', $mail);
$stmt->bindParam(':age', $age);
//Lưu ý: Không cần thiết phải sử dụng dấu hai chấm cho các key
$data =array('name'=>'Vu Hoang Lam', 'mail'=>'lamvh@live.com', 'age'=> 22);Một mẹo hữu ích khác khi sử dụng Named Placeholder đó là insert Object
Trang 15$person -> name = 'Vu Hoang Lam' ;
$person -> mail = 'lamvh@live.com' ;
$person -> age = 22 ;
$stmt = $conn -> prepare ( 'INSERT INTO users (name, email, age)
$stmt -> execute (( array )$person);
Ở dòng cuối cùng, chúng ta đã thực hiện "ép kiểu" (cast) Object $personthành array để truyền vào phương thức execute();
Việc sử dụng Prepared Statement sẽ giúp chúng ta tránh được SQL Injection
Select Data - "Đọc" dữ liệu từ database
Khi đọc dữ liệu từ database, PDO sẽ trả về dữ liệu theo cấu trúc mảng (array)hoặc đối tượng (object) thông qua phương thức fetch() Bạn nên thiết lập trước cấutrúc dữ liệu trước khi gọi phương thức này, PDO hỗ trợ các tuỳ chọn sau:
• PDO::FETCH_ASSOC: Trả về dữ liệu dạng mảng với key là tên của column(column của các table trong database)
• PDO::FETCH_BOTH (default): Trả về dữ liệu dạng mảng với key là tên củacolumn và cả số thứ tự của column
• PDO::FETCH_BOUND: Gán giá trị của từng column cho từng biến đã khởitạo trước đó qua phương thức bindColumn()
• PDO::FETCH_CLASS: Gán giá trị của từng column cho từng thuộc tính(property/attribute) của một lớp Class theo tên column và tên thuộc tính
• PDO::FETCH_INTO: Gán giá trị của từng column cho từng thuộc tính củamột Class Instance (thể hiện của một lớp)
PDO::FETCH_BOTH/PDO::FETCH_OBJ
Trang 16• PDO::FETCH_NUM: Trả về dữ liệu dạng mảng với key là số thứ tự củacolumn
• PDO::FETCH_OBJ: Trả về một Object của stdClass (link is external) vớitên thuộc tính của Object là tên của column
Trong thực tế, chúng ta chỉ thường dùng 3 kiểu fetch đó là: FETCH_ASSOC,FETCH_CLASS và FETCH_OBJ Để thiết lập cấu trúc dữ liệu (Fetch Style hayFetch Mode) trước khi fetch ta dùng câu lệnh sau:
//Tạo Prepared Statement
$stmt = $conn -> prepare ( 'SELECT email, age from users WHERE name = :name' );
//Thiết lập kiểu dữ liệu trả về
$stmt -> setFetchMode (PDO::FETCH_ASSOC);
//Gán giá trị và thực thi
$stmt -> execute ( array ( 'name' => 'a' ));
//Hiển thị kết quả, vòng lặp sau đây sẽ dừng lại khi đã duyệt qua toàn bộ kết quả
while ($row = $stmt -> fetch ()) {
echo $row[ 'name' ] , '\n' ;
echo $row[ 'email' ] , '\n' ;
Trang 17echo $row[ 'age' ] , '\n' ;
}
FETCH_OBJ
Kiểu fetch này trả về một Object của stdClass cho mỗi row của kết quả
//Tạo Prepared Statement
$stmt = $conn -> prepare ( 'SELECT email, age from users WHERE name = :name' );
//Thiết lập kiểu dữ liệu trả về
$stmt -> setFetchMode (PDO::FETCH_OBJ);
//Gán giá trị và thực thi
$stmt -> execute ( array ( 'name' => 'a' ));
//Hiển thị kết quả, vòng lặp sau đây sẽ dừng lại khi đã duyệt qua toàn bộ kết quả trả về
while ($row = $stmt -> fetch ()) {
echo $row -> name , '\n' ;
echo $row -> email , '\n' ;
echo $row -> age , '\n' ;
}
FETCH_CLASS
Kiểu fetch này cho phép chúng ta đưa kết quả vào Object của một Class màchúng ta chỉ định Khi sử dụng FETCH_CLASS, thuộc tính của class sẽ được gángiá trị trước khi constructor của class đó được gọi (phải chú ý vì điều này rất quantrọng) Nếu không có thuộc tính khớp với tên của một column bất kỳ thì thuộc tính
đó sẽ được tự động tạo ra (public)
Giả sử table users có một ta đã có Class User được định nghĩa như sau:
class User {
public $name;
public $email;
Trang 18public $isAdmin = 'No' ;
function construct () {
if ($this -> name == 'Vu Hoang Lam' )
$this -> isAdmin = 'Yes' ;
}
}
Khi query data từ database sử dụng đoạn code sau:
//Tạo Prepared Statement
$stmt = $conn -> prepare ( 'SELECT email, age from users WHERE name = :name' );
//Thiết lập kiểu dữ liệu trả về, chỉ định dữ liệu được đưa vào object của class User
$stmt -> setFetchMode (PDO::FETCH_CLASS, 'User' );
//Gán giá trị và thực thi
$stmt -> execute ( array ( 'name' => 'a' ));
//Hiển thị kết quả, vòng lặp sau đây sẽ dừng lại khi đã duyệt qua toàn bộ kết quả trả về
while ($obj = $stmt -> fetch ()) {
echo $obj -> email ;
echo $obj -> isAdmin ;
}
Vì constructor được gọi sau khi thuộc tính $name được gán bằng Vu HoangLam nên isAdmin sẽ mang giá trị Yes Nếu muốn constructor của class được gọitrước khi các thuộc tính được gán giá trị, chúng ta phải sử dụng thêmPDO::FETCH_PROPS_LATE Cách sử dụng như sau:
//Hãy thử sử dụng kiểu fetch trên và so sánh kết quả hiển thị
Trang 19$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,
'User');
Nếu cần truyền các tham số cho constructor của class thông qua phương thứcfetch(), chúng ta có thể đặt chúng trong một array theo thứ tự tương ứng cụ thể nhưsau:
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User', array('param1', 'param2',
'param3'));
Exceptions - Xử lý ngoại lệ
PDO dùng các Exceptions để xử lý các lỗi phát sinh khi làm việc vớidatabase, vì thế tất cả những gì chúng ta làm với PDO nên được đặt trong mộttry/catch block PDO cung cấp 3 chế độ xử lý lỗi (Error Mode) được thiết lập thôngqua phương thức setAttribute():
$conn -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$conn -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$conn -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
PDO::ERRMODE_SILENT
Đây là chế độ xử lý lỗi mặc định của PDO, khi gặp mỗt lỗi bất kỳ, PDO sẽ
im lặng (silent) và chương trình vẫn tiếp tục chạy Chúng ta có thể lấy mã lỗi vàthông tin về các lỗi đã xảy ra qua PDO::errorCode() và PDO::errorInfo()
PDO::ERRMODE_WARNING
Ở chế độ này khi gặp phải lỗi PDO sẽ ném ra một PHP Warning, chươngtrình sẽ tiếp tục chạy
PDO::ERRMODE_EXCEPTION
Trang 20Đây là mode mà chúng ta nên sử dụng nhất, khi đặt trong một try/catch block
sẽ giúp bạn kiểm soát các lỗi phát sinh một cách uyển chuyển và giấu các thông báolỗi có thể khiến Attacker khai thác hệ thống của bạn
$stmt -> prepare ( 'SELECT name FORM people' );
}
catch (PDOException $e) {
echo "ERROR! Co loi xay ra voi PDO" ;
file_put_contents ( 'PDOErrors.txt' , $e -> getMessage (),
Phương thức trên trả về Auto Incremented ID của rows được thêm gần nhất
$conn->exec('DELETE FROM users WHERE uid = 1');
Đối với các lệnh SQL không có dữ liệu trả về, và không cần thiết phải truyềntham số thì có thể sử dụng phương thức exec() Phương thức này sẽ trả về số lượng
Trang 21row bị tác động sau khi thực hiện câu lệnh Như ví dụ trên sẽ trả về số lượng row bịxoá.
$conn = $DBH->quote($foo);
Phương thức quote() sẽ giúp chúng ta thêm dấu nháy cho một string để string
đó an toàn khi sử dụng để truy vấn, nếu chúng ta không muốn sử dụng PreparedStatement
$stmt->rowCount();
Phương thức rowCount() trả về số lượng row bị tác động sau khi thực hiệncác thao tác DELETE, INSERT và UPDATE Dùng rowCount() cho thao tácSELECT có thể sẽ trả về kết quả không đúng với một số loại database
2 Kết nối và truy vấn cơ sở dữ liệu sử dụng MySQLi
Mở kết nối tới MySQL
Ví dụ (MySQLi Hướng đối tượng)
$conn = new mysqli($servername, $username, $password);
// Kiểm tra kết nối
Trang 22$conn = mysqli_connect($servername, $username, $password);
// Kiểm tra kết nối
Trang 23Dưới đây là một số quy tắc cú pháp cần tuân theo:
Truy vấn SQL phải được đặt trong cặp dấu nháy (“”) bằng PHP
Giá trị chuỗi bên trong truy vấn SQL đặt trong cặp dấu nháy (“”)
Giá trị số không đặt trong cặp dấu nháy (“”)
Từ NULL đặt trong cặp dấu nháy (“”)
Câu lệnh INSERT INTO được sử dụng để thêm các bản ghi mới vào bảng MySQL:
INSERT INTO table_name (column1, column2, column3, )
VALUES (value1, value2, value3, )
Sau đây là ví dụ thêm một bản ghi mới vào bảng "MyGuests":
Ví dụ (MySQLi Hướng đối tượng)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
Trang 24$sql = "INSERT INTO MyGuests (firstname, lastname, email)
Lấy ID của bản ghi được chèn sau
Nếu chúng ta thực hiện INSERT hoặc UPDATE trên bảng có trường
AUTO_INCREMENT, chúng ta có thể nhận được ID của bản ghi được chèn/cập nhật lần cuối ngay lập tức
Trong bảng "MyGuests", cột "id" là trường AUTO_INCREMENT:
Trang 25CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
Các ví dụ sau tương đương với các ví dụ từ trước (Insert dữ liệu), ngoại trừ việcchúng ta thêm một dòng mã duy nhất để truy xuất ID của bản ghi được chèn cuốicùng Chúng ta cũng lặp lại ID được chèn lần cuối:
Ví dụ (MySQLi Hướng đối tượng)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
if ($conn->query($sql) === TRUE) {
Trang 26$sql = "INSERT INTO MyGuests (firstname, lastname, email)
Trang 27mysqli_close($conn);
?>
Insert nhiều bản
Nhiều câu lệnh SQL phải được thực thi bằng hàm mysqli_multi_query()
Các ví dụ sau thêm ba bản ghi mới vào bảng "MyGuests":
Ví dụ (MySQLi Hướng đối tượng)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
Trang 28$sql = "INSERT INTO MyGuests (firstname, lastname, email)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
Trang 29Câu lệnh Prepared và tham số Bound
Câu lệnh Prepared là một tính năng được sử dụng để thực thi các câu lệnhSQL giống nhau (hoặc tương tự) lặp đi lặp lại với hiệu quả cao
Các câu lệnh Prepared về cơ bản hoạt động như sau:
1 Prepared: Một mẫu câu lệnh SQL được tạo và gửi đến cơ sở dữ liệu Các giátrị nhất định không được xác định, được gọi là tham số (có nhãn "?") Ví dụ:INSERT INTO MyGuests VALUES (?,?,?)
2 Cơ sở dữ liệu phân tích cú pháp, biên dịch và thực hiện tối ưu hóa truy vấntrên mẫu câu lệnh SQL và lưu trữ kết quả mà không cần thực thi nó
3 Execute: Sau đó, ứng dụng liên kết các giá trị với các tham số và cơ sở dữliệu thực thi câu lệnh Ứng dụng có thể thực thi câu lệnh bao nhiêu lần tùy ývới các giá trị khác nhau
So với việc thực thi trực tiếp các câu lệnh SQL, các câu lệnh Prepared có ba ưuđiểm chính:
Các câu lệnh Prepared giảm thời gian phân tích cú pháp vì việc chuẩn bị trêntruy vấn chỉ được thực hiện một lần (mặc dù câu lệnh được thực hiện nhiềulần)
Tham số ràng buộc (Bound) giảm thiểu băng thông đến máy chủ vì chúng tachỉ cần gửi các tham số mỗi lần, chứ không phải toàn bộ truy vấn
Các câu lệnh Prepared rất hữu ích để chống lại việc tấn công SQL, bởi vì cácgiá trị tham số, được truyền sau này bằng một giao thức khác, không cầnphải được thoát một cách chính xác Nếu mẫu câu lệnh ban đầu không cónguồn gốc từ đầu vào bên ngoài, thì không thể xảy ra chèn SQL
Câu lệnh Prepared
Sau đây là ví dụ sử dụng câu lệnh prepared và tham số bound trong MySQLi:
Ví dụ
Trang 30$conn = new mysqli($servername, $username, $password, $dbname);
// Kiểm tra kết nối
if ($conn->connect_error) {
die ( "Lỗi kết nối: " $conn->connect_error);
}
// prepare và bind
$stmt = $conn->prepare( "INSERT INTO MyGuests (firstname,
$stmt->bind_param( "sss" , $firstname, $lastname, $email);
// Thiết lập các tham số và thực thi
Trang 31$conn->close();
?>
Mô tả các dòng code từ ví dụ trên:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
Trong SQL của chúng ta, chúng ta chèn một dấu chấm hỏi (?) Mà chúng tamuốn thay thế bằng giá trị số nguyên, chuỗi, kép hoặc blob
Sau đó, hãy xem hàm bind_param ():
$stmt->bind_param("sss", $firstname, $lastname, $email);
Hàm này liên kết các tham số với truy vấn SQL và cho cơ sở dữ liệu biết cáctham số là gì Đối số "sss" liệt kê các loại dữ liệu của các tham số Ký tự s chomysql biết rằng tham số là một chuỗi
Đối số có thể là một trong bốn loại:
• i - integer
• d - double
• s - string
• b - BLOB
Chúng ta phải có một trong những thứ này cho mỗi tham số
Bằng cách cho mysql biết loại dữ liệu mong đợi, chúng ta giảm thiểu nguy
cơ bị tấn công SQL
Trang 32Select dữ liệu
Câu lệnh SELECT được sử dụng để lựa chọn dữ liệu từ một hoặc nhiều bảng:
SELECT column_name(s) FROM table_name
Hoặc chúng ta có thể sử dụng ký tự * để lựa chọn tất cả các cột của bảng:
SELECT * FROM table_name
Ví dụ sau đây chọn cột id, firstname và lastname từ bảng MyGuests và hiểnthị nó trên trang:
Ví dụ (MySQLi Hướng đối tượng)
while ($row = $result->fetch_assoc()) {
echo "id: " $row[ "id" ] " - Name: " $row[ "firstname" ] "
Trang 33Code lines to explain from the example above:
First, we set up an SQL query that selects the id, firstname and lastname columnsfrom the MyGuests table The next line of code runs the query and puts theresulting data into a variable called $result
Then, the function num_rows() checks if there are more than zero rows returned
If there are more than zero rows returned, the function fetch_assoc() puts all theresults into an associative array that we can loop through The while() loop loopsthrough the result set and outputs the data from the id, firstname and lastnamecolumns
The following example shows the same as the example above, in the MySQLiprocedural way:
Các dòng code của ví dụ trên được mô tả như sau:
Đầu tiên, chúng ta thiết lập một truy vấn SQL chọn các cột id, firstname vàlastname từ bảng MyGuests Dòng mã tiếp theo chạy truy vấn và đặt dữ liệu kếtquả vào một biến được gọi là $result
Sau đó, hàm num_rows () kiểm tra nếu có nhiều hơn 0 hàng được trả về.Nếu có nhiều hơn 0 hàng được trả về, hàm fetch_assoc() đặt tất cả kết quảvào một mảng kết hợp mà chúng ta có thể lặp qua Vòng lặp while() lặp qua tập kếtquả và xuất dữ liệu từ các cột id, firstname và lastname
Sau đây là ví dụ theo hướng thủ tục:
Trang 34while ($row = mysqli_fetch_assoc($result)) {
echo "id: " $row[ "id" ] " - Name: " $row[ "firstname" ] "
Trang 35while ($row = $result->fetch_assoc()) {
echo "<tr><td>" $row[ "id" ] "</td><td>" $row[ "firstname" ] " "
Mệnh đề WHERE được sử dụng để lọc các bản ghi
Mệnh đề WHERE chỉ được sử dụng để trích xuất những bản ghi đáp ứng một điều kiện cụ thể
SELECT tên_cột(s) FROM tên_bảng WHERE tên_cột toán tử giá trị
Trang 36Ví dụ sau lựa chọn cột id, firstname và lastname từ bảng MyGuests với điều kiệnlastname là "Doe” và hiển thị lên trang::
Ví dụ (MySQLi Hướng đối tượng)
while ($row = $result->fetch_assoc()) {
echo "id: " $row[ "id" ] " - Name: " $row[ "firstname" ] "