Th.S: NGUYEN MINH - LUONG PHUC va nhom tin hoc thuc dung
Kỹ thuật và thủ thuật
lập trình hướng đối tượng
Khái niệm, kỹ thuật
® Trọn bộ 2 tập bạn sẽ có cơ hội cọ xát để nâng cao
kỹ năng lập trình thông qua việc thực hành sử dụng các tính năng cao cấp, chẳng hạn như các vấn tin cơ
rK -' .,wW sở dữ liệu, MySQL, SQLite và PDO của PHP
Với phương pháp hướng dẫn bằng ví dụ bạn sẽ không những dễ dàng nắm bắt các khái niệm căn bản, nâng cao hơn cũng như cách sử dụng các công cụ lập trình của PHP để viết các chương trình PHP ne THƯ VIỆN ĐH NHA TRANG ` i 3000 ii
chương còn có nhiều bài tập thực hành mà n làm theo để nắm vững nội dung được trình
o gồm sự cài đặt phần mềm, cú pháp ngôn
møu, các cấu trúc dữ liệu
Mà điển: đặc biệt của bộ sách chính là ở phương pháp hướng dẫn rất đơn giản và cực kỳ dễ tiếp thu
th
Trang 2Th.S: NGUYEN MINH - LƯƠNG PHÚC va nhém tin hoc thực dụng SO TAY TIN HOC LAP TRINH Kỹ thuật và thủ thuật
lập trình hướng đối tượng
Khái niệm, kỹ thuật và viết mã
Tập 3
New Edition
¢ Trọn bộ 8 tập bạn sẽ cô cơ hội cọ xát để nâng cao kỹ
năng lập trình thông qua việc thực hành sử dụng các
tỉnh năng cao cấp, chẳng hạn như các vấn tin cơ sở
đữ liệu, MySQL, SQLäite và PDO của PHP
® Với phương pháp hướng dẫn bằng ví dụ bạn sẽ không
những dễ dàng nắm bắt các khái niệm căn bản, nâng
cao hơn cũng như cách sử dụng các công cụ lập trình
của PHP để viết các chương trình PHP căn bản
* Mỗi chương còn có nhiều bài tập thực hành mà bạn
niên làm theo để nắm vững nội dung được trình bày, bao gồm sự cài đặt phần mềm, cú pháp ngôn ngữ, các
cấu trúc đữ liệu
* Mà điểm đặc biệt của bộ sách chỉnh là ở phương phát
hướng dẫn rất đơn giản và cực kỳ dễ tiếp thu
Trang 3
Lo NÓI ĐẦU
Bộ sách "Kỹ thuật và thủ thuật lập trình hướng đối
tượng PHP" được biên soạn nhằm mục đích đành cho
những người mới bắt đầu bước chân vào thế giới của ngôn
ngữ lập trình PHP Không giống như những sách khác, sách này không đòi hỏi bạn phải học qua trước các van dé căn bản về lập trình Web hay cơ sở dữ liệu Mà điểm đặc biệt của bộ sách chính là ở phương pháp hướng dẫn rất đơn giản và cực kỳ đễ tiếp thu
Thực vậy, với phương pháp hướng dẫn bằng ví dụ bạn
sẽ không những để dàng nắm bắt các khái niệm căn bản, mà thông qua đó sẽ dần trở nên quen thuộc với các khái niệm nâng cao hơn cũng như cách sử dụng các công cụ lập trình của PHP để viết các chương trình PHP căn bản Hơn nữa, với trọn bộ 9 tập bạn sẽ có cơ hội cọ xát để nâng
cao kỹ năng lập trình thông qua việc thực hành sử dụng các tỉnh năng cao cấp, chẳng hạn như các vấn tin cơ sở đữ
liệu, MySQL,„ SQLäte và PDO của PHP, các công nghệ
XML, cAc cookie, session va header, va các phần mở rộng của bên thứ ba
Sách có bố cục rõ ràng theo từng chương và đề mục,
các bước hướng dẫn cụ thể và dễ hiểu Mỗi chương còn có nhiều bài tập thực hành mà bạn nên làm theo để nắm
vững nội dung được trình bày, bao gồm sự cài đặt phần mềm, cú pháp ngôn ngữ, các cấu trúc đữ liệu, các thường
trình điều khiển, các hầm cài sẵn, và nhiều tác vụ hữu ích khác
Hy vọng sách sẽ là một tài liệu học tập hữu ích cho bạn
đọc trong quá trình trở thành một chuyên gia về PHP
Trang 4Chương 7: Làm việc với các cơ sở dữ liệu và SQL PHẦN 2 Làm việc với dữ liệu từ những nguồn khác Chuong 7: Lam viéc véi các cơ sở dit liéu va SQL
Chuong 8: Lam viéc véi XML
Trang 58 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
Lòm việc với các cơ sở dữ
liệu và SQL
Những kỹ trăng 0à kbái niệm cbính
@ Hoc nbiing khdi niém co sé dit liéu va Structured Query Language
Ỉ # Thêm, biên tập, xóa uà xem các record si? dụng các cơ sở dữ liệu
MYSQL vat SQLite ,
# Try tim cdc record co sé dit liéu véi PHP
M@ Hiéu luc héa va lieu dit iéu nbdap cia ngiwi ding sang mét co sé dit
liệu uới PHP
#§ Viết các chương trình điều khién bang cơ sở dữ liệu bbả chuyển (portable)
ột trong những lý do cho sự thông dụng của PHP như là một ngôn ngữ viết script Web là nó hỗ trợ một dãy rộng các hệ
thống đữ liệu quan hệ Sự hỗ trợ làm cho các nhà phát triển Web dễ dàng tạo các Web site điều khiển bằng dữ liệu và tạo nguyên mẫu
Trang 6Chương 7: Làm việc với các cơ sở dữ liệu và SQL 9
‘PHP hé trợ hơn 15 bộ máy cơ sở dữ liệu khác nhau bao gồm Microsoft
SQL Server, IBM DB2, PostgreSQL, và Oracle Cho đến PHP 5, sự hỗ trợ này đã được cung cấp qua các extension cơ sở đữ liệu riêng, mỗi extension có chức năng và tính năng riêng của nó Tuy nhiên, điều này đã làm cho các nhà phát triển khó thay đổi từ một bộ máy cơ sở đữ liệu này sang một bộ máy cơ sở đữ liệu khác PHP 5 đã giải quyết tình huống này bằng việc giới thiệu một API chung cho sự truy cập cơ sở đữ liệu: extension PHP Data Objects (PDO), cung cấp một giao diện hợp nhất để làm việc với cơ sở dữ liệu và giúp các nha phát triển xử lý những cơ sở đữ liệu khác nhau một cách nhất quán
Trong PHP 5.3, extension PDO đã được cải tiến thêm nữa với sự hỗ trợ cho các bộ máy cơ sở đữ liệu mới và những tối ưu hóa thêm nữa cho an ninh và biệu suất Dé dat duoc khả năng tương thích ngược, các extension cơ sở dữ liệu riêng cũng tiếp tục được hỗ trợ Bởi vì bạn sẽ thường tự nhận thấy mình đã chọn giữa một extension riêng của mình (mà có thể nhanh hơn hoặc đưa ra nhiều tính năng hơn) hoặc PDO (đưa ra tính khả chuyển và tính nhất quán qua các bộ máy cơ sở dữ liệu), chương này đề cập đến hai tùy chọn: chương giới thiệu về PDO và cũng thảo luận hai trong số các exten- sion riêng thông dụng nhất của PHP, extension MySQL Improved va ex- tension SQLite
Giới thiệu các cơ sở dữ liệu và SQL
Trong thời đại Internet, thông tin không còn được trình bày trong các tủ dung hé so nữa Thay vào đó, nó được lưu trữ dưới dạng các số 1 và số 0 trong các kiểu đữ liệu điện tử vốn là những "hộp chứa" lưu trữ dữ liệu áp đặt một cấu trúc nhất định về thông tin Những cơ sở đữ liệu điện tử này không chỉ chiếm ít không gian vật lý hơn không gian gỗ và kim loại tương ứng mà chúng còn chứa đẩy những công cu để giúp người dùng lọc và truy tìm nhanh thông tin sử dụng những tiêu chí khác nhau Cụ thể hầu hết các cơ sở đữ liệu điện tử ngày nay là những cơ sở dữ liệu quan hệ (relational database) cho phép người dùng định nghĩa mối quan hệ giữa các bảng cơ sở
đữ liệu khác nhau để tìm kiếm và phân tích hiệu quả hơn
Trang 7
10 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
chính phủ, thường cho những mục đích rất quan trọng Trước khi đi vào chỉ tiết cụ thể của việc xử lý các record cơ sở dữ liệu với PHP, trước tiên cần
phải hiểu rõ các khái niệm cơ sở dữ liệu cơ bản Nếu bạn mới làm quen với
cơ sở đữ liệu này, các phân sau đây cung cấp một nên tầng và cũng cho bạn thử nghiệm với một bài tập thực tiễn trong Structured Query Language (SQL) Thông tin này sẽ hữu dụng để hiểu nội dung nâng cao hơn trong các phần tiếp theo
Tìm hiểu các cơ sở dữ liệu, record, và khóa chính (Pri-
mary Key)
Mọi cơ sở dữ liệu gồm một hoặc nhiều bảng (table) Những bảng này tạo cấu trúc đữ liệu thành các hàng và cột, áp đặt sự tổ chức lên dữ liệu Hình
7.1 minh họa một bảng điển hình
Bảng này chứa các số liệu bán hàng cho các vị trí khác nhau với mỗi hàng hoặc record (bản ghỉ) chứa thông tin cho một vị trí và năm khác Mỗi reeord được phân chia trở thành các cột hoặc field (trường) với mỗi trường chứa một đoạn thông tin khác Cấu trúc dạng bảng này làm cho dễ tìm kiếm trên bảng để tìm ra các record khớp với tiêu chí (criteria) cụ thể: ví dụ, tất cả vị trí có đoanh số lớn hơn $10,000 hoặc doanh số cho tất cả vị trí trong năm 2008
Các record trong bảng không được sắp xếp theo bất kỳ thứ tự cụ thể -
chúng có thể được phân loại theo thứ tự bảng chữ cái, theo năm, theo tổng
doanh số, theo vị trí hoặc theo bất kỳ tiêu chí mà bạn chọn xác định Do đó để làm cho đễ nhận đạng một record cụ thể, cần phải thêm một thuộc tính nhận dang duy nhất vào mỗi record chẳng hạn như một số serial hoặc mã trình tự Trong ví dụ trước, mỗi record được nhận dạng bằng một trường "record ID" duy nhất; trường này được gọi là primary key (khóa chính) cho bảng
Trang 8Chương 7: Làm việc với các cơ sở dữ liệu và SQL 11
: ®@eeœeeee
Thủ thuật
Một cách dễ dàng để hiểu những khái niệm này là i bang một sự tương đồng Hãy xem một cơ sở dữ liệu như là một thư viện và mỗi bảng là một kệ sách bên trong thư viện này Do đó một record là sự đại diện điện tử của một cuốn sách trên một kệ sách với tựa đề của cuốn sách là khóa chính của record Nếu thiếu tựa để này, không thể dễ dang phan biệt một cuốn sách này với một cuốn sách
khác (Cách duy nhất để làm điều này là mở mỗi cuốn sách và kiểm tra nội
dung của nó - một tiến trình mất thời gian mà khóa chính sẽ giúp bạn tránh được)
Một khi bạn đã đưa thông tin vào một bảng, bạn thường muốn sử dụng nó để trả lời các câu hồi cụ thể - ví dụ, bao nhiêu vị trí có doanh số lớn hơn $5000 trong 2008? Những câu hồi này được gọi là các query (mẫu truy vấn) và kết quả được trả về bởi cơ sở đữ liệu nhằm phản hồi lại những query này được gọi là các tập hợp kết quả (result set) Các query được thực thi sử dụng Structured Query Language
Tìm hiểu các mối quan hệ và khóa ngoại (Foreign Key) Bạn đã biết rằng một cơ sở đữ liệu có thể chứa nhiều bảng Trong một hệ
thống cơ sở đữ liệu quan hệ, những bảng này có thể được liên kết với nhau bằng một hoặc nhiều trường chung được gọi là các khóa ngoại (foreign key) Những khóa ngoại này làm cho có thể tạo các mối quan hệ một đối một (one-to-one) hoặc một đối nhiều (one-to-many) giữa các bảng khác nhau và kết hợp dữ liệu từ nhiều bảng để tạo các tập hợp kết quả toàn diện hơn
Để minh họa, hãy xem xét hình 7.2 trình bày ba bảng được liên kết
GenreID | GenreName AuthorD | AuthorName
1| Horror 1| Stephen King
Trang 9\
12 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
Hình 7.2 minh họa ba bảng, chứa thông tin về các tác giả (bảng À), các thể loại (bảng G), và các sách (bảng B) Các bảng G và B khá đơn giản: chúng chứa một danh sách các tên thể loại (genre) và tác giả, với mỗi record được nhận dạng bằng một khóa chính duy nhất Bảng B hơi phức tạp hơn: mọi sách trong bảng được liên kết với một thể loại cụ thể bằng khóa chính của genre (từ bảng G) và với một tác giả cụ thể qua khóa chính của author (từ bảng A)
Bằng cách đò theo những khóa này đi đến các bảng nguồn tương ứng của chúng, bạn có thể dễ dàng nhận dạng tác giả và thể loại cho một cuốn sách cụ thể Ví dụ, có thể thấy rằng tựa để "The Shining" được viết bởi "Stephen King" và thuộc về thể loại "Horror" Tương tự, bắt đầu từ đâu kia có thể thấy rằng tác gid "Michael Connelly” da viét hai cuén séch "The Overlook” va "Trunk Music’
Những mối quan hệ như vậy được thấy trong hình 7.2 tạo nên nên tảng của một hệ thống cơ sở dữ liệu quan hệ Liên kết các bảng sử dụng các khóa ngoại cũng hiệu quả hơn lựa chọn khác: trong khi tạo một bảng mọi thứ
ngoại trừ bên rửa nhà bếp để chứa tất cả thông tin thoạt nhìn trông tiện
lợi, cập nhật một bảng như vậy luôn là một tiến trình thủ công (và dé sai sót) để tìm mọi trường hợp của một giá trị cụ thể và thay thế nó bằng một giá trị mới Phân chia thông tin thành các bảng độc lập và liên kết những bảng này bằng các khóa ngoại sẽ bảo đảm rằng một mẫu thông tin cụ thể xuất hiện một lần và chỉ một lần trong cơ sở đữ liệu; điều này loại bổ những phần dư thừa, đơn giản hóa các thay đổi (bằng việc cục bộ hóa chúng sang một vị trí) và làm cho cơ sở đữ liệu gọn hơn và đễ quản lý hơn
Tiến trình hợp lý hóa một cơ sở đữ liệu bằng việc định nghĩa và thực thì các mối quan hệ một đối một và một đối nhiều giữa các bảng thành phan của nó được gọi là sự chuẩn hóa cơ sở dữ liệu (đatabase normalization) va nó là một tác vụ chính mà một kỹ sư cơ sở dữ liệu phải đối mặt khi tạo một cơ sở đữ liệu mới Trong tiến trình chuẩn hóa, kỹ sư cơ sở đữ liệu cũng nhận dạng các mối quan hệ chéo và những sự phụ thuộc không chính xác giữa các
bảng và tối ưu hóa việc tổ chức dữ liệu sao cho các query SQL thực thi với
hiệu suất tối đa Cũng có một số dạng chuẩn giúp bạn test phạm vi một cơ sở đữ liệu được chuẩn hóa; những dạng chuẩn này cung cấp những hướng
dẫn hữu dụng để giúp bảo đảm việc thiết kế cơ sở dữ liệu vừa nhất quán về
Trang 10Chương 7: Làm việc với các cơ sở dữ liệu và SQIL 13
Tìm hiểu các câu lệnh SQL
Struetured Query Language hoặc SQL là ngôn ngữ chuẩn được sử dụng để giao tiếp với một cơ sở đữ liệu, thêm hoặc thay đổi các record và các đặc quyển người dùng và thực thi các query Ngôn ngữ này trở thành một chuẩn ANSI vào năm 1989 và hiện được sử dụng bởi hầu như tất cả RDBM thương mại ngày nay
Các câu lệnh SQL bao gồm một trong ba hạng mục:
# Data Definition Language (DDL) DDL gồm nbững câu lệnh định ngbĩa cấu trúc uà những mối quan bệ của một cơ sở di liệu uà các bằng của nó Những câu lệnh này thường được sử dụng để tạo, xóa tà chỉnh sửa các cơ sở dữ liệu uà bằng, xác định các tên 0à loại trường, 0à xác lập các index
# Data Maniupulation Language (DML) Cac cau lénb DML lién quan đến uiệc tbay đối uà trícb xuất dữ liệu từ một cơ sở dĩ liệu Những câu
lệnh này được sử dụng dé thém cdc record uào uà xóa các record ra
khéi mét co sé att liu; thuc thi cdc query, truy tim cdc record bang khép voi mOt bodc nbiéu tiêu cbí do người dùng xác định; uà nối các bằng lại uới nbat sử dụng các trường chung của chúng
# Data Control Language (DCL) Cac cau lénb DCL duoc sit dung dé định nghĩa các cấp truy cập uà các đặc quyền an ninb trong mét co sé dữ liệu Bạn thường sử dụng những câu lệnh này dé cbo phép boặc từ chối các đặc quyền người dùng, phân công các uai trò, thay đối các ÐaSsstuord, xem các quyén (permission), va tao cdc tap hop quy tắc (ruleset)
dé bdo uệ uiệc truy cập dữ liệu
Các lệnh SQL giống như tiếng Anh nói, nhằm làm cho ngôn ngữ dễ học
hơn Cú pháp cũng khá trực giác: Mọi câu lệnh SQL bắt đầu với một "từ
hành động" như DELETE, INSERT, ALTER, hoặc DESCRIBE và kết thúc
bằng một dấu chấm phẩy Khoảng trắng, các tab và các ký tự trở về đầu dong được bổ qua Sau đây là một vài ví dụ về những câu lệnh SQL hợp lệ:
CREATE DATABASE library ;
SELECT movie FROM movies WHERE rating > 4;
DELETE FROM cars WHERE year_of_manufacture < 1980;
Bảng 7.1 liệt kê cú pháp cho một số câu lệnh SQL phổ biến với các giải
Trang 1114 Chương 7: Làm việc với các cơ sở dữ liệu và SQL Bảng 7.1 Các câu lệnh §0L thơng thường Cau lénh SQL CREATE DATABASE database-name CREATE TABLE table-name (field1, field2, .)
INSERT INTO table-name
(field1, field2, ) VALUES (valuel, value2, ) UPDATE table-name SET field1=valuel, ñeld2=value2, (WHERE condition) DELETE FROM table-name (WHERE condition)
SELECT field1, field2
FROM table-name [WHERE condition] RENAME table-name TO new-table-name DROP TABLE table-name DROP DATABASE database-name Chức năng Tạo một cơ sở đữ liệu mới Tạo một bảng mới Chèn một record mới vào một bảng có các giá trị được xác định Cập nhật các record trong một bảng có các giá trị mới
Xóa các record ra khỏi một bảng
Truy tìm các record tương hợp từ một bảng Đổi tên một bảng Xóa một bảng Xóa một cơ sở dữ liệu
Hỏi chuyên gia
.Hỏi: SQL được hỗ trợ rộng như thế nào?
Đáp: SQL vừa là một chuẩn ANSI vừa là chuẩn ISO, và được hỗ trợ rộng rãi bởi các hệ thống cơ sở dữ liệu SQL tương thích các chuẩn Nói như vậy, nhiều nhà cung cấp cơ sở dữ liệu cũng đã mở rộng SQL "chuẩn" bằng các extension độc quyền để mang đến cho các khách hàng một tập hợp tính năng cải tiến hoặc hiệu suất tốt hơn Những extension này khác nhau giữa các nhà cung cấp và các câu lệnh SQL sử dụng những extension này có thể không làm việc theo cùng một cách trên tất cả hệ thống cơ sở dữ liệu Do đó, sẽ luôn khôn ngoan nếu tham khảo tài liệu của hệ thống cơ sở dữ liệu và tìm hiểu các extension độc quyền nào nếu có mà nó cung cấp và xem các extension này ảnh hưởng đến những câu lệnh SQL mà bạn viết như thế nào
Thực hành 7.1: Tạo và tập hợp lại một cơ sở dữ liệu
Trang 12Chương 7: Làm việc với các cơ sở dữ liệu và SQL 15 này bạn sẽ su dung client ddng lénh MySQL tuong tác để tạo một cơ sở đữ liệu và các bảng, thêm và biên tập các record và tạo các tập hợp kết quả khớp với những tiêu chí khác nhau
Gli che
Qua suốt bai tập sau đây, chữ in đậm biểu thị các lệnh mà bạn nên gõ nhập tại dòng nhắc dòng lệnh MySQL Các lệnh có thể được
nhập bằng hoặc chữ hoa hoặc chữ thường Trước khi bắt đầu với bài tập, bấy chắc chắn rằng bạn đã cài đặt, cấu hình và test hệ thống cơ sở dữ liệu MySQL theo những hướng dẫn trong những phụ lục của sách này
Bắt đầu bằng việc khởi động client dòng lệnh MySQL và kết nối với cơ sở đữ liệu MySQL bằng username va password:
shell> mysql -u user -panel Password: ******
Nếu mọi thứ đều diễn ra tốt đẹp, bạn sẽ thấy một thông báo chào đón và một đòng nhắc SQL tương tác như sau:
mysql >
Bây giờ bạn có thể tiến hành nhập các câu lệnh SQL tại dòng nhắc này
Những câu lệnh này sẽ được chuyển sang và được thực thi trên server MySQL và kết quả sẽ được hiển thị trên các dòng sau dòng nhắc Nhớ kết thúc mỗi câu lệnh bằng một dấu chấm phẩy
Tạo cơ sở dữ liệu
Vì tất cả bảng được lưu trữ trong một cơ sở đữ liệu, bước đầu tiên là tạo
một cơ sở đữ liệu, sử dụng câu lệnh CREATE DATABASE: mysql> CREATE DATABASE music;
Query OK, 1 row affected (0 05 sec)
Tiếp theo, chọn cơ sở đữ liệu mới tạo này làm cơ sở dữ liệu mặc định cho tất cả lệnh tương lai bằng câu lệnh USE:
mysql> USE music; Database changed Thém cac bang
Trang 13ñ
16 Chương 7: Làm việc với các cơ sở dữ liệu và SQL này đòi hỏi một tên bảng và một mô tả chỉ tiết về các trường của bạn Sau đây là một ví dụ:
mysql> CREATE TABLE artists (
-> artist_id INT(4) NOT NULL PRIMARY KEY AUTO_INCREMENT, -> artist_name VARCHAR (50) NOT NULL,
-> artist_country CHAR (2) NOT NULL >);
Query OK, 0 rows affected (0.07 sec)
Câu lệnh này tạo một bảng có tên là artists có ba trudng artist_id, artist_name, và artist_country Chú ý rằng theo sau mỗi tên trường là một phần khai báo kiểu (type declaration); phần khai báo này nhận dạng kiểu đữ liệu mà trường sẽ chứa cho dù là string (chuỗi), numeric (sé), temporal (thời gian), hoặc Boolean MySQL hỗ trợ một số kiểu dữ liệu khác nhau và
các kiểu dữ liệu quan trọng nhất được tóm tắt trong bảng 7.2
'Có thêm một vài ràng buộc (modifier) được xác lập cho bảng trong câu lệnh trước:
M@ Modifier NOT NULL bdo ddm rang trudng kbéng thé chap nban mot gid
trị NUIL sau mỗi định rigbĩa trường
„ Modifier PRIMARY KEY đánh dấu trường tương ting la khoa chinb (pri- mary key) ctla bang
M@ Modifier AUTO_INCREMENT, chi co séin cho cdc tritiing 86, yéu cau MySQL tự động tạo một giá trị cbo trường này mỗi lần một record mới được cbèn Uuào bảng, tăng giá trị truóc lên 1
Bảng 7.2 Các kiểu dữ liệu MyS0L
Kiểu trường Mô tả
Trang 14Chương 7: Làm việc với các cơ sở dữ liệu và SQL 17
YEAR Một trường cụ thể cho năm hiển thị trong
dãy 1901 đến 2155 theo định dạng YYYY hoặc YY TIMESTAMP Một kiểu tem thời gian theo định dạng YYYYMMDDHHMMSS CHAR Một kiểu chuỗi có kích cỡ tối đa 255 ký tự và một chiểu dài cố định
VARCHAR, Một kiểu chuỗi có kích cỡ tối đa 255 ký tự và một chiều dài khả biến
'TEXT Một kiểu chuỗi có kích cỡ tối đa 65535 ký tự
BLOB Một kiểu nhị phân cho đữ liệu biến
ENUM Một kiểu chuỗi có thể chấp nhận một giá trị
từ một danh sách các giá trị có thể có được định nghĩa trước đó
SET Một kiểu chuỗi có thể chấp nhận zero hoặc
nhiều giá trị từ một tập hợp giá trị có thể có được định nghĩa trước đó
Bây giờ hãy tiến hành tạo thêm hai bang sử đụng các câu lệnh SQL này: mysql> CREATE TABLE ratings (
-> fating_id INT(2) NOT NULL PRIMARY KEY, -> rating_name VARCHAR (50) NOT NULL >);
Query OK, 0 rows affected (0.13 sec) mysql> CREATE TABLE songs (
-> song_id INT(4) NOT NULL PRIMARY KEY AUTO_INCREMENT, -> song_title VARCHAR(100) NOT NULL,
-> fk_song_artist INT(4) NOT NULL, -> fk_song_rating INT(2) NOT NULL >);
Query OK, 0 rows affected (0.05 sec) Thém cac Record
Trang 15Ss
18 Chương 7: Làm việc với các cơ sở dữ liệu và SQL mysql> INSERT INTO artists (artist_id, artist_ name, artist_country)
-> VALUES (‘1’, ‘Aerosmith’, ‘US’); Query OK, 1 row affected (0.00 sec)
Từ phần trước bạn sẽ nhớ rằng trường artist_id đã được đánh dấu bằng cờ đlag) AUTO INCREMENT Đây là một phần mở rộng My§QL cho SQL chuẩn yêu câu My§QL tự động gán một giá trị vào trường này nếu nó không được xác định Để thấy trực tiếp điều này, hãy thử thêm một reeord mới sử dụng câu lệnh sau đây:
mysql> INSERT INTO artists (artist_name, artist_country) -> VALUES (‘Abba’, ‘SE’);
Query OK, 1 row affected (0.00 sec)
Tương tự, thêm một sé record vao bang ratings:
mysql> INSERT INTO ratings (rating_id, rating_name) VALUES (4, ‘Good’); Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO ratings (rating_id, rating_name) VALUES (5, 'Excel- lent’);
Query OK, 1 row affected (0.00 sec) Thém mét sé record vao bang songs:
mysql> INSERT INTO songs (song_title, fk_song_artist, fk_song_rating) -> VALUES (‘Janie\’s Got A Gun’, 1, 4);
Query OK, 1 row affected (0.04 sec)
mysql> INSERT INTO songs (song_title, fk_song_artist, fk_song_rating) -> VALUES (‘Crazy’, 1, 5);
Query OK, 1 row affected (0.00 sec)
“Chú ý rằng các record trong bảng songs được liên kết với các record trong các bảng artists và ratings thông qua các khóa ngoại (foreign key) Ban sẽ thấy trực tiếp những mối quan hệ khóa ngoại này trong phần tiếp theo
Ghi chit
Nguồn lưu trữ mã cho sách này có một danh sách day đủ các câu
lệnh SQL INSERT để tập hợp lại ba đoạn được sử dụng trong bài
tập này Chạy các câu lệnh này và hoàn tất việc xây dựng các bằng
Trang 16
Chương 7: Làm việc với các cơ sở dữ liệu và SQL 19 Thue thi cde query
Một khi dữ liệu nằm trong cơ sở dữ liệu, đã đến lúc làm một điều gì đó với nó SQL cho phép bạn tìm kiếm các record khớp với những tiêu chí cụ thể sử dụng câu lệnh SELECT Sau đây là một ví dụ, ví dụ này trả về tất cả
record từ bảng artists: ;
mysql> SELECT artist_id, artist_name FROM artists; artist_id artist name 1 Aerosmith 2 Abba 3 Timbaland 4 Take That 5 Girls Aloud 6 Cubanismo 6 rows in set (0.00 sec)
Trong hầu hết các trường hợp, bạn sẽ muốn thêm các bộ loc (filter) vao query dé gidm kích cỡ của tập hợp kết quả và báo đảm rằng nó chứa chỉ các record khớp với những tiêu chí nhất định Điều này được hoàn tất bằng việc thêm một mệnh đề WHERE vào câu lệnh SELECT cùng với một hoặc nhiều biểu thức có điều kiện Sau đây là một ví dụ, ví dụ này liệt kê chỉ các nghệ sĩ từ nước Mỹ:
mysql> §ELEGT artist_id, artist name FROM artists -> WHERE artist_country = ‘US’;
artist_id artist_name 1 Aerosmith
3 Timbaland
2 rows in set (0.00 sec)
Tất cả toán tử so sánh chuẩn mà bạn đã quen thuộc từ PHP được hỗ trợ
bởi SQL Ví dụ trước minh họa toán tử đẳng thức (=); ví dụ tiếp theo sau đây
Trang 1720 Chuong 7: Lam việc với các cơ sở dữ liệu và SQL Crazy 5 En Las Delicious Pray SOS Dancing Queen 7 rows in set (0.00 sec) 5 4 Apologize 4 4 4
Bạn có thể kết hợp những biểu thức có điều kiện sử dụng các toán tử logic AND, OR, và NOT (như với câu lệnh có điều kiện PHP thông thường) Sau đây là một ví dụ, ví dụ này liệt kê các nghệ sĩ từ nước Mỹ hoặc vương quốc Anh:
mysql> SELEễT artisi name, artist_œountry FROM artists -> WHERE artist_country = ‘US’ -> OR artist_country = ‘UK’; artist_name artist_country Aerosmith US Timbaland US Take That UK Girls Aloud UK 4 rows in set (0.02 sec) Sắp xếp thứ tự và giới hạn các tập hợp kết quả
Nếu bạn muốn thấy dữ liệu từ một bảng được sắp xếp thứ tự theo một trường cụ thể, SQL đưa ra mệnh đề ORDER BY Mệnh đề này cho bạn định
nghĩa tên trường để phân loại và hướng phân loại (tăng dân hoặc giảm dần)
Vi dụ để thấy một danh sách ảng nhạc được phân loại theo thứ tự bảng chữ cái, sử dụng câu lệnh SQL sau đây:
Trang 18Chương 7: Làm việc với các cơ sở dữ liệu và SQL 21 Crazy
Dancing Queen En Las Delicious Gimme Gimme Gimme Janie’s Got A Gun Pray
S0S Sure Voulez Vous
12 rows in set (0.04 sec)
Để phân loại đảo ngược danh sách nay, thém modifier DESC như trong ví dụ tiếp theo:
mysql> SELECT song_title FROM songs -> ORDER BY song_title DESC; song_title song_title Sure S0S Pray
Janie’s Got A Gun Gimme Gimme Gimme En Las Delicious Dancing Queen Crazy Babe Apologize
Another Crack In My Heart 12 rows in set (0.00 sec)
Trang 1922 Chương 7: Làm việc với các cơ sở dữ liệu và SQL mysql> SELECT song_title FROM songs -> ORDER BY song_title -> LIMIT 3,6; song_title Crazy Dancing Queen En Las Delicious Gimme Gimme Gimme Janie’s Got A Gun Pray
5 rows in set (0.00 sec)
Sử dụng các ky tu dai dién (Wildcard)
Câu lệnh SQL SELECT cũng hỗ trợ một mệnh dé LIKE, mệnh đề này có thể được sử dụng để tìm kiếm bên trong các trường text sử dụng những ký tự đại điện (wildcard) Có hai loại wildcard được cho phép trong một mệnh
dé LIKE: ký tự % được sử dụng để báo hiệu zero hoặc nhiều trường hợp của
một ký tự và ký tự _ được sử dụng để báo hiệu chính xác một trường hợp của một ký tự
Ví dụ sau đây minh họa tiếp một mệnh dé LIKE, tìm kiếm các tựa để bản nhạc có ký tự 'g' trong đó:
mysql> SELECT song_id, song_title FROM songs -> WHERE song_title LIKE ‘%g%’; song_id song_title 1 Janie’s Got A Gun 7 Apologize 8 Gimme Gimme Gimme 10 Dancing Queen 4 rows in set (0.00 sec) Nối các bảng
Trang 20Chương 7: Làm việc với các cơ sở dữ liệu và SQL một join vì nó đòi hỏi eaten
nối" các bảng khác nhau tại các trường chung (các khóa ngoại) để tạo các view mới của dữ liệu
Thủ thuật
23
Khi nối các bảng, bắt đâu mỗi tên trường bằng tên của bảng mà nó thuộc về để tránh sự nhầm lẫn phòng hờ các trường trong các bảng khác nhau có cùng một
tên
Sau đây là một ví dụ về việc nối các bảng songs và artists lại với nhau sử dụng trường artist_id chung (ménh dé WHERE được sử dụng để ánh xạ các trường chung sang với nhau)
mysql> SELECT song_id, song_titte, artist_name FROM songs, artists -> WHERE songs.fk_song_artist = artists.artist_id; song_id 1 2 8 9 10 12 3 song_title Janie’s Got A Gun Crazy Gimme Gimme Gimme S0S Dancing Queen Voulez Vous Apologize Sure Pray Another Crack In My Heart Babe En Las Delicious 12 rows in set (0.00 sec) artist_name Aerosmith Aerosmith Abba Abba Abba Abba Timbaland Take That Take That Take That Take That Cubanismo
Va đây là một ví dụ về việc nối cả ba bảng lại với nhau và sau đó lọc tập hợp kết quả thậm chí nhiều hơn nữa để bao hàm chỉ các bản nhạc có một rating là 4 trở lên và có các nghệ sĩ không phải ở Mỹ:
mysql> SELECT song_title, artist_name, rating_name -> FROM songs, artists, ratings
Trang 2124 Chương 7: Làm việc với các cơ sở dữ liệu và SQL -> AND artists.artist_country != ‘US’;
song_title artist_name rating_name En Las Delicious Cubanismo Excellent
Pray Take That Good
SOS Abba Good
Dancing Queen Abba Good
4 rows in set (0.02 sec)
Chỉnh sửa và loại bỏ các Record
Tương tự như bạn INSERT các record vào một bảng, bạn cũng có thể xóa các record bằng câu lệnh DELETE Điển hình, bạn thường chọn một tập hợp con các hàng cụ thể cần xóa bằng việc thêm mệnh đề WHERE vào câu lénh DELETE nhu trong ví dụ tiếp theo, ví dụ này xóa tất cả bản nhạc có một rating nhỏ hơn hoặc bằng 8:
mysql> DELETE FR0M songs -> WHERE fk_song_rating <= 3; Query OK, 5 rows affected (0.02 sec)
Cũng có một câu lệnh UPDATE, câu lệnh này có thể được sử dụng để thay đổi nội dung của một record; câu lệnh này cũng chấp nhận một mệnh
đẻ WHERE để bạn có thể áp dụng những thay đổi vào chỉ các record khớp
với những tiêu chí riêng biệt Xem xét ví dụ sau đây, ví dụ này thay đổi rating ‘Excellent’ thanh 'Fantastic:
mysql> UPDATE ratings SET rating_name = ‘Fantastic’ -> WHERE rating_name = ‘Excellent’;
Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
Bạn có thể thay đổi nhiều trường bằng việc tách biệt chúng bằng các dấu
phẩy Sau đây là một ví dụ cập nhật một record bản nhạc cụ thể trong bảng songs, thay đổi cả tựa để của nó và rating của nó:
mysql> UPDATE songs SET song_title = ‘Waterloo’, -> tk_song_rating = 5
Trang 22Chương 7: Làm việc với các cơ sở dữ liệu và SQL 25
'Hỏi chuyên gia
Hỏi: Tôi đang sử dụng cơ sở dữ liệu và nó không hỗ trợ kiểu trường Tôi phải làm gì bây giờ?
Đáp: Các cơ sở dữ liệu khác nhau có cú pháp khác nhau cho các kiểu dữ liệu trường Ví dụ, MySQL gọi các trường số nguyên là INT, trong khi SGLite gọi các trường y như thế là INTEGER Tuy nhiên, hầu như mọi cơ sở dữ liệu sẽ hỗ trợ - tối thiểu - các kiểu dữ liệu cho những giá trị số nguyên (integer), giá trị dấu động (floading-point), giá trị chuỗi (string), giá trị nhị phân (binary) và giá trị NULL Tất cả những gì bạn cần làm là dò tìm tài liệu cơ sở dữ liệu và xác định cú pháp để sử dụng chính xác những kiểu dữ liệu đó trong các câu lệnh SQL
Hỏi: Tại sao tôi cần liệt kê tất cả trường bắt buộc trong câu lệnh SELECT? Tôi không thể sử dụng ký tự đại diện * để nhận được trở lại tất cả trường có sẵn phải không?
Đáp: Trong khi SQL hỗ trợ ký tự đại diện dấu sao (*) để đại diện cho "tất cả trường trong một bảng", ưu tiên luôn đặt tên cụ thể các trường mà bạn muốn thấy trong tập hợp kết quả Điều này cho phép ứng dụng sống sót sau những thay đổi cấu trúc trong bảng của nó và thường cũng có hiệu quả hơn về khía cạnh bộ nhớ bởi vì tập hợp kết quả sẽ không chứa dữ liệu không mong muốn hoặc dữ liệu không liên quan
Sử dụng Extension MySQL của PHP
Như được giải thích trước đó, PHP cho phép các nhà phát triển tương tác
với những cơ sở dữ liệu bằng hai cách: bằng việc sử dụng một extension riêng biệt của cơ sở dữ liệu được tùy biến hoặc bằng việc sử đụng extension PHP Data Objects (PDO) trung hòa với cơ sở dữ liệu Trong khi extension PDO có tính khả chuyển (portable) hơn, nhiều nhà phát triển vẫn thấy sử dụng extension cơ sở đữ liệu riêng thì ưu tiên hơn đặc biệt khi extension riêng có hiệu suất tốt hơn hoặc nhiều tính năng hơn phiên bản PDO
Trong số những bộ máy cơ sở dữ liệu khác nhau được hỗ trợ bởi PHP, cho đến bây giờ bộ máy cơ sở dữ liệu thông dụng nhất là MySQL Không khó hiểu tại sao: Ca PHP va MySQL déu là những dự án nguồn mở và bằng việc
sử dụng chúng cùng với nhau, các nhà phát triển có thể có lợi từ những
Trang 2326 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
Ngoài việc hỗ trợ MySQL thông qua extension PHP Data Objects (được thảo luận trong phần tiếp theo), PHP cũng có một extension MySQL tùy ý có tên là MySQL Improved (MySQL) mang lại những lợi ích về tốc độ và tính năng so với phiên bản PDO và là một lựa chọn tốt cho các dự án phát triển đành riêng cho MySQL Các phần tiếp theo thảo luận chỉ tiết hơn extension này
Truy tìm dữ liệu
"Trong phần trước bạn tạo một bảng cơ sở dữ liệu và đã sử dụng một query SELECT để truy tìm một tập hợp kết quả từ nó Bây giờ hãy làm tương tự sử dụng PHP trong script sau đây:
<?php
// attempt database connection
$mysqli = new mysqli(“localhost”, “user”, “pass”, “music”); if ($mysqli === false) {
die(“ERROR: Could not connect “ mysqli_connect_error()); }
// attempt query execution // iterate over result set
// print each record and its fields /f output: “1:Aerosmith \n 2:Abba \n .”
Trang 24Chương 7: Làm việc với các cơ sở dữ liệu và SQL 27 // close connection $mysqli->close(); s Aerosmith tabba : Timbaland tTake That Girls Aloud :Cuban smo{
Hình 7.3 Truy tìm các record từ một cơ sử dữ liệu MyS0L với PHP Hình 7.3 minh họa kết quả của script này
Như bạn có thể thấy sử dụng PHP để nhận đữ liệu từ cơ sở dữ liệu đòi hỏi một số bước được mô tả ở đây:
1 Dé bat dau giao tiếp với server cơ sở dữ liệu MySQL, trước tiên bạn cần mở một nối kết với server Tất cả sự giao tiếp giữa PHP và server cơ sở dữ liệu xảy ra qua nối kết này
Để khởi tạo nối kết này, khởi tạo một instance của class MySQL và chuyển đến phương thức tạo đối tượng bốn đối số: tên host của server MySQL để kết nối, một username và password hợp lệ để truy cập nó
vào tên cơ sở đữ liệu để sử dụng
Giả sử nỗ lực kết nối thành công, instance đối tượng này tượng trưng cho nối kết cơ sở dữ liệu cho tất cả hoạt động tương lai và phơi bày những phương thức để truy vấn, truy tìm và xử lý các tập hợp kết quả Nếu nỗ lực kết nối không thành công, instance đối tượng sẽ trở thành false; một thông báo lỗi giải thích lý do thất bại bây giờ có thể nhận được bằng việc gọi hàm mysqli_connect_error ()
@eeeoeee
Thu thuat
Nếu server cơ sở dữ liệu và Web server đều chạy trên cùng một máy vật lý, bạn có thể sử dụng localhost làm tên server
Trang 2528
Lư, ý
Chương 7: Làm việc với các cơ sở dữ liệu và SQL đến nó query cần được thực thi Nếu query không thành công, phương thức trả về Boolean false và một thông báo giải thích nguyên nhân thất bại được lưu trữ trong thuộc tính 'error'` của đối tượng MySQLi Mặt khác, nếu query thành công và trả về một hoặc nhiều record, giá trị trả về của phương thức query Q là một đối tượng khác, đối tượng này là một instance cia class MySQLi_Result Déi tugng này tượng trưng cho tập hợp kết quả được trả về bởi query và nó phơi bày những phương thức khác nhau dành cho việc xử lý những record riêng lẻ trong tập hợp kết quả
Một phương thức như vậy là phương thức fetch_array O Mỗi lần
fetch_array Q được gọi ra, nó trả về record tiếp theo trong tập hợp kết quả dưới dạng một mảng Điều này làm cho phương thức fetch_array O rất thích hợp để sử dụng trong một vòng lặp while hoặc for Bộ đếm vòng lặp (loop counter) quyết định vòng lặp nên chạy bao nhiêu lần; giá trị này có được từ thuộc tính 'num_rows' của đối tượng MySQLi_Result, thuộc tính này lưu trữ số hàng được trả về bởi query Các trường riêng lẻ từ record có thể được truy cập dưới dạng các phần tử mảng, sử dụng index trường hoặc tên trường
Thuộc tính 'num_rows' chỉ có ý nghĩa khi được sử dụng với các query trả về dữ liệu chẳng hạn như các query SELECT; nó không nên được sử dụng với những query INSERT, UPDATE hoặc DE-
LETE
4 Mỗi tập hợp kết quả được trả về sau một query chiếm một lượng bộ nhớ nào đó Một khi tập hợp kết quả được xử lý, nên tiêu hủy đối tượng MySQLi_Result, và giải phóng bộ nhớ được sử dụng bằng việc gọi phương thức close Q của đối tượng Và một khi ban đã làm việc xong với cơ sở dữ liệu bạn cũng nên hủy bỏ đối tượng MySQLi chính một cách tương tự bằng việc gọi phương thức close Q của nó
Trả về các Record dưới dạng các mắng và đối tượng
Trang 26Chương 7: Làm việc với các cơ sở dữ liệu và SQL 29 Listing trước minh họa cách truy tìm những trường riêng lẻ sử dụng số index trường Listing sau đây tương đương listing trước thực hiện cùng một tác vụ sử dụng các tên trường:
<?php
// attempt database connection
$mysqli = new mysqli(“localhost”, “user”, “pass”, “music”); if ($mysqli === false) {
die(“ERROR: Could not connect “ mysqli_connect_error()); }
// attempt query execution // iterate over result set
// print each record and its fields // output: “1:Aerosmith \n 2:Abba \n .”
$sql = “SELECT artist_id, artist_name FROM artists”; if ($result = $mysqli->query($sql)) { if ($result->num_rows > 0) { while($row = $result->fetch_array()) { echo $row[‘artist_id’] “:" $row[‘artist_name’] “\n”: } $result->close(); } else { echo “No records matching your query were found.”; } } else { echo “ERROR: Could not execute $sql “ $mysqli->error: } // close connection $mysqli->close(); ?>
Trang 2730 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
được truy cập sử dụng ký hiệu $object-> property chuẩn Listing sau đây - minh họa phương pháp này:
<?php
// attempt database connection
$mysqli = new mysqli(“iocalhost”, “user”, “pass”, “ if ($mysqli === false) {
die(“ERROR: Could not connect “ mysqli_connect_error()); music”);
}
// attempt query execution // iterate over result set
// print each record and its fields // output: “1:Aerosmith \n 2:Abba \n .”
$sql = “SELECT artist_id, artist_name FROM artists”; if ($result = $mysqli->query($sql)) { if ($result->num_rows > 0) { while($row = $result->fetch_object()) { echo $row->artist_id “:" $row->artist_name “\n”; } $result->close(); } else { echo “No records matching your query were found.”: } } else { echo “ERROR: Could not execute $sql “ $mysqli->error; } # close connection $mysqli->close(); 2>
Thêm hoặc chỉnh sửa dữ liệu
Trang 28Chương 7: Làm việc với các cơ sở dữ liệu và SQL 31 <?php
// attempt database connection
ÿmysqli = new mysdli(“localhost”, “user”, pass”, “music”); if ($mysqli === false) {
die(“ERROR: Could not connect “ mysqli_connect_error()); }
// attempt query execution /f add a new record
// output: “New artist with id:7 added.”
$sql! = “INSERT INTO artists (artist_name, artist_country) VALUES (‘Kylie Minogue’, ‘AU’)”; if ($mysqli->query($sql) === true) { echo ‘New artist with id:’ $mysqli->insert_id ‘ added.’; } else { echo “ERROR: Could not execute query: $sqi “ $mysqli->error: } // close connection $mysaqli->close(); ?>
Như bạn sẽ thấy lập trình này không khác mấy so với lập trình cần thiết để thực thi một query SELECT Thực tế, nó hơi đơn giản hơn bởi vì không có tập hợp kết quả để xử lý Tất cả những gì cần là test giá trị trả về của phương thức query Q và kiểm tra xem query đã được thực thi thành công hay không Cũng chú ý việc sử dụng một thuộc tính mới, thuộc tính 'insert_iđ: thuộc tính này trả về ID được tạo ra bởi query INSERT cuối cùng (chỉ hữu dụng nếu bảng mà INSERT xảy ra trong đó chứa một trường tự động tăng)
Còn về việc cập nhật một record hiện có thì sao? Tất cả những gì cần thiết là thay đổi chuỗi query SQL:
<?php
// attempt database connection
Trang 2932 Chương 7: Làm việc với các cơ sở dữ liệu và SQL die(“ERROR: Could not connect “ mysqli_connect_error());
}
// attempt query execution // add a new record
// output: “1 row(s) updated.”
$sql = “UPDATE artists SET artist_name = ‘Eminem’, artist_country = ‘US’ WHERE artist_id = 7°; if ($mysqli->query($sql) === true) { echo $mysali->affected_rows ‘ row(s) updated.’; } else { echo “ERROR: Could not execute query: $sql “ $mysqli->error; } // close connection $mysqli->close(); ?>
Khi thực thi một UPDATE hoặc DELETE, số hàng bị ảnh hưởng bởi câu lệnh sẽ được lưu trữ trong thuộc tính 'affected_rows' của đối tượng MySQLiI Listing trước minh họa thuộc tính này đang được sử dụng
Sử dụng các câu lệnh được chuẩn bị
Trong trường hợp bạn cần thực thi một query cụ thể nhiều lần với những giá trị khác nhau - ví dụ, một loạt các câu lệnh INSERT - server cơ sở dữ liệu MyS§QL hỗ trợ các câu lệnh được chuẩn bị (prepared statement) cung cấp một phương tiện hiệu quả hơn để hoàn thành tác vụ này so với liên tục gọi phương thức $mysqli->query ()
Về cơ bản, một câu lệnh được chuẩn bị là một khuôn mẫu (template) query SQL chia cdc bién placeholder cho nhiing gid tri cần được chèn hoặc được chỉnh sửa Câu lệnh này được lưu trữ trên database server và được gọi
ra bao nhiêu lần tùy mức cần thiết với các placeholder được thay thế bằng
Trang 30Chương 7: Làm việc với các cơ sở dữ liệu và SQL 33
Hồi chuyên gia
Hỏi: Các câu lệnh được chuẩn bị mang lại hiệu suất tốt hơn như thế nào?
Đáp: Trong tiến trình bình thường, mỗi lần một câu lệnh SQL được thực thi trên database server, server phải phân tích mã SQL và kiểm tra cú pháp và cấu trúc của nó trước khi cho nó thực thi Với một câu lệnh được chuẩn bị, câu lệnh SQL được lưu trữ trong một vị trí tạm thời trên database server và do đó chỉ cần được phân tích và được hiệu lực hóa một lần Hơn nữa câu lệnh mỗi lần được thực thi, chỉ các giá trị placeholder mới cần được chuyển đến server thay vì câu lệnh hoàn chỉnh
.Để thấy trực tiếp một câu lệnh được chuẩn bị, xem xét seript sau đây, script này chèn nhiều bảng vào cơ sở dữ liệu sử dụng một câu lệnh được chuẩn bị véi extension MySQli cua PHP: <?php // define values to be inserted $songs = array( array(‘Patience’, 4, 3), array(‘Beautiful World’, 4, 4), array(‘Shine’, 4, 4), array(‘Hold On’, 4, 3), )
// attempt database connection
$mysqli = new mysqli(“localhost”, “user”, “pass”, “music”); if ($mysqli === false) {
die(“ERROR: Could not connect “ mysqli_connect_error()); }
// prepare query template // execute multiple times
Trang 3134 - Chương 7: Làm việc với các cơ sở dữ liệu và SQL if ($stmt = $mysqli->prepare($sql)) { foreach ($songs as $s) { $stmt->bind_param(‘sii’, $s[0], $s[1], $s[2]); if ($stmt->execute()) { echo “New song with id: “ $mysqli->insert_id “ added.\n’; } else { echo “ERROR: Could not execute query: $sql “ $mysqli->error; } } else { echo “ERROR: Could not prepare query: $sql “ $mysqli->error: } // close connection $mysqli->close(); 2>
Như listing này minh họa, sử dụng một câu lệnh được chuẩn bị đòi hỏi một thủ tục khác với thủ tục mà bạn đang thấy từ những ví dụ trước
Để sử dụng một câu lệnh được chuẩn bị trước tiên cần phải định nghĩa chuỗi query SQL mà sẽ được thực thi nhiều lần Chuỗi query này thường chứa một hoặc nhiều placeholder để biểu thị bằng các dấu hỏi (?) Các placeholder này sẽ được thay thế bằng những giá trị thực sự vào mỗi lần thực thi câu lệnh Chuỗi query với các placeholder của nó sau đó được chuyển đến phương thức prepare () của đối tượng MySQLi, phương thức này
kiểm tra SQL để tìm các lỗi và trả về một đối tượng MySQLi_Stm tượng
trưng cho câu lệnh được chuẩn bị
Thực thi câu lệnh được chuẩn bị bây giờ là một vấn đề thực hiện hai hành động, thường là bên trong một vòng lặp:
1 Liên kết các giá trị với câu lệnh được chuẩn bị Các giá trị mà cần
được nội suy vào câu lệnh phải được liên kết với các placeholder của chúng bằng phương thức bind_param(Q của đối tượng MySQLi_Stm Đối số đầu tiên cho phương thức này phải là một trình tự chuỗi có ký
tự biểu thị các kiểu đữ liệu của các giá trị cÂn được nội suy (s cho
Trang 32Chương 7: Làm việc với các cơ sở dữ liệu va SQL 35 sự Trong listing trước chuỗi 'sii' biểu thị rằng các giá trị cần được nội suy vào câu lệnh được chuẩn bị sẽ, theo trình tự, là một kiểu chuỗi (tựa đề bản nhạc), một kiểu số nguyên (khóa ngoại artist), và một kiểu số nguyên (khóa ngoại rating)
2 Thực thi câu lệnh được chuẩn bị Một khi các giá trị đã được liên kết vớt các placeholder của chúng; câu lệnh được chuẩn bị được thực thi bằng việc gọi phương thức executeQ của đối tượng MySQLi_Smt Phương thức này thay thế các placeholder trong câu lệnh được chuẩn bị bằng những giá trị thực sự và thực thi nó trên server
Do đó, sử dụng một câu lệnh được chuẩn bị mang lại những lợi ích hiệu suất khi bạn cần thực thi cùng một câu lệnh nhiều lần với chỉ các thay đổi thay đổi vào mỗi lần thực thi Hầu hết các cơ sở dữ liệu thông dụng bao gồm My§SL, PostgreSQL, Oracle, và InterBase, hỗ trợ các câu lệnh được chuẩn bị và tính năng này nên được sử dụng nơi có sẵn để làm cho các hoạt động lô SQL hiệu quả hơn
Xử lý các lôi
Nếu mã cơ sở dữ liệu không làm việc như mong đợi, đừng lo lắng - extension MySQLi có một chùm các hàm có thể cho bạn biết tại sao Bạn đã thấy trực tiếp những hàm này ở những nơi khác nhau trong các listing trước, nhưng sau đây là một danh sách hồn chỉnh:
„§ Thuộc tính error' của đối tượng MySQLi chứa thông báo lỗi sau cùng được tạo ra béi database server
M@ Thuéc tinh ‘errno’ cila d6i tuong MySQLi chita md lỗi sau cùng được trả vé bởi database server
@ Ham mysqli_connect_error O tra vé thong bdo bi được tạo ra bởi nỗ lực két n6i sau cting (that bai)
@ Ham mysqli_connect_error O tra vé ma 16i duoc tao ra béi né hic két nối sai cùng (that bai)
Để làm cho ứng dụng mạnh hơn trước các lỗi và để làm cho dễ tìm kiếm và giải
Trang 3336 Chương 7: Làm việc với các cơ sở dữ liệu và SQL
Thực hành 7.2: Thêm các nhân viên vào một cơ sở dữ liệu
Bây giờ khi bạn biết một số điểm cơ bản về việc sử dụng extension MySQLI của PHP, hãy áp dụng những gì bạn đã học trong phần trước vào một ứng dụng "thực tế" Ứng dụng ở đây là một Web form cho phép một người dùng nhập các tên nhân viên vào một cơ sở đữ liệu nhân viên dựa vào MySQL Các giá trị được nhập vào form được hiệu lực hóa sử dụng PHP và được biến đổi thành các record cơ sở dữ liệu sử dụng extension PHP MySQLi Để bắt đầu xây dựng các ứng dụng này, đầu tiên hãy khởi động client dòng lệnh MySQL và khởi tạo một cơ sở đữ liệu rỗng:
Mysql> CREATE DATABASE employees; Query OK, 1 row affected (0 20 sec)
Tiếp theo, tạo một bảng để chứa các record nhân viên: mysql> USE employees;
Database changed
mysql> CREATE TABLE employees (
-> id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY, -> name VARCHAR(255) NOT NULL,
-> designation VARCHAR(255) NOT NULL >);
Query OK, 0 rows affected (0.26 sec)
Bước tiếp theo là xây dựng một Web form để chấp nhận đữ liệu nhân viên - trong trường hợp này, tên và chức vụ của mỗi nhân viên Sau khi gởi,
bộ xử lý form sẽ kiểm tra đầu vào và nếu hợp lệ, tạo một query INSERT để
ghỉ nó sang bảng cơ sở đữ liệu được tạo ở bước trước Sau đây là script (employee.php):
Trang 34Chương 7: Làm việc với các cơ sở đữ liệu và SQL 37 } margin-left:auto; margin-right:auto; width:40%; border: solid 2px green </style> </head> <body>
<h2>Project 7-2: Adding Employees to a Database</h2> <h3>Add New Employee</h3>
<?php
/ƒ if form submitted /f process form input
if (isset($_POST['submit’])) {
// attempt connection to MySQL database
$mysqli = new mysqli(“localhost”, “user”, “pass”, “employees”); if ($mysqli === false) {
die(“ERROR: Could not connect to database “ mysqli_connect_error());
}
/f open message block echo ‘<div id=”"message”>’; // retrieve and check input values $inputError = false; if (empty($_POST[‘emp_name’])) { echo ‘ERROR: Please enter a valid employee name’; $inputError = true; } else { $name = $mysgli->escape_siring($_POST['emp_name']); }
if (SinputError != true && empty($_POST[‘emp_desig’])) { echo ‘ERROR: Please enter a valid employee designation’; $inputError = true;
Trang 3538 Chương 7: Làm việc với các cơ sở dữ liệu và SQL $designation = $mysqli->escape_string($_POST['emp_desig’}); }
// add values to database using INSERT query if ($inputError != true) {
Trang 36Chương 7: Làm việc với các cơ sở dữ liệu và SQL 39 Khi script nay được gọi ra, nó tạo một Web form có các trường đành cho tên và chức vụ của một nhân viên Hình 7.4 minh họa điện mạo của form ban đầu
_Project 7-2: Adding Employees to a Database
Add New Employee Employee name: ; Employee designation: “s 2G 4 Hình 7.4 Một Web form để nhập một nhân viên mới
Khi form được gởi, script tiến hành khởi tạo một đối tượng My8QLi mới và mở một nối kết đến database server MySQL Sau đó nó kiểm tra các trường form để bảo đảm rằng chúng chứa những giá trị đầu vào hợp lệ Nếu
hợp lệ, mỗi giá trị đầu vào được “sanitize” (kiém tra vé sinh) sử dụng
phương thức escape_string () cia đối tượng MSQLi, phương thức này tự động thoát những ký tự đặc biệt trong đầu vào như là bước mở đầu để chèn nó vào cơ sở đữ liệu và sau đó được nội suy vào query INSERT, vốn được thực thi thông qua phương thức query Q của đối tượng để lưu những giá trị sang cơ sở dữ liệu Các lỗi, nếu có sẽ được hiển thị sử dụng thuộc tinh error của đối tượng MySQLi
Hình 7.ð minh họa đầu ra khi một record được thêm thành công và hình 7.6 minh họa đầu ra khi một trường nhập liệu không vượt qua việc hiệu lực hóa
Bây giờ, còn về việc chỉnh sửa script này sao cho ngoài việc cho phép bạn thêm những nhân viên mới vào cơ sở dữ liệu, nó cũng hiển thị các record nhân viên hiện có từ cơ sở dữ liệu thì sao? Điều này không khó cho lắm - thêm một lệnh gọi khác vào phương thức query (), lan nay với một query SELECT, và xử lý tập hợp kết quả sử dụng một vòng lặp Sau đây là mã được chỉnh sửa:
Trang 3740 Chương 7: Làm việc với các cơ sở dữ liệu va SQL <!DOCTYPE htmi PUBLIC “-/AW30//DTD XHTML 1.0 Transitional⁄/EN” “DTD/xhtml1-transitional.dtd”> <html xmlns="http:/www.w3.org/1999/xhtml” xmi:lang="en” lang="en"> <head> <title>Project 7-2: Adding Employees †o a Database</title> <style type="text/css”> div#message { text-align:center; margin-left:auto; margin-right:auto; width:40%; border: solid 2px green } table { border-collapse: collapse; width: 320px; } tr.heading { font-weight: bolder; } td { border: 1px solid black; padding: 0 0.5em; } </style> </head> <body>
<h2>Project 7-2: Adding Employees to a Database</h2> <h3>Add New Employee</h3>
<?php
/f attempt connection to MySQL database
Trang 38Chương 7: Làm việc với các cơ sở dữ liệu va SQL 41 if ($mysqli === false) { die(“ERROR: Could not connect to database “ mysqli_connect_error()); } /{ if form submitted /! process form input if (isset($_POST[‘submit’])) {
// open message block echo ‘<div jd="message”>’; # retrieve and check input values $inputError = false; if (empty($_POST[‘emp_name’])) { echo ‘ERROR: Please enter a valid employee name’ $inputError = true; } else { $name = $mysqli->escape_string($_POST['emp_name’]); }
if (SinputError != true && empty($_POST[‘emp_desig’])) { echo ‘ERROR: Please enter a valid employee designation’: $inputError = true; } else { $designation = $mysqli->escape_string($_POST[‘emp_desig’]), } // add values to database using INSERT query if ($inputError {= true) {
Trang 40Chương 7: Làm việc với các cơ sở dữ liệu và SQL 43 echo “ </tr>\n”: } echo “</table>”; $result->close(); } else { echo “No employees in database.”; } } else { echo “ERROR: Could not execute query: $sql “ $mysqli->error; } // close connection $mysqli->close(); ?> </body> </html> 8 hitp:Jfocahostjphpébookjch07pvojectf2Jemployee.ghp
: Project 7-2: Adding Employees to a Database