Chào các bạn yêu thích Laravel,
Hôm nay, chúng ta sẽ cùng nhau khám phá mô hình HMVC (Hierarchical Model-View-Controller) và cách triển khai nó trên Laravel 5. Bài viết này sẽ cung cấp một hướng dẫn chi tiết, giúp bạn tận dụng tối đa lợi ích của HMVC trong các dự án Laravel của mình.
Mục Lục
1. HMVC là gì? Tại sao nên sử dụng HMVC?
HMVC là một kiến trúc phần mềm mở rộng từ MVC (Model-View-Controller), cho phép tổ chức ứng dụng thành các module phân cấp. Mỗi module hoạt động độc lập, có MVC riêng, giúp tăng tính tái sử dụng, khả năng bảo trì và mở rộng của ứng dụng.
Những lợi ích chính mà HMVC mang lại:
- Modularization (Tính Module hóa): Chia ứng dụng thành các module nhỏ, dễ quản lý.
- Organization (Tính Tổ Chức): Cấu trúc ứng dụng rõ ràng, mạch lạc.
- Reusability (Tính Tái Sử Dụng): Các module có thể được tái sử dụng trong nhiều dự án khác nhau.
- Extendibility (Khả Năng Mở Rộng): Dễ dàng thêm các tính năng mới vào ứng dụng mà không ảnh hưởng đến các module hiện có.
Sơ đồ cấu trúc HMVC
Khi tìm kiếm về HMVC, bạn sẽ thấy nhiều kết quả liên quan đến CodeIgniter. Tuy nhiên, việc áp dụng HMVC vào Laravel 5 cũng rất đơn giản và hiệu quả. Hãy cùng tìm hiểu cách thực hiện trong phần tiếp theo.
2. Triển khai HMVC trên Laravel 5
Trong hướng dẫn này, chúng ta sẽ tận dụng Package Development của Laravel để xây dựng cấu trúc HMVC. Bạn có thể tham khảo project mẫu tại sentayho.com.vn/sethsandaru/laravel-hmvc-sample để có cái nhìn trực quan hơn.
2.1. Xây dựng cấu trúc thư mục dự án
Trong mô hình HMVC, chúng ta có một MVC gốc (Base MVC) và các MVC module (con) phân cấp bên dưới. Cấu trúc thư mục sẽ như sau:
app(Base MVC)app/Modules(Modules MVC)
Đây là bước khởi đầu quan trọng để tổ chức dự án theo kiến trúc HMVC.
2.2. Cấu trúc MVC của một Module
Mỗi module sẽ có cấu trúc MVC riêng, bao gồm các thư mục sau:
Configs: Chứa các file cấu hình (định dạng theo Laravel).Controllers: Chứa các class Controller.Language: Chứa các file ngôn ngữ (localization), định dạng theo Laravel.Libraries: Chứa các class Library hỗ trợ.Migrations: Chứa các file migration schema, định dạng theo Laravel.Models: Chứa các Model sử dụng trong module.Views: Chứa các file view.routes.php: Định nghĩa các route cho module này.
Cấu trúc này đảm bảo tính đầy đủ và dễ quản lý cho mỗi module.
2.3. Tạo Service Provider để khởi động HMVC
Tạo một class HMVCServiceProvider trong thư mục app/Modules, kế thừa từ ServiceProvider. Class này sẽ giúp chúng ta khởi động HMVC thông qua method boot:
<?php
namespace AppModules;
use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesFile;
class HMVCServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*/
public function boot()
{
$directories = array_map('basename', File::directories(__DIR__));
foreach ($directories as $moduleName) {
$this->_registerModule($moduleName);
}
}
private function _registerModule($moduleName)
{
$modulePath = __DIR__ . "/$moduleName/";
// boot route
if (File::exists($modulePath . "routes.php")) {
$this->loadRoutesFrom($modulePath . "routes.php");
}
// boot migration
if (File::exists($modulePath . "Migrations")) {
$this->loadMigrationsFrom($modulePath . "Migrations");
}
// boot languages
if (File::exists($modulePath . "Languages")) {
$this->loadTranslationsFrom($modulePath . "Languages", $moduleName);
}
// boot views
if (File::exists($modulePath . "Views")) {
$this->loadViewsFrom($modulePath . "Views", $moduleName);
}
}
}
Sau đó, mở file config/app.php và khai báo class này trong mảng providers:
'providers' => [
// ...
AppModulesHMVCServiceProvider::class,
],
2.4. Tạo Module đầu tiên: Home
Tạo thư mục app/Modules. Sau đó, tạo thư mục Home (tên module) bên trong app/Modules.
Tiếp theo, tạo các thư mục cần thiết bên trong Home (Controllers, Views, …) tùy theo nhu cầu của bạn.
2.5. Khai báo Routes (tùy chọn)
Nếu bạn sử dụng route, hãy khai báo như sau trong file routes.php của module:
<?php
use IlluminateSupportFacadesRoute;
$module_namespace = "AppModulesHomeControllers";
Route::prefix('/home')->namespace($module_namespace)->group(function () {
Route::get('/index', "HomeController@index");
Route::get('/view', "HomeController@view");
Route::get('/test_insert_model', "HomeController@test_insert_model");
Route::get('/get_model', "HomeController@get_model");
});
Bạn nên đặt ra một quy tắc nhất định khi định nghĩa route cho module. Ví dụ, module Home sẽ luôn bắt đầu bằng /home.
2.6. Tạo các File cần thiết
Tạo Controller, View và Model cho module.
-
Controller: Kế thừa từ
Controllertrongapp/Http. -
Model: Nếu sử dụng Eloquent, kế thừa từ
Modelbình thường. -
Views: Tạo thêm thư mục bên trong
viewsđể quản lý view dễ dàng hơn, ví dụ:- views - home - index.blade.php - abc.blade.php - ...
Đến đây, bạn đã có một module cơ bản cho dự án của mình.
Ví dụ về cấu trúc thư mục cho module “Home”, thể hiện rõ các thành phần MVC và các thư mục hỗ trợ khác.
3. Laravel Loader
3.1. Load View
Để load view, sử dụng alias đã định nghĩa trong ServiceProvider:
return view('Home::home.view', $arrData);
3.2. Load Translation Text (Language Text)
Sử dụng alias để lấy translation:
trans('Home::home.hello'); // Hello
3.3. Load Config
Để tạo config cho module:
-
Tạo file config trong
app/Modules/<Module>/Configs. -
Mở file
HMVCServiceProvider.php, tìm property$configFile. -
Đăng ký file config của bạn như sau:
(config_alias => config_file_location)private $configFile = [ 'homeconfig' => 'Home/Configs/homeconfig.php', // more here ];
Để lấy config item, sử dụng hàm config():
config('homeconfig.text'); // get 'text' in homeconfig
4. Migrations
Khi chạy lệnh php artisan migrate:
- Các migration trong
database/migrationssẽ được chạy trước. - Sau đó, các migration trong từng module sẽ được chạy theo thứ tự.
Tạo Migrations
Tạo các file migration trong thư mục Migrations của module. Lưu ý: Tên file và class name phải tuân theo quy ước của Laravel.
5. Kết luận
Bài viết này đã cung cấp một cái nhìn tổng quan về cách xây dựng HMVC cho Laravel 5. Mặc dù đây không phải là HMVC hoàn toàn, nhưng chúng ta đã tận dụng lợi thế modular của HMVC để module hóa ứng dụng Laravel. Điều này mang lại nhiều lợi ích, đặc biệt là đối với các dự án lớn.
Hy vọng bài viết này hữu ích cho bạn. Chúc bạn thành công!
