Đăng nhập Đăng ký website 
DÙNG THỬ MIỄN PHÍ

Phần 3: Tổ chức cấu trúc và mô hình MVC cho PHP Framework

Trong phần này chúng ta sẽ phân tích và thống nhất các phần sau:
+ Tên và cấu trúc thư mục ban đầu của dự án DFramework
+ Chọn được dạng Url sẽ sử dụng cho toàn bộ hệ thống
+ Cơ chế hoạt động của Template Engine
+ Lập trình và chạy thử hệ thống DFramework

Xây dựng cấu trúc hệ thống và Template Engine riêng là những bước cơ bản đầu tiên để hình thành lên framework.
Chúng ta sẽ không sử dụng bất kỳ mã nguồn nào có sẵn mà sẽ xây dựng tất cả mọi thứ từ A-Z.
Lưu ý: chúng ta không sử dụng mã nguồn có sẵn nghĩa là chúng ta không dùng code được cung cấp sẵn mà sẽ tự code, mô hình và cách thức tổ chức dữ liệu chúng ta vẫn tham khảo các mã nguồn khác để học hỏi điểm hay của từng loại và áp dụng vào đúng mục đích mà chúng ta cần.
Việc đầu tiên chúng ta cần làm là đặt một cái tên để dễ làm việc, chúng ta sẽ gọi hệ thống của mình là DFramework (Dynamic Framework) cho dễ nhớ, bạn có thể đặt bất kỳ tên nào bạn thích cũng được.
Chúng ta có thể đặt tất cả các file .php và .html vào cùng 1 thư mục cũng được, hoặc chia ra làm 2 thư mục là template để chứa file .html và libs để chứa file .php về mặt lập trình thì file nằm đâu cũng không ảnh hưởng gì cả, nhưng về mặt sử dụng, tìm kiếm hay nâng cấp sau này sẽ dễ dàng hơn, nhưng nếu chia quá nhiều thư mục nhỏ lại gây khó khăn, vì vậy chúng ta sẽ cố gắng tổ chức thư mục vào 2 hoặc 3 cấp là tối đa.
DFramework của chúng ta sẽ được tổ chức như sau:
File index.php nằm ở thư mục gốc
Các thư mục khác như sau:
+ config: là thư mục ta chứa những file config cho toàn bộ hệ thống
+ templates: là thư mục chứa tất cả các file giao diện, ta cần 2 loại là giao diện của website và giao diện dành cho phần quản trị, ta sẽ bố trí như sau: những file nằm trong thư mục templates là dành cho website, những file nằm trong thư mục manage sẽ dùng cho quản trị.
+ libs: là thư mục chứa tất cả các file lập trình php, tương ứng với templates ta sẽ có như sau: những file nằm trong thư mục libs là dành cho website, những file nằm trong thư mục manage sẽ dùng để lập trình cho quản trị.
+ thumb: là thư mục chứa tất cả các file tạm dùng trong quá trình hoạt động.
Như vậy tạm thời ban đầu DFramework của chúng ta sẽ có cấu trúc thư mục như sau:

