Basic Từng bước học lập trình PHP cơ bản qua dự án website giới thiệu sản phẩm

Language
Tiếng Việt
Hôm nay tôi sẽ bắt đầu viết loạt bài hướng dẫn các bạn học lập trình PHP cơ bản thông qua việc hoàn thành dự án website giới thiệu sản phẩm.

Những nội dung tôi sẽ hướng dẫn các bạn bao gồm:
  • Cài đặt và sử dụng web server.
  • Xây dựng cấu trúc thư mục website.
  • Xây dựng cấu trúc cơ sở dữ liệu (Còn gọi là database và viết tắt là DB).
  • Sử dụng phpMyAdmin để quản lý cơ sở dữ liệu.
  • Từng bước hoàn thành dự án website giới thiệu sản phẩm (Trang quản trị và trang người dùng) và qua đó các bạn sẽ được học các vấn đề liên quan tới lập trình PHP (Câu lệnh, biến, kiểu dữ liệu, toán tử, điều kiện, vòng lặp, hàm, MySQL và các vấn đề khác).
Các bạn lưu ý, với bài hướng dẫn này tôi chỉ hướng tới các bạn mới bắt đầu tìm hiểu về lập trình PHP ở mức cơ bản nhất chứ tôi không đi sâu vào các vấn đề nâng cao của PHP.

Chân thành cảm ơn sự quan tâm của các bạn!
 
PHẦN 1: WEB SERVER

Để ứng dụng web có thể chạy được trên trình duyệt web các bạn cần phải cài đặt một số thành phần sau:
  • PHP: Trình biên dịch các tập tin PHP do các bạn viết.
  • MySQL: Hệ quản trị cơ sở dữ liệu để lưu trữ dữ liệu website.
  • Apache: Chương trình máy chủ HTTP giúp website hoạt động.
Tất cả các thành phần trên là yêu cầu tối thiểu để website hoạt động. Hiện nay, trên Internet các thành phần trên đã được đóng gói thành một phần mềm duy nhất như: WampServer, Xampp, AppServ, MAMP...

Đối với tôi, tôi sử dụng WampServer để phát triển ứng dụng web trên máy tính (Tạm gọi là máy local). Và lưu ý là WampServer chỉ hỗ trợ cho hệ điều hành Windows, nếu các bạn sử dụng hệ điều hành macOS thì có thể dùng MAMP để làm web server.

Để cài đặt WampServer các bạn thực hiện theo các bước sau:
  1. Tải WampServer tại http://www.wampserver.com/en/#download-wrapper (Tùy theo phiên bản hệ điều hành 32 bits hay 64 bits).
  2. Chạy tập tin EXE các bạn tải về được để tiến hành cài đặt. Trong quá trình cài đặt WampServer các bạn giữ nguyên các thông số mặc định.
Sau khi cài đặt xong, các bạn sẽ thấy một biểu tượng chương trình "start WampServer" trong Start menu. Khi chạy chương trình WampServer các bạn sẽ thấy một biểu tượng ở khay hệ thống. Biểu tượng này có ba trạng thái tương ứng với ba màu như sau:
  • Màu đỏ: Chương trình mới khởi động và chưa có thành phần nào được khởi động.
  • Màu vàng: Có một hoặc nhiều thành phần chưa được khởi động.
  • Màu xanh: Tất cả các thành phần đã được khởi động. Trạng thái này các bạn mới có thể sử dụng WampServer.
Sau khi cài đặt WampServer, các bạn sẽ thấy một thư mục quan trọng C:\wamp\www (Sau này gọi là thư mục www hoặc thư mục web root). Đây là thư mục chứa các tập tin của website (PHP, HTML, CSS, JS, hình ảnh...). Phải đảm bảo 100% các tập tin của ứng dụng web nằm trong thư mục www.

Bây giờ để kiểm tra xem WampServer có hoạt động không các bạn mở trình duyệt web (Firefox, Chrome, IE...) lên và truy cập địa chỉ localhost (Đối với Windows 8 thì truy cập 127.0.0.1). Nếu các bạn thấy trang giao diện của WampServer thì tức là WampServer đã hoạt động tốt và các bạn có thể bắt đầu sử dụng WampServer để lập trình ứng dụng web của mình.

Để thuận tiện sau này, các bạn vào thư mục www xóa tất cả các tập tin trong thư mục này (Thường chỉ có tập tin index.php). Lưu ý, sau khi xóa tất cả các tập tin trong thư mục www thì khi truy cập localhost các bạn sẽ không còn thấy trang giao diện WampServer nữa.
 
PHẦN 2: CẤU TRÚC THƯ MỤC WEB

Trong ứng dụng web, việc bố trí cấu trúc thư mục web phần nào ảnh hưởng tới quá trình viết mã lệnh ứng dụng. Để cho cấu trúc thư mục web được rõ ràng, tường minh và quan trọng đó là khả năng mở rộng ứng dụng mà không làm thay đổi cấu trúc ban đầu thì các bạn cần phải xây dựng cho ứng dụng của mình một cấu trúc tốt trước khi bắt đầu viết mã lệnh đầu tiên.

Mỗi phong cách viết khác nhau có thể các bạn sẽ có những cấu trúc khác nhau. Vì vậy, tôi cũng không yêu cầu các bạn tuân theo cấu trúc của tôi đưa ra nhưng để tiện lợi trong quá trình theo dõi loạt bài viết này thì các bạn nên bố trí cấu trúc thư mục web như của tôi cho thuận tiện.

Cấu trúc thư mục web mà tôi đề nghị như sau:
admin
configs
extends
libraries
models
views
-----admin
-----front
templates
-----admin
-----front
userfiles
Trong đó:
  • admin: Chứa các tập tin xử lý của trang quản trị.
  • configs: Chứa các tập tin cấu hình website.
  • extends: Chứa các thành phần mở rộng (Bộ soạn thảo...).
  • libraries: Chứa thư viện cần thiết để lập trình.
  • models: Chứa các tập tin xử lý tương tác với DB (Lấy dữ liệu, thêm mới, chỉnh sửa, xóa...).
  • views: Chứa các tập tin giao diện HTML của website. Tôi chia thành hai nhóm là admin (Trang quản trị) và front (Trang người dùng).
  • templates: Chứa các tập tin CSS, JS, hình ảnh... Tôi cũng chia làm hai nhóm là admin và front.
  • userfiles: Chứa các tập tin do người dùng tải lên.
Mỗi trang của ứng dụng web tôi đã chia thành ba phần như sau:
  • Trang xử lý: Chứa mã lệnh PHP xử lý các yêu cầu từ người dùng và trả kết quả lại cho người dùng.
  • Model: Thành phần tương tác trực tiếp với DB. Mỗi bảng dữ liệu trong DB tôi sẽ có một tập tin tương ứng trùng tên với bảng dữ liệu đó và đặt trong thư mục models để dễ kiểm soát.
  • View: Thành phần giao diện HTML của website. Thành phần này sẽ nhận kết quả trả lại từ trang xử lý để trình bày dữ liệu đó theo giao diện HTML đã thiết kế.
Với cấu trúc như trên, tôi đã tách tối đa phần mã lệnh PHP với mã lệnh HTML để giúp mã lệnh web trở nên trong sáng hơn, dễ bảo trì, nâng cấp hơn.
 
PHẦN 3: CẤU TRÚC CƠ SỞ DỮ LIỆU

Dự án web mà tôi hướng dẫn để làm ví dụ cho các bạn học lập trình PHP cơ bản được thiết kế gồm các thành phần sau:

Phần quản trị (Tôi gọi là admin):
  • Đăng nhập, đăng xuất.
  • Quản lý thành viên (Danh sách, thêm mới, chỉnh sửa, xóa).
  • Quản lý danh mục sản phẩm (Danh sách, thêm mới, chỉnh sửa, xóa).
  • Quản lý sản phẩm (Danh sách, thêm mới, chỉnh sửa, xóa).
Phần người dùng (Tôi gọi là front):
  • Trang chủ (Hiển thị những sản phẩm mới nhất).
  • Trang danh sách sản phẩm (Danh sách tất cả sản phẩm, danh sách các sản phẩm theo danh mục).
  • Trang chi tiết sản phẩm.
  • Và một số thành phần phụ trên website (Danh mục).
Với website được thiết kế như trên, cấu trúc DB tôi sẽ thiết kế đơn giản như sau:

Bảng thành viên (Đặt tên là tbl_user):
  • user_id: Khóa chính, tăng tự động (Kiểu int, độ dài 11).
  • username: Tài khoản (Kiểu varchar, độ dài 32).
  • password: Mật khẩu (Kiểu varchar, độ dài 32).
  • fullname: Họ tên (Kiểu varchar, độ dài 100).
  • email: Email (Kiểu varchar, độ dài 100).
  • status: Trạng thái (Kiểu tinyint, độ dài 1).
  • created: Ngày giờ thêm mới (Kiểu datetime).
  • modified: Ngày giờ chỉnh sửa sau cùng (Kiểu datetime).
Bảng danh mục sản phẩm (Đặt tên là tbl_category):
  • category_id: Khóa chính, tăng tự động (Kiểu int, độ dài 11).
  • name: Tên danh mục (Kiểu varchar, độ dài 255).
  • status: Trạng thái (Kiểu tinyint, độ dài 1).
  • created: Ngày giờ thêm mới (Kiểu datetime).
  • modified: Ngày giờ chỉnh sửa sau cùng (Kiểu datetime).
Bảng sản phẩm (Đặt tên là tbl_product):
  • product_id: Khóa chính, tăng tự động (Kiểu int, độ dài 11).
  • category_id: ID danh mục (Kiểu int, độ dài 11).
  • name: Tên sản phẩm (Kiểu varchar, độ dài 255).
  • price: Giá bán (Kiểu float, độ dài 10,0).
  • detail: Chi tiết (Kiểu text).
  • image: Hình ảnh (Kiểu varchar, độ dài 255).
  • status: Trạng thái (Kiểu tinyint, độ dài 1).
  • created: Ngày giờ thêm mới (Kiểu datetime).
  • modified: Ngày giờ chỉnh sửa sau cùng (Kiểu datetime).
Nếu các bạn muốn thêm thông tin lưu trữ trong DB thì các bạn có thể tự thêm vào và tôi sẽ hỗ trợ các bạn.
 
PHẦN 4: QUẢN LÝ CƠ SỞ DỮ LIỆU VỚI PHPMYADMIN

