June 30, 2013

Zend Framewok 2: Create custom library

Thư viện PHP trong Zend 2
Đã lâu rồi mới có dịp quay lại cái blog của mình mà viết thêm bài vào đây. Thời gian gần đây mình bị cuốn vào công việc, nên cũng ít chăm lo cho cái blog thân yêu này, hôm nay quay lại, tiếp tục chủ đề Zend Frameword 2 (ZF2) mà bấy lâu vẫn theo đuổi. Bài viết này sẽ giới thiệu tới các bạn kỹ thuật tạo một library riêng dùng chung cho tất cả module trong ZF2. Điều này chắc hẳn bạn nào từng làm việc với ZF1 sẽ dễ nhận ra ngay, và với cả mình, khi tiếp xúc với ZF2 cũng đã đặt ra câu hỏi là làm sao có một thư viện riêng mà các module đều xài được.
Việc đầu tiên, chúng ta sẽ tạo thêm 1 cấu trúc thư mục trong ứng dụng của mình như hình bên dưới.
Cấu trúc thư mục dành cho thư viện mới
Cấu trúc thư mục mới thêm 
Như hình thì chúng ta sẽ tạo thêm thư mục MyNamespace/Model bên trong thư mục vendor (thư mục này có sẵn khi chúng ta dùng ZF2 Skeleton - Xem lại bài sau để biết cách cài đặt ZF2). Trong thư mục Model mới tạo này, chúng ta tạo một tập tin Test.php để tiện việc thí nghiệm cho bài này.

Tiếp theo, chúng ta bắt đầu viết code cho tập tin Test.php này như hình bên dưới.
Tập tin Test.php
Code cho tập tin Test.php mới tạo
Ở đây, chúng ta sẽ khai báo class này thuộc namespace MyNamespace\Model vì trong ZF2 đa phần sẽ load class theo chế độ namespace có từ PHP 5.3 trở lên. Và trong class này, mình chỉ đơn giản tạo một function để echo 1 chuỗi lên màn hình. Như vậy là xong phần library, bước tiếp theo, chúng ta cần thông báo cho cơ chế AutoLoad trong Zend2 có thể hiểu được Namespace mới này của mình.

Để thực hiện điều này, bạn sử dụng tập tin init_autoloader.php (ngay thư mục gốc của ứng dụng ZF2) và bổ sung tại phần if ($zf2Path) như hình bên dưới.
Cấu hình autoload namespace mới
Cấu hình autoload namespace mới
Tại đây, bạn sẽ khai báo thêm những namespace mới và đường dẫn tới namespace đó để có thể autoload trong ZF2.

Việc cuối cùng, chúng ta sẽ test thử vấn đề này trong 1 controller nào đó, và mình dùng luôn IndexController trong module Application để thực hiện điều này như hình bên dưới.
Test load namespace mới trong IndexController, module Application
Test load namespace mới trong IndexController, module Application

Và khi bạn chạy ứng dụng, kết quả sẽ tương tự như sau

Xem thêm các bài viết khác về Zend Framework 2 (ZF2) tại đây

