Với Zend Framework 3 có một số cơ chế nạp các thư viện, các thành phần độc lập, module vào ứng dụng. Mỗi cơ chế có ảnh hưởng đến cách tổ chức thư mục trong ứng dụng.

Tự động nạp theo chuẩn PSR-4 của Zend Framework

Các thư viện, thành phần độc lập cài đặt ở thư mục vendor sẽ được ZF tự động nạp khi cần dùng đến bằng cách sử dụng khai báo namespace và tên lớp thích hợp. Để xem PSR-4 hoạt động như thế nào hãy xem lại Tiêu chuẩn PSR-4

Một trong yếu tố cốt yếu của Zend Framework là bạn phát triển ứng dụng với các module, mỗi module thực hiện một chức năng nào đó. Các module bạn xây dựng sẽ được nạp khi ứng dụng hoạt động theo nguyên lý của PSR-4

Trong ứng dụng Zend Skeleton, một module mặc định được tạo sẵn cho bạn đó là Application nằm ở thư mục module/Application, trong đó định nghĩa các lớp, các thành phần của module

Giờ bạn xem ZF nạp module đó như thế nào: Mở file composer.json bạn thấy đoạn cấu hình

"autoload": {
    "psr-4": {
        "Application\\": "module/Application/src/"
    }
},

Đoạn code đó cho biết Composer đã từng phát sinh code để tự động nạp module Application vào ứng dụng. Do khai báo psr-4 là "Application\\": "module/Application/src/" có nghĩa namespace đầu tiên Application trở vào thư mục module/Application/src/, và các lớp sẽ viết theo thư mục con trong src dần dẫn đến tên lớp.

Ví dụ có lớp: Application\Controller\IndexController, có nghĩa trong src có thư mục Controller, và có file IndexController.php, bên trong định nghĩa lớp IndexController: bạn mở thư mục ứng dụng ra kiểm tra

Áp dụng PSR-4

Giờ áp dụng, nếu bạn muốn xây dựng một module mới, giả sử module có tên MyFirstModule và tự động nạp các thành phần của module đó theo psr-4:

(Ví dụ này sử dụng Zend Skeleton Application cài đặt theo cách của bài 1)

Bước 1) Tạo một thư mục có tên MyFirstModule trong thư mụcmodule

