March 28, 2013

Zend Framework 2 - Routing - Part 2

Tree Routing
Cải tiến hơn so với version 1, ZF2 không chỉ dừng lại ở mức routing cho từng path URI cụ thể. Đến với ZF2, chúng ta sẽ làm quen với khái niệm Tree Routing - hay có thể nói là làm sao kết nối các routing lại với nhau để tạo hiệu ứng tốt hơn cho việc làm đẹp url.

Ngoài ra, với tree routing còn giúp cải thiện tốc độ load web nhanh hơn. Nhưng đây cũng là một khái niệm khá mới nên có vẻ cũng hơi khó làm quen với nó. Mình cũng chỉ mới tập tành làm quen với dạng routing này.

1 - Cơ chế hoạt động

Một router bất kỳ có thể chứ nhiều (vô hạn) những router con của nó. Tuy nhiên, router con chỉ được kích hoạt khi router cha được khớp với URI. Một router con có thể là bất kỳ dạng routing nào đã được liệt kê ở phần 1.

Đối với ZF2, không có cơ chế mặc định cho việc routing, nên những route con chỉ có thể kích hoạt khi route cha có cài đặt khai báo "tao có con - nhớ tìm con tao".

2 - Kết nối nhiều route - tree routing

Trong khai báo route, chúng ta thêm phần chỉ định có route con như bên dưới để xác lập tree routing

array(
  'articles' => array(
    'type' => 'literal',
    'options' => array(
      'route' => '/articles', 'defaults' => array(
        'controller' => 'Application\Controller\Article',
        'action' => 'index'
      )
    ),
    'may_terminate' => true,
    'child_routes' => array(
      'details' => array(
        'type' => 'segment', 'route' => '/:id',
        'constraints' => array('articles' => '\d+'),
        'defaults' => array('action' => 'details')
      )
    )
  )
)

3 - Sử dụng WildCard để giống ZF1

Nếu bạn từng là 1 tín đồ của ZF1, thì việc route mặc định của ZF1 có phần tự động hiểu các tham số phát sinh thêm do người tự nhập vào. Chúng ta cũng có thể tái thiết lập định dạng này ở ZF2 như sau:

array(
  'type' => 'segment',
  'options' => array(
    'route' => '/application[/:controller][/:action][/:id]',
    'constraints' => array(
      'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
      'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
      'id' => '[0-9]+',
    ),
    'defaults' => array(
      '__NAMESPACE__' => 'Application\Controller',
      'controller' => 'Index',
      'action' => 'index',
    ),
  ),
  'may_terminate' => true,
  'child_routes' => array(
    'default' => array(
      'type' => 'Wildcard',
      'options' => array(
      ),
    ),
  ),
)

4 - Nhận tham số khớp route

Đối với ZF1, việc nhận tham số request rất đơn giản bằng phương thức sau ở tầng controller:
$this->_request->getParam('key', 'default-value'); hoặc
$this->_request->getParams();

Nhưng đối với ZF2, thì chúng ta nhận tham số khớp route bằng phương thức sau ở tầng controller:
$this->getEvent()->getRouteMatch()->getParam('key', 'default-value'); hoặc
$this->getEvent()->getRouteMatch()->getParams();

Bài viết được tham khảo tại http://stuff.dasprids.de/slides/zendcon2012/introducing-the-new-zend-framework-2-router/presentation.html
Zend Framework 2 - Startup
Zend Framework 2 - Access Db via PDO
Zend Framework 2 - Routing - Part 1
Các bài viết khác về Zend Framework 2 - tmquang6805.blogspot.com

6 comments:

  1. Anh cho em hỏi, làm sao mình chạy cùng 1 lúc nhiều modules được vậy anh
    vd: http://localhost/zend2tut/public/album/

    thì mình chỉ chạy dc module album

    ReplyDelete
    Replies
    1. Hi em,

      Tại 1 thời điểm nó chị chạy được 1 action DUY NHẤT, và action đó thuộc module nào thì nó sẽ thực hiện chạy thôi. Còn việc chạy đồng thời nhiều modules như em nói sẽ không thể có trong bất kỳ hệ thống nào.

      Họa chăng là trong quá trình xử lý bên module A, có gọi sang các function/method của những modules khác thì hợp lý.

      Thanks em

      Delete
  2. anh ơi cho em hỏi, em muốn config url thành dạng action?param=value&param2=value2 trong zend2 thì làm thế nào ạ! tks a

    ReplyDelete
    Replies
    1. Hi em,

      Routing là để có URL đẹp, còn nếu ko muốn nó đẹp thì ko cần routing :D
      Dạng của em thì dùng cái Literal bình thường là đc, vì tham số query (sau dấu ?) là của HTTP rồi, ko việc gì lo.
      Nếu em thắc mắc là trong action lấy data thế nào thì
      $this->params()->fromQuery('xyz');

      Vậy em nhá

      Delete
  3. Chào anh, xin cho em hỏi phải dùng kiểu route nào để ra được đường route giống như thế nào ạ: http://www.lazada.vn/product-name-43121.html

    Em làm theo kiểu Segment thì theo kiểu: abc.com/product/detail/id thì nó không được đẹp ạ.
    Cảm ơn anh!

    ReplyDelete
    Replies
    1. Chào em,
      Đã thử segment thế sao không thử tiếp Regular Expression nhỉ :)

      Delete