Cách tạo file PHP Helpers riêng trong Laravel

Cách tạo file PHP Helpers riêng trong Laravel

Nội dung bài viết


Rất vui được gặp lại các bạn, cảm ơn các bạn đã ủng hộ và theo dõi Flipper. Hôm nay chúng ta sẽ nói về chủ đề Laravel framework. Các bạn có bao giờ nghĩ đến việc sẽ tạo một file helpers riêng để mà khai báo các helper cho chính dự án Laravel của mình chưa? Mình thì có rồi đấy, đôi lúc mình muốn tạo một helper để xử lý một số công việc lặp đi lặp lại nhưng gặp phải một số hạn chế. Bài này mình sẽ nói về mặt hạn chế của việc viết định nghĩa các helper trong file default helpers và đồng thời hướng dẫn các bạn cách làm thế nào để có thể tạo file helpers riêng trong Laravel.

1. Nguyên nhân

Trước tiên mình sẽ nói về những vấn đề bản thân mình gặp phải của việc viết các helper trực tiếp tại file default helpers.

Vấn đề thứ nhất là do cấu trúc thư mục của file helpers mặc định quá "sâu" vendor\laravel\framework\src\Illuminate\Foundation\helpers.php, phải qua gần chục cấp mới đến được file để code. Nhiều bạn nếu thành thạo với việc mở file bằng phím tắt thì có thể vấn đề này sẽ không mấy ảnh hưởng đến các bạn, vậy mình sẽ thuyết phục bằng vấn đề thứ hai.

Vấn đề mình muốn nói đến tiếp theo là do source code trong file default helpers này đã quá dài rồi, nó lên tới con số gần 1000 dòng code. Việc viết tiếp những helper do chính bạn tạo ra dù append hay prepend code đi nữa cũng tạo một cảm giác không "thoáng" và khó quản lý.

Vì vậy chúng ta cần phải tạo một file helpers riêng để có thể giải quyết các hạn chế này, còn việc tạo thế nào chúng ta sẽ đi qua phần tiếp theo.

2. Tiến hành thực hiện

Chúng ta sẽ thực hiện việc này thông qua cơ chế autoload của Composer được tích hợp trong Laravel.

2.1. Tạo helpers riêng trong project

Bước đầu tiên cũng không quá phức tạp, chỉ đơn giản là tạo một file helpers.php đơn thuần tại bất cứ vị trí nào trong project Laravel mà bạn mong muốn nếu như nó nằm trong phạm vi autoload của Composer. Tuy nhiên bạn có thể tham khảo các gợi ý của mình bên dưới:

  • app/helpers.php
  • app/Http/helpers.php

Mình cảm thấy hai gợi ý trên khá thuận tiện trong việc quản lý helpers cũng như thao tác mở nó, bản thân mình sẽ chọn app/helpers.php.

2.2. Autoload helpers với Composer

Composer cung cấp cho chúng ta một khóa files để có thể khai báo các file PHP mà chúng ta muốn tự động require vào ứng dụng. Nó có giá trị là một đường dẫn hoặc một mảng chứa các đường dẫn đến các file cần autoload. Việc cần làm của chúng ta bây giờ là mở file composer.json trong project lên và định nghĩa khóa files này trong object autoload.

"autoload": {
    "files": [
        "app/helpers.php"
    ],
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/seeds",
        "database/factories"
    ]
},

Ở đây mình sử dụng đường dẫn app/helpers.php, các bạn có thể sửa lại sao cho phù hợp với lựa chọn của mình.

Để có thể nạp file vừa khai báo, bạn cần dump autoload thông qua lệnh:

composer dump-autoload

Nếu có kết quả như hình thì bạn đã hoàn tất quá trình đăng ký autoload cho file helpers rồi đấy.

Composer dump autoload file helpers riêng trong Laravel

Việc cần làm của chúng ta bây giờ là testing những gì vừa làm được thôi nào.

3. Testing

Bây giờ bạn hãy định nghĩa một helper trong file helpers vừa tạo, lưu ý rằng nên có một bước ràng buộc trước khi định nghĩa helper thông qua method function_exists(). Việc này nhằm đảm bảo việc tránh bị xung đột trong quá trình đặt tên helpers, dẫn đến những lỗi nghiêm trọng. Nhưng trong quá trình phát triển, bạn có thể không cần thực hiện bước này để có thể phát hiện thông qua thông báo lỗi nếu vô tình đặt tên đã sử dụng trước đó, như vậy sẽ tránh được các lỗi tìm ẩn không mong muốn. Hoặc bạn có thể quy định prefix cho tên các helper của mình nhằm tránh trường hợp xung đột, ngoài ra có thể phân biệt được đâu là helper tự định nghĩa, đâu là helper có sẵn trong ứng dụng.

Chẳng hạn mình muốn viết một helper có thể tách chuỗi thành mảng thông qua hàm explode() trong PHP và trả về phần tử cuối cùng trong mảng, nếu không có kết quả thì trả về chuỗi gốc.

if (! function_exists('explode_end')) {
    function explode_end(string $delimiter, string $str) {
        $arr = explode($delimiter, $str);
        
        return end($arr);
    }
}

Trông có vẻ ổn, giờ hãy tạo một route trong routes/web.php để test xem như thế nào.

Route::get('/testing', function () {
    dump(explode_end('-', 'a-b-c'));
});

Chạy ứng dụng và truy cập vào route, ta sẽ có kết quả như hình bên dưới:

Tesing helper riêng trong Laravel

Có lẽ đến đây chúng ta đã hoàn tất quá trình kiểm thử, nhưng mình muốn kiểm chứng xem liệu giữa file default helpers và file custom helpers của mình, cái nào sẽ được require trước khi ứng dụng Laravel khởi động. Để kiểm chứng điều này cũng hết sức đơn giản, chúng ta chỉ việc khai báo một helper có sẵn do Laravel cung cấp ngay tại trong file custom helper của chúng ta và chạy ứng dụng. Nếu có thông báo lỗi tức là helper đó đã được khai báo trước khi chúng ta định nghĩa nó, ngược lại nếu nó không có lỗi gì thì tức là file custom helper của chúng ta đã được require trước.

Chúng ta chỉ việc định nghĩa lại helper env() có sẵn trong Laravel mà không qua ràng buộc của method function_exists() như thế này:

function env()
{
    
}

Và... yub! Một fatal error đã hiện ra, một lỗi nghiêm trọng đến nỗi error handle của Laravel cũng không xử lý được, đó là lỗi khai báo tên hàm đã bị trùng trước đó.

Testing trùng tên helper giữa default helper và custom helper trong Laravel

Vậy có thể kết luận rằng:

File default helpers luôn được require trước các file custom helpers khác.

4. Lời kết

Qua bài này chúng ta đã có thể tự tạo cho mình một file helpers riêng trong dự án, đồng thời cũng hiểu thêm cách autoload file của Composer và tích lũy được một kiến thức thông qua testing nữa. Mình hi vọng bài viết này sẽ mang lại hữu ích cho các bạn trong quá trình làm việc cũng như học tập với Laravel framework. Một lần nữa cảm ơn các bạn đã luôn theo dõi, đồng hành cùng Flipper và chúc các bạn một ngày tốt lành. Tạm biệt và hẹn gặp lại!


Ủng hộ chúng tôi

Bình luận