Cấu trúc thư mục DFramework
Tổ chức mô hình MVC
Trong mô hình MVC thì Controller đóng vai trò xử lý tất cả các yêu cầu từ người dùng và trả về kết quả, trên thực tế đây chính là file index.php của chúng ta, tất cả các yêu cầu sẽ tập trung về file này, tùy theo yêu cầu mà các thành phần tương ứng sẽ được gọi lên để thực hiện.
Lưu ý: chúng ta cần tổ chức hệ thống theo mô hình MVC nghĩa là cách thức dữ liệu của chúng ta sẽ được xử lý theo mô hình này, không phải tất cả các chức năng đều cần có đủ 3 file đặt trong thư mục tương ứng model, view, controller thì mới gọi là mô hình MVC.
- Đối với website các đường dẫn (URL) là yếu tố chính để xác định kết quả mà website trả về. Chúng ta cùng tìm hiểu một số dạng URL để lựa chọn được dạng phù hợp cho DFramework. Việc lựa chọn này rất quan trọng vì nó sẽ ảnh hưởng tới cách thức lưu trữ và load dữ liệu của toàn bộ hệ thống mà chúng ta xây dựng sau này.
Dạng cơ bản: URL có dạng www.yourdomain.com/index.php?w=tintuc&id=8 đây là dạng cơ bản nhất, dạng url này không tối ưu cho Seo, để chuyển đổi thành Url thân thiện chúng ta sẽ phải cần đến mod_rewrite, trong trường hợp website có nhiều trang với nhiều dữ liệu cần truyền khác nhau ta sẽ cần rất nhiều lệnh chuyển đổi (thường dùng trong .htaccess), chúng ta sẽ không xây dựng website trên url này mà ngay từ đầu chúng ta sẽ xây dựng Url website tối ưu dành cho Seo.
Dạng 1: URL có 1 cấp duy nhất cũng chính là khóa dữ liệu. Ví dụ: www.yourdomain.com/kien-thuc-lap-trinh.html theo dạng này thì kien-thuc-lap-trinh sẽ là khóa chính để load dữ liệu, như vậy trong database sẽ cần tổ chức để chỉ có duy nhất 1 bài viết với khóa này.
Dạng 2: URL có 2 cấp trở lên, 1 cấp dùng làm khóa quản lý, 1 cấp làm khóa dữ liệu, 1 cấp dùng để truyền giá trị.
Ví dụ: www.yourdomain.com/tin-tuc/kien-thuc-lap-trinh.html
Cả 2 dạng đường dẫn trên đều đảm bảo dễ nhớ, tối ưu cho SEO, thân thiện với các Search Engine, tuy nhiên cách lập trình sẽ khác nhau rất nhiều, chúng ta cùng so sánh qua bảng sau:

Dạng 1 Dạng 2
Yêu cầu hiển thị dữ liệu từ table Tin tức
Domain.com/lap-trinh-php.html
=> Lấy dữ liệu từ table tin tức, table tin tức là mặc định.
Hoặc luôn dùng dạng đầy đủ:
Domain.com/tin-tuc-lap-trinh-php.html
Domain.com/tin-tuc/lap-trinh-php.html
=> Lấy dữ liệu từ table tin tức, nhận biết table thông qua khóa tin-tuc
Yêu cầu hiển thị dữ liệu từ table Sản phẩm
Domain.com/quat-treo-tuong.html
=> Dữ liệu mặc định lấy từ table Tin tức sẽ không đúng, trong trường hợp này cần thêm thông tin, sẽ cần url như sau:
Domain.com/san-pham-quat-treo-tuong.html
Domain.com/san-pham/quat-treo-tuong.html
=> Lấy dữ liệu từ table sản phẩm, nhận biết table qua khóa san-pham
Kỹ thuật phân tích dữ liệu từ URL
Phân tích Url như sau:
Bước 1: Tách Url thành mảng dựa vào ký tự /
Bước 2: Tách dữ liệu từ phần tử thứ 2 để xác định khóa, từ đó xác định file sẽ được load lên.
Việc phân tích dữ liệu sẽ phải dựa vào từng Url cụ thể
Ví dụ: Domain.com/san-pham-quat-treo-tuong.html và domain.com/product-fan.html sẽ phải phân tích khác nhau để lấy được khóa san-pham và product
Bước 3: Dựa vào giá trị thu được từ bước 2 để xác định dữ liệu cần hiển thị.
Phân tích Url như sau:
Bước 1: Tách Url thành mảng dựa vào ký tự /
Bước 2: Dựa vào phần tử thứ 2 để xác định khóa, từ đó xác định file sẽ được load lên.
Việc phân tích dữ liệu sẽ dựa vào từng nhóm Url
Ví dụ: domain.com/san-pham/quat-treo-tuong.html và domain.com/product/fan.html sẽ được xếp cùng nhóm do đó việc phân tích sẽ giống nhau
Bước 3: Dựa vào phần tử thứ 3 để xác định dữ liệu cần hiển thị.
Về sử dụng cả 2 loại trên đều phù hợp, chỉ cần truyền Url đúng cách và trích xuất dữ liệu tương ứng là có thể sử dụng.
Về mặt kỹ thuật Url dạng 2 sẽ dễ phân tích hơn dạng 1, đáp ứng được nhiều trường hợp tổng quát hơn do đó chúng ta sẽ chọn Url dạng 2 cho hệ thống DFramework
Cơ chế hoạt động của Template Engine:
Như chúng ta đã biết việc tách riêng code php và giao diện giúp tăng tốc độ xây dựng website, lập trình và design có thể làm việc độc lập với nhau, 1 file lập trình có thể sử dụng được cho nhiều giao diện khác nhau, nhưng các file giao diện chỉ là file text không lập trình được, mà trong thực tế khi thực hiện giao diện ta cần rất nhiều đến lập trình, ví dụ yêu cầu là in ra danh sách 10 khách hàng đầu tiên trên website, do không lập trình được trong giao diện nên ta sẽ báo cho kỹ thuật là ta cần thông tin 10 khách hàng tại vị trí này, lúc đó lập trình sẽ điều chỉnh file code để có 10 thông tin tại đây, nhưng cũng website này khi vào giao diện bên trong ta chỉ cần hiển thị 5 khách hàng lúc đó ta phải báo lại kỹ thuật, kỹ thuật sẽ phải xử lý bằng cách điều chỉnh lại code, như vậy bất kỳ khi nào ta thay đổi trên giao diện thì bên code cũng phải thay đổi lại, theo cách làm này thì việc tách code và giao diện còn phức tạp và mất thời gian hơn để chung trong 1 file, từ đó các Template Engine được ra đời nhằm hỗ trợ giao diện cũng có thể lập trình được.


