Đã lâu mới có thời gian ngồi viết bài chia sẻ với các bạn về các kỹ thuật trong quá trình làm việc với PHP của mình. Hôm nay, mình chia sẻ đến các bạn một số vấn đề khi xây dựng một framework PHP cho riêng mình. Bài viết không dành cho phụ nữ có thai và các bạn dị ứng với ngôn ngữ lập trình web PHP.
Không ít người luôn nói rằng viết PHP framework chi cho khổ, có biết bao nhiêu cái PHP framework tốt lắm rồi, viết chi cho mệt mà chưa chắc tốt và mình nghĩ hầu hết các bạn cũng nghe điều này thường xuyên. Thật sự đúng là như vậy, có rất nhiều PHP framework rất tốt hiện giờ, vậy các bạn có tự hỏi liệu các framework đó ở đâu ra nếu ai cũng theo cái triết lý dùng framework của người khác ^^.
Hầu hết các PHP framework đều hướng đến một tập đối tượng developer nào đó, từ dễ đến khó, từ quy mô ứng dụng to đến nhỏ, từ tập tính năng nhiều đến ít…và chắc chắn chẳng có cái PHP framework nào viết ra để đáp ứng 100% nhu cầu cho website của bạn hay website mà khách hàng yêu cầu bạn phát triển và thường là thừa cái này, thiếu cái kia vì các PHP framework đưa ra thường theo nguyên lý “One Size Fits All” để cộng đồng sử dụng. Do đó, bạn sẽ tiếp cận các vấn đề nhanh hơn nếu đó là framework của bạn, có thể là phát triển mới hoặc cải tiến, nâng cấp, cập nhật.
Mình không tập trung vào việc so sánh các PHP framework cũng như công dụng của framework tự tui nhiều vì các bạn cũng có thể hình dung được phần nào công dụng của việc đi theo framework của mình. Mình chia sẻ một số vấn đề kỹ thuật mà mình đã áp dụng cho framework đã xây dựng cho các website của mình cũng như là Reader.vn để các bạn có thể hình dung được việc xây dựng một PHP framework không có gì là “đáng sợ”.
Một PHP Framework theo mình có thể dùng được là framework có hỗ trợ một số đặc điểm sau:
1. OOP
2. Cấu trúc File/Directory đơn giản
3. Registry và Front-Controller Pattern
4. Mô hình MVC
5. Phân quyền
6. Caching & Scalability
7. Database Abstraction
8. Template Engine
9. Hỗ trợ URL Rewrite
10. Đa ngôn ngữ
Nếu các bạn đã từng làm nhiều hoặc đọc nhiều về PHP Framework thì còn khá nhiều đặc điểm khác mà các framework hỗ trợ như ORM, HMVC, Test…Mình không phải là developer nặng về lý thuyết cao siêu, bởi cách tiếp cận của mình hướng đến việc framework phải thực sự đơn giản nhưng cũng đủ sức mạnh cũng như sự uyển chuyển để xây dựng các ứng dụng lớn khi cập nhật, cải tiến.
1. OOP
Nếu bạn nào chưa nghe đến OOP (Lập trình hướng đối tượng) thì mình nghĩ có thể bạn đang thiếu sót một cái gì đó cực kỳ nghiêm trọng nếu muốn phát triển web trong thời đại bây giờ. Hầu hết các PHP Framework hiện nay đều tiếp cận theo OOP nên việc triển khai framework của bạn theo OOP sẽ giúp việc làm việc nhóm, tái sử dụng code khi triển khai website của bạn dễ dàng và thuận tiện hơn.
Thường thì mỗi class sẽ được tạo riêng trong một file php và đặt trong các thư mục tương ứng để đúng ngữ cảnh khi include để chạy. Hệ thống của bạn có thể có nhiều loại Class, ví dụ các class là các Model, Controller, View hoặc đơn giản là các class Utility để thực hiện một số tính năng đơn lẻ như gởi email, download, resize, helper…
OOP trong framework của bạn nên hỗ trợ Lazyloading, tức là cơ chế tự động include file Class nếu tạo object chứ không phải mỗi lần chạy là include file manual bằng hàm include…
2. Cấu trúc File/Directory đơn giản
Đây có lẽ là điều bạn nên cân nhắc kỹ trước khi xây dựng framework cũng như dùng framework nào đó. Nếu framework của bạn có hệ thống file, thư mục rườm rà, không theo quy luật, nhóm chức năng thì khi có vấn đề cần debug để chỉnh sửa, cải tiến sẽ ảnh hưởng đến bạn và team của mình rất nhiều.
Nguyên tắc của mình là hệ thống không có quá nhiều thư mục, ví dụ có các thư mục cho Model, View, Controller, Include, Upload, Language, Library… để gom các class hay file liên quan vào. Rồi trong những thư mục đó, tùy thiết kế mà mình có thể chia thư mục con cho phù hợp.
3. Registry và Front-Controller Pattern
Sử dụng một số Pattern thông dụng sẽ giúp mô hình ứng dụng của bạn dễ hiểu hơn cho người khác tiếp cận lần đầu với framework của bạn.
Registry Pattern là một pattern đơn giản, giống như một biến global chung cho toàn bộ ứng dụng để có thể truy cập theo dạng thuộc tính đối tượng và chứa các thông tin chung như object config, setting, language, db…
Front-Controller Pattern cũng là một pattern thông dụng, quy ước là tất cả request PHP phải đi qua 1 file nào đó để tập trung xử lý các tiền xử lý, hậu xử lý trước khi điều hướng đến các controller/action tương ứng. Pattern này thường thấy ở hình thức tất cả các request đều đi qua file /index.php, ở đó sẽ có các xử lý chung như include thư viện, bootstrap hệ thống, tạo registry…
4. Mô hình MVC
Mô hình MVC là một mô hình tùy theo cảm nhận của từng người và hướng tiếp cận thì cách thiết kế mô hình MVC cũng khác. Không đặt nặng các vấn đề lý thuyết như Model, View, Controller là gì, nó phải như thế nào mới gọi là Model, View, Controller…nhảm. Tui làm thế, tui gọi là Model, còn anh nói không phải Model là chuyện của anh. Đó là cách tiếp cận MVC của mình và mình cũng chia sẻ bên dưới.
– Model: Model là các Class kết nối trực tiếp đến Database thông qua Database Abstraction (PDO…) để thao tác lên các Table, cũng như mô hình ORM, mỗi table nên có 1 Model thực hiện các thao tác như Thêm (INSERT INTO…), Chỉnh sửa (UPDATE…), ‘Xóa (DELETE FROM…), Truy xuất – tìm kiếm (SELECT…). Ngoài ra, tùy theo Model mà có các method khác ví dụ như model USER của mình có thể có các phương thức getSmallImage() để lấy avatar path…
– View: là layer đảm nhận việc xuất kết quả request ra fromt-end, đó có thể là HTML, XML, JSON, Plain text hoặc HTML, CSS, Image…Hệ thống View thường kết nối tới một template engine nào đó để giúp View triển khai đơn giản và nhanh chóng hơn.
– Controller: Tùy theo hệ thống của bạn thì bạn thiết kế controller. Các controller thường là các xử lý kết nối các Model với nhau, thực hiện các xử lý cơ bản liên quan đến Request (GET, POST, Form Validate…) và kết nối với View để xuất ra HTML, XML…như thiết kế của View. Trong Controller sẽ có các Action, tức là các xử lý nhỏ cho 1 chức năng. Ví dụ ta có Controller Product có thể có các Action như Liệt kê, chi tiết, tìm kiếm…
Ngoài ra, hệ thống của mình sử dụng khái niệm Controller Group, tức là gom các controller chung lại bỏ vào 1 thư mục gọi là 1 controller group, ví dụ các controller xử lý back-end hoặc front-end hoặc background task…
5. Phân quyền
Hệ thống phân quyền của bạn phải chi tiết để đảm bảo đúng người, đúng việc. Bạn có thể thiết kế các User Group khác nhau và phân quyền theo từng Group ví dụ Group Guest, Member, Moderator, Admin…kết hợp với hệ thống chức năng của Controller Group, Controller, Action, bạn có thể phân quyền chi tiết đến từng đối tượng có thể thực hiện được tính năng này, tính năng kia…
Bạn không nhất thiết phải thiết kế database để thực hiện việc này, vì hệ thống lớn mà cần đến database để phân quyền thì hơi tội cho Database. Ta chỉ đơn giản dùng file setting nào đó để phân quyền user, còn table user bạn chỉ cần thêm một field là GROUP ID để phân quyền thích hợp cho user đó.
6. Caching & Scalability
Caching sẽ giúp hệ thống của bạn giảm tải ở các tính năng thường xuyên cần truy xuất database hoặc các truy xuất database tốn nhiều thời gian. Bạn cần thiết kế để tận dụng các cơ chế cache từ đơn giản đến phức tạp vì có nhiều cơ chế cache đòi hỏi bạn cài đặt hoặc cấu hình trên 1 hoặc nhiều server.
Bạn có thể xem xét việc cache cho Model data hoặc cache cho xử lý của 1 Action nào đó, ví dụ thấy trang chủ không thay đổi nhiều thì bạn cache toàn bộ nội dung trang chủ vô file hoặc RAM (tùy theo bạn chọn cache ở đâu) để giảm tải các truy vấn database lặp đi lặp lại ở trang chủ.
Còn cache cho Model thì đơn giản hơn, ví dụ thông tin của 1 User thay vì lúc nào bạn cũng SELECT từ table User để lấy chi tiết thì sao mình không lưu vào cache, rồi khi muốn lấy thông tin user ta chỉ cần vào cache để lấy thông tin user này, nếu bạn chọn thời gian cache phù hợp thì dữ liệu của bạn sẽ gần như là thời gian thực (real-time data)
Scalability là khả năng mở rộng của website. Bạn nên thiết kế sao cho có thể thay thế các thành phần riêng rẻ, tối ưu riêng rẻ để khi mở rộng website không phải thay đổi nhiều. Ví dụ thay đổi cơ chế cache, việc sử dụng các phương thức của Model không thay đổi, chỉ là chi tiết triển khai trong Model thay đổi. Bạn có thể chuyển cache file sang cache RAM hoặc từ RAM trong APC lên RAM trong Memcache.
7. Database Abstraction
Ngày nay, hiếm khi còn thấy các truy vấn database sử dụng mysql_*() hoặc các hàm tương tự khác mà thường thấy dạng Abstraction thông qua các Object Db để truy vấn database. Thậm chí với ORM, bạn cũng có thể thấy rằng không còn khái niệm SQL mặc dù bạn đang sử dụng SQL DB Server.
Có nhiều Database Abstraction cho bạn lựa chọn, nhưng nếu bạn đang phát triển PHP5 thì PDO có lẽ là giải pháp tốt nhất bởi sự đơn giản cũng như hỗ trợ khá nhiều thứ như transaction, prepared statement cho bảo mật…
8. Template Engine
Template engine là hệ thống làm việc trực tiếp với HTML template và phối hợp với View layer trong MVC để xuất webpage, dữ liệu ra cho người dùng. Có khá nhiều template engine để lựa chọn từ đơn giản đến phức tạp. Mình chọn Smarty bởi tính thông dụng và phong phú của nó. Nếu ai nói smarty là một Template engine chậm thì nếu có dịp nói chuyện với mình thì mình sẽ chỉ cho bạn biết có lẽ bạn…sai.
9. Hỗ trợ URL Rewrite
Ngày nay, SEO là một phần tất yếu của các website. Không phải chỉ mang mục đích SEO, việc rewrite URL còn có nhiều mục đích như làm cho việc chia sẻ các link hiệu quả và dễ hiểu hơn. Khi xây dựng Framework, bạn cần xem xét việc hỗ trợ rewrite URL để giúp cho website của bạn tốt hơn. Có nhiều bạn than phiền là làm Rewrite URL thì phải can thiệp Regular Expression trên file .htaccess khá nhiều. Thực ra, nếu bạn sử dụng Front-controller pattern cho Rewrite URL thì sẽ thấy mọi việc đơn giản hơn.
Thay vì để file .htaccess lo việc rewrite, bạn hãy để cho PHP lo vụ này, khi đã vào PHP file, bạn sẽ rất thoải mái để rewrite kiểu gì cũng được, phân tích tha hồ bởi có nhiều trường hợp rewrite dùng PHP kèm với website của bạn mới hiệu quả. Do đó, nếu áp dụng pattern này thì file htaccess của bạn chỉ cần 1 dòng rewrite rule sau:
Options +FollowSymLinks Options -Indexes RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
10. Đa ngôn ngữ
Ngoài việc hỗ trợ Đa ngôn ngữ dữ liệu (nếu bạn có nhu cầu thì bắt buộc bạn phải triển khai) thì hỗ trợ Đa ngôn ngữ cho giao diện cũng rất quan trọng. Việc thiết kế sao cho việc thay đổi, thêm bớt ngôn ngữ phải đơn giản và đồng bộ sẽ giúp bạn tiết kiệm rất nhiều thời gian khi mở rộng hệ ngôn ngữ của website sua này.
Ở trên là 10 đặc điểm mà mình thấy khi triển khai một PHP Framework bạn cần phải xem xét triển khai. Tất nhiên, các yếu tố như bảo mật, Documentation, Code style…phải là điều bắt buộc khi triển khai 1 framework. Bài viết không thể nào tiếp cận theo hướng Code được vì có rất nhiều Code, vì thực sự nếu bạn đã muốn code framework thì bạn cũng đã biết phải code gì rồi, bài viết này giúp bạn thấy được một bức tranh cụ thể để tìm hiểu thêm và tự xây dựng cho mình 1 PHP framework thật ưng ý và có thể trở thành 1 Open source nổi tiếng.
——————-
Nối tiếp bài viết này, nằm trong chuỗi hoạt động “Funding for Reader.vn“, bloghoctap sẽ tổ chức một buổi hội thảo cụ thể hướng dẫn xây dựng PHP framework đến các đối tượng quan tâm, đồng thời tìm kiếm kinh phí để tiếp tục duy trì và mở rộng mạng xã hội sách Reader.vn ^^.
Nội dung hội thảo sẻ xoay quanh việc chia sẻ kinh nghiệm xây dựng một PHP Framework như đã từng làm với Reader.vn cũng như chia sẻ đến các bạn 10 vấn đề đã trình bày ở trên để các bạn có thể nhìn tường tận hơn về Code phải như thế nào chứ không trừu tượng như ở trên.
Tên hội thảo: “Làm Framework không khó.“
Trình bày: Võ Duy Tuấn – Bloghoctap.com & Reader.vn Founder
Thời gian: 8:30 – 11:30, Chủ nhật, ngày 02/10/2011
Địa điểm: đang cập nhật…[TP. Hồ Chí Minh]
Số lượng dự kiến: 50 người.
Tuấn không post cái framework của mình ở đây cho pà kon nghiên cứu luôn nhỉ ?
Có 1 cái quan trọng khi sử dụng các popular frameworks là nó có 1 active community và mình sẽ thường xuyên được update các chức năng mới 🙂
Hi anh, nếu em quăng cái framework lên thì đâu phải mất công ngồi viết bài này làm gì mà chỉ là..blah blah..framework của tui nè, xài đi ^^. Đó không phải là cách tiếp cận của em, hihi. Vả lại framework của em cùi bắp quá, đưa lên chỉ tổ mọi người không biết xài, vì nó là “made in tự tui” mà, đâu phải xây ra để open source.
Url Routing with PHP thật là khó hiểu. Hôm nào anh làm 1 bài hướng dẫn kỹ lưỡng về nó đê 😛
Ui cái này thuộc cấp tổng thể cao.
Em làm quen với khái niệm framework ở quy mô thấp thôi ạ – thường thì em hay tiếp xúc framework dưới dạng theme wordpress ( em toàn làm cái này mà) .
Nếu mọi thứ đều tốt đẹp cả. Rất mong sẽ được nghe anh giảng đạo vào buổi hôm đó. Mình biết cơ cấu của cái to. Mình làm cái nhỏ dễ hơn nhiều. hihi
Đúng là không nên cái gì cũng “It’s mine, but it’s for free!”. Nếu cái mình nghĩ ra hoặc cook mà nó đáng thì cũng phải được trả chút phí chứ, có vậy thì contributor mới có hứng mà làm việc được. Developers và người dùng VN ăn hàng free (hoặc cracked) quá lâu rồi nên đâm ra dị ứng với chuyện trả tiền cho bản quyền. Ủng hộ cách làm của Tuấn, sau này nếu tổ chức seminar thì mình cũng chỉ có thể làm theo cách này thôi. Nếu không thì chỉ có vớt cám mà ăn để nghiên cứu và học tập!
framework made in tự tui mình có 1 2 rev nhưng vẫn khó khăn cái khoản đa ngôn ngữ và đa giao diện. Tham khảo qua 1 vài framework thì họ cũng vẫn bị hạn chế đa ngôn ngữ và đa giao diện
Với kinh nghiệm lăng và lộn trên các loại framework (từ framework tự tui tui sướng đến framework opensource) và CMS Opensource thì mình vẫn thích xài những framework opensource & CMS Opensource hơn. Sở dĩ vậy là vì 1 số lý do sau:
1. Framework tự build tự sướng chỉ do từ 1 đến 3 hoặc nhiều hơn chút ngồi lại tự build với nhau. Do đó chất lượng của framework sẽ tùy thuộc vào kinh nghiệm và trình độ của từng thành viên. Mà thành viên càng ít thì kinh nghiệm từng trải cũng càng ít. Đó là 1 điểm thua thiệt so với Framework Opensource do nhiều đóng góp
2. Đối với các website cooperate hoặc phức tạp hơn chút là những trang tin tức cho phép đăng ký user, comment, like, v.v.. thì mình sẽ dùng CMS Opensource vì nó nhanh, an toàn, hiệu quả.
3. Còn đối với các ứng dụng phức tạp trên nền web thì mình se sử dụng Framework Opensource vì tránh được rủi ro cơ bản mà mình chưa gặp, tận dụng được những thành quả của người đi trước.
Hi anh Tuấn! Đọc blog anh lâu nhưng h mới comment 1 cái ^^.
Bài viết rất hay, nhưng e có một điều thắc mắc là: đã là mô hình MVC rồi thì đâu nhất thiết phải cần đến Template Engine (Smarty), phần code và giao diện đã được tách biệt rồi mà, chức năng cache thì đã có mục 6 đảm nhận.
Mong anh trả lời. 😀
Hi Sono,
MVC là một pattern chung chung, còn Template Engine là một ứng dụng rõ ràng để sử dụng cho View Layer hay Presentation Layer. Em có thể không dùng Template Engine thì cái View của em thế nào?
Ý em nói là phần code và phần giao diện đã tách biệt đó hả?
Không biết em thế nào chứ điều anh mô tả về sự khác biệt ở trên chính là đã là View, tức Design thì không có bất kỳ một đoạn Code PHP nào dính vô, tức là khi làm với View, em sẽ làm hoàn toán với HTML, CSS và JS. Và có thể thoải mái tận dụng sức mạnh của IDE để design riêng mà không bó buộc vào code PHP, do đó, designer không quan tâm đến PHP khi làm việc với Template engine, đây mới chính là sự riêng biệt mà anh đề cập đến.
Thân.
Anh có thể nói rõ hơn về cơ chế Lazy Loading được không ạ?
Thanks Anh nhiều
Em thích những câu hỏi của Anh trong đăng kí tukhoa.info
Bác nào có nhiệt huyết với php, bác Tuấn giới thiệu giúp về quản lý php.vn cái 😀
Anh Tuấn ơi mở đi anh , em rất muốn được tham gia buổi offline này … Khi nào tổ chức thì cho em biết với nha a .
hẹn giác ngô anh em vào buổi đó nhé
Từ những ý niệm của pác Tuấn sau 1 thời gian “mài & mò” thì cũng cook dc cái 1 tini Framwork. Sau mấy ngày săm soi tìm và so sánh các template engine để gắn vào thì mình quyết định dùng Twig làm Template Engine. Đi sâu vào Class & Object của PHP mới thấy nó nhiều cái hay mà mình chưa biết…
Em chào cả nhà ạ.
Em xin hỏi 1 chút: Khi em làm 1 website bán hàng theo mô hình mvc. và ko sử dụng framework nào cả.
Tư tưởng xử lý :
Controllers:Các controller.
Models: Các model
View: Các view
Controller gọi Model rùi đổ dữ liệu và trong View.
——-
Ví dụ: controllers/produc.php sẽ gọi model của nó ở
models/model_product.php và sau đó view ra views/product/index.php
Em làm web bán hàng nhỏ.
Bây giờ trong trang chủ của website em muốn view lên đc:
view/product/index.php ở 1 góc nhỏ bên phải thì phải làm như thế nào ạ.
Hay trang mình muốn xây dựng cái Menu lấy dữ liệu từ CSDL ra.
Thì phải viết thêm controller và model rùi view cái này em làm đc.
Nhưng để hiệu thị view nó trên hết các trang thì em chưa làm đc.
Hi! Em thấy có người bảo viết thêm lớp helpers, em cũng chưa rõ lắm.
Mong đc các bạn giúp đỡ/
Chào a, e mới được học về Mvc, e đang nghiên cứu về nó nhưng thây hơi hoang mang, e muôn build 1 web đơn gian giong framework.Anh có thể share cho e framework anh tự build cho e nghiên cứu được không ạ. Chân thành cảm ơn a …
Bài phân tích quá hay quá tuyệt vời rất mong được giao lưu học hỏi a