17 comments:

  1. Hi anh,
    em có làm theo các bước của anh mà sao lúc chạy nó lại báo lỗi là ko tìm thấy class.

    Fatal error: Class 'kutara\Model\Test' not found in D:\xampp\htdocs\source_cms_saycheese\module\Admin\src\Admin\Controller\AdminController.php on line 39

    ReplyDelete
  2. Hi em,
    Em cần kiểm tra các vấn đề sau:

    1 - Em tạo project ZF2 này theo hướng dẫn của anh hay clone từ github.
    2 - Nếu em tạo project theo hướng dẫn trên blog của anh thì cách này áp dụng được, còn nếu clone từ github thì em phải chỉnh lại cấu trúc autoload class của zend_skeleton

    Thanks em

    ReplyDelete
  3. Cảm ơn thầy
    Bài hay quá :)

    ReplyDelete
  4. thầy ơi cho em hỏi chỉnh lại cấu trúc autoload_class là chỉnh như thế nào vậy thầy?

    ReplyDelete
    Replies
    1. Chào bạn,

      Anh có đi dạy ZF2 tại trung tâm tin học, nhưng trên blog thì anh không phải là thầy :D
      Anh chưa hiểu ý câu hỏi này lắm, em nêu rõ hơn tí ha

      Delete
    2. em bị lỗi giống bạn Lê Minh ở trên những không biết phải sửa thế nào hết.

      Delete
    3. Check kỹ lại phần thiết lập AutoLoader bên trên, xem đã cấu hình đúng các thứ sau:
      1 - Namespace
      2 - Path
      3 - File name

      Delete
  5. cho mình hỏi làm sao dùng được thư viện zf2 trong thư viện tự tạo vậy

    ReplyDelete
    Replies
    1. Đã xài ZF2 thì dù đứng chỗ nào: Controller, Model, hay 1 class bất kỳ tự tạo ra thì đều dùng đc các class ZF2 hết. Vì nó được khởi tạo từ đầu mà

      Delete
  6. chào anh Quang!
    Em đã cấu hình file init_autoloader.php giống như anh hướng dẫn và bị lỗi giống bạn Lê Minh và có cùng câu hỏi với bạn Ngọc Toàn.
    Thêm nữa, em thắc mắc là của anh cũng vốn clone từ github skeleton và sửa lại ở init_autoloader.php và em cũng làm vậy, nhưng anh nói "cần làm theo blog" của anh là như thế nào?

    ReplyDelete
    Replies
    1. Chào em,

      1 - Trả lời thắc mắc về câu nói "cần làm theo blog" của anh là thế này.
      Anh cũng dùng Zend Skeleton nhưng đã có tùy biến bằng việc dùng trực tiếp library và cấu hình lại ZF2_PATH (em xem lại bài 1 của loạt hướng dẫn ZF2 này sẽ thấy)
      Trong khi nếu em dùng composer clone về thì không dùng ZF2_PATH và cách autoload class được khai báo hơi khác 1 xí. Bài viết của anh dựa trên project anh làm nên nếu mọi người khởi tạo ZF2 như trên trang chủ hướng dẫn thì có lẽ khác một tí. Khi đó thì phải tự sửa lại tí tí.
      2 - Đa số mọi người đều dính phải 1 vấn đề tương tự nhau, cách anh làm thật ra là làm 1 module nhỏ của ZF2 nhưng bỏ qua 1 số thứ như config, class Module,... (vì chủ yếu mình muốn xây 1 thư viện dạng bổ trợ cho code nên không cần config). Nếu thấy gặp trở ngại, tốt nhất em nên viết thành 1 module riêng có đầy đủ các thành phần.
      Em xem thêm trên đây để biết cách làm (hy vọng anh có thời gian viết bài để giúp mọi người sau này)
      http://zf2.readthedocs.org/en/latest/user-guide/modules.html

      Delete
  7. em muốn tạo và sử dụng controller trong custom library thì phải làm sao anh ơi

    ReplyDelete
    Replies
    1. Thì lúc đó nó trở thánh 2 module bình thường. Bài blog trên chủ yếu hướng dẫn tạo 1 cái không có controller, còn có controller thì nó chính là module thông thường đó em :)

      Delete
    2. vậy giờ em muốn load thêm js hoặc css trong library của mình thì phải làm sao ạ

      Delete
    3. JS, CSS nó chỉ là static thôi em, nó ko liên quan lắm đến ZF2 hay PHP nói chung. Trong tầng layout, em có thể gắn JS, CSS trực tiếp. Hoặc nếu muốn linh động, có thể dùng các view helper của ZF2

      Delete
    4. tức là trong library của em cần load nhiều file khác nhau. không chỉ là js và css. những file đó đều được load cùng với package composer trong vendor thì làm sao có thể load nó ra được ạ.

      Delete
    5. Nhiều file hay 1 file gì cũng như vậy thôi. Vấn đề là em cần phải hiểu giữa file static (JS, CSS, Images,...) là 1 nơi riêng, PHP là 1 nơi riêng. Không nên trộn 2 cái làm 1. Còn composer vendor là nơi của PHP. Trong bài này anh không đề cập các tạo package trên composer.

      Một package composer khi load lên nó chỉ autoload cho PHP, còn JS hay những file static nói chung, nó thường đc load ở khu vực View/Layout

      Delete