Hướng dẫn - Từng bước học lập trình PHP nâng cao qua dự án website giới thiệu sản phẩm | VN-Zoom | Cộng đồng Chia Sẻ Kiến Thức Công Nghệ và Phần Mềm Máy Tính

Adblocker detected! Please consider reading this notice.

We've detected that you are using AdBlock Plus or some other adblocking software which is preventing the page from fully loading.

We need money to operate the site, and almost all of it comes from our online advertising.

If possible, please support us by clicking on the advertisements.

Please add vn-z.vn to your ad blocking whitelist or disable your adblocking software.

×

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

filiallion

Búa Gỗ Đôi
Sau loạt bài hướng dẫn "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" tôi sẽ tiếp tục viết loạt bài hướng dẫn các bạn học lập trình PHP nâng cao thông qua việc hoàn thành dự án website giới thiệu sản phẩm (Tương tự như ở loạt bài cơ bản).

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) các bạn sẽ được học các vấn đề liên quan tới lập trình PHP nâng cao (Lập trình hướng đối tượng).

Các bạn lưu ý, bài hướng dẫn này tôi chỉ trình bày và giải thích các vấn đề nâng cao trong lập trình PHP. Các vấn đề tôi đã trình bày, giải thích ở loạt bài cơ bản rồi thì tôi sẽ không trình bày hay giải thích cho các bạn nữa. Và tôi cũng khuyên các bạn nên tìm hiểu, nghiên cứu thật kỹ phần cơ bản trước khi tìm hiểu phần nâng cao này.

Chân thành cảm ơn sự quan tâm của các bạn!
 
Sửa lần cuối:

filiallion

Búa Gỗ Đôi
PHẦN 1: THÔNG TIN CẤU HÌNH WEBSITE

Về cấu trúc thư mục, cấu trúc DB và các chức năng của website tương tự như ở loạt bài hướng dẫn "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".

Nội dung kiến thức phần này gồm:
  • Lớp (Class).
  • Hằng (Constant).
Trong thư mục configs, tạo mới tập tin Config.php để khai báo các thông tin cấu hình website. Bạn lưu ý tập tin Config.php tôi viết hoa chữ "C". Chuẩn đặt tên tập tin, lớp, hàm, biến... các bạn lưu ý các nội dung hướng dẫn của tôi.

Nội dung tập tin configs/Config.php như sau:
PHP:
<?php
class Config
{
    //Thông tin website
    const SITE_URL = 'http://localhost/';
    const BASE_PATH = 'C:\Wamp\www\\';

    //Thông tin cấu hình DB
    const DB_SERVER = 'localhost';
    const DB_USERNAME = 'root';
    const DB_PASSWORD = '';
    const DB_DATABASE = 'training_php_02';
}
?>
1. Lớp (Class):

Lớp các bạn có thể hiểu như một bản thiết kế (Hay khuôn mẫu) của một đối tượng nào đó với các thuộc tính, trạng thái, hành động... theo mục đích của người lập trình.

Bên trong một lớp có các thành phần:
  • Thuộc tính (Property): Mô tả thuộc tính của đối tượng. Thuộc tính của một lớp bao gồm các biến, các hằng, hay tham số nội tại của lớp đó. Ở đây, vai trò quan trọng nhất của các thuộc tính là các biến vì chúng có thể bị thay đổi trong suốt quá trình hoạt động của một đối tượng. Các thuộc tính có thể được xác định kiểu và kiểu của chúng có thể là các kiểu dữ liệu cổ điển hay đó là một lớp đã định nghĩa từ trước.
  • Phương thức (Method): Mô tả một hành vi nào đó của đối tượng (Hoặc của lớp). Phương thức thực chất như một hàm bên trong một lớp.
Ví dụ:

Lớp "Người" dùng để chỉ những thực thể sống trên trái đất với các thuộc tính là "chân, tay, mắt, mũi..." và có những hành vi như "đi, đứng, nằm...".

Để tạo ra một lớp, các bạn thực hiện theo mẫu sau:
Mã:
class Tên_lớp
{
    //Nội dung của lớp
}
Ví dụ:
PHP:
class Person
{}
Các bạn lưu ý khi đặt tên lớp:

  • Tên lớp trùng với tên tập tin PHP (Vì vậy tên tập tin PHP cũng phải tuân thủ quy tắc đặt tên của lớp).
  • Nếu tên lớp có từ hai từ trở lên thì phải viết hoa đầu từ và có thể viết liền nhau hoặc sử dụng dấu gạch dưới "_" để phân cách (Ví dụ: Person, UserProfile hoặc User_Profile).
