2012-02-24 9 views
5

Tôi đã đọc tất cả các bài đăng về định tuyến và Tài liệu Zend nhưng tôi vẫn không thể giải quyết vấn đề này.Các sự cố định tuyến Zend

Tôi có ứng dụng đa ngôn ngữ với hai mô-đun: mặc định và quản trị viên. Việc lựa chọn ngôn ngữ đang làm việc tốt (trong một điều khiển routeShutdown Plugin), nhưng tôi có một số vấn đề cấu hình router:

Tôi muốn có những URL làm việc:

/ 
/controller 
/controller/action 
/action     (default controller) 
/controller/param  (default action) 
/admin 
/admin/admin-controller 
/admin/admin-controller/action 

và sử dụng bộ chọn ngôn ngữ nó sẽ là :

/en 
/en/controller 
/en/controller/action 
/en/action     (default controller) 
/en/controller/param  (default action) 
/en/admin/admin-controller 
/en/admin/admin-controller/action 

tôi thêm này để tập tin của tôi bootstap (index.php):

$frontController = Zend_Controller_Front::getInstance(); 
$router = $frontController->getRouter(); 
$router->removeDefaultRoutes(); 
$router->addRoute('langmodcontrolleraction', 

new Zend_Controller_Router_Route('/:lang/:module/:controller/:action', 
    array('lang' => ':lang')) 
); 

$router->addRoute('langmodcontroller', 
new Zend_Controller_Router_Route('/:lang/:module/:controller', 
    array('lang' => ':lang', 
     'action' => 'index')) 
); 

$router->addRoute('langmod', 
new Zend_Controller_Router_Route('/:lang/:module', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index')) 
); 

$router->addRoute('lang', 
new Zend_Controller_Router_Route('/:lang', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index', 
     'module' => 'default')) 
); 

$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers', 
'admin'=>BASE_PATH.'app/modules/admin/controllers'));  

Để kiểm tra cách router được phân tích cú pháp URL, tôi đã thêm một var_dump để các plugin routeShutdown:

Bước tới /en, tôi nhận được:

array 
'lang' => string 'en' (length=2) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 
'module' => string 'default' (length=7) 

đó là OK. Nhưng khi tôi nhập để /en/controller1 tôi nhận được:

array 
'lang' => string 'en' (length=2) 
'module' => string 'controller1' (length=8) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 

Nó được thiết lập module để "controller1". Làm thế nào tôi có thể nói cho router để thiết lập giá trị mặc định cho module? Và cho một URL như/en/controller/param? (đặt mô-đun và hành động thành mặc định)

Trả lời

6

Tôi e rằng bạn sẽ cần phải suy nghĩ lại sơ đồ URL của mình một chút hoặc thay đổi cách thiết lập tuyến đường của bạn, khi bạn đã đạt đến hai giới hạn của cách ZF định tuyến hoạt động.

Đầu tiên là bộ định tuyến không có kiến ​​thức về mô-đun, bộ điều khiển hoặc hành động hợp lệ là gì; tất cả những gì nó làm là khớp các chuỗi trong URL với các biến trong tuyến đường. Nó thực hiện điều này bằng cách kiểm tra từng tuyến liên tiếp, theo thứ tự ngược lại, cho đến khi nó tìm thấy kết quả khớp. Khi bạn nhấn /en/controller, trước tiên, bạn sẽ kiểm tra tuyến đường /:lang của mình, tuyến đường này sẽ không khớp. Sau đó, nó sẽ kiểm tra /:lang/:module, sẽ khớp với nhau, bởi vì /:lang/:module sẽ khớp với/bất kỳ thứ gì/thứ gì trừ khi bạn nói khác đi.

Với ý nghĩ đó, bạn sẽ không thể có cả hai:

/en/controller 
/en/action 

trừ khi bạn đặt một số hạn chế, như một URL như /en/foo sẽ luôn luôn được kết hợp bởi bất cứ của hai bạn xác định cuối cùng.

Nếu bạn có một số lượng khá nhỏ của các hành động/điều khiển mà không thường xuyên thay đổi, cách đơn giản nhất xung quanh này là để hardcode trong một số giá trị có thể cho lần thứ 2 của hai tuyến đường, ví dụ:

$router->addRoute('langmod', new Zend_Controller_Router_Route(
    '/:lang/:module', 
    array(
     'lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index' 
    ), 
    array(
     'module' => '(foo|bar|something)' 
    ) 
)); 

thay thế foo, thanh vv bằng tên mô-đun hợp lệ. Bây giờ khi bạn nhấn /en/controller1, nó sẽ không khớp với tuyến đường này vì controller1 không khớp với mẫu regexp được xác định cho biến: module. Sau đó, bạn sẽ cần một tuyến đường riêng rẽ /:lang/:controller (hoặc có thể là /:lang/:controller/:action) để phù hợp.

Bạn đã hỏi cách đặt giá trị mặc định cho một số biến.Bạn đang thực sự đã làm điều này với các hành động trong một vài tuyến đường của bạn, nhưng đối với điều khiển/mô-đun sẽ không hoàn toàn làm việc theo cách bạn đang hy vọng. Nếu chúng tôi sử dụng tuyến đường điều khiển langmodcontroller của bạn và thay đổi nó thành:

$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
    '/:lang/:module/:controller', 
    array(
     'lang' => ':lang', 
     'controller' => 'index' 
     'action' => 'index' 
    ) 
)); 

bây giờ là giá trị mặc định cho biến điều khiển. Nếu chúng ta giả vờ một giây rằng đây là tuyến đường duy nhất, một yêu cầu cho /en/blog bây giờ sẽ được kết hợp bởi điều này và đặt các tham số yêu cầu cho lang = vi, module = blog, controller = index, action = index. /en/blog/index/foo cũng sẽ khớp với tuyến đường này và sẽ cung cấp cho bạn module = blog, controller = index, action = foo. Nhưng lưu ý rằng mặc dù controller = index bạn vẫn cần nó trong URL. Vì vậy, giới hạn số hai là bạn luôn cần biến trong URL (ngay cả khi nó được đặt thành mặc định của bạn) miễn là bạn có thứ gì đó sau đó không phải là mặc định.

Với những hạn chế này trong tâm trí tôi muốn đề nghị bạn đi với một cái gì đó như thế này (được xác định theo thứ tự này):

/:lang/:controller/:action/ (with 'index' defaults for controller and action) 
/:lang/:action (with 'action' restricted to some predefined values) 
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default) 

Điều này sẽ cung cấp cho bạn các URL như thế này:

/en 
/en/controller 
/en/controller/action 
/en/action 
/en/controller/param 
/en/admin/controller 
/en/admin/controller/action 

đó là khá nhiều những gì bạn đang sau.

Định tuyến trong ZF rất mạnh mẽ, bạn chỉ cần biết những điều kỳ quặc của nó.

+0

đây là một câu trả lời rất hữu ích, giải thích của bạn là hoàn hảo, bây giờ tôi hiểu cách thức hoạt động của định tuyến :) cảm ơn bạn! Khi tôi đạt đến 15 đại diện. Tôi sẽ bỏ phiếu cho câu trả lời của bạn. Đây là trang web của tôi, nơi tôi sẽ thực hiện điều này: [tryandsay.com] (http://www.tryandsay.com) – Gustavo