Để quản lý DB (Tạo mới, chỉnh sửa, xóa...) tôi thường sử dụng một ứng dụng mã nguồn mở có tên phpMyAdmin. Trong bộ cài đặt WampServer thì phpMyAdmin đã được tích hợp sẵn. Để sử dụng phpMyAdmin quản lý DB, các bạn thực hiện theo một số hướng dẫn sau (Tôi sử dụng phiên bản phpMyAdmin 4.7.3):

Truy cập phpMyAdmin tích hợp sẵn trong WampServer:
  1. Khởi động WampServer.
  2. Mở trình duyệt web và truy cập địa chỉ http://localhost/phpmyadmin. Nếu xuất hiện giao diện phpMyAdmin trên trình duyệt thì bạn đã truy cập thành công ứng dụng phpMyAdmin.
Tạo mới, xóa DB:
  • Tạo mới:
    1. Nhấp tab "Databases" để mở giao diện tạo mới DB.
    2. Ở khu vực "Create database" nhập tên DB ở trường "Database name", chọn collation ở danh sách "Collation" (Thường thì chọn là "utf8mb4_general_ci").
    3. Nhấp nút "Create" để tạo mới DB.
    4. DB được tạo mới sẽ xuất hiện trong danh sách ở khung bên trái.
  • Xóa:
    1. Tại giao diện danh sách các DB, chọn các DB cần xóa.
    2. Nhấp chọn "Drop" để xóa các DB đã được chọn.
Tạo mới, chỉnh sửa, xóa bảng dữ liệu, trường dữ liệu trong DB:
  • Tạo mới:
    1. Chọn DB cần tương tác bằng cách nhấp vào tên DB trong danh sách ở khung bên trái.
    2. Tại tab "Structure", ở khu vực "Create table" các bạn nhập tên bảng dữ liệu vào trường "Name", số lượng các trường dữ liệu của bảng ở trường "Number of columns".
    3. Nhấp nút "Go".
    4. Ở giao diện khai báo thông tin các trường dữ liệu của bảng, các bạn khai báo các thông tin như tên trường dữ liệu (Cột "Name"), kiểu dữ liệu (Cột "Type"), độ dài (Cột "Length/Values"), chọn khóa chính (Cột "Index", chọn "PRIMARY"), tăng tự động (Check chọn cột "A_I").
    5. Nhấp nút "Save" để tạo bảng dữ liệu với các trường dữ liệu đã khai báo.
  • Chỉnh sửa, xóa bảng dữ liệu, trường dữ liệu:
    1. Để chỉnh sửa bảng dữ liệu bạn nhấp vào "Structure" của bảng dữ liệu đó rồi vào tab "Operations" để chỉnh sửa.
    2. Để xóa bảng dữ liệu bạn chỉ cần chọn bảng dữ liệu cần xóa và chọn "Drop" ở danh sách "With selected".
    3. Để chỉnh sửa hoặc xóa trường dữ liệu của bảng, bạn cũng vào "Structure" của bảng dữ liệu đó vào lựa chọn các tác vụ chỉnh sửa hoặc xóa trường dữ liệu bạn muốn.
Để tìm hiểu chi tiết hơn về cách sử dụng phpMyAdmin, các bạn có thể xem thêm tại địa chỉ https://docs.phpmyadmin.net/en/latest.
 
PHẦN 5: THÔNG TIN CẤU HÌNH WEBSITE

Kể từ phần này tôi bắt đầu hướng dẫn các bạn từng bước hoàn thành dự án website giới thiệu sản phẩm và qua đó tôi sẽ hướng dẫn các bạn nắm rõ các kiến thức về lập trình PHP cơ bản.

Một điều quan trọng tôi cần lưu ý với các bạn là trong quá trình lập trình thì tôi sẽ đưa ra nhiều khối lệnh và tôi sẽ lựa chọn ra một số kiến thức trong khối lệnh đó để trình bày, giải thích cho các bạn nắm kiến thức lập trình PHP. Những kiến thức mới nhưng tôi không hướng dẫn, giải thích là do những kiến thức đó chưa tới lúc phải truyền đạt cho các bạn biết và mặc nhiên các bạn chấp nhận viết mã lệnh giống như tôi đưa ra. Tất nhiên những kiến thức mới đó tôi sẽ trình bày, giải thích cho các bạn ở những phần sau.

Những kiến thức tôi đề cập trong phần này bao gồm:
  • Tập tin PHP.
  • Câu lệnh PHP.
  • Hằng.
  • Ghi chú.
Và để bắt đầu lập trình website các bạn cần khai báo thông tin cấu hình website (Thông tin cấu hình DB và một số thông tin cần thiết khác). Các thông tin cấu hình được khai báo trong tập tin PHP cấu hình (Tôi gọi là tập tin config.php) đặt trong thư mục configs của web.

Nội dung tập tin configs/config.php như sau:
PHP:
<?php
//Thông tin website
define('SITE_URL', 'http://localhost/');

//Thông tin cấu hình DB
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'training_php_01');
?>
1. Tập tin PHP:

Để viết lệnh PHP các bạn cần phải viết mã lệnh PHP trong tập tin có phần mở rộng là ".php". Ví dụ như tập tin config.php tôi vừa tạo.

Lưu ý khi các bạn đặt tên tập tin cần tuân thủ theo quy tắc sau:
  • Tên tập tin đồng nhất Tiếng Việt không dấu hoặc Tiếng Anh.
  • Chỉ sử dụng các số từ 0 đến 9, từ a đến z (Không phân biệt hoa, thường), dấu gạch dưới "_", dấu gạch giữa "-". Như vậy, khoảng trắng không được phép dùng để đặt tên tập tin.
2. Câu lệnh PHP:

Trong khối lệnh trên, toàn bộ các câu lệnh PHP đều được đặt trong cặp ký hiệu bắt đầu là "<?php" và kết thúc là ký hiệu "?>". Cặp ký hiệu này để khai báo cho trình PHP biết để biên dịch các câu lệnh bên trong.

Mỗi câu lệnh được viết trên một dòng và kết thúc câu lệnh là dấu chấm phẩy ";".

3. Hằng:

Ở đây, tôi đã khai báo 5 hằng sau:
  • SITE_URL: Địa chỉ liên kết tuyệt đối tới website.
  • DB_SERVER: Tên server chạy DB (Mặc định là localhost).
  • DB_USERNAME: Tài khoản kết nối DB (Đối với ứng dụng WampServer thì tài khoản này mặc định là root).
  • DB_PASSWORD: Mật khẩu kết nối DB (Đối với ứng dụng WampServer thì mật khẩu mặc định là rỗng).
  • DB_DATABASE: Tên DB mà các bạn khởi tạo (Tôi đặt tên là "training_php_01").
Như vậy, để định nghĩa một hằng các bạn sử dụng hàm define (Hàm là gì tôi sẽ giải thích ở những phần sau). Hàm define có hai tham số (Tham số cũng sẽ được giải thích ở những phần sau):
  • Tham số đầu tiên là tên hằng (Ví dụ SITE_URL, DB_SERVER...) được viết toàn bộ bằng chữ in hoa.
  • Tham số thứ hai là giá trị của hằng (Ví dụ localhost...).
Khi định nghĩa hằng, các bạn lưu ý là không thể định nghĩa một hằng hai lần (Tức hằng là duy nhất).

Để sử dụng hằng đã được định nghĩa, các bạn chỉ việc gọi tên là được (Ví dụ là SITE_URL, DB_SERVER...).

4. Ghi chú:

Trong đoạn lệnh trên, các bạn còn thấy hai dòng bắt đầu bằng dấu "//". Đây là hai dòng ghi chú giúp nhắc nhở cho người lập trình ghi nhớ chứ trình PHP không biên dịch hai dòng này và hai dòng này cũng không ảnh hưởng hay gây ra lỗi gì cho khối lệnh PHP.

Để ghi chú các bạn có nhiều cách như sau:
  • Để ghi chú trên một dòng, các bạn sử dụng ký hiệu "//".
  • Để ghi chú trên nhiều dòng, các bạn sử dụng ký hiệu "/**/".
Ví dụ:
Code:
//Ghi chú một dòng
/*
Ghi chú dòng 1
Ghi chú dòng 2
*/
Qua bài này, hi vọng các bạn nắm được những câu lệnh PHP đầu tiên.
 
PHẦN 6: KẾT NỐI CƠ SỞ DỮ LIỆU

Nội dung kiến thức phần này gồm:
  • Liên kết tập tin (Require, include).
  • Biến (Variable).
  • Kiểu dữ liệu (Type).
Website giới thiệu sản phẩm là một website động (Có lưu trữ dữ liệu trong DB) nên để PHP có thể kết nối, tương tác với DB (Ở đây là MySQL) thì PHP đã cũng cấp sẳn các hàm để làm việc đó.

Bây giờ, các bạn tạo một tập tin dùng để viết mã lệnh PHP kết nối tới DB (Tôi gọi là tập tin connect.php) trong thư mục libraries.

Nội dung tập tin libraries/connect.php như sau:
PHP:
<?php
//Require
require 'configs/config.php';

//Kết nối
$connect = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE) or die('Not connected DB!');

//Yêu cầu lưu trữ UTF8 (Tiếng Việt)
mysqli_query('SET NAMES UTF8', $connect);
?>
Khối lệnh trên dùng để thực hiện kết nối với MySQL bằng thư viện MySQLi. Trong đó:
  • Hàm mysqli_connect dùng để kết nối tới DB với 4 tham số lần lượt là tên máy chủ chứa DB (Đã khai báo ở hằng DB_SERVER), tài khoản kết nối DB (Đã khai báo ở hằng DB_USERNAME), mật khẩu kết nối DB (Đã khai báo ở hằng DB_PASSWORD) và tên DB (Đã khai báo ở hằng DB_DATABASE). Nếu kết nối thành công thì PHP sẽ tiếp tục thực hiện các câu lệnh bên dưới, ngược lại nếu kết nối không thành công (Có thể thông tin khai báo bị sai) thì phần lệnh phía sau "die('Not connected DB!')" sẽ được thực thi in ra màn hình câu "Not connected DB!" và PHP sẽ dừng lại tại đây (Tức những câu lệnh bên dưới sẽ không được thực thi). Nếu kết nối thành công thì hàm mysqli_connect sẽ trả về dữ liệu kết nối và gán vào biến $connect.
  • Hàm mysqli_query dùng để truy vấn câu lệnh SQL "SET NAMES UTF8" với mục đích yêu cầu MySQL lưu trữ dữ liệu theo kiểu UTF8 (Tức là lưu được tiếng Việt).