Liên quan tới lớp còn có khái niệm đối tượng (Object), thuộc tính, phương thức.. tôi sẽ trình bày sau.

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

2. Hằng (Constant):

Hằng là gì thì tôi đã trình bày ở loạt bài hướng dẫn "cơ bản". Ở phần này thì tôi chỉ trình bày cho các bạn biết cách khai báo, sử dụng hằng trong một lớp.

Tập tin configs/Config.php, tôi đã khai báo 6 hằng (SITE_URL, BASE_PATH, DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE). Như vậy, để khai báo hằng trong một lớp các bạn thực hiện theo mẫu sau:
Mã:
const Tên_hằng = Giá_trị_của_hằng;
Ví dụ:
PHP:
const SITE_URL = 'http://localhost/';
Các bạn có thể tìm hiểu thêm về hằng tại địa chỉ http://php.net/manual/en/language.oop5.constants.php.
 

filiallion

Búa Gỗ Đôi
mong a làm bàn pdf hoặc video để share ạ
PDF thì mình chưa nghĩ tới nhưng video thì thời gian tới mình sẽ sắp xếp thực hiện bộ video cơ bản trước rồi mới tới bài nâng cao này.
 

filiallion

Búa Gỗ Đôi
PHẦN 2: KẾT NỐI CƠ SỞ DỮ LIỆU

Nội dung kiến thức phần này gồm:
  • Thuộc tính (Property).
  • Phương thức (Method).
  • Kế thừa (Extends).
Trong thư mục libraries, các bạn tạo mới 2 tập tin MySql.php và Db.php để viết mã lệnh kết nối DB.

Nội dung tập tin libraries/MySql.php như sau:
PHP:
<?php
class MySql
{
    protected $connection;
    protected $query;
 
    public function __construct()
    {
        //Kết nối DB
        $this->connection = mysqli_connect(Config::DB_SERVER, Config::DB_USERNAME, Config::DB_PASSWORD, Config::DB_DATABASE) or die('Not connected DB!');
     
        //Yêu cầu lưu trữ UTF8 (Tiếng Việt)
        mysqli_query('SET NAMES UTF8', $this->connection);
    }
 
    public function query($sql)
    {
        //Truy vấn
        return $this->query = mysqli_query($this->connection, $sql);
    }
 
    public function fetch()
    {
        //Lấy dữ liệu
        return mysqli_fetch_assoc($this->query);
    }
}
?>
Nội dung tập tin libraries/Db.php như sau:
PHP:
<?php
require Config::BASE_PATH . 'libraries/MySql.php';

class Db extends MySql
{}
?>
Như các bạn thấy, toàn bộ các câu lệnh kết nối tới DB đều nằm ở lớp MySql được viết trong tập tin libraries/MySql.php. Vậy lớp Db được viết trong tập tin libraries/Db.php có vai trò gì khi mà lớp Db này chỉ mở rộng (Extends) từ lớp MySql chứ không có thêm thuộc tính hay phương thức nào mới? Lớp Db này có một vai
trò quan trọng mà các bạn nên tìm hiểu thêm.

Các bạn lưu ý tới 2 phương thức query và fetch của lớp MySql. Trong đó:
  • Phương thức query dùng để thực thi câu lệnh
    SQL và gán kết quả vào thuộc tính $query để sử dụng ở phương thức fetch
    (Trong trường hợp truy vấn lấy dữ liệu).
  • Phương thức fetch dùng để lấy từng dòng dữ
    liệu theo kết quả truy vấn được lưu ở thuộc tính $query (Trong trường
    hợp truy vấn lấy dữ liệu).
1. Thuộc tính (Property):

