Trong quá trình phát triển web, một nhu cầu rất thường xuyên nảy ra là việc truyền dữ liệu từ trang web này sang trang web khác. Một cách đã biết là dùng form để submit và truyền data qua phương thức POST hoặc truyền dữ liệu qua URL theo phương thức GET. Trong nhiều trường hợp, cách dùng form hoặc URL gây khá nhiều phiền phức hoặc hầu như không thể thực hiện được.
Chúng ta phải nhớ rằng Web là môi trường không trạng thái (Stateless). Đây là một thuộc tính của Giao thức truyền dữ liệu siêu văn bản. Tính không trạng thái có nghĩa là mọi yêu cầu mới về văn bản của trình duyệt sẽ tạo ra một kết nối mới tới máy chủ Web và kết nối này sẽ bị đóng ngay lập tức sau khi văn bản được trả về. Điều này có nghĩa là máy chủ không thể duy trì thông tin trạng thái của những yêu cầu kế tiếp nhau từ trình duyệt. Máy chủ Web sẽ không biết ai yêu cầu thông tin, cookies và (hoặc) session sẽ giúp chúng ta giữ thông tin người dùng khi họ di chuyển quanh site
Trong PHP cung cấp rất sẵn nhiều hàm và phương tiện để làm việc dễ dàng và hiệu quả với COOKIE và SESSION.
12.2 Cookie
Cookie là 1 đoạn dữ liệu được ghi vào đĩa cứng hoặc bộ nhớ của máy người sử dụng. Nó được trình duyệt gởi ngược lên lại server mỗi khi browser tải 1 trang web từ server.
Những thông tin được lưu trữ trong cookie hoàn toàn phụ thuộc vào website trên server. Mỗi website có thể lưu trữ những thông tin khác nhau trong cookie, ví dụ thời điểm lần cuối ta ghé thăm website, đánh dấu ta đã login hay chưa, v.v...
Cookie được tạo ra bởi website và gởi tới browser, do vậy 2 website khác nhau (cho dù cùng host trên 1 server) sẽ có 2 cookie khác nhau gởi tới browser. Ngoài ra, mỗi browser quản lý và lưu trữ cookie theo cách riêng của mình, cho nên 2 browser cùng truy cập vào 1 website sẽ nhận được 2 cookie khác nhau.
Sử dụng Cookie trong PHP khá đơn giản. Để đặt (set) cookie, ta sử dụng 1 lệnh setcookie(“tên_cookie”, “giá trị”). Và để đọc (get) lại giá trị của cookie, chỉ cần đọc biến thông qua mảng COOKIE như sau $_COOKIE[tên_cookie].
Hàm setcookie phải được gọi trước khi có dữ liệu gửi trả về trình duyệt (do vậy trước thẻ HTML của trang kết quả). Cú pháp của hàm setcookie như sau:
setcookie(name[, value[, time_to_expire[, path[, domain[, security ]]]]]); - name: tên cookie
- value: giá trị cookie, sẽ được lưu trên máy tính người sử dụng
- time_to_expire:Thời gian cookie hết hiệu lực. Giá trị là một số nguyên là tổng số giây tính từ 1/1/1970.
- Domain: miền mà cookie có hiệu lực
- security: có giá trị 0, 1. Có giá trị 1, cookie sẽ được xác lập nếu có kết nối an toàn. Mặc định là 0.
Ví dụ 1
setcookie(“mycookie”, “my_id”, time()+ (60*60*24*30),”/”,”.mydomain.com”,0); Cookie này thiết lập những tham số như sau:
- Lưu trữ tên biến có tên là mycookie. - Giá trị của biến là my_id.
- cookie có giá trị 30 ngày kể từ ngày thiết lập. - cookie có hiệu lực trong mọi trang của domain.
- Nó có hiệu lực trong mọi chỗ của tền miền mydomain.com - Không có thiết lập an toàn đặc biệt
Ví dụ 2: Khởi tạo cookie ở trang page1.php khi người sử dụng truy cập vào và hiển thị giá trị cookie khi người sử dụng duyệt trang page2.php:
Trang page1.php <?php $t = time(); setcookie(“time_save”, $t); ?> <html> <head><title>Example Cookie</title></head>
<body>Giá trị của cookie đã được gán giá trị <?php echo $t; ?>. Click <a href="page2.php">vào đây</a> để kiểm tra.</body>
</html>
Trang page2.php
<html>
<head><title>Show cookie</title></head> <body>
Giá trị của Cookie được gán trong <a href="page1.php">page1.php</a>: <?php
echo $_COOKIE[“abc”]; ?>.
</body> </html>
Đầu tiên, dùng browser truy cập vào file page1.php, cookie tự động được lưu vào đĩa của người sử dụng (nếu được phép). Khi link trang page2.php, giá trị này được gửi lên server, trang page2.php có thể truy cập và hiển thị.
Tên của cookie cũng có thể xác lập thành tên mảng và ta có thể sử dụng vòng lặp để duyệt qua.
Tuy nhiên, vì cookie thường tiềm ẩn nhiều rủi ro, vì vậy một số người sử dụng thường tắt không cho các website lưu các thông tin này trên đĩa. Do đó việc sử dụng cookie bị hạn chế. 12.3 Session
Một cách khác quản lý người sử dụng là session. Session được hiểu là khoảng thời gian người sử dụng giao tiếp với 1 ứng dụng. Một session được bắt đầu khi người sử dụng truy cập vào ứng dụng lần đầu tiên, và kết thúc khi người sử dụng thoát khỏi ứng dụng. Mỗi session sẽ có được cấp một định danh (ID) khác nhau và nội dung được lưu trong thư mục thiết lập trong file php.ini (tham số session.save_path).
Trong PHP, session được xem như một điều khiển phía server để lưu trữ và quản lý phiên làm việc. Để làm được điều này, khi một người sử dụng truy cập vào một website, webserver cung cấp cho người sử dụng một xâu giá trị là SessionID gọi là xâu định danh- ví dụ 9b02405434373d6d96c8db11ed819a60. Gía trị xâu này một giá trị ngẫu nhiên và nó được gửi tới máy người sử dụng thông qua cookie có tên PHPSESSID. Giá trị này tồn tại cho đến khi nào chu kỳ sống của session kết thúc hoặc người sử dụng di chuyển tới website khác. Chu kỳ sống của session do webserver qui định. Ta có thể điều chỉnh chu kỳ này khi cấu hình webserver.
Bên phía server, một tập tin có tên tương ứng PHPSESSID cũng được tạo ra. Các biến session sẽ được lưu trong một tập tin văn bản này và ở tại vị trí được qui định trong file php.ini ở dòng session.save_path. Ví dụ nội dung dòng trong file php.ini là:session.save_path = D:\PHP\sessiondata, khi đó các file lưu trữ biến session sẽ ở thư mục D:\PHP\sessiondata. Ta có thể sử dụng notepad để mở file và kiểm tra điều này.
Ví dụ: file session1.php có nội dung:
<?
//Khởi tạo session session_start();
//Nhận giá trị PHPSESSID mà server cung cấp $filename = session_id();
//Lưu giá trị cho 2 biến session UserName và Email $_SESSION["UserName"] = "Thanh";
$_SESSION["Email"] = "thanh@yahoo.com";
echo "File session luu trong " .session_save_path() ." co ten la " . $filename; echo "<br>Noi dung:<br>UserName:" .$_SESSION["UserName"] ;
echo "<br>Email:" .$_SESSION["Email"]; ?>
Khi duyệt, ta có thể thấy nội dung được hiển thị trên trình duyệt như sau: File session luu trong D:\PHP\sessiondata co ten la
b5f0f01a37494e0e56a8a6b198047294 Noi dung:
UserName:Thanh
Vào thư mục D:\PHP\sessiondata và mở file b5f0f01a37494e0e56a8a6b198047294 bằng notepad, ta thấy nội dung của nó như sau:
UserName|s:5:"Thanh";
Email|s:15:"thanh@yahoo.com";
Đây chính là tên (UserName), kiểu (S-string), độ dài (5) và nội dung của các biến session lưu trữ trên server. Các biến phân cách nhau bằng dấu chấm phẩy.
Để sử dụng Session trong PHP, đầu tiên cần khởi tạo Session. Session được khởi tạo bằng cách gọi hàm session_start() hoặc tự động. Trong file php.ini, nếu giá trị session.auto_start = 1 (giá trị mặc định khi cài đặt là session.auto_start = 0), session sẽ được khởi động tự động. Do vậy ta không cần thiết dùng hàm session_start(). Trong trường hợp cần gọi hàm session_start(), hàm này phải được gọi trước bất cứ hàm nào của session và trước đó chưa có thông tin nào được gửi về bộ đệm đưa thông tin về trình duyệt.
Việc truy cập thông tin (nhận, gán) session rất đơn giản: Đặt giá trị cho session chỉ là lệnh gán $_SESSION[tên_session] = giá_trị; và để đọc session, chỉ cần đọc giá trị của biến $_SESSION[tên_session]. Các biến session này sẽ có giá trị toàn cục với tất cả các trang trong cùng session. Ta cũng có thể lấy giá trị duy nhất cấp cho một session bằng hàm session_id() như trong ví dụ trên.
Khi không sử dụng một biến session nào nữa, ta huỷ chúng đi bằng hàm unset($_SESSION[“biến”]). Khi đó sử dụng hàm isset để kiểm tra biến này sẽ nhận được kết quả là false. Cũng có thể sử dụng hàm session_unset() để huỷ toàn bộ các biến session đã tạo. Do tất cả các biến session được lưu trong mảng $_SESSION, do vậy ta có thể sử dụng vòng lặp để duyệt qua tất cả các biến session như trong ví dụ sau.
Ví dụ gồm 3 trang session2.php, session3.php, session4.php. Mỗi trang có các chức năng khởi tạo, huỷ bỏ và hiển thị một số biến session. Mỗi trang cũng có những liên kết tới trang kia để chạy thử. Trang session2.php <? session_start(); if (!isset($_SESSION["sess1"])) $_SESSION["sess1"] =1; else $_SESSION["sess1"]++; if (!isset($_SESSION["userID"])) { $_SESSION["userID"] ="thanh"; $_SESSION["Email"] ="thanh@company.com"; }
echo "Danh sach cac bien da tao:"; while ($svar = each ($_SESSION)) {
echo "<br> ". $svar["key"] ."=" . $svar["value"]; }
?> <body> <hr>
<a href="session3.php"> Trang session 3 (Huy bien sess1)</a><br> <a href="session4.php"> Trang session 4 (Huy)</a><br>
</body>
Trang session3.php <?
session_start();
unset($_SESSION["sess1"]); echo "Danh sach cac bien da tao:"; while ($svar = each ($_SESSION)) {
echo "<br> ". $svar["key"] ."=" . $svar["value"]; }
?> <body> <hr>
<a href="session2.php"> Trang session 2 (Hien thi)</a><br> <a href="session4.php"> Trang session 4 (Huy tat ca)</a><br> </body> Trang session4.php <? session_start(); session_unset();
echo "Danh sach cac bien da tao:"; while ($svar = each ($_SESSION)) {
echo "<br> ". $svar["key"] ."=" . $svar["value"]; }
?> <body> <hr>
<a href="session2.php"> Trang session 2 (hien thi)</a><br>
<a href="session3.php"> Trang session 3 (Huy bien sess1)</a><br> </body>
12.4 Sử Dụng Session Như Cơ Chế Chứng Thực Người Dùng
Trong hầu hết các ứng dụng web, đều được chia làm hai phần chính:
- Phần dành cho người sử dụng là khách hàng: Cho phép người sử dụng Internet có thể liệt kê tìm kiếm, sắp xếp thông tin, …
- Phần dành cho người sử dụng là người quản trị: cho phép người quản trị, xử lý điều khiển hay quản lý các nghiệp vụ cũng như chức năng khác của ứng dụng.
Phần này sẽ mô tả các chức năng thường hay sử dụng trong các website thương mại điện tử. Phần dành cho người quản trị là phần quản lý của các doanh nghiệp quản lý ứng dụng, nó thường bao gồm các chức năng chính như sau:
Quản lý danh mục: Cho phép cập nhật các danh mục trong CSDL: thêm, sửa, xoá các mẩu tin của các bảng dữ liệu dạng danh mục như: loaihang, mathang, …
Quản trị user: Cho phép phân quyền với người dùng trong ứng dụng. Các quyền của người dùng thường là Read, Wite hay Full. Với quyền Read, người dùng chỉ được phép xem mà không được cập nhật dữ liệu. Với quyền Write, người dùng có thề cập nhật dữ liệu. Với quyền Full, người dùng có thể xem, cập nhật dữ liệu và thay đổi các quyền sử dụng của các người sử dụng khác.
Quản lý khách hàng: Cho phép theo dõi quá trình đặt hàng của khách hàng cho đến khi kết thúc hợp đồng.
Nhân viên kinh doanh: Quản lý các hợp đồng, thanh toán, phân công giao hàng cho nhân viên giao nhận. Quản lý các hợp đồng mới đặt hàng, hợp đồng đã thanh toán, hợp đồng chưa thanh toán, hợp đồng đã giao hàng, hợp đồng cần huỷ bỏ, …
Báo cáo: Thống kê báo cáo các doanh số bán hàng, thanh toán, biểu đồ doanh thu và các báo cáo phục vụ cho quá trình kinh doanh khác…
Để phân biệt được các đối tượng quản trị này, mỗi người quản trị sẽ thường được cung cấp một thông tin để kiểm soát. Thông tin này được lưu trong một bảng (ví dụ bảng admin) Admin(userid, pass, permission). Khi đăng nhập vào những trang của quản trị, chương trình sẽ chạy một đoạn mã đòi hỏi nhập và kiểm tra thông tin xem đây có phải là một người quản trị hay không, và người quản trị này có được quyền thao tác với trang này hay không. Nếu không đúng, chương trình sẽ chuyển tới trang để có thể đăng nhập lại hay tới trang báo lỗi. Trong phần này sẽ giới thiệu chung các công việc quản lý của người có quyền Full. Nghĩa là ta không phân chia các quyền riêng biệt. Mỗi người sử dụng trong bảng admin đều có quyền như nhau. Khi xây dựng một ứng dụng cụ thể, ta chỉ cần kiểm tra thêm xem user này có quyền gì? Quyền này có được phép thao tác trong trang này hay không, để có thể cho phép thực thi các đoạn mã của trang hay chuyển tới trang báo lỗi.
12.4.1 Qui Trình Đăng Nhập
Một người khi vào các trang admin của ứng dụng web, đều phải qua quá trình kiểm tra gọi là đăng nhập. Sau khi đã đăng nhập, chương trình sẽ lưu thông tin để chứng thực sự đăng nhập này khi người sử dụng di chuyển sang các trang khác nhau trong website. Để xác định được người sử dụng đã đăng nhập hay chưa, ta có thể sử dụng đối tượng Session đã giới thiệu ở phần trước.
- Khi vào một trang của phần quản trị, người dùng phải đăng nhập thông tin qua một form có hai field nhập: user và password và được gửi đến trang kiểm tra.
- Thông tin này được kiểm tra để so sánh với dữ liệu trong bảng admin. Nếu đúng, quá trình đăng nhập được ghi nhận và sẽ chuyển tới một trang quản trị mặc định hay một trang nào được yêu cầu.
- Trong mỗi trang phần quản trị, đều có chức năng thoát ra ngoài. Nếu người sử dụng chọn chức năng này, chương trình sẽ huỷ hết các thông tin của người quản trị này (trang logout.php) và chuyển tới trang login để đăng nhập lại.
- Trường hợp nếu người sử dụng gõ trực tiếp vào trang của người quản trị mà không đăng nhập qua trang login, các trang này sẽ có các đoạn mã để kiểm tra là người dùng đã qua trang login chưa, nếu chưa, sẽ chuyển trang quay lại trang login để nhập user và password và đăng nhập lại.
12.4.2 Biến Quản Lý Và Mã Đăng Nhập
Để có thể quản lý tốt phần admin, ta sẽ sử dụng các biến session để lưu trữ và cập nhật thông tin người sử dụng. Các biến session sử dụng trong phần này là:
- sUserID: Quản lý và kiểm soát người sử dụng.
- sMess: Quản lý các thông báo thích hợp cho người sử dụng. - sFilePath: Quản lý đường dẫn tới file mà người sử dụng cần.
- sLogin: Quản lý xem người sử dụng đã vào một trang qua form login hay chưa. Để quản lý, ta xây dựng các trang sau:
- Trang login.php chứa một form gồm hai phần nhập liệu userID và Password. Các thông tin này khi form submit sẽ được đưa tới trang login_authentication.php.
- Trang login_authentication.php sẽ tạo các câu truy vấn và kiểm tra trong CSDL. Nếu đúng, sẽ đưa người sử dụng tới các trang thích hợp. Mặc định là trang admin.php (đây là trang chứa các liên kết đến các danh mục của người quản trị). Nếu sai, quay lại trang login.php và hiền thị các câu thông báo thích hợp. Như vậy, khi nào vào các trang của admin, người sử dụng đều phải qua bước kiểm tra để chứng minh mình được phép vào các trang xác định. Sau đây là mã cho hai trang này.
- Để chuyển người sử dụng tới một trang khác, ta sử dụng hàm header("Location: $url"). Trong đó $url là địa chỉ trang cần chuyển đến. Hàm này cũng như
session_start(), nó không gây lỗi khi được gọi trước bất cứ thông tin xuất dữ liệu về trình duyệt. Trang login.php <?php session_start(); if (!isset($_SESSION["sMess"])) {
$sMess =" Nhap vao day du User va Password."; $txtUID = ""; } else { $sMess = $_SESSION["sMess"]; $txtUID = $_SESSION["sUserID"]; } if (!isset($_SESSION["sFilePath"])) { $_SESSION["sFilePath"] = "admin.php"; } ?> <center>
Ban se toi file:<?=$_SESSION["sFilePath"]?> sau khi login <hr> Hay nhap vao day du thong tin de vao cac trang admin.<hr>
<form name="frmLogin" method="POST" action="login_authentication.php"> <table border=1>
<tr>
<td align="center" colspan=2><b><?=$sMess?></b></td></tr> <tr><td align="left">User:</td>
<td align="left">
<input type="text" name="txtUser" size="25" maxlength="100" value="<? =$txtUID?>" >
</td></tr>
<tr><td align="left" >Password:</td> <td align="left">
<input type="password" name="txtPWD" size="25" maxlength="8" Value=""> </td> </tr>
<tr><td align="left" colspan=2>
<input type="submit" name="Signin" value="Sign me in!" > <input type="reset" name="Reset" value="Reset">
</td> </tr> </table> </form> </center> </body> </html>
Hình sau hiển thị form và thông báo (sMess) khi người sử dụng nhập vào thông tin User bị sai.
Trang login_authentication.php <?php
/*
Input: User và password (được gửi từ login.php). Output: Return - 1: Không có user này trong csdl
- 2: Có user này nhưng password sai.
- 3: Thông tin nhập vào đúng (trùng user and password */
function CheckUser($UserID, $Password) {
include ("Includes/conn.inc");
$sql = "Select * from admin where userID= '$UserID' "; $result = mysql_query($sql, $conn);
//Return 1 if have no this userID if (mysql_num_rows($result) == 0) return 1;
else {
$row = mysql_fetch_array($result);
//Return 2: if have userID but password is wrong.
//Return 3: if userID, password input are the same userID, password in the table admin if ($Password !== $row["pass"]) return 2; else return 3; } }
session_start();