1. Liên kết tập tin (Require, include):

Phần trước, tôi có tạo một tập tin configs/config.php để khai báo các thông tin cấu hình website. Ở tập tin libraries/connect.php này tôi cần sử dụng các thông tin đó dưới dạng các hằng đã được khai báo. Vì vậy, tôi cần liên kết với tập tin configs/config.php đã tạo bằng lệnh require như trên.

Vậy, lệnh require các bạn có thể hiểu là dùng để liên kết một tập tin PHP đã tồn tại vào một tập tin PHP khác (Hoặc cũng có thể hiểu là với câu lệnh require như trên thì toàn bộ nội dung tập tin configs/config.php đã nằm ngay tại vị trí câu lệnh).

Ngoài lệnh require, chúng ta còn có một lệnh tương tự là require_once với cách sử dụng như require chỉ khác một điều là lệnh require_once có kiểm tra xem tập tin được liên kết đã được liên kết trước đó chưa. Nếu tập tin chưa được liên kết thì lệnh này sẽ liên kết mới, ngược lại thì lệnh này sẽ không liên kết tập tin đó nữa.

Có ý nghĩa và tác dụng tương tự lệnh require, require_once tương ứng là lệnh include, include_once. Hai lệnh requireinclude (Tương tự là require_onceinclude_once) về cơ bản là giống nhau nhưng có một sự khác biệt nhỏ các bạn có thể tìm hiểu thêm tại địa chỉ http://php.net/manual/en/function.require.phphttp://php.net/manual/en/function.include.php.

2. Biến (Variable):

Ở khối lệnh trên tôi có sử dụng một biến là $connect. Như vậy, để tạo ra một biến trong PHP các bạn chỉ việc khai báo bằng cách đặt dấu "$" ngay đầu tên biến.

Một số lưu ý khi khai báo biến như sau:
  • Tên biến chỉ chấp nhận các số từ 0 đến 9, ký tự từ a đến z (Kể cả chữ in hoa) và dấu gạch dưới "_".
  • Tên biến không được bắt đầu bằng số.
  • Không đặt tên biến là $this vì biến $this là một biến đặc biệt mặc định của PHP.
Ví dụ một số cách đặt tên biến như sau:
PHP:
$a;
$_a;
$a1;
Khi khai báo biến các bạn có thể gán giá trị cho biến bằng toán tử gán "=". Ví dụ:
PHP:
$a = 1;
$b = 'Hello';
Các bạn có thể tìm hiểu thêm về biến trong PHP tại địa chỉ http://php.net/manual/en/language.variables.php.

3. Kiểu dữ liệu (Type):

Kiểu dữ liệu trong PHP có thể được chia thành 3 nhóm sau:
  • Nhóm vô hướng (Scalar).
  • Nhóm hỗn hợp (Compound).
  • Nhóm đặc biệt (Special).
Nhóm vô hướng gồm:
  • Boolean: Gồm hai giá trị là "true" và "false".
  • Integer: Kiểu số nguyên.
  • Float: Kiểu số thực.
  • String: Kiểu chuổi.
Đối với kiểu chuổi (String) thì các bạn phải đặt trong dấu nháy đơn hoặc dấu nháy đôi. Dấu nháy đơn hay dấu nháy đôi cũng có một chút khác biệt (Các bạn có thể tìm hiểu thêm).

Nhóm hỗn hợp gồm:
  • Array: Mãng.
  • Object: Đối tượng.
Nhóm đặc biệt gồm:
  • NULL: Kiểu null (Tức là không có gì hết. Lưu ý là khác với chuổi rỗng).
  • Resource: Kiểu tài nguyên do PHP tạo ra.
Các bạn có thể tìm hiểu thêm về kiểu dữ liệu trong PHP tại địa chỉ http://php.net/manual/en/language.types.php.
 
PHẦN 7: TRANG ĐĂNG NHẬP, ĐĂNG XUẤT

Từ phần này, tôi sẽ hướng dẫn các bạn thực hiện các trang trong phần quản trị (Admin).

Nội dung kiến thức phần này gồm:
  • Session.
  • Câu lệnh điều kiện (Cấu trúc điều khiển).
  • Toán tử.
Trong thư mục admin, các bạn tạo mới một thư mục tên là user để chứa các tập tin xử lý liên quan tới người dùng (Đăng nhập, đăng xuất, danh sách, thêm mới, chỉnh sửa).

Trong thư mục admin/user, tạo mới tập tin login.php để viết mã lệnh xử lý đăng nhập.

Nội dung tập tin admin/user/login.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu đã đăng nhập thì quay về trang chủ quản trị
if (isset($_SESSION['user'])) {
    header('location:../home/home.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/user.php';

//Kiểm tra dữ liệu POST lên
if (isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['password']) && !empty($_POST['password'])) {
    //Gán tài khoản và mật khẩu nhận được từ form vào 2 biến tương ứng
    $username = $_POST['username'];
    $password = $_POST['password'];

    //Lấy thông tin người dùng từ DB
    $user = get_user_by_username($username, $connect);

    //Kiểm tra sự tồn tại của người dùng và mật khẩu có trùng khớp
    if ($user && $user['password'] === md5($password)) {
        //Tạo session lưu thông tin người dùng đăng nhập thành công
        $_SESSION['user'] = $user;
   
        //Chuyển hướng về trang chủ quản trị
        header('location:../home/home.php');
    } else {
        //Bật cờ lỗi
        $error = true;
    }
}

//Require tập tin giao diện (View)
require '../../views/admin/user/login.tpl.php';
?>
Lưu ý:
  • Các bạn mở tập tin libraries/connect.php và xóa dòng lệnh "require 'configs/config.php';". Tập tin configs/config.php sẽ được require ở các tập tin xử lý chứ không require trong tập tin libraries/connect.php nữa. Phần trước tôi thực hiện như vậy là để các bạn dễ hình dung vấn đề.
  • Trang chủ quản trị tôi sẽ không hướng dẫn các bạn thực hiện mà sẽ để mở cho các bạn tự phát triển, hoàn thiện website.
Tiếp theo, trong thư mục models các bạn tạo một tập tin tên là user.php để viết các hàm tương tác với DB (Tôi gọi là model và tôi sẽ giải thích ở các phần sau).

Nội dung tập tin models/user.php như sau:
PHP:
<?php
function get_user_by_username($username, $connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_user WHERE username = '$username' AND status = 1";

    //Query
    $query = mysqli_query($connect, $sql);

    //Return
    return mysqli_fetch_assoc($query);
}
?>
Tập tin admin/user/login.php ở trên chỉ mới là tập tin xử lý, trang đăng nhập còn cần phải có giao diện (Tôi gọi là view). Về giao diện HTML tôi chỉ trình bày đơn giản và cũng không giải thích về mã lệnh HTML.

Trong thư mục views/admin, các bạn tạo mới một thư mục tên là user để chứa các tập tin trình bày giao diện HTML.

Trong thư mục views/admin/user, tạo mới tập tin login.tpl.php để trình bày giao diện trang đăng nhập (Tên tập tin này tôi thêm ".tpl" để dễ phân biệt với tập tin xử lý login.php).

Nội dung tập tin views/admin/user/login.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Đăng nhập</title>
</head>
<body>
<form name="login" method="post" action="">
    <?php if (isset($error) && $error == true): ?>
        <p style="color: red;">Sai Tài khoản hoặc Mật khẩu!</p>
    <?php endif; ?>

    <p>
        <label>Tài khoản:</label>
        <input type="text" name="username" value="">
    </p>
    <p>
        <label>Mật khẩu:</label>
        <input type="password" name="password" value="">
    </p>
    <p>
        <input type="submit" value="Đăng nhập">
    </p>
</form>
</body>
</html>
Bây giờ các bạn vào phpMyAdmin để thêm mới một dòng dữ liệu vào bảng tbl_user với các thông tin như tài khoản, mật khẩu (Mã hóa MD5), trạng thái (Nhập giá trị là 1)... rồi bắt đầu truy cập trang đăng nhập theo địa chỉ http://localhost/admin/user/login.php để kiểm tra.

Đối với trang đăng xuất, trong thư mục admin/user các bạn tạo một tập tin tên là logout.php để xử lý đăng xuất.

Nội dung tập tin admin/user/logout.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Hủy toàn bộ session
session_destroy();

//Quay về trang đăng nhập
header('location:login.php');
?>
Trang đăng xuất không có giao diện hay truy cập DB nên mã lệnh chỉ đơn giản như vậy.

1. Session:

Session dùng để lưu thông tin mà người lập trình muốn lưu giữ (Hoặc truyền qua trang khác) để có thể sử dụng ở mọi tập tin PHP của website. Nếu các bạn chỉ lưu thông tin và sử dụng duy nhất ở một tập tin PHP nào đó thì tôi khuyên các bạn nên sử dụng biến thay vì sử dụng session.

Tập tin admin/user/login.php, tôi có khai báo hàm session_start với mục đích khởi động session. Các bạn lưu ý là cần phải khởi động session trước khi sử dụng.

Để tạo ra một session, các bạn sử dụng biến $_SESSION do PHP cung cấp. $_SESSION là một biến kiểu mãng nên các bạn sẽ sử dụng như một mãng (Sẽ trình bày ở các phần sau). Các bạn có thể tạo ra một session theo mẫu sau:
Code:
$_SESSION['Tên_session'] = 'Giá_trị_của_session';
Ví dụ:
PHP:
$_SESSION['a'] = 1;
$_SESSION['b'] = 'Hello';
Để sử dụng session đã khởi tạo, các bạn sử dụng theo mẫu sau:
Code:
$_SESSION['Tên_session'];
Ví dụ:
PHP:
$_SESSION['a'];
Các bạn có thể tìm hiểu thêm về session tại địa chỉ http://php.net/manual/en/book.session.php.

2. Câu lệnh điều kiện (Cấu trúc điều khiển):

Câu lệnh IF...ELSE:
Code:
if (Điều_kiện) {
    //Khối lệnh thỏa điều kiện
}
Hoặc
Code:
if (Điều_kiện) {
    //Khối lệnh thỏa điều kiện
} else {
    //Khối lệnh không thỏa điều kiện
}
Hoặc
Code:
if (Điều_kiện_1) {
    //Khối lệnh thỏa điều kiện 1
} elseif (Điều_kiện_2) {
    //Khối lệnh không thỏa điều kiện 1 nhưng thỏa điều kiện 2
} else {
    //Khối lệnh không thỏa điều kiện 1 và 2
}
Các bạn có thể tham khảo các ví dụ sau:

Ví dụ 1:
PHP:
if (1 == 1) {
    echo '1 = 1';
}
Ví dụ 2:
PHP:
if (1 > 2) {
    echo '1 > 2';
} else {
    echo '1 < 2';
}
Ở ví dụ 1, câu lệnh "echo '1 = 1';" sẽ được thực hiện và in ra màn hình dòng "1 = 1". Ví dụ 2, câu lệnh "echo '1 < 2';" sẽ được thực hiện và in ra màn hình dòng "1 < 2".

Trong PHP, để in ra một nội dung nào đó các bạn sử dụng câu lệnh "echo" như trên.

Các bạn có thể tìm hiểu thêm về câu lệnh điều kiện IF...ELSE tại địa chỉ http://php.net/manual/en/control-structures.if.php.

Câu lệnh SWITCH...CASE:
Code:
switch (Giá_trị_đem_so_sánh) {
    case Giá_trị_so_sánh_1:
        //Khối lệnh thỏa giá trị so sánh 1
        break;
    case Giá_trị_so_sánh_2:
        //Khối lệnh thỏa giá trị so sánh 2
        break;
    default:
        //Khối lệnh không thỏa giá trị so sánh nào ở trên
}
Về SWITCH...CASE tôi không giải thích nhiều, các bạn có thể tìm hiểu thêm tại địa chỉ http://php.net/manual/en/control-structures.switch.php.

3. Toán tử:

Ngoài toán tử gán "=" mà phần trước tôi đã giới thiệu thì phần này tôi sẽ trình bày cho các bạn một số toán tử khác (Toán tử so sánh, toán tử toán học, toán tử "and", "or").

Toán tử so sánh gồm:
  • Bằng (Về giá trị): ==
  • Bằng (Về mọi thứ): ===
  • Khác (Không bằng về giá trị): !=
  • Khác (Không bằng về mọi thứ): !==
  • Lớn hơn: >
  • Lớn hơn hoặc bằng: >=
  • Nhỏ hơn: <
  • Nhỏ hơn hoặc bằng: <=
  • Phủ định: !
Toán tử toán học gồm:
  • Cộng: +
  • Trừ: -
  • Nhân: *
  • Chia: /
  • Phần dư: %
Ngoài ra, có hai toán tử quan trọng là:
  • Toán tử và (and): &&
  • Toán tử hoặc (or): ||
Các bạn có thể tìm hiểu thêm về toán tử tại địa chỉ http://php.net/manual/en/language.operators.php.
 
PHẦN 8: TRANG DANH SÁCH NGƯỜI DÙNG

Nội dung kiến thức phần này gồm:
  • Hàm (Function).
  • Tham số (Argument).
Trong thư mục admin/user, tạo mới tập tin list.php để viết mã lệnh trang danh sách người dùng.

Nội dung tập tin admin/user/list.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/user.php';

//Lấy danh sách người dùng
$user_list = get_user_list($connect);

//Require tập tin giao diện (View)
require '../../views/admin/user/list.tpl.php';
?>
Mở tập tin models/user.php và thêm vào khối lệnh mới dưới đây:
PHP:
function get_user_list($connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_user ORDER BY user_id DESC";
 
    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/user, tạo mới tập tin list.tpl.php để trình bày giao diện trang danh sách người dùng.

Nội dung tập tin views/admin/user/list.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Người dùng - Danh sách</title>
</head>
<body>
<table width="100%" cellpadding="10">
    <tr>
        <th>ID</th>
        <th>Tài khoản</th>
        <th>Họ tên</th>
        <th>Trạng thái</th>
        <th>Ngày tạo</th>
        <th>Ngày chỉnh sửa</th>
        <th>Tác vụ</th>
    </tr>
    <?php while ($user = mysqli_fetch_assoc($user_list)): ?>
        <tr>
            <td>
                <?php echo $user['user_id']; ?>
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/user/edit.php?user_id=' . $user['user_id']; ?>"><?php echo $user['username']; ?></a>
            </td>
            <td>
                <?php echo $user['fullname']; ?>
            </td>
            <td>
                <?php echo ($user['status'] == 1) ? 'Kích hoạt' : 'Không kích hoạt'; ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($user['created'])); ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($user['modified'])); ?>
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/user/delete.php?user_id=' . $user['user_id']; ?>">Xóa</a>
            </td>
        </tr>
    <?php endwhile; ?>