Để khai báo thuộc tính trong lớp, các bạn thực hiện theo mẫu sau:
Mã:
Phạm_vi $Tên_thuộc_tính;
Hoặc
Mã:
Phạm_vi $Tên_thuộc_tính = Giá_trị_của_thuộc_tính;
Thuộc tính trong lớp phải có phạm vị hoạt động (Tầm vực) và được thể hiện qua 3 từ khóa phạm vi sau:
  • Public: Có phạm vị sử dụng rộng nhất và không
    bị giới hạn. Nếu các bạn không khai báo phạm vi cho thuộc tính thì mặc
    định thuộc tính đó là public.
  • Protected: Có phạm vi hoạt động bên trong nội tại của lớp và các lớp kế thừa (Còn gọi là lớp con hay lớp dẫn xuất).
  • Private: Có phạm vi hoạt động hẹp nhất, chỉ hoạt động bên trong nội tại của lớp.
Ví dụ:
PHP:
public $a;
protected $b;
private $c;
Các bạn lưu ý về cách đặt tên thuộc tính (Áp dụng cho cả tên biến) như sau:
  • Tuân theo các qui tắc đặt tên biến.
  • Từ đầu tiên là chữ thường. Nếu có từ 2 từ trở
    lên thì chữ cái đầu tiên của từ thứ hai trở đi là chữ hoa (Ví dụ:
    $user, $userProfile, $deltailUserProfile).
Để gọi (Sử dụng) thuộc tính đã được khai báo các bạn thực hiện theo mẫu sau:
Mã:
$this->Tên_thuộc_tính;
Hoặc
Mã:
self::$Tên_thuộc_tính;
Hoặc
Mã:
parent::$Tên_thuộc_tính;
Ví dụ:
PHP:
$this->a;
self::$b;
parent::$c;
Với 3 mẫu trên, tùy từng trường hợp các bạn sử dụng cho đúng chứ
không phải muốn sử dụng mẫu nào cũng được. Các bạn có thể sử dụng như
sau:
  • Mẫu thứ nhất được dùng khi gọi một thuộc tính của chính lớp đó hoặc lớp cơ sở (Còn gọi là lớp cha).
  • Mẫu thứ hai được dùng khi gọi một thuộc tính của chính lớp đó.
  • Mẫu thứ ba được dùng khi gọi một thuộc tính của lớp cơ sở.
Trình bày thì đơn giản như vậy nhưng khi sử dụng thì tùy từng mục đích, yêu cầu mà các bạn sử dụng cho phù hợp. Ngoài ra, còn có một cách sử dụng nữa dành cho thuộc tính có phạm vi public tôi sẽ trình bày sau.

Các bạn có thể tìm hiểu thêm về thuộc tính tại địa chỉ http://php.net/manual/en/language.oop5.properties.php.

2. Phương thức (Method):

Để khai báo phương thức trong lớp, các bạn thực hiện theo mẫu sau:
Mã:
Phạm_vi function Tên_phương_thức()
{
    //Nội dung phương thức
}
Hoặc
Mã:
Phạm_vi function Tên_phương_thức($Tham_số_1, $Tham_số_2, $Tham_số_n)
{
    //Nội dung phương thức
}
Ví dụ:
PHP:
public function query($sql)
{}
Phạm vi của phương thức hoàn toàn tương tự với phạm vi của thuộc tính.

Quy tắc đặt tên phương thức cũng tương tự như thuộc tính.

Để gọi (Sử dụng) phương thức đã khai báo các bạn thực hiện theo mẫu sau:
Mã:
$this->Tên_phương_thức();
Hoặc
Mã:
self::Tên_phương_thức();
Hoặc
Mã:
parent::Tên_phương_thức();
Ví dụ:
PHP:
$this->query('SELECT * FROM tbl_user');
self::fetch();
parent::get();
Ba cách sử dụng trên cũng hoàn toàn tương tự như thuộc tính.

Ngoài các phương thức do người lập trình định nghĩa, PHP còn cung cấp các phương thức magic như: __construct, __destruct... Các bạn có thể tìm hiểu thêm về các phương thức magic tại địa chỉ http://php.net/manual/en/language.oop5.magic.php.

Thuộc tính và phương thức còn nhiều kiến thức nâng cao khác mà tôi không trình bày cho các bạn ở đây. Trong quá trình tìm hiểu, các bạn có vấn đề cần hỗ trợ thì các bạn có thể hỏi và tôi sẽ giải đáp cho các bạn.

3. Kế thừa (Extends):

