Tự viết một Package trong Laravel 8 (Phần 1)

29th Aug 2021
Table of contents

Package là là một dạng đóng gói tính năng để thêm vào trong các dự án. Package có thể là bất cứ thứ gì từ việc xử lý ngày giờ như Carbon hay nguyên bộ framework như Laravel. Có rất nhiều loại Package, một số Package thì stand-alone, nghĩa là chúng có thể hoạt động với bất kỳ framework nào miễn là sử dụng chung 1 loại ngôn ngữ (Carbon là một ví dụ), một số Package khác thì lại được tạo ra để sử dụng cho 1 framework nhất định.

Bài hướng dẫn này phần lớn sẽ nói về việc phát triển các Package dành cho Laravel và phiên bản mình sử dụng để Hướng dẫn đó là Laravel 7 (Các phiên bản Laravel khác cũng có thể áp dụng). Và ở bài đầu tiên này mình sẽ đưa ra cấu trúc thư mục và khai báo ban đầu cho một Package.

Cấu trúc thư mục Package cơ bản

Một Package cơ bản sẽ gồm có cấu trúc thư mục như sau:

packages
├── demo
│   ├── configs
│   │   └── demo.php
│   ├── helpers
│   │   └── functions.php
│   ├── migrations
│   ├── resources
│   │   └── assets
│   │   └── lang
│   │   └── views
│   ├── routes
│   │   └── routes.php
│   ├── src
│   │   └── Commands
│   │   └── Http
│   │   |   └── Controllers
│   │   |   └── Middlewares
│   │   └── Models
│   │   └── Providers
│   │   |   └── DemoServiceProvider.php
│   ├── composer.json
│   ├── Readme.md
├── demo2
│   ├── ...

Các thư mục tại Package có công dụng giống như các thư mục cùng tên tại thư mục chính. Thư mục "src" có công dụng như thư mục "\app".

Tên các thư mục không nhất thiết phải đặt giống mình nhưng mình khuyến khích các bạn chỉ thay đổi khi đã hiểu rõ về hướng phát triển Package.

P/S: Các thư mục trên không nhất thiết bắt buộc phải có mà nó còn tùy theo Package đó có dùng hay không. 

Thư mục packages/ đặt cùng cấp với thư mục app/

Khai báo composer.json tại packages

Đây là thư mục quan trọng nhất của một Package. Nó giúp khai báo Package với "composer" từ đó khởi tạo đường dẫn dạng link đến thư mục "\vendor".

Cấu trúc file cơ bản được viết như sau:

{
    // Tên của package dùng để khai báo tại composer.json tại root
    "name": "packages/demo", 
    // Đây là phần mô tả tính năng của Package
    "description": "Mô tả", 
    //
    "type": "library",
    "license": "MIT",
    "minimum-stability": "dev",
    // Khai báo tác giả
    "authors": [
        {
            "name": "Tac gia",
            "email": "[email protected]"
        }
    ],
    // Khai báo các packages khác
    "require": {
        //
    },
    // Khai báo namespace psr-4
    "autoload": {
        "psr-4": {
            "Package\\Demo\\": "src/"
        }
    },
    "extra": {
        "laravel": {
            // Khai báo ServiceProvider của Package
            "providers": [
                "Package\\Demo\\Providers\\DemoServiceProvider"
            ],
            "aliases": {}
        }
    }
}

P/S: Mình đã giải thích các khai báo tại ghi chú và các ghi chú này cần xóa đi khi chạy để tránh gây lỗi.

Khởi tạo ServiceProvider của Package

ServiceProvider là điểm kết nối giữa package của bạn và Laravel. Một ServiceProvider chịu trách nhiệm kết nối các thành phần vào trong container của Laravel và thông báo cho Laravel vị trí để load các tài nguyên của package như views, config, helpers,...

Một ServiceProvider kế thừa từ class "Illuminate\Support\ServiceProvider" và chứa hai phương thức chính là register và boot.

Một ServiceProvider cơ bản có cấu trúc như sau:

<?php

    namespace Package\Demo\Providers;
    
    use Illuminate\Support\Facades\File;
    use Illuminate\Support\Facades\Log;
    use Illuminate\Support\ServiceProvider;
    use Illuminate\Support\Facades\Schema;

    class DemoServiceProvider extends ServiceProvider
    {

        /**
        * Register bindings in the container.
        */
        public function register()
        {
            //
        }

        public function boot()
        {
            //
        }

    }

Khai báo package tại composer.json tại thư mục gốc

Chúng ta sẽ khai báo "name" của Package tại "require" và khai báo thư mục chứa Package tại "repositories".

{
    ...
    "require": {
        ...
        "package/demo": "dev-master"
    },
    ...
    "repositories": [
        {
            "type": "path",
            "url": "./packages/*"
        }
    ]
}

Kiểm thử Package

B1: Khởi chạy "composer update" để composer nạp "package/demo" vào vendor (Chỉ cần chạy 1 lần khi khai báo package, sau khi khai báo thì mỗi thay đổi tại package sẽ tự động được update vào thư mục tại vendor)

B2: Cập nhật lại ServiceProvider để kiểm tra xem package đã được update thành công hay chưa:

...
public function boot()
{
    dd('Kiểm tra Package');
}
...

B3: Refresh (F5) lại trang nếu hiện ra đòng chữ "Kiểm tra Package" thì nghĩa là Package của bạn đã được chạy thành công.

Tổng kết

Tổ chức theo dạng Package/Module là một dạng phát triển khá hay giúp chúng ta có thể sử dụng được những Module được dựng sẵn mà mất rất ít công sức, dễ dàng duy trì và phát triển, đặc biệt PHỤ THUỘC ÍT VÀO LARAVEL cũng như dễ dàng CẬP NHẬT ĐƯỢC PHIÊN BẢN nếu như laravel lên bản 8 hay 9.

Download source mẫu

Attach
Bạn thấy bài viết này như thế nào?
0 reactions

Add new comment

Image CAPTCHA
Enter the characters shown in the image.
Câu nói tâm đắc: “Điều tuyệt với nhất trong cuộc sống là làm được những việc mà người khác tin là không thể!”

Related Articles

Mỗi kết nối cơ sở dữ liệu được định nghĩa trong một mảng, với tên kết nối là khóa của mảng

Eager Loading là một kỹ thuật tối ưu hóa truy vấn cơ sở dữ liệu trong Laravel, giúp tăng tốc độ truy vấn và giảm số lượng truy vấn cần thiết để lấy dữ liệu liên quan đến một bản ghi.

Để sử dụng Eager Loading với điều kiện trong Laravel, bạn có thể sử dụng phương thức whereHas hoặc orWhereHas trong Eloquent Builder.

E hiểu đơn giản vầy nha. auth() hay Auth trong laravel là những function global hay class, nó cũng chỉ là 1 thôi

Xin chào các bạn, tuần này mình sẽ viết một bài về cách xử lý Real Time(thời gian thực) với Laravel và Pusher