</table>
</body>
</html>
Các bạn truy cập trang danh sách người dùng theo địa chỉ http://localhost/admin/user/list.php để kiểm tra.

1. Hàm (Function):

Ở phần trước trong tập tin models/user.php, tôi có khởi tạo một hàm tên là get_user_by_username và ở phần này tôi cũng tạo một hàm là get_user_list. Theo như những gì các bạn thấy thì hàm là một khối lệnh làm một nhiệm vụ gì đó theo ý đồ của người lập trình nhằm mục đích "đóng gói" và "tái sử dụng" ở nhiều nơi.

Để định nghĩa một hàm, các bạn thực hiện theo mẫu sau:
Code:
function Tên_hàm()
{
    //Khối lệnh thực hiện nhiệm vụ nào đó
}
Hoặc
Code:
function Tên_hàm(Tham_số_1, Tham_số_2, Tham_số_n)
{
    //Khối lệnh thực hiện nhiệm vụ nào đó
}
Hoặc
Code:
function Tên_hàm(Tham_số_1 = 'Giá_trị_mặc_định_1', Tham_số_2 = 'Giá_trị_mặc_định_2', Tham_số_n = 'Giá_trị_mặc_định_n')
{
    //Khối lệnh thực hiện nhiệm vụ nào đó
}
Trong đó:
  • Tên hàm phải tuân theo quy tắc đặt tên mà PHP quy định là chỉ chấp nhận các số từ 0 đến 9, chữ cái từ a đến z (Kể cả chữ hoa và chữ thường), dấu gạch dưới "_". Tên hàm không được bắt đầu bằng số và không được trùng lặp.
  • Một hàm có thể có hoặc không có tham số truyền vào. Nếu có nhiều hơn một tham số thì các tham số phân cách nhau bởi dấu phẩy ",". Các tham số có thể gán giá trị mặc định cho nó.
Ví dụ:
PHP:
function get_user_list($connect)
{
    //Những dòng lệnh các bạn đã biết ở trên
}
Tôi đã tạo ra một hàm tên là get_user_list và hàm này có một tham số truyền vào là $connect. Nhiệm vụ của hàm get_user_list là lấy danh sách người dùng từ DB và trả về lại kết quả.

Ở ví dụ trên, tôi có nhắc đến "trả về lại kết quả" vậy đó là gì? Câu này được thể hiện bằng từ khóa "return" ở cuối mỗi hàm mà các bạn thấy.

Ví dụ:
PHP:
return mysqli_query($connect, $sql);
Dòng lệnh này ở hàm get_user_list mà tôi đã định nghĩa ở trên dùng để trả về lại kết quả mà người lập trình mong muốn (Ở ví dụ này đó là kết quả truy vấn từ DB).

Một hàm có thể có giá trị trả về hoặc có thể không có giá trị trả về tùy vào mục đích của người lập trình.

Các bạn có thể tìm hiểu thêm về hàm tại địa chỉ http://php.net/manual/en/language.functions.php.

2. Tham số (Argument):

Ở hàm get_user_list có khai báo một tham số là $connect. Vậy tham số là những biến nhận giá trị truyền vào nhằm mục đích nào đó theo ý đồ của người lập trình.

Các tham số và biến được khởi tạo bên trong hàm thì chỉ tồn tại bên trong hàm đó.

Tham số bao gồm 2 loại là:
  • Tham trị.
  • Tham biến (Tham chiếu).
Các bạn có thể tìm hiểu thêm về tham số tại địa chỉ http://php.net/manual/en/functions.arguments.php.
 
PHẦN 9: TRANG THÊM MỚI NGƯỜI DÙNG

Nội dung kiến thức phần này gồm:
  • Lập trình với form.
  • Mãng (Array).
Trong thư mục admin/user, tạo mới tập tin add.php để viết mã lệnh trang thêm mới người dùng.

Nội dung tập tin admin/user/add.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/user.php';

//Nếu có post dữ liệu lên thì xử lý
if ($_POST) {
    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'username' => $_POST['username'],
        'password' => md5($_POST['password']),
        'fullname' => $_POST['fullname'],
        'email' => $_POST['email'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'created' => date('Y-m-d H:i:s'),
        'modified' => date('Y-m-d H:i:s')
    );

    //Thêm mới
    if (add_user($data, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để reset form)
        header('location:add.php');
    }
}