Trong PHP, các bạn có thể mở rộng lớp, hay nói một cách khác, một lớp có thể được kế thừa từ một lớp nào đó đã được khai báo trước. Trong đó, lớp được kế thừa gọi là lớp cơ sở (Lớp cha), lớp kế thừa gọi là lớp dẫn xuất (Lớp con). Lớp dẫn xuất có quyền sử dụng các thuộc tính, phương thức có phạm vi public và protected của lớp cơ sở.

Một lớp có thể kế thừa các thuộc tính và phương thức của lớp khác, bằng cách sử dụng từ khóa extends. Các bạn có thể khai báo kế thừa theo mẫu sau:
Mã:
class Lớp_dẫn_xuất extends Lớp_cơ_sở
{}
Ví dụ:
PHP:
class Db extends MySql
{}
Với ví dụ trên, lớp Db được gọi là lớp dẫn xuất, lớp MySql được gọi là lớp cơ sở. Toàn bộ các thuộc tính, phương thức có phạm vi public và protected của lớp MySql (Lớp cơ sở) đều được lớp Db (Lớp dẫn xuất) kế thừa (Tức có quyền sử dụng).

Các bạn có thể tìm hiểu thêm về kế thừa (Chủ yếu là nói về từ khóa extends) tại địa chỉ http://php.net/manual/en/keyword.extends.php.

Kế thừa và các kỹ thuật lập trình liên quan tới kế thừa các bạn có thể tìm hiểu thêm để mở rộng kiến thức.
 

filiallion

Búa Gỗ Đôi
PHẦN 3: 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).

Các bạn lưu ý là trang chủ quản trị tôi sẽ không hướng dẫn các bạn.

Nội dung kiến thức phần này gồm:
  • Đối tượng (Object).
Trong thư mục admin, các bạn tạo mới 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 '../../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'];
    
    //Khởi tạo đối tượng người dùng (User)
    $userModel = new User();
    
    //Lấy thông tin người dùng
    $user = $userModel->getByUsername($username);
    
    //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->getPassword() === 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';
?>
Trong thư mục models các bạn tạo mới 2 tập tin UserObj.php và User.php để thể hiện đối tượng người dùng (Lớp UserObj) và tương tác với DB (Lớp User).

Nội dung tập tin models/UserObj.php như sau:
PHP:
<?php
class UserObj
{
    protected $userId;
    protected $username;
    protected $password;
    protected $fullname;
    protected $email;
    protected $status;
    protected $created;
    protected $modified;
    
    public function setUserId($userId)
    {
        $this->userId = $userId;
    }
    
    public function getUserId()
    {
        return $this->userId;
    }
    
    public function setUsername($username)
    {
        $this->username = $username;
    }
    
    public function getUsername()
    {
        return $this->username;
    }
    
    public function setPassword($password)
    {
        $this->password = $password;
    }
    
    public function getPassword()
    {
        return $this->password;
    }
    
    public function setFullname($fullname)
    {
        $this->fullname = $fullname;
    }
    
    public function getFullname()
    {
        return $this->fullname;
    }
    
    public function setEmail($email)
    {
        $this->email = $email;
    }
    
    public function getEmail()
    {
        return $this->email;
    }
    
    public function setStatus($status)
    {
        $this->status = $status;
    }
    
    public function getStatus()
    {
        return $this->status;
    }
    
    public function setCreated($created)
    {
        $this->created = $created;
    }
    
    public function getCreated()
    {
        return $this->created;
    }
    
    public function setModified($modified)
    {
        $this->modified = $modified;
    }
    
    public function getModified()
    {
        return $this->modified;
    }
}
?>
Nội dung tập tin models/User.php như sau:
Mã:
<?php
require_once Config::BASE_PATH . 'libraries/Db.php';
require_once Config::BASE_PATH . 'models/UserObj.php';

class User
{
    protected $db;
    
    public function __construct()
    {
        $this->db = new Db();
    }
    
    public function getByUsername($username)
    {
        //SQL
        $sql = "SELECT * FROM tbl_user WHERE username = '$username' AND status = 1";
        
        //Query
        $this->db->query($sql);
        
        //Fetch
        $row = $this->db->fetch();
        
        //Khởi tạo đối tượng UserObj
        $userObj = new UserObj();
        
        //Gán thông tin
        $userObj->setUserId($row['user_id']);
        $userObj->setUsername($row['username']);
        $userObj->setPassword($row['password']);
        $userObj->setFullname($row['fullname']);
        $userObj->setEmail($row['email']);
        $userObj->setStatus($row['status']);
        $userObj->setCreated($row['created']);
        $userObj->setModified($row['modified']);
        
        //Return
        return $userObj;
    }
}
?>
Trong thư mục views/admin, các bạn tạo mới thư mục tên là user để chứa các tập tin trình bày giao diện HTML trang người dùng.

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.

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ới tập tin 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.

