VIII. Làm Việc Với CSDL MySQL
D. PHP & MYSQL
Bài viết này sẽ tập trung vào việc khai thác hệ quản trị CSDL miễn phí
MySQL.
Các bước xây dựng chương trình có kết nối tới CSDL My SQL:
Thông thường, trong một ứng dụng có giao tiếp với CSDL, ta phải làm theo bốn trình tự sau:
Bước 1: Thiết lập kết nối tới CSDL.
Bước 2: Lựa chọn CSDL.
Bước 3: Tiến hành các truy vấn
SQL, xử lý các kết quả trả về nếu có
Bước 4: Đóng kết nối tới CSDL.
Nếu như trong lập trình thông thường trên
Windows sử dụng các chương trình điều khiển trung gian (ADO,
ODBC...)
để thực hiện kết nối và truy vấn, thì trong PHP, khi lập trình tương
tác với CSDL, chúng ta thường sử dụng thông qua các hàm.
Chú ý: Trước
khi sử dụng PHP để lập trình với MySQL, hãy sử dụng chương trình quản
lý phpMyAdmin để tạo trước một CSDL, vài bảng cũng như người dùng... để
tiện thực hành. Bài hướng dẫn sử dụng phpMyAdmin sẽ được trình bày sau.
Trong bài viết này, tôi sử dụng MySQL chạy trên nền máy chủ
localhost, người sử dụng của CSDL này có username là mysql_user, mật khẩu là mysql_password
Thiết lập kêt nối tới MySQL.
Để kết nối tới MySQL, ta sử dụng hàm mysql_connect()
Cú pháp:
mysql_connect(host,tên_truy_cập,mật_khẩu);
trong đó:
host là chuỗi chứa tên (hoặc địa chỉ IP) của máy chủ cài đặt MySQL.
tên_truy_cập là chuỗi chứa tên truy cập hợp lệ của CSDL cần kết nối
mật_khẩu là chuỗi chứa mật khẩu tương ứng với tên truy cập
Ví dụ:
<?
mysql_connect ("localhost", "thu_mot_ti","thu_hai_ti");
?>
Khi
kết nối tới MySQL thành công, hàm sẽ trả về giá trị là một số nguyên
định danh của liên kết, ngược lại, hàm trả về giá trị false.
Ta có thể dùng hàm if để kiểm tra xem có kết nối được tới MySQL hay không:
<?php
$link = mysql_connect("localhost", "mysql_user", "mysql_password");
if (!$link)
{
echo "Không thể kết nối được tới CSDL MySQL";
}
?>
Lựa chọn CSDL
Để lựa chọn một CSDL nào đó mà người sử dụng có tên là tên_truy_cập" có quyền sử dụng, ta dùng hàm mysql_select_db:
mysql_select_db (tên_CSDL);
Hàm
này thường được dùng sau khi thiết lập kết nối bằng hàm mysql_connect.
Hàm này trả về true nếu thành công, false nếu thất bại.
VD:
<?php
$link = mysql_connect("localhost", "mysql_user", "mysql_password");
if (!$link)
{
echo "Không thể kết nối được tới MySQL";
}
if (!mysql_select_db ("
Forums"))
{
echo "Không thể lựa chọn được CSDL Forums";
}
?>
Đóng kết nối tới CSDL:
Để đóng kết nối tới CSDL, ta dùng hàm mysql_close.
Hàm này có nhiệm vụ đóng kết nối tới CSDL có mã định danh được tạo ra bởi hàm mysql_connect().
Cú pháp: mysql_close(mã_định_danh_kết_nối).
Ví dụ:
<?php
$link = mysql_connect("localhost", "mysql_user", "mysql_password");
if (!$link)
{
echo "Không thể kết nối được tới MySQL";
}
mysql_close($link);
?>
Trong bài viết này, tôi sử dụng
MySQL chạy trên nền máy chủ localhost, người sử dụng có username là mysql_user, mật khẩu là mysql_password.
CSDL
có tên là CMXQ_Forum, trong đó có một bảng là CMXQ_Users để lưu thông
tin về những thành viên của diễn đàn. Bảng CMXQ_Users có các trường sau:
User_ID: Autonumber.// mã số của người dùng
User_Name: Varchar [20] // tên truy cập của người dùng
User_Pass: Varchar[64] //mật khẩu của người dùng
User_IP: Varchar [15] //Địa chỉ IP của người dùng.
User_Post: Number // Số bài viết của người dùng.
Bây giờ tôi sẽ tiến hành một số thao tác thêm, sửa và xóa dữ liệu trên bảng đó. Xin xem lại bài Căn bản về
SQL.
Để thực thi một câu lệnh
SQL bất kỳ trong
PHP tác động lên
MySQL, ta dùng hàm mysql_query (chuỗi_câu_lệnh_SQL)
I. Thêm một bản ghi vào bảng.
Ví dụ tôi muốn chèn thêm một người sử dụng có User_Name là "CMXQ", User_Pass là "123456", User_Post=0 ta làm như sau:
<?
$sql = "
INSERT INTO CMXQ_Users (User_Name, User_Pass) VALUES ("CMXQ","123456",0);
mysql_query ($sql);
?>
II. Xóa một bản ghi khỏi bảng.
Trong trường hợp này, ta sử dụng câu lệnh
SQL DELETE FROM:
VD: tôi muốn xóa khỏi bảng CMXQ_Users tất cả những người có User_Name="CMXQ":
<?
$sql = "DELETE FROM CMXQ_Users WHERE User_Name='CMXQ'";
mysql_query ($sql);
?>
III. Sửa thông tin của bản ghi trong bảng.
Trong trường hợp này, tôi sử dụng cú pháp UPDATE:
VD: Tôi muốn cập nhật địa chỉ IP cho người có User_Name="CMXQ" với địa chỉ IP được lấy từ trình duyệt:
<?
$sql = "UPDATE CMXQ_Users SET User_IP ='" . $_SERVER['REMOTE_ADDR'] . "' Where User_Name='CMXQ'";
mysql_query ($sql);
?>
(
Biến $_SERVER['REMOTE_ADDR'] chứa địa chỉ IP của trình duyệt. Xin xem lại ở bài trước)
Chúng ta đã biết
cách dùng hàm mysql_query() để tiến hành các truy vấn sửa, thêm và xóa.
Bài này tập trung vào việc ứng dụng PHP để lấy thông tin từ CSDL.
Qua những
phần ở trên, chúng ta đã biết cách làm việc với các câu truy vấn SELECT. Bây giờ, kết hợp với hàm mysql_query() để lấy thông tin.
Cú pháp hàm mysql_query như sau:
mysql_query(câu lệnh
sql).
VD: Để lấy tất cả các bản ghi trong bảng "Members", ta sẽ gọi hàm mysql_query() như sau:
<?
mysql_query ("Select * from Members")
?>
Vấn
đề là khi thực hiện truy vấn này, dữ liệu sẽ được trả về dưới dạng một
bảng. Ta sẽ tiến hành lấy từng dòng của bảng đó ra dưới dạng một mảng
(sử dụng hàm mysql_fetch_array()), tiếp đó, việc xử lý các phần tử của
mảng đó như thế nào là tùy ý các bạn.
Xem ví dụ sau:
<?php
$result = mysql_query("SELECT id, name FROM mytable");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
printf ("ID: %s Name: %s", $row["name"]);
}
mysql_free_result($result);
?>
Đoạn
lệnh trên lặp duyệt qua bảng kết quả result, đối với mỗi dòng của bảng,
hàm mysql_fetch_array() sẽ đảm nhiệm việc tách dòng đó rồi đưa vào một
mảng có tên là $row. Mỗi phần tử của mảng này sẽ là giá trị của cột có
tên tương ứng.
Như vậy, trước khi xác định dữ liệu cần lấy là gì, chúng ta phải thiết
kế câu truy vấn SQL sao cho hợp lý và đảm bảo rằng truy vấn đó chỉ lấy
ra những thông tin gì cần sử dụng. Nếu lấy ra nhiều quá sẽ gây quá tải
hệ thống dẫn đến treo máy.
Sau khi đã có được câu truy vấn SQL, ta chỉ việc kết hợp với hàm mysql_query() để trả kết quả về dưới dạng một biến nào đó.
Phần tiếp theo, chúng ta sẽ dùng một hàm có tên là mysql_fetch_array () để lấy từng dòng dữ liệu ra để xử lý.
Hàm mysql_fetch_array có hai tham số:
- Tham số đầu tiên xác định biến nắm giữ kết quả trả về bởi hàm mysql_query()
- Tham số thứ hai xác định kiểu định danh trường:
+ MYSQL_ASSOC: Đưa ra một mảng với chỉ số của mảng là tên trường
+ MYSQL_NUM: Đưa ra một mảng với chỉ số của mảng là số thứ tự của trường được liệt kê trong câu truy vấn SQL
+ MYSQL_BOTH: Đưa ra một mảng với chỉ số kết hợp giữa hai loại trên
Thông thường, ta dùng MYSQL_ASSOC để sử dụng chỉ số bằng tên các trường.
Khi truy vấn CSDL
MySQL, ta có thể sử dụng thêm một số hàm phụ trợ:
mysql_num_rows(biến kết quả): trả về số các dòng lấy được từ biến kết quả.
VD:
<?php
$link = mysql_connect("
localhost", "mysql_user", "mysql_password");
mysql_select_db("database", $link);
$result = mysql_query("SELECT * FROM table1", $link);
$num_rows = mysql_num_rows($result);
echo "Có $num_rows bản ghi được tìm thấy\n";
?>
Tương tự ta có:
mysql_num_fields (biến kết quả): Trả về số trường (cột) trong tập kết quả
mysql_affected_rows (): Trả về số bản ghi bị ảnh hưởng bởi các câu lệnh
SQL INSERT, UPDATE, DELETE.
Ví dụ:
<?php
mysql_pconnect("localhost", "mysql_user", "mysql_password") or
die ("Could not
connect");
mysql_query("DELETE FROM mytable WHERE id < 10");
printf ("Số bản ghi bị xóa: %d\n", mysql_affected_rows());
?>
mysql_data_seek ( nguồn kết quả, dòng cần truy cập):
Hàm này chuyển con trỏ dòng của nguồn kết quả đến một dòng nào đó. Dòng
đầu tiên trong bảng kết quả được đánh số là 0, dòng cuối cùng chính là
mysql_num_rows()-1. Hàm trả về TRUE nếu thành công, ngược lại là FALSE
Chú ý rằng hàm này chỉ sử dụng cùng với hàm mysql_query
Ví dụ:
<?php
$link = mysql_pconnect("localhost", "mysql_user", "mysql_password")
or die("Could not connect");
mysql_select_db("samp_db")
or exit("Could not select database");
$query = "SELECT last_name, first_name FROM friends";
$result = mysql_query($query)
or die("Query failed");
/* fetch rows in reverse order */
for ($i = mysql_num_rows($result) - 1; $i >= 0; $i--) {
if (!mysql_data_seek($result, $i)) {
echo "Cannot seek to row $i\n";
continue;
}
if(!($row = mysql_fetch_object($result)))
continue;
echo "$row->last_name $row->first_name<br />\n";
}
mysql_free_result($result);
?>
Phân trang trong ứng dụng PHP/MySQL
Khi truy vấn dữ liệu mà nhận được một danh sách kết
quả quá dài, người ta thường phải phân trang ứng dụng cho phù hợp (ít
nhất là về mặt thẩm mỹ).
Nguyên tắc của việc phân trang ứng dụng như sau:
- Bước 1: Tính tóan số lượng bản ghi thỏa mãn điều kiện trả về ( thường sử dụng hàm count trong câu lệnh SQL).
- Bước 2: Xác định số lượng bản ghi sẽ hiển thị trên một trang.
- Bước 3: Dựa trên các thông tin có được từ bước 1 và 2, xác định được số trang cần hiển thị.
- Bước 4: Tính tóan số lượng bản ghi sẽ hiển thị tính từ trang nào đó do NSD lựa chọn (Sử dụng câu lệnh LIMIT).
Dưới đây tôi sẽ cung cấp cho các bạn 2 function,
-
Function GetPageLinks ($Sql, $PageSize): Trả về một chuỗi văn bản chứa
số trang hiển thị, với dữ liệu vào bao gồm câu lệnh SQL ($Sql) xác định
số lượng bản ghi thỏa mãn điều kiện tìm kiếm, và "kích thước" của một
trang ($PageSize)
function GetPageLinks($Sql,$PageSize)
{
$result=mysql_query ($Sql);
if (!$result or mysql_num_rows ($result)==0)
{
}
else
{
$line=mysql_fetch_array($result);
$Pages=ceil($line[0]/$PageSize);
if ($Pages>1)
{
$PageLink="Trang ";
for ($i=0;$i<=$Pages-1;$i++)
{
$j=$i+1;
if ($j==$_GET["page"])
{
$PageLink.=" {$j} | ";
}
else
{
$NewGet="";
reset ($_GET);
while (list($key, $val) = each($_GET))
{
if ($key!='page')
{
$NewGet.="&{$key}={$val}";
}
}
$NewGet.="&page={$j}";
$NewGet=substr($NewGet,1);
$PageLink.=" <a href='?{$NewGet}'>{$j}</a> | ";
}
}
$PageLink=substr($PageLink,0,-2);
}
}
return $PageLink;
}
Hàm tiếp theo sẽ hiển thị danh sách các record của một trang nào đó, đồng thời demo cách sử dụng hàm GetPageLinks ở trên:
(VD dưới đây sử dụng một câu truy vấn lấy dữ liệu từ một bảng dulieu với một Category có id xác định:
function LoadList()
{
if (isset($_GET["CatId"]) and is_numeric ($_GET["CatId"]))
$Dieukien="where CatId={$_GET["CatId"]}";
// Cau lenh truy van chinh khi chua phan trang:
$Sql="Select * from dulieu {$Dieukien} ";
// Tinh toan so luong ban ghi tra ve:
$PageSize=20;
$CountSQL="Select count(*) from dulieu {$Dieukien}";
$PageLinks= GetPageLinks ($CountSQL,$PageSize);
if (isset ($_GET["page"]) and is_numeric ($_GET["page"]))
{
$StartNum=$PageSize * ($_GET["page"]-1); // Xac dinh vi tri ban ghi bat dau
}
else
{
$StartNum=0;
}
//Tiep tuc xay dung cau lenh truy van de lay du lieu theo trang
$Sql.= " Limit {$StartNum}, {$PageSize}";
$result=mysql_query ($Sql);
if (!$result or mysql_num_rows ($result)==0)
{
$tmp="Híc, tui chẳng mò được chi cả!";
}
else
{
$tmp="{$PageLinks}";
//========== Hiển thị dữ liệu, các bạn tự viết cho phù hợp với yêu cầu
$tmp.="{$PageLinks}";
}
return $tmp;
}