//Require tập tin giao diện (View)
require '../../views/admin/user/add.tpl.php';
?>
Mở tập tin models/user.php và thêm vào khối lệnh mới dưới đây:
PHP:
function add_user($data, $connect)
{
    //SQL
    $sql = "INSERT INTO tbl_user(username, password, fullname, email, status, created, modified) VALUES ('{$data['username']}', '{$data['password']}', '{$data['fullname']}', '{$data['email']}', {$data['status']}, '{$data['created']}', '{$data['modified']}')";

    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/user, tạo mới tập tin add.tpl.php để trình bày giao diện trang thêm mới người dùng.

Nội dung tập tin views/admin/user/add.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Người dùng - Thêm mới</title>
</head>
<body>
<form name="add" method="post" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Người dùng đã được thêm mới thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>

    <p>
        <label>Tài khoản:</label>
        <input type="text" name="username" value="">
    </p>
    <p>
        <label>Mật khẩu:</label>
        <input type="password" name="password" value="">
    </p>
    <p>
        <label>Họ tên:</label>
        <input type="text" name="fullname" value="">
    </p>
    <p>
        <label>Email:</label>
        <input type="text" name="email" value="">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1">
    </p>
    <p>
        <input type="submit" value="Thêm mới">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang thêm mới người dùng theo địa chỉ http://localhost/admin/user/add.php để kiểm tra.

1. Lập trình với form:

Form là vùng giành cho người dùng nhập dữ liệu. Form có hai phương thức để gửi dữ liệu lên máy chủ là POST và GET. Hai phương thức POST và GET đều cùng làm một nhiệm vụ là gửi dữ liệu lên máy chủ nhưng cách thức thì khác nhau.

Đối với phương thức POST dữ liệu được gửi lên máy chủ mà người dùng không nhìn thấy được dữ liệu được gửi đi là gì. Còn phương thức GET thì dữ liệu gửi đi được thể hiện trên URL (Thanh nhập địa chỉ website của trình duyệt).

Thông thường, khi gửi dữ liệu lên máy chủ để cập nhật DB thì nên sử dụng phương thức POST. Phương thức GET thường được sử dụng trong một số trường hợp như phân trang, hiển thị theo danh mục...

Để tạo một form với phương thức POST, các bạn khai báo thuộc tính method là POST trong thẻ form HTML.

Ví dụ:
HTML:
<form name="add" method="post" action="">
Để nhận dữ liệu do form đưa lên theo phương thức POST thì các bạn thực hiện theo mẫu sau:
Code:
$_POST['Tên_trường'];
Ví dụ:
PHP:
$_POST['username'];
$_POST['password'];
Để tạo một form với phương thức GET, các bạn khai báo thuộc tính method là GET trong thẻ form HTML.

Ví dụ:
HTML:
<form name="add" method="get" action="">
Ngoài ra, đối với phương thức GET các bạn còn có thể truyền dữ liệu trên URL bằng cách thực hiện theo mẫu sau:
Code:
urlpath?Biến_1=Giá_trị_1&Biến_2=Giá_trị_2&Biến_n=Giá_trị_n
Với mẫu trên, để khai báo các biến và giá trị tương ứng các bạn sẽ khởi đầu bằng dấu hỏi "?" và kế tiếp sau đó là các biến và giá trị tương ứng với biến. Nếu có nhiều hơn một biến thì các bạn phân cách bởi dấu và "&".

Ví dụ:
Code:
http://localhost/admin/user/edit.php?user_id=1
Để nhận dữ liệu theo phương thức GET thì các bạn thực hiện theo mẫu sau:
Code:
$_GET['Tên_trường'];
Hoặc
Code:
$_GET['Tên_biến'];
Ví dụ:
PHP:
$_GET['user_id'];
Các bạn có thể tìm hiểu thêm về POST tại địa chỉ http://php.net/manual/en/reserved.variables.post.php và GET tại địa chỉ http://php.net/manual/en/reserved.variables.get.php. Ngoài ra, các bạn nên tìm hiểu thêm một số biến PHP khác tại địa chỉ http://php.net/manual/en/reserved.variables.php.

2. Mãng (Array):

Mãng là một kiểu dữ liệu trong PHP.

Để khởi tạo một mãng các bạn thực hiện theo mẫu sau:
Code:
$Tên_mãng = array();
Hoặc
Code:
$Tên_mãng = array(Phần_tử_1, Phần_tử_2, Phần_tử_n);
Hoặc
Code:
$Tên_mãng = array(
    'Khóa_1' => 'Giá_trị_1',
    'Khóa_2' => 'Giá_trị_2',
    'Khóa_n' => 'Giá_trị_n'
);
Trong đó:
  • Mẫu thứ nhất là tạo một mãng rỗng (Không có phần tử).
  • Mẫu thứ hai là tạo một mãng có phần tử.
  • Mẫu thứ ba là tạo một mãng có phần tử nhưng các phần tử là "một cặp" gồm "khoá" và "giá trị".
Để gọi các phần tử của mãng các bạn thực hiện theo mẫu sau:
Code:
$Tên_mãng[Chỉ_số];
Hoặc
Code:
$Tên_mãng['Tên_khóa'];
Lưu ý: Chỉ số trong mãng PHP được tính bắt đầu từ 0.

Các bạn có thể tìm hiểu thêm về mãng tại địa chỉ http://php.net/manual/en/language.types.array.php.
 
PHẦN 10: TRANG CHỈNH SỬA NGƯỜI DÙNG

Nội dung kiến thức phần này gồm:
  • Đường dẫn.
  • Các hàm PHP (isset, empty, header, date, md5, mysqli_query, mysqli_fetch_assoc).
Trong thư mục admin/user, tạo mới tập tin edit.php để viết mã lệnh trang chỉnh sửa người dùng.

Nội dung tập tin admin/user/edit.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/user.php';

//Lấy user_id từ URL
$user_id = $_GET['user_id'];

//Nếu có post dữ liệu lên thì xử lý cập nhật
if ($_POST) {
    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'username' => $_POST['username'],
        'password' => empty($_POST['password']) ? null : md5($_POST['password']),
        'fullname' => $_POST['fullname'],
        'email' => $_POST['email'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'modified' => date('Y-m-d H:i:s')
    );
  
    //Cập nhật
    if (edit_user($data, $user_id, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để tải lại thông tin mới)
        header('location:edit.php?user_id=' . $user_id);
    }
}

//Lấy thông tin người dùng để trình bày trên form
$user = get_user_by_id($user_id, $connect);

//Require tập tin giao diện (View)
require '../../views/admin/user/edit.tpl.php';
?>
Mở tập tin models/user.php và thêm vào khối lệnh mới dưới đây:
PHP:
function get_user_by_id($user_id, $connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_user WHERE user_id = $user_id";
  
    //Query
    $query = mysqli_query($connect, $sql);
  
    //Return
    return mysqli_fetch_assoc($query);
}

function edit_user($data, $user_id, $connect)
{
    //SQL
    $sql = "UPDATE tbl_user SET username = '{$data['username']}', fullname = '{$data['fullname']}', email = '{$data['email']}', status = {$data['status']}, modified = '{$data['modified']}'";

    //Nếu có cập nhật mật khẩu
    if ($data['password'] != null) {
        $sql .= ", password = '{$data['password']}'";
    }

    //Điều kiện
    $sql .= " WHERE user_id = $user_id";

    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/user, tạo mới tập tin edit.tpl.php để trình bày giao diện trang chỉnh sửa người dùng.

Nội dung tập tin views/admin/user/edit.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Người dùng - Chỉnh sửa</title>
</head>
<body>
<form name="edit" method="post" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Thành viên đã được chỉnh sửa thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>
  
    <p>
        <label>Tài khoản:</label>
        <input type="text" name="username" value="<?php echo $user['username']; ?>">
    </p>
    <p>
        <label>Mật khẩu:</label>
        <input type="password" name="password" value="">
    </p>
    <p>
        <label>Họ tên:</label>
        <input type="text" name="fullname" value="<?php echo $user['fullname']; ?>">
    </p>
    <p>
        <label>Email:</label>
        <input type="text" name="email" value="<?php echo $user['email']; ?>">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1" <?php echo ($user['status'] == 1) ? 'checked="checked"' : ''; ?>>
    </p>
    <p>
        <input type="submit" value="Chỉnh sửa">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang danh sách người dùng và nhấp vào tài khoản để truy cập tới trang chỉnh sửa người dùng (Lưu ý tới liên kết của trang chỉnh sửa người dùng).

1. Đường dẫn:

Trong các trang, các bạn đều require các tập tin configs/config.php, libraries/connect.php và một số tập tin khác. Khi require các bạn phải chỉ đúng đường dẫn tới tập tin cần require và để thực hiện được thì PHP cung cấp một số ký hiệu giúp bạn thực hiện điều đó một cách linh hoạt. Và đường dẫn theo hướng dẫn dưới đây được gọi là đường dẫn tương đối.

Một số ký hiệu các bạn cần biết như sau:
  • Đứng tại vị trí thư mục hiện hành: ./
  • Ra ngoài một cấp thư mục: ../
  • Ra thư mục gốc (Web root): /
Ví dụ với cấu trúc thư mục như sau:
Code:
admin
-----user
----------edit.php
configs
-----config.php
libraries
-----connect.php
Với cấu trúc thư mục như trên nếu:

- Đứng ở vị trí tập tin admin/user/edit.php để viết lệnh và require tập tin configs/config.php thì đường dẫn sẽ là:
Code:
../../configs/config.php
- Đứng ở vị trí tập tin libraries/connect.php để viết lệnh và require tập tin configs/config.php thì đường dẫn sẽ là:
Code:
../configs/config.php
Ngoài ra, các bạn còn có thể sử dụng một số hàm do PHP cung cấp để lấy chính xác đường dẫn tới tập tin. Với tôi thì tôi thường sử dụng hằng __DIR__ để lấy đường dẫn tuyệt đối tới vị trí tập tin đang viết mã lệnh.

2. Các hàm PHP (isset, empty, header, date, md5, mysqli_query, mysqli_fetch_assoc):
  • isset: Kiểm tra sự tồn tại của một biến. Nếu biến tồn tại thì trả về true, ngược lại trả về false.
  • empty: Kiểm tra chuỗi dữ liệu có rỗng hay không. Nếu chuỗi rỗng thì trả về true, ngược lại trả về false.
  • header: Chuyển hướng trang sang một trang mới.
  • date: Định dạng ngày giờ.
  • md5: Mã hóa một chuỗi theo thuật toán MD5.
  • mysqli_query: Thực thi (Truy vấn) câu SQL.
  • mysqli_fetch_assoc: Trả về một dòng dữ liệu từ "recordset" dưới dạng một mãng.
Tất cả các hàm trên các bạn có thể vào trang http://php.net/docs.php và sử dụng chức năng tìm kiếm để tìm hàm cần tìm hiểu.
 
PHẦN 11: XOÁ NGƯỜI DÙNG

Phần này tôi không trình bày kiến thức lập trình PHP, các bạn chỉ thực hiện chức năng xóa người dùng dưới đây.

Trong thư mục admin/user, tạo mới tập tin delete.php để viết mã lệnh chức năng xóa người dùng.

Nội dung tập tin admin/user/delete.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/user.php';

//Lấy user_id từ URL
$user_id = $_GET['user_id'];

//Xóa
delete_user($user_id, $connect);

//Quay về trang danh sách người dùng
header('location:list.php');
?>
Mở tập tin models/user.php và thêm vào khối lệnh mới dưới đây:
PHP:
function delete_user($user_id, $connect)
{
    //SQL
    $sql = "DELETE FROM tbl_user WHERE user_id = $user_id";
    
    //Return
    return mysqli_query($connect, $sql);
}
Xóa người dùng là một chức năng nên các bạn không phải tạo giao diện (View).

Các bạn truy cập trang danh sách người dùng, ở cột "Tác vụ" các bạn chọn tác vụ "Xóa" để thực hiện xóa người dùng tương ứng.
 
PHẦN 12: TRANG DANH SÁCH DANH MỤC SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • Vòng lặp.
  • SQL (SELECT).
Trong thư mục admin, các bạn tạo mới thư mục tên là category để chứa các tập tin xử lý danh mục sản phẩm.

Trong thư mục admin/category, tạo mới tập tin list.php để viết mã lệnh trang danh sách danh mục sản phẩm.

Nội dung tập tin admin/category/list.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';

//Lấy danh sách danh mục sản phẩm
$category_list = get_category_list($connect);

//Require tập tin giao diện (View)
require '../../views/admin/category/list.tpl.php';
?>
Trong thư mục models, tạo mới tập tin category.php để viết mã lệnh xử lý DB.

Nội dung tập tin models/category.php như sau:
PHP:
<?php
function get_category_list($connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_category ORDER BY category_id DESC";
  
    //Return
    return mysqli_query($connect, $sql);
}
?>
Trong thư mục views/admin, tạo mới thư mục tên là category để chứa các tập tin trình bày giao diện các trang danh mục sản phẩm.

Trong thư mục views/admin/category, tạo mới tập tin list.tpl.php để trình bày giao diện trang danh sách danh mục sản phẩm.

Nội dung tập tin views/admin/category/list.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Danh mục sản phẩm - Danh sách</title>
</head>
<body>
<table width="100%" cellpadding="10">
    <tr>
        <th>ID</th>
        <th>Tên danh mục</th>
        <th>Trạng thái</th>
        <th>Ngày tạo</th>
        <th>Ngày chỉnh sửa</th>
        <th>Tác vụ</th>
    </tr>
    <?php while ($category = mysqli_fetch_assoc($category_list)): ?>
        <tr>
            <td>
                <?php echo $category['category_id']; ?>
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/category/edit.php?category_id=' . $category['category_id']; ?>"><?php echo $category['name']; ?></a>
            </td>
            <td>
                <?php echo ($category['status'] == 1) ? 'Kích hoạt' : 'Không kích hoạt'; ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($category['created'])); ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($category['modified'])); ?>
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/category/delete.php?category_id=' . $category['category_id']; ?>">Xóa</a>
            </td>
        </tr>
    <?php endwhile; ?>