Template Engine hoạt động như sau: các file giao diện sẽ được đọc lên và phân tích, khi gặp cú pháp theo quy định các dữ liệu này sẽ được thay thế bằng dữ liệu tương ứng. Ví dụ: trong file giao diện ta có biến quy định như sau: {mydata.title} thì khi giao diện này được thực thi giá trị {mydata.title} sẽ được thay thế bằng giá trị cụ thể nào đó tùy thuộc vào file điều khiển .php
File template chúng ta có thể quy định phần mở rộng là gì cũng được, ví dụ banner.dframework hoặc banner.tpl, banner.ten_ban v.v... Trong DFramework chúng ta sẽ thống nhất quy định các file template sẽ có phần mở rộng là .html.
“Như vậy bản chất của Template Engine là thực hiện việc load file giao diện lên, tìm và thay thế các giá trị hoặc cấu trúc được quy định trong đó bằng giá trị tương ứng trong file điều khiển”
Chúng ta sẽ xây dựng framework từ những yêu cầu nhỏ và hoàn thiện dần thành một hệ thống hoàn chỉnh.
+ Template Engine của chúng ta sẽ gồm các chức năng chính:
loadtemplate: có chức năng load file giao diện và phân tích cú pháp trong đó
assign: gán các giá trị cần thay thế
display: có chức năng gán giá trị và hiển thị nội dung HTML hoàn chỉnh
File lập trình .php của chúng ta sẽ có cấu trúc cơ bản như sau:
?php
$tpl = new DFramework;
$tpl->loadtemplate(‘giao-dien.html’);
… xử lý dữ liệu tại đây…
$tpl->display();
?>
File giao-dien.html cơ bản sẽ có nội dung như sau:
html>
body>
... giá trị hiển thị tại đây ...
/body>
/html>

Không chỉ đơn giản là biến, Template Engine còn bao gồm cả các cấu trúc if else, vòng lặp điều khiển for, while, include các template khác v.v…
Chúng ta sẽ đi sâu phân tích và lập trình trong Phần 4 xây dựng Template Engine riêng.

+ Lập trình hệ thống DFramework
Chúng ta sẽ thực hiện yêu cầu đơn giản nhất là load trang chủ và hiển thị thông tin “Hello world” đầu tiên.
Trong toàn bộ quá trình lập trình DFramework chúng ta sẽ dùng các hàm chuẩn trong PHP 5, chúng ta không dùng các hàm chỉ có trên PHP mới nhất vì trên thực tế không phải server nào cũng được cài đặt phiên bản mới nhất.
File index.php cụ thể của chúng ta như sau:
?php
include(‘libs/dframework.php’);
$tpl = new DFramework;
$tpl->loadtemplate(‘index.html’);
$tpl->assign(‘data.giatri’,’Hello world’);
$tpl->display();
?>
File index.html sẽ có nội dung sau:
html>
body>
{data.giatri }
/body>
/html>

Như vậy chúng ta đã có cái nhìn tổng quát về các file lập trình và giao diện mà chúng ta sẽ xây dựng, trong bước tiếp theo chúng ta sẽ đi sâu vào lập trình chi tiết.
Đầu tiên chúng ta cần xây dựng class DTemplate, class này sẽ có nhiệm vụ xử lý tất cả các tác vụ liên quan đến giao diện, nó chính là linh hồn Template Engine của chúng ta.
File dtemplate.php của chúng ta sẽ có nội dung sau:
?php
class DTemplate{
    protected $content; /*Biến chứa nội dung template*/
    protected $data=array(); /*Biến chứa các giá trị cần thay thế*/
    public function assign($m_key,$m_data=''){
        $this->data[$m_key] = $m_data;
    }
    public function loadtemplate($m_path){
        if(is_file($m_path)){
            if($m_content = file_get_contents($m_path)){
                $this->content = $m_content;
            }
        }
        return false;
    }
    public function display(){
        $m_content = $this->content;
        foreach($this->data as $m_key => $m_value){
            $m_content = str_replace('{'.$m_key.'}',$m_value,$m_content);
        }
        echo $m_content;
    }
}
?>

Lưu ý:
Trong PHP mảng đóng vai trò rất quan trọng, ngoài việc rất dễ sử dụng, nhiều hàm được xây dựng sẵn, mảng còn rất linh hoạt trong việc lưu trữ dữ liệu do đó chúng ta sẽ sử dụng mảng để lưu các dữ liệu cơ bản.
Mảng data của chúng ta sẽ có cấu trúc như sau:
$data = array(
    ‘bien_ben_template’ => ‘gia_tri_thay_the’
);
Ví dụ:
$data = array(
    ‘title’ => ‘Bài viết số 1’,
    ‘description’ => ‘Phần mô tả’,
    ‘content’ => ‘Nội dung chi tiết’
);
Như vậy mỗi biến bên template sẽ là 1 khóa, và sẽ được gán giá trị cụ thể khi sử dụng.

Sau khi xây dựng xong lớp DTemplate ta sẽ xây dựng lớp DFramework.
File dframework.php sẽ có nội dung sau:
?php
include(__DIR__.'/dtemplates.php');
class DFramework extends DTemplate{
}
?>

Lớp DFramework sẽ được xây dựng kế thừa từ lớp DTemplate nghĩa là tất cả các thuộc tính và phương thức mà lớp DTemplate có thì lớp DFramework đều có.
Mục đích là tạo ra lớp DFramework có thể xử lý tất cả các yêu cầu trên website
Chúng ta có thể tổ chức theo 2 cách.
Cách 1: Xây dựng 1 file duy nhất trong đó chứa tất cả các thuộc tính và hàm mà chúng ta cần xây dựng. Cách này có ưu điểm là tiện lợi, khi cần sử dụng chỉ cần include 1 file lên là được, tuy nhiên nhược điểm là khi hệ thống lớn thì file này sẽ chứa nhiều code và khó bảo trì hơn.
Cách 2: Chia code ra thành từng file riêng theo từng nhóm chức năng, khi cần đến chức năng nào thì load file chứa chức năng đó lên. Ưu điểm dễ bảo trì và nâng cấp, nhược điểm là có nhiều file, khi nào cần sử dụng thì phải include đúng file, đây cũng là cách chúng ta sẽ sử dụng để xây dựng lớp DFramework.

Tổng kết:
Đến đây chúng ta đã xây dựng xong các bước cơ bản của mô hình MVC, chúng ta đã có thể load được file template, thay thế biến trong template bằng các giá trị trong file php nghĩa là đã tách riêng được code và giao diện, trong bước tiếp theo chúng ta sẽ xây dựng các quy tắc để viết Template Engine riêng.

+ Xem kết quả chạy thử file index.php
+ Download toàn bộ mã nguồn tại đây
+ Bạn nào chưa biết cách cài đặt để chạy PHP trên localhost có thể tham khảo tại đây


Các tin khác
CÔNG TY TNHH THƯƠNG MẠI DỊCH VỤ THƯƠNG HIỆU TRỰC TUYẾN
Address: 216/14 Bùi Văn Ba, Phường Tân Thuận Đông, Quận 7, Tp.HCM
Hotline: 0908.622.880 -  Zalo: 0908 622 880
Email: Email info
Số Hotline
Zalo