Đối tượng (Object):

Đối tượng có thể xem như một thực thể của lớp. Trong thực tế, các đối tượng thường được trừu tượng hóa qua việc định nghĩa các lớp. Trong đó:

  • Tập hợp các giá trị hiện có của các thuộc tính tạo nên trạng thái của một đối tượng.
  • Mỗi phương thức hay mỗi dữ liệu nội tại cùng với các tính chất được định nghĩa được xem là một đặc tính riêng của đối tượng.
Như vậy có thể hiểu một đối tượng được tạo ra từ một lớp và mang các đặc điểm, trạng thái của lớp đó. Sự khác biệt giữa lớp và đối tượng là không rõ ràng, vì vậy để phân biệt hai khái niệm này đòi hỏi các bạn phải có kinh nghiệm trong lập trình hướng đối tượng (OOP).

Để khởi tạo một đối tượng các bạn thực hiện theo mẫu sau:
Mã:
$Tên_đối_tượng = new Tên_lớp();
Ví dụ:
PHP:
$userObj = new UserObj();
Đối tượng được tạo ra từ một lớp có quyền truy cập (Sử dụng) các thuộc tính và phương thức có phạm vi public của lớp đó. Để truy cập các thuộc tính, phương thức của lớp các bạn thực hiện theo mẫu sau:
Mã:
$Tên_đối_tượng->Tên_thuộc_tính;
$Tên_đối_tượng->Tên_phương_thức();
Ví dụ:
PHP:
$obj = new Obj();
$obj->propertyOne;
$obj->methodOne();
Với ví dụ trên thì các bạn biết chắc chắn rằng thuộc tính $propertyOne và phương thức methodOne đều có phạm vi public.

Các bạn có thể tìm hiểu thêm về đối tượng tại địa chỉ http://php.net/manual/en/language.types.object.php.
 

filiallion

Búa Gỗ Đôi
PHẦN 4: TRANG DANH SÁCH NGƯỜI DÙNG

Từ phần này tôi sẽ trình bày cho các bạn các kiến thức PHP nâng cao mà không liên quan tới dự án website tôi đang hướng dẫn các bạn thực hiện.

Nội dung kiến thức phần này gồm:
  • Biểu thức chính quy (Regular expressions).
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 '../../models/User.php';

//Khởi tạo đối tượng người dùng (User)
$userModel = new User();

//Lấy danh sách người dùng
$userList = $userModel->getList();

//Tiêu đề trang
$title = 'Người dùng - Danh sách';

//Giao diện (View)
$view = 'user/list.tpl.php';

//Require khung giao diện (Layout)
require '../../views/admin/layout.tpl.php';
?>
Mở tập tin models/User.php và thêm vào lớp User khối lệnh mới dưới đây:
PHP:
public function getList()
{
    //SQL
    $sql = "SELECT * FROM tbl_user ORDER BY user_id DESC";

    //Query
    $this->db->query($sql);

    //Tạo mãng lưu trữ
    $listUser = array();

    //Fetch
    while ($row = $this->db->fetch()) {
        //Khởi tạo đối tượng UserObj
        $userObj = new UserObj();

        //Gán thông tin
        $userObj->setUserId($row['user_id']);
        $userObj->setUsername($row['username']);
        $userObj->setPassword($row['password']);
        $userObj->setFullname($row['fullname']);
        $userObj->setEmail($row['email']);
        $userObj->setStatus($row['status']);
        $userObj->setCreated($row['created']);
        $userObj->setModified($row['modified']);

        //Gán vào mãng lưu trữ
        $listUser[] = $userObj;
    }

    //Return
    return $listUser;
}
Về phần giao diện (View) của website, tôi mở rộng thêm phần khung giao diện (Layout) của website. Khung giao diện là phần giao diện HTML chung của toàn bộ các trang (Trừ trang đăng nhập). Mục đích của việc tạo ra khung giao diện là để giúp cho việc lập trình, bảo trì đơn giản, khoa học hơn.