</table>
</body>
</html>
Các bạn truy cập trang danh sách danh mục sản phẩm theo địa chỉ http://localhost/admin/category/list.php để kiểm tra.

1. Vòng lặp:

Trong lập trình PHP có 4 kiểu vòng lặp phổ biến mà các bạn cần tìm hiểu là:
  • For.
  • While.
  • Do...While.
  • Foreach.
Vòng lặp for với mẫu sau:
Code:
for ($Biến_đếm = Bắt_đầu; $Biến_đếm < Giới_hạn; Bước_nhảy) {
    //Khối lệnh lặp
}
Với mẫu trên, bước nhảy là tăng dần đến giới hạn thì kết thúc vòng lặp. Tuy nhiên, với vòng lặp for thì các bạn có thể lặp với bước nhảy tăng hoặc giảm đều được.

Ví dụ:
PHP:
for ($i = 0; $i < 10; $i++) {
    echo $i;
}
Với vòng lặp ở ví dụ trên sẽ in ra màn hình các số từ 0 đến 9. Trong đó, $i là biến đếm bắt đầu chạy từ 0 và kết thúc là 9 (< 10), sau mỗi lần lặp biến đếm sẽ tăng lên một đơn vị.

Các bạn có thể tìm hiểu thêm về vòng lặp for tại địa chỉ http://php.net/manual/en/control-structures.for.php.

Vòng lặp while với mẫu sau:
Code:
while (Điều_kiện_lặp) {
    //Khối lệnh lặp
}
Ví dụ:
PHP:
$i = 0;
while ($i < 10) {
    echo $i;
    $i++;
}
Với vòng lặp ở ví dụ trên sẽ in ra màn hình các số từ 0 đến 9. Trong đó, $i có giá trị ban đầu là 0 và điều kiện lặp là $i < 10, cuối mỗi lần lặp thì biến $i sẽ tăng lên một đơn vị ($i++).

Các bạn có thể tìm hiểu thêm về vòng lặp while tại địa chỉ http://php.net/manual/en/control-structures.while.php.

Tương tự như vòng lặp while có một vòng lặp nữa là do...while, các bạn có thể tìm hiểu thêm về vòng lặp do...while tại địa chỉ http://php.net/manual/en/control-structures.do.while.php.

Vòng lặp foreach với mẫu sau:
Code:
foreach ($Mãng_lặp as $Giá_trị) {
    //Khối lệnh lặp
}
Hoặc
Code:
foreach ($Mãng_lặp as $Khóa => $Giá_trị) {
    //Khối lệnh lặp
}
Ví dụ:
PHP:
$a = array(1, 2, 3, 4, 5);
foreach ($a as $v) {
    echo $v;
}
Với vòng lặp ở ví dụ trên sẽ in ra màn hình các giá trị 1, 2, 3, 4, 5.

Vòng lặp foreach chỉ sử dụng để lặp một mãng và vòng lặp foreach sẽ lặp cho tới hết phần tử trong mãng mới kết thúc. Tuy nhiên, các bạn cũng có thể dừng vòng lặp với một điều kiện nào đó bằng lệnh break.

Các bạn có thể tìm hiểu thêm về vòng lặp foreach tại địa chỉ http://php.net/manual/en/control-structures.foreach.php.

2. SQL (SELECT):

Phần này là kiến thức về SQL (Tôi hướng dẫn theo phiên bản MySQL mới nhất cho tới lúc này là 5.7.x).

Cú pháp SQL đầu tiên mà tôi hướng dẫn các bạn đó là cú pháp SELECT kết hợp với WHERE, ORDER BY và LIMIT.

SELECT dùng để lấy dữ liệu từ một bảng (Hoặc nhiều bảng) dữ liệu chứa trong DB.

Cú pháp của SELECT như sau:
Code:
SELECT Trường_1, Trường_2, Trường_n FROM Tên_bảng_dữ_liệu
Hoặc
Code:
SELECT Trường_1, Trường_2, Trường_n FROM Tên_bảng_dữ_liệu WHERE Điều_kiện
Hoặc
Code:
SELECT Trường_1, Trường_2, Trường_n FROM Tên_bảng_dữ_liệu WHERE Điều_kiện ORDER BY Trường_sắp_xếp Kiểu_sắp_xếp
Hoặc
Code:
SELECT Trường_1, Trường_2, Trường_n FROM Tên_bảng_dữ_liệu WHERE Điều_kiện ORDER BY Trường_sắp_xếp Kiểu_sắp_xếp LIMIT Số_lượng, Bắt_đầu
Các bạn cần lưu ý một số điểm sau:
  • Nếu các bạn muốn lấy thông tin toàn bộ các trường thì các bạn thay danh sách các trường bằng dấu sao "*".
  • Kiểu sắp xếp có hai kiểu là ASC (Tăng dần) và DESC (Giảm dần).
Ví dụ:
SQL:
SELECT * FROM tbl_category ORDER BY category_id DESC
Ví dụ trên sẽ lấy danh sách danh mục sản phẩm trong bảng tbl_category và sắp xếp giảm dần theo trường category_id.

Các bạn có thể tìm hiểu thêm về câu lệnh SELECT trong MySQL tại địa chỉ https://dev.mysql.com/doc/refman/5.7/en/select.html.
 
PHẦN 13: TRANG THÊM MỚI DANH MỤC SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • Hàm PHP (unset).
  • SQL (INSERT).
Trong thư mục admin/category, tạo mới tập tin add.php để viết mã lệnh trang thêm mới danh mục sản phẩm.

Nội dung tập tin admin/category/add.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';

//Nếu có post dữ liệu lên thì xử lý
if ($_POST) {
    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'name' => $_POST['name'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'created' => date('Y-m-d H:i:s'),
        'modified' => date('Y-m-d H:i:s')
    );

    //Thêm mới
    if (add_category($data, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để reset form)
        header('location:add.php');
    }
}