Bước 2) Tạo một thư mục tên src trong MyFirstModule, và các thư mục con khác đến cấp thư mục con tùy thích trong src. Ví dụ dự định đặt một vài lớp trong thư mục Lib1 thì tạo thư mục Lib1 (giờ đường dẫn đầy đủ đến thư mục Lib1 là module/MyFirstModule/src/Lib1

Tạo lớp PHP có tên Vidupsr4, tạo ra file có tên Vidupsr4.php trong Lib1, và mở ra cập nhật nội dung như sau

<?php
//Khai báo đúng namespace: tên-module/đường-dẫn-đến-class
namespace MyFirstModule\Lib1;

//Tên class trùng tên file.php
class Vidupsr4 {

    public function __construct()
    {
        echo __CLASS__.' đã được tạo';
    }
}

?>

Với cách tổ chức thư mục và xây dựng code như trên, đã hương tới việc gọi ra được lớp Vidupsr4 bằng cách viết: MyFirstModule\Lib1\Vidupsr4

Bước 3 cập nhật autoload

Để khai báo tự động nạp theo đúng PSR-4, mở file composer.json, và thêm vào khu vực psr-4 một dòng:
"MyFirstModule\\": "module/MyFirstModule/src/"

"autoload": {
    "psr-4": {
        "Application\\": "module/Application/src/",
         "MyFirstModule\\": "module/MyFirstModule/src/"
    }
},

Cuối cùng cập nhật vào autoload.php trong vendor bằng cách gõ lệnh composer tại thư mục dự án

composer dump-autoload

Ứng dụng

Từ giờ bạn có thể sử dụng 'MyFirstModule' với lớp MyFirstModule\Lib1\Vidupsr4 bất kỳ đâu.

Ví dụ: Mở file IndexController.php của module Application, cập nhật phương thức indexAction() (file này Controller gọi khi gõ đường dẫn gốc vào trình duyệt, tìm hiểu sau)thành:

public function indexAction()
{
new \MyFirstModule\Lib1\Vidupsr4();
return new ViewModel();
}

Kiểm tra thử kết quả trên trình duyệt, có dòng: MyFirstModule\Lib1\Vidupsr4 đã được tạo, như vậy thư viện, module đã nạp chính xác

Nạp module với ModuleManager

Các nạp các module ZF với chuẩn PSR-4 ở trên được khuyến khích ở các phiên bản sau này của Zend Framework, trong ZF có thành phần quản lý các module gọi là Module Manager (tìm hiểu sau), sẽ phối hợp để cấu hình chính xác module. Ngoài cách trên Module Manager, kết hợp với Zend Loader nạp module tự động theo cách tìm tên module trong các thư mục khái báo trước. Cách này phổ biến ở các phiên bản ZF2, nhưng vẫn có thể dùng lại cùng với ZF3

Khai báo đường dẫn tới các module

Bạn mở file: config/application.config.php, sẽ thấy có vị trí khai báo mảng chứa các đường dẫn này

'module_paths' => [
'./module',
'./vendor',
],

Bạn thấy ứng dụng khung khai báo sẵn hai đường dẫn chứa các thư viện, module là ./module./vendor, tại đây nếu muốn bổ xung thêm thư mục chứa module thì thêm vào.

PHP7 cho phép sử dụng thêm ký hiệu ngoặc vuông [] biểu diễn mảng, thay thế được cho array()

Tạo một module theo kiểu để ModuleManager/Loader tự động tìm tải

Ở đây là các bước thực hành cơ bản, bạn chưa cần hiểu rõ nhiều (vì còn nhiều thứ trình bày sau), mục đích chỉ là tìm hiểu cơ chế nạp module

Tạo một module có tên ModuleA, chứa trong thư mục ./module:

Cấu trúc file/thư mục moduleA cuối cùng sẽ như sau

ModuleA
|
|   autoload_classmap.php
|   Module.php
|
+---config
+---src
|    ClassA.php
|
\---view

Bước 1) Tạo một folder có tên ModuleA, trong thư mục ./module

Bước 2) Tạo 3 folder con thuộc thư mục ModuleAconfig, src, view (không bắt buộc nhưng đây là cách tổ chức chuẩn, ý nghĩa giải thích ở các phần tiếp theo)

Bước 3) Trong thư mục ModuleA tạo file Module.php là file để ModuleManager đọc và nạp với nội dung như sau:

≶?php
namespace ModuleA;

class Module
{
    public function getAutoloaderConfig()
    {
        return [
            'Zend\Loader\ClassMapAutoloader' => [
                __DIR__ . '/autoload_classmap.php']
        ];
    }
    public function getConfig()
    {
        return [];
    }
}

Bước 4) Tạo ra file có tên autoload_classmap.php trong ModuleA, là nơi khai báo các đường dẫn đến các lớp của ModuleA, nội dung nó như sau:

<?php
return [
    //... dẫn tới các lớp
];

Bước 5 tạo một lớp

Tạo ra một lớp tên ClassA trong thư mục src bằng cách tạo trong thư mục đó file ClassA.php và cập nhật nội dung như sau:

<?php
namespace ModuleA;

class ClassA
{
    public function __construct()
    {
        echo __CLASS__. ' đã khởi tạo thành công';
    }
}

Quay lại file: autoload_classmap.php, cập nhật thành

<?php
return [
    ModuleA\ClassA::class => __DIR__.'/src/ClassA.php',
];

Đến đây, bằng cách này bạn đã tạo ra một module có tên ModuleA, giờ chỉ việc khai báo sử dụng

Ứng dụng

Mở file modules.config.php trong thư mục config gốc của dự án. Thêm vào cuối mảng tên module 'ModuleA'

Từ đây bạn đã có thể sử dụng các lớp của ModuleA

Ví dụ: Mở file IndexController.php của module Application, cập nhật phương thức indexAction() thành:

public function indexAction()
{
    new \ModuleA\ClassA();
    return new ViewModel();
}

Kiểm tra thử kết quả trên trình duyệt, có dòng: ModuleA\ClassA đã khởi tạo thành công, như vậy thư viện, module đã nạp chính xác


Đăng ký nhận bài viết mới