Trong thư mục views/admin, tạo mới tập tin layout.tpl.php để trình bày khung giao diện của website.

Nội dung tập tin views/admin/layout.tpl.php như sau:
PHP:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Quản trị - <?php echo $title; ?></title>
</head>
<body>
    <?php require Config::BASE_PATH . 'views/admin/' . $view; ?>
</body>
</html>
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:
<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 foreach ($userList as $user): ?>
        <tr>
            <td>
                <?php echo $user->getUserId(); ?>
            </td>
            <td>
                <a href="<?php echo Config::SITE_URL . 'admin/user/edit.php?user_id=' . $user->getUserId(); ?>"><?php echo $user->getUsername(); ?></a>
            </td>
            <td>
                <?php echo $user->getFullname(); ?>
            </td>
            <td>
                <?php echo ($user->getStatus() == 1) ? 'Kích hoạt' : 'Không kích hoạt'; ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($user->getCreated())); ?>
            </td>
            <td>
                <?php echo date('d/m/Y H:i:s', strtotime($user->getModified())); ?>
            </td>
            <td>
                <a href="<?php echo Config::SITE_URL . 'admin/user/delete.php?user_id=' . $user->getUserId(); ?>">Xóa</a>
            </td>
        </tr>
    <?php endforeach; ?>
</table>
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.

Biểu thức chính quy (Regular expressions):

Biểu thức chính quy là một chuỗi hoặc một mẫu các ký tự miêu tả một bộ các chuỗi khác.

Biểu thức chính quy thường được sử dụng trong trường hợp tìm kiếm một chuỗi bên trong một chuỗi khác, thay thế một chuỗi bằng chuỗi khác và có thể tách một chuỗi thành nhiều chuỗi.

Nếu bạn sử dụng tốt biểu thức chính quy, chúng sẽ đơn giản hơn nhiều trong lập trình và quá trình xử lý văn bản, có những vấn đề sẽ không thể giải quyết được nếu không sử dụng biểu thức chính quy.

Về biểu thức chính quy, các bạn có thể tìm hiểu thêm về khái niệm, nguồn gốc của nó. Và tôi khuyên các bạn nên sử dụng biểu thức chính quy để việc lập trình trở nên đơn giản, tối ưu và chính xác hơn.

Tôi giới thiệu với các bạn một số cú pháp về biểu thức chính quy sau đây hi vọng các bạn có đủ kiến thức để tiếp tục tìm hiểu:

- Dấu ngoặc vuông ([]): Dấu ngoặc vuông có một ý nghĩa đặc biệt khi sử dụng trong bối cảnh của biểu thức chính quy. Dấu ngoặc vuông thường được dùng khi các bạn muốn tìm kiếm một loạt các ký tự theo mẫu đã khai báo bên trong nó.

Ví dụ:

[0-9]: Phù hợp với bất kỳ các chữ số từ 0 đến 9.
[a-z]: Phù hợp với bất kỳ các ký tự chữ in thường từ a đến z.
[A-Z]: Phù hợp với bất kỳ các ký tự chữ in hoa từ A đến Z.
[0-9a-zA-Z]: Phù hợp với bất kỳ các chữ số từ 0 đến 9, ký tự in thường và in hoa từ a đến z.

- Các ký hiệu định lượng: Các bạn cần quan tâm tới các ký hiệu +, *, ?, {} và $. Các ký hiệu này biểu thị số lượng hoặc vị trí hoặc một ký tự cụ thể nào đó.

Ví dụ:

p+: Phù hợp với bất kỳ chuỗi mà có chứa ít nhất một ký tự p.
p*: Phù hợp với bất kỳ chuỗi mà có chứa số 0 hoặc chứa nhiều hơn ký tự p.
p?: Có ý nghĩa tương tự như p*.
p{5}: Phù hợp với chuỗi có chứa đúng 5 ký tự p.
p{1,5}: Phù hợp với bất kỳ chuỗi mà có chứa từ 1 đến 5 ký tự p.
p{5,}: Phù hợp với bất kỳ chuỗi mà có chứa ít nhất 5 ký tự p.
p$: Phù hợp với bất kỳ chuỗi mà có ký tự p là cuối cùng.
^p: Phù hợp với bất kỳ chuỗi mà có ký tự p là bắt đầu.
[^a-zA-Z]: Phù hợp với bất kỳ chuỗi mà không chứa các ký tự in thường và in hoa từ a đến z.
^.{2}$: Phù hợp với bất kỳ chuỗi có chứa hai ký tự.

Lưu ý là các mẫu ví dụ trên không bao gồm dấu hai chấm.

Ngoài loại biểu thức chính quy như trên (POSIX), trong PHP còn có một loại biểu thức chính quy khác gọi là PCRE (Hoặc PERL) các bạn có thể tìm hiểu thêm.

Các bạn có thể tìm hiểu thêm về các hàm PHP xử lý biểu thức chính quy tại địa chỉ http://php.net/manual/en/ref.regex.phphttp://php.net/manual/en/ref.pcre.php.
 

filiallion

Búa Gỗ Đôi
PHẦN 5: TRANG THÊM MỚI NGƯỜI DÙNG

Nội dung kiến thức phần này gồm:
  • Xử lý lỗi (Error handling).
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 '../../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 (Có thể sử dụng UserObj để lưu dữ liệu)
    $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')
    );

    //Khởi tạo đối tượng người dùng (User)
    $userModel = new User();

    //Thêm mới
    if ($userModel->add($data)) {
        //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');
    
        //Ngừng thực thi
        exit();
    }
}

//Tiêu đề trang
$title = 'Người dùng - Thêm mới';

//Giao diện (View)
$view = 'user/add.tpl.php';

//Require khung giao diện (Layout)
require '../../views/admin/layout.tpl.php';
?>
Mở tập tin models/User.php và thêm vào lớp User khối lệnh mới dưới đây:
PHP:
public function add($data)
{
    //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 $this->db->query($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:
<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>
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.

Xử lý lỗi (Error handling):

Xử lý lỗi là quá trình bắt lỗi chương trình (Khối lệnh) do người lập trình viết với mục đích thực hiện những hành động (Hoặc thông báo) tương ứng với lỗi để chương trình không thực thi sai mục đích.

Việc xử lý lỗi trong PHP khá đơn giản và các bạn sẽ thường thấy 2 cách xử lý lỗi sau đây:
  • Sử dụng hàm die.
  • Sử dụng trường hợp ngoại lệ (Exceptions).
Hàm die có chức năng kết thúc thực thi khối lệnh. Các lập trình viên thường ít khi sử dụng hàm die vào mục đích bắt lỗi vì thường không đáp ứng được yêu cầu lập trình.

Ví dụ:
PHP:
if (!file_exists('path/content.txt')) {
    die('File not found!');
} else {
    unlink('path/content.txt');
}
Kể từ PHP 5 trở đi thì có thêm cách xử lý lỗi chuyên nghiệp hơn đó là dùng ngoại lệ (Exceptions) với cú pháp try...catch. Các bạn có thể sử dụng theo mẫu sau:
Mã:
try {
    //Khối lệnh cần bắt lỗi
} catch(Exception $Biến_exception) {
    //Xử lý ngoại lệ
}
Ví dụ:
PHP:
try {
    if (!file_exists('path/content.txt')) {
        //Nếu không tìm thấy tập tin thì lưu thông báo lỗi và chuyển sang catch
        throw new Exception('File not found!');
    }

    //Nếu tìm thấy tập tin
    unlink('path/content.txt');
} catch (Exception $e) {
    echo $e->getMessage();
}
Các bạn có thể tìm hiểu thêm về xử lý lỗi ngoại lệ tại địa chỉ http://php.net/manual/en/language.exceptions.php.

Ngoài ra, trong PHP các bạn có thể tùy biến xuất các thông báo lỗi PHP mà người lập trình không kiểm soát được bằng hàm error_reporting. Các bạn có thể sử dụng hàm error_reporting theo mẫu sau:
Mã:
error_reporting(Cấp_độ_báo_lỗi);
Ví dụ:
PHP:
error_reporting(E_ALL);
error_reporting(0);
Trong đó, câu lệnh đầu với cấp độ "E_ALL" là hiển thị tất cả các thông báo lỗi còn câu lệnh thứ hai thì ngăn chặn tất cả các thông báo lỗi.

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


Top