//Require tập tin giao diện (View)
require '../../views/admin/category/add.tpl.php';
?>
Mở tập tin models/category.php và thêm vào khối lệnh mới dưới đây:
PHP:
function add_category($data, $connect)
{
    //SQL
    $sql = "INSERT INTO tbl_category(name, status, created, modified) VALUES ('{$data['name']}', {$data['status']}, '{$data['created']}', '{$data['modified']}')";
  
    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/category, tạo mới tập tin add.tpl.php để trình bày giao diện trang thêm mới danh mục sản phẩm.

Nội dung tập tin views/admin/category/add.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Danh mục sản phẩm - Thêm mới</title>
</head>
<body>
<form name="add" method="post" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Danh mục sản phẩm đã được thêm mới thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>
  
    <p>
        <label>Tên danh mục:</label>
        <input type="text" name="name" value="">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1">
    </p>
    <p>
        <input type="submit" value="Thêm mới">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang thêm mới danh mục sản phẩm theo địa chỉ http://localhost/admin/category/add.php để kiểm tra.

1. Hàm PHP (unset):

Hàm unset dùng để hủy bỏ một biến (Hoặc một phần tử của mãng) đã tồn tại.

Ví dụ:
PHP:
unset($a);
unset($_SESSION['success']);
Các bạn có thể tìm hiểu thêm về hàm unset tại địa chỉ http://php.net/manual/en/function.unset.php.

2. SQL (INSERT):

Để thêm mới một dòng (Hoặc nhiều dòng) dữ liệu vào một bảng dữ liệu trong DB các bạn sử dụng câu lệnh INSERT để thực hiện.

Cú pháp câu lệnh INSERT như sau:
Code:
INSERT INTO Bảng_dữ_liệu(Trường_1, Trường_2, Trường_n) VALUES (Giá_trị_1, Giá_trị_2, Giá_trị_n)
Hoặc
Code:
INSERT INTO Bảng_dữ_liệu(Trường_1, Trường_2, Trường_n) VALUES (Giá_trị_dòng_1_1, Giá_trị_dòng_1_2, Giá_trị_dòng_1_n), (Giá_trị_dòng_2_1, Giá_trị_dòng_2_2, Giá_trị_dòng_2_n)
Trong đó:
  • Cú pháp thứ nhất dùng để thêm mới một dòng dữ liệu vào bảng dữ liệu.
  • Cú pháp thứ hai dùng để thêm mới hai (Tương tự cho nhiều) dòng dữ liệu vào bảng dữ liệu.
Ví dụ:
SQL:
INSERT INTO tbl_category(name, status, created, modified) VALUES ('Apple', 1, '2017-12-21 08:09:10', '2017-12-21 08:09:10')
Các bạn lưu ý là thứ tự giá trị khai báo phải tương ứng với thứ tự khai báo của các trường dữ liệu.

Trong SQL thì chuỗi cũng được đặt trong dấu nhấy đơn.

Các bạn có thể tìm hiểu thêm về cú pháp INSERT tại địa chỉ https://dev.mysql.com/doc/refman/5.7/en/insert.html.
 
PHẦN 14: TRANG CHỈNH SỬA DANH MỤC SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • SQL (UPDATE).
Trong thư mục admin/category, tạo mới tập tin edit.php để viết mã lệnh trang chỉnh sửa danh mục sản phẩm.

Nội dung tập tin admin/category/edit.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';

//Lấy category_id từ URL
$category_id = $_GET['category_id'];

//Nếu có post dữ liệu lên thì xử lý cập nhật
if ($_POST) {
    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'name' => $_POST['name'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'modified' => date('Y-m-d H:i:s')
    );

    //Cập nhật
    if (edit_category($data, $category_id, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để tải lại thông tin mới)
        header('location:edit.php?category_id=' . $category_id);
    }
}

//Lấy thông tin danh mục sản phẩm để trình bày trên form
$category = get_category_by_id($category_id, $connect);

//Require tập tin giao diện (View)
require '../../views/admin/category/edit.tpl.php';
?>
Mở tập tin models/category.php và thêm vào khối lệnh mới dưới đây:
PHP:
function get_category_by_id($category_id, $connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_category WHERE category_id = $category_id";

    //Query
    $query = mysqli_query($connect, $sql);

    //Return
    return mysqli_fetch_assoc($query);
}

function edit_category($data, $category_id, $connect)
{
    //SQL
    $sql = "UPDATE tbl_category SET name = '{$data['name']}', status = {$data['status']}, modified = '{$data['modified']}' WHERE category_id = $category_id";

    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/category, tạo mới tập tin edit.tpl.php để trình bày giao diện trang chỉnh sửa danh mục sản phẩm.

Nội dung tập tin views/admin/category/edit.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Danh mục sản phẩm - Chỉnh sửa</title>
</head>
<body>
<form name="edit" method="post" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Danh mục sản phẩm đã được chỉnh sửa thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>
    
    <p>
        <label>Tên danh mục:</label>
        <input type="text" name="name" value="<?php echo $category['name']; ?>">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1" <?php echo ($category['status'] == 1) ? 'checked="checked"' : ''; ?>>
    </p>
    <p>
        <input type="submit" value="Chỉnh sửa">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang danh sách danh mục sản phẩm và nhấp vào tên danh mục để truy cập tới trang chỉnh sửa danh mục sản phẩm.

SQL (UPDATE):

Để cập nhật một dòng (Hoặc nhiều dòng) dữ liệu trong bảng dữ liệu các bạn sử dụng câu lệnh UPDATE của SQL.

Cú pháp của câu lệnh UPDATE như sau:
Code:
UPDATE Tên_bảng_dữ_liệu SET Trường_1 = Giá_trị_1, Trường_2 = Giá_trị_2, Trường_n = Giá_trị_n WHERE Điều_kiện
Ví dụ:
SQL:
UPDATE tbl_category SET name = 'Apple', status = 1, modified = '2017-12-21 08:09:10' WHERE category_id = 1
Các bạn lưu ý là nếu câu lệnh UPDATE không có điều kiện thì SQL sẽ cập nhật tất cả các dòng dữ liệu có trong bảng dữ liệu (Tức là tất cả các dòng trong bảng sẽ có cùng một giá trị).

Các bạn có thể tìm hiểu thêm về câu lệnh UPDATE tại địa chỉ https://dev.mysql.com/doc/refman/5.7/en/update.html.
 
PHẦN 15: XOÁ DANH MỤC SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • SQL (DELETE).
Trong thư mục admin/category, tạo mới tập tin delete.php để viết mã lệnh chức năng xóa danh mục sản phẩm.

Nội dung tập tin admin/category/delete.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';

//Lấy category_id từ URL
$category_id = $_GET['category_id'];

//Xóa
delete_category($category_id, $connect);

//Quay về trang danh sách danh mục sản phẩm
header('location:list.php');
?>
Mở tập tin models/category.php và thêm vào khối lệnh mới dưới đây:
PHP:
function delete_category($category_id, $connect)
{
    //SQL
    $sql = "DELETE FROM tbl_category WHERE category_id = $category_id";
    
    //Return
    return mysqli_query($connect, $sql);
}
Xóa là một chức năng nên các bạn không phải tạo giao diện (View).

Các bạn truy cập trang danh sách danh mục sản phẩm, ở cột "Tác vụ" các bạn chọn tác vụ "Xóa" để thực hiện xóa danh mục sản phẩm tương ứng.

SQL (DELETE):

Để xóa một dòng (Hoặc nhiều dòng) dữ liệu các bạn sử dụng câu lệnh DELETE của SQL.

Cú pháp của câu lệnh DELETE như sau:
Code:
DELETE FROM Tên_bảng_dữ_liệu WHERE Điều_kiện
Ví dụ:
SQL:
DELETE FROM tbl_category WHERE category_id = 1
Các bạn lưu ý là nếu câu lệnh DELETE không có điều kiện thì toàn bộ các dòng dữ liệu trong bảng dữ liệu sẽ bị xóa tất cả. Vì vậy, khi sử dụng câu lệnh DELETE các bạn cần phải lưu ý về điều kiện truy vấn.

Các bạn có thể tìm hiểu thêm về câu lệnh DELETE tại địa chỉ https://dev.mysql.com/doc/refman/5.7/en/delete.html.
 
PHẦN 16: TRANG DANH SÁCH SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • Hàm PHP (number_format).
Trong thư mục admin, tạo mới thư mục tên là product để chứa các tập tin xử lý trang sản phẩm.

Trong thư mục admin/product, tạo mới tập tin list.php để viết mã lệnh trang danh sách sản phẩm.

Nội dung tập tin admin/product/list.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/product.php';

//Lấy danh sách sản phẩm
$product_list = get_product_list($connect);

//Require tập tin giao diện (View)
require '../../views/admin/product/list.tpl.php';
?>
Trong thư mục models, tạo mới tập tin product.php để viết mã lệnh tương tác DB.

Nội dung tập tin models/product.php như sau:
PHP:
<?php
function get_product_list($connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_product ORDER BY product_id DESC";
    
    //Return
    return mysqli_query($connect, $sql);
}
?>
Trong thư mục views/admin, tạo mới thư mục tên là product để chứa các tập tin trình bày giao diện trang sản phẩm.

Trong thư mục views/admin/product, tạo mới tập tin list.tpl.php để trình bày giao diện trang danh sách sản phẩm.

Nội dung tập tin views/admin/product/list.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Sản phẩm - Danh sách</title>
</head>
<body>
<table width="100%" cellpadding="10">
    <tr>
        <th>ID</th>
        <th>Hình ảnh</th>
        <th>Tên sản phẩm</th>
        <th>Giá bán</th>
        <th>Trạng thái</th>
        <th>Ngày tạo</th>
        <th>Ngày chỉnh sửa</th>
        <th>Tác vụ</th>
    </tr>
    <?php while ($product = mysqli_fetch_assoc($product_list)): ?>
        <tr>
            <td>
                <?php echo $product['product_id']; ?>
            </td>
            <td>
                <img src="<?php echo SITE_URL . 'userfiles/' . $product['image']; ?>" width="30" height="30">
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/product/edit.php?product_id=' . $product['product_id']; ?>"><?php echo $product['name']; ?></a>
            </td>
            <td>
                <?php echo number_format($product['price'], 0, '', '.'); ?> VNĐ</td>
            <td>
                <?php echo ($product['status'] == 1) ? 'Kích hoạt' : 'Không kích hoạt'; ?>
            </td>
            <td>
                <?php echo date('d-m-Y H:i:s', strtotime($product['created'])); ?>
            </td>
            <td>
                <?php echo date('d-m-Y H:i:s', strtotime($product['modified'])); ?>
            </td>
            <td>
                <a href="<?php echo SITE_URL . 'admin/product/delete.php?product_id=' . $product['product_id']; ?>">Xóa</a>
            </td>
        </tr>
    <?php endwhile; ?>
</table>
</body>
</html>
Các bạn truy cập trang danh sách sản phẩm theo địa chỉ http://localhost/admin/product/list.php để kiểm tra.

Hàm PHP (number_format):

Hàm number_format dùng để định dạng số (Thực, nguyên) theo mục đích người lập trình. Các bạn có thể định số chữ số thập phân, định dấu phân cách hàng nghìn, hàng triệu...

Ví dụ:
PHP:
number_format(123456, 0, '', '.');
Ví dụ trên sẽ trả về cho các bạn một chuỗi số "123.456".

Các bạn có thể tìm hiểu thêm về hàm number_format tại địa chỉ http://php.net/manual/en/function.number-format.php.
 
PHẦN 17: TRANG THÊM MỚI SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • Tải tập tin lên máy chủ (Upload).
Trong thư mục admin/product, tạo mới tập tin add.php để viết mã lệnh trang thêm mới sản phẩm.

Nội dung tập tin admin/product/add.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';
require '../../models/product.php';

//Nếu có post dữ liệu lên thì xử lý
if ($_POST) {
    //Tải hình ảnh lên máy chủ (Upload)
    if (($image = $_FILES['image']['name']) != null) {
        move_uploaded_file($_FILES['image']['tmp_name'], 'userfiles/' . $image);
    } else {
        $image = '';
    }
    
    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'category_id' => $_POST['category_id'],
        'name' => $_POST['name'],
        'detail' => $_POST['detail'],
        'image' => $image,
        'price' => $_POST['price'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'created' => date('Y-m-d H:i:s'),
        'modified' => date('Y-m-d H:i:s')
    );

    //Thêm mới
    if (add_product($data, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để reset form)
        header('location:add.php');
    }
}

//Lấy danh sách danh mục sản phẩm có trạng thái kích hoạt (Status = 1)
$category_active_list = get_category_active_list($connect);

//Require tập tin giao diện (View)
require '../../views/admin/product/add.tpl.php';
?>
Mở tập tin models/category.php và thêm vào khối lệnh mới dưới đây:
PHP:
function get_category_active_list($connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_category WHERE status = 1 ORDER BY category_id ASC";
    
    //Return
    return mysqli_query($connect, $sql);
}
Mở tập tin models/product.php và thêm vào khối lệnh mới dưới đây:
PHP:
function add_product($data, $connect)
{
    //SQL
    $sql = "INSERT INTO tbl_product(category_id, name, detail, image, price, status, created, modified) VALUES ({$data['category_id']}, '{$data['name']}', '{$data['detail']}', '{$data['image']}', {$data['price']}, {$data['status']}, '{$data['created']}', '{$data['modified']}')";

    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/product, tạo mới tập tin add.tpl.php để trình bày giao diện trang thêm mới sản phẩm.

Nội dung tập tin views/admin/product/add.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Sản phẩm - Thêm mới</title>
</head>
<body>
<form name="add" method="post" enctype="multipart/form-data" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Sản phẩm đã được thêm mới thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>
    
    <p>
        <label>Danh mục:</label>
        <select name="category_id">
            <?php while ($category_active = mysqli_fetch_assoc($category_active_list)): ?>
                <option value="<?php echo $category_active['category_id']; ?>">
                    <?php echo $category_active['name']; ?>
                </option>
            <?php endwhile; ?>
        </select>
    </p>
    <p>
        <label>Tên sản phẩm:</label>
        <input type="text" name="name" value="">
    </p>
    <p>
        <label>Chi tiết:</label>
        <textarea name="detail"></textarea>
    </p>
    <p>
        <label>Hình ảnh:</label>
        <input type="file" name="image">
    </p>
    <p>
        <label>Giá bán:</label>
        <input type="text" name="price" value="">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1">
    </p>
    <p>
        <input type="submit" value="Thêm mới">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang thêm mới sản phẩm theo địa chỉ http://localhost/admin/product/add.php để kiểm tra.

Tải tập tin lên máy chủ (Upload):

Upload là thao tác tải một (Hoặc nhiều) tập tin từ máy người dùng lên máy chủ để lưu trữ.

Để tải tập tin lên máy chủ các bạn cần phải đảm bảo các yếu tố sau:
  • Form HTML chứa input file phải khai báo thuộc tính "enctype" có giá trị là "multipart/form-data".
  • Thư mục chứa tập tin được tải lên phải tồn tại và được quyền ghi tập tin.
  • Tập tin được tải lên phải đảm bảo thỏa mãn các yêu cầu do người lập trình quy định (Nếu có).
Để viết mã lệnh upload các bạn cần quan tâm tới biến của PHP là $_FILES. Biến $_FILES là một mãng chứa các thông tin liên quan tới tập tin được tải lên như tên (Name), kích thước (Size)...

Các bạn có thể tìm hiểu thêm về biến $_FILES tại địa chỉ http://php.net/manual/en/reserved.variables.files.php.

Hàm move_uploaded_file dùng để di chuyển tập tin tạm được lưu trữ tạm thời ở thư mục tạm của máy chủ sang thư mục chứa tập tin được tải lên do người lập trình khai báo.

Các bạn có thể tìm hiểu thêm về upload tại địa chỉ http://php.net/manual/en/features.file-upload.php và hàm move_uploaded_file tại địa chỉ http://php.net/manual/en/function.move-uploaded-file.php.
 
PHẦN 18: TRANG CHỈNH SỬA SẢN PHẨM

Nội dung kiến thức phần này gồm:
  • Câu lệnh IF...ELSE ngắn gọn (Viết tắt).
Trong thư mục admin/product, tạo mới tập tin edit.php để viết mã lệnh trang chỉnh sửa sản phẩm.

Nội dung tập tin admin/product/edit.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/category.php';
require '../../models/product.php';

//Lấy product_id từ URL
$product_id = $_GET['product_id'];

//Nếu có post dữ liệu lên thì xử lý cập nhật
if ($_POST) {
    //Tải hình ảnh lên máy chủ (Upload)
    if (($image = $_FILES['image']['name']) != null) {
        move_uploaded_file($_FILES['image']['tmp_name'], 'userfiles/' . $image);
    } else {
        $image = null;
    }

    //Nhận dữ liệu từ form và gán vào một mãng
    $data = array(
        'category_id' => $_POST['category_id'],
        'name' => $_POST['name'],
        'detail' => $_POST['detail'],
        'image' => $image,
        'price' => $_POST['price'],
        'status' => isset($_POST['status']) ? 1 : 0,
        'modified' => date('Y-m-d H:i:s')
    );

    //Cập nhật
    if (edit_product($data, $product_id, $connect)) {
        //Tạo session để lưu cờ thông báo thành công
        $_SESSION['success'] = true;

        //Tải lại trang (Mục đích là để tải lại thông tin mới)
        header('location:edit.php?product_id=' . $product_id);
    }
}

//Lấy thông tin sản phẩm để trình bày trên form
$product = get_product_by_id($product_id, $connect);

//Lấy danh sách danh mục sản phẩm có trạng thái kích hoạt (Status = 1)
$category_active_list = get_category_active_list($connect);

//Require tập tin giao diện (View)
require '../../views/admin/product/edit.tpl.php';
?>
Mở tập tin models/product.php và thêm vào khối lệnh mới dưới đây:
PHP:
function get_product_by_id($product_id, $connect)
{
    //SQL
    $sql = "SELECT * FROM tbl_product WHERE product_id = $product_id";

    //Query
    $query = mysqli_query($connect, $sql);

    //Return
    return mysqli_fetch_assoc($query);
}

function edit_product($data, $product_id, $connect)
{
    //SQL
    $sql = "UPDATE tbl_product SET category_id = {$data['category_id']}, name = '{$data['name']}', detail = '{$data['detail']}', price = {$data['price']}, status = {$data['status']}, modified = '{$data['modified']}'";

    //Nếu có cập nhật hình ảnh
    if ($data['image'] !== null) {
        $sql .= ", image = '{$data['image']}'";
    }

    //Điều kiện
    $sql .= " WHERE product_id = $product_id";

    //Return
    return mysqli_query($connect, $sql);
}
Trong thư mục views/admin/product, tạo mới tập tin edit.tpl.php để trình bày giao diện trang chỉnh sửa sản phẩm.

Nội dung tập tin views/admin/product/edit.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - Sản phẩm - Chỉnh sửa</title>
</head>
<body>
<form name="edit" method="post" enctype="multipart/form-data" action="">
    <?php if (isset($_SESSION['success'])): ?>
        <p style="color: green;">Sản phẩm đã được chỉnh sửa thành công!</p>
        <?php unset($_SESSION['success']); ?>
    <?php endif; ?>
    
    <p>
        <label>Danh mục:</label>
        <select name="category_id">
            <?php while ($category_active = mysqli_fetch_assoc($category_active_list)): ?>
                <option value="<?php echo $category_active['category_id']; ?>" <?php echo ($category_active['category_id'] == $product['category_id']) ? 'selected="selected"' : ''; ?>>
                    <?php echo $category_active['name']; ?>
                </option>
            <?php endwhile; ?>
        </select>
    </p>
    <p>
        <label>Tên sản phẩm:</label>
        <input type="text" name="name" value="<?php echo $product['name']; ?>">
    </p>
    <p>
        <label>Chi tiết:</label>
        <textarea name="detail"><?php echo $product['detail']; ?></textarea>
    </p>
    <p>
        <label>Hình ảnh:</label>
        <input type="file" name="image">
    </p>
    <p>
        <label>Giá bán:</label>
        <input type="text" name="price" value="<?php echo $product['price']; ?>">
    </p>
    <p>
        <label>Trạng thái:</label>
        <input type="checkbox" name="status" value="1" <?php echo ($product['status'] == 1) ? 'checked="checked"' : ''; ?>>
    </p>
    <p>
        <input type="submit" value="Chỉnh sửa">
    </p>
</form>
</body>
</html>
Các bạn truy cập trang danh sách sản phẩm và nhấp vào tên sản phẩm để truy cập tới trang chỉnh sửa sản phẩm.

Câu lệnh IF...ELSE ngắn gọn (Viết tắt):

Ngoài cách sử dụng câu lệnh IF...ELSE thông thường mà tôi đã hướng dẫn các bạn thì PHP còn cung cấp thêm một cách sử dụng IF...ELSE khác giúp người lập trình sử dụng ngắn gọn hơn. Các bạn sử dụng IF...ELSE ngắn gọn theo mẫu sau:
PHP:
Điều_kiện ? Nếu_điều_kiện_là_TRUE : Nếu_điều_kiện_là_FALSE;
Ví dụ:
PHP:
echo (1 > 0) ? 'OK!' : 'Not OK!';
Ví dụ trên sẽ in ra màn hình chữ "OK!". Như vậy, dòng lệnh ở ví dụ trên tương đương với khối lệnh sau:
PHP:
if (1 > 0) {
    echo 'OK!';
} else {
    echo 'Not OK!';
}
Các bạn có thể tìm hiểu thêm về những cách viết khác của các câu lệnh điều kiện (Điều khiển) tại địa chỉ http://php.net/manual/en/control-structures.alternative-syntax.php.
 
PHẦN 19: XOÁ SẢN PHẨM

Phần này tôi không trình bày kiến thức lập trình PHP. Các bạn thực hiện theo các hướng dẫn dưới đây để hoàn thành chức năng xóa sản phẩm.

Trong thư mục admin/product, tạo mới tập tin delete.php để viết mã lệnh chức năng xóa sản phẩm.

Nội dung tập tin admin/product/delete.php như sau:
PHP:
<?php
//Khởi động session
session_start();

//Kiểm tra nếu chưa đăng nhập thì quay về trang đăng nhập
if (!isset($_SESSION['user'])) {
    header('location:../user/login.php');
}

//Require các tập tin cần thiết
require '../../configs/config.php';
require '../../libraries/connect.php';
require '../../models/product.php';

//Lấy product_id từ URL
$product_id = $_GET['product_id'];

//Xóa
delete_product($product_id, $connect);

//Quay về trang danh sách sản phẩm
header('location:list.php');
?>
Mở tập tin models/product.php và thêm vào khối lệnh mới dưới đây:
PHP:
function delete_product($product_id, $connect)
{
    //SQL
    $sql = "DELETE FROM tbl_product WHERE product_id = $product_id";

    //Return
    return mysqli_query($connect, $sql);
}
Xóa là một chức năng nên các bạn không phải tạo giao diện (View).

Các bạn truy cập trang danh sách sản phẩm, ở cột "Tác vụ" các bạn chọn tác vụ "Xóa" để thực hiện xóa sản phẩm tương ứng.
 
Back
Top