[Laravel Tutorials] Tổ chức theo dạng packages/modules trong ứng dụng Laravel – Phần 1
Mình là người đã trải qua khá nhiều công ty làm outsoursing (4 công ty cho tới thời điểm này, nhảy việc hơi nhiều :D) và đã tiếp cận khá nhiều cách để làm website dựa trên Laravel.
Và cách cơ bản mình thường thấy nhất đó là sửa/thêm mới trực tiếp trong thư mục /app, thay đổi config trong /config. Cách tiếp cận này hoàn toàn đúng, không sai và được Laravel
khuyến khích sử dụng. Tuy nhiên, nó làm cho ứng dụng của chúng ta quá ràng buộc vào Laravel trong khi Laravel là framework luôn thay đổi chóng mặt.
Vì vậy, hôm nay mình xin giới thiệu 1 cách khác để phát triển ứng dụng Laravel một cách giảm phụ thuộc vào Laravel nhất có thể.
Đầu tiên, hãy cài đặt Laravel nhé, trên mạng có quá nhiều hướng dẫn rồi, việc cài đặt khá đơn giản nên mình không nhắc lại nữa. Các bạn có thể sử dụng Ampps, Open server hay Docker để tạo
tên miền ảo cho dễ dàng nhé.
Cấu trúc ứng dụng:
Làm việc theo mô hình này thì chúng ta sẽ tạo 1 thư mục mới trong source mặc định của Laravel nhé, bạn có thể tạo trong thư mục app với tên khác cũng được, nhưng mình khuyến khích
đặt ngoài thư mục gốc cho đúng chuẩn nhé. Có thể đặt là core, modules hay packages đều được. Thư mục này sẽ chứa các modules/packages của chúng ta, trong ví dụ này thì module đó
mình đặt là demo.
Theo mô hình này, mỗi module sẽ có ít nhất 1 file service provider, đây là file quan trọng nhất của 1 module, nó sẽ được load đầu tiên và được dùng để bind các services vào service container.
Các bạn có thể tìm hiểu thêm về nó trong bài viết này.
Nội dung cơ bản thế này:
<?php namespace Botble\Demo\Providers; use Illuminate\Support\ServiceProvider; class DemoServiceProvider extends ServiceProvider { }
Ban đầu thì nó chỉ cần có vậy. Trong nội dung file này bạn có thể thấy namespace là Botble\Demo, tiếp theo mình sẽ trình bày cách để khai báo namespace đó.
Bạn hãy mở file composer.json và thêm vào phần autoload -> psr-4.
"psr-4": { "App\\": "app/", "Botble\\Demo\\": "core/demo/src" }
Chúng ta khai báo để composer load thư mục “core/demo/src” theo đúng chuẩn psr-4 nhé. Bạn có thể đặt tên tuỳ ý nhé, namespace không nhất thiết phải là Botble\\Demo\\ mà có thể
đặt tên bất kỳ, chỉ cần lưu ý mấy dấu “/“.
Xem thêm về chuẩn này tại đây https://www.php-fig.org/psr/psr-4/
Tiếp theo, để composer có thể biết được sự thay đổi, chúng ta cần chạy lệnh composer dump-autoload nhé.
Sau đó, hãy đăng ký nó vào /config/app.php như những thư viện bạn hay cài đặt từ Github.
'providers' => [ ... Botble\Demo\Providers\DemoServiceProvider::class, ... ],
Ok, vậy là chúng ta đã đăng ký xong, thử xem nó đã chạy chưa nào.
Hãy thêm vào /core/demo/src/Providers/DemoServiceProvider.php
public function register() { dd('Ok'); }
Sau đó, bạn có thể chạy php artisan serve và truy cập vào http://localhost:8000 hoặc vào domain ảo của bạn nếu bạn đã cấu hình. Nếu xuất hiện giống hình dưới thì bạn đã thiết lập
được module đầu tiên thành công rồi đó.
Load route:
Route là thứ đầu tiên mà người dùng được điều hướng tới khi truy cập ứng dụng Laravel nên trong series này mình sẽ hướng dẫn load nó đầu tiên nhé.
Hãy tạo file /core/demo/routes/web.php với nội dung cơ bản thế này nhé.
<?php Route::get('/demo', function () { return 'First module "Demo" is loaded.'; });
Trông nó sẽ giống như hình dưới.
Tiếp theo, hãy sửa lại /core/demo/src/Providers/DemoServiceProvider.php một chút để load route từ thư mục /core/demo/routes/web.php nhé.
public function register() { $this->loadRoutesFrom(__DIR__ . '/../../routes/web.php'); }
Và bây giờ, khi truy cập vào http ://localhost:8000/demo bạn sẽ thấy nội dung được load từ route /demo ra.
Cũng khá là dễ dàng phải không nào. Bài đầu tiên trong series này mình xin tạm dừng tại đây nhé. Trong các bài sau mình sẽ hướng dẫn các bạn load views, chạy database từ module… nhé.
Full source code: https://github.com/sangnguyenplus/laravel-package-demo
Hi vọng các bạn có thể thực hiện được!
Phần tiếp theo: [Laravel Tutorials] Tổ chức theo dạng packages/modules – Phần 2: Load views và controllers
- Địa chỉ: Hồ Chí Minh
- Facebook: Sang Nguyen