Zend Framework - 路由



路由將請求 URI對映到特定控制器的 方法。在本章中,我們將瞭解如何在 Zend Framework 中實現路由。

一般來說,任何 URI 都有三個部分:

  • 主機名段;
  • 路徑段;以及
  • 查詢段。

例如,在 URI/URL http://www.example.com/index?q=data 中,www.example.com 是主機名段,index 是路徑段,q=data 是查詢段。通常,路由會根據一組約束檢查路徑段。如果任何約束匹配,則它會返回一組值。其中一個主要值是控制器。

在某些情況下,路由還會檢查主機段、查詢段、請求 HTTP 方法、請求 HTTP 頭等。

路由 & 路由棧

路由是路由中的主要物件。Zend Framework 為路由物件提供了一個特殊的介面,即RouteInterface。所有路由物件都需要實現 RouteInterface。RouteInterface 的完整列表如下:

namespace Zend\Mvc\Router;  
use Zend\Stdlib\RequestInterface as Request;  
interface RouteInterface { 
   public static function factory(array $options = []); 
   public function match(Request $request); 
   public function assemble(array $params = [], array $options = []); 
}

主要方法是match。此 match 方法會根據其中定義的約束檢查給定的請求。如果找到任何匹配項,它將返回RouteMatch 物件。此 RouteMatch 物件提供匹配請求的詳細資訊作為引數。這些引數可以使用getParams 方法從RouteObject 中提取。

RouteObject 的完整列表如下:

namespace Zend\Mvc\Router;  
class RouteMatch { 
   public function __construct(array $params); 
   public function setMatchedRouteName($name); 
   public function getMatchedRouteName(); 
   public function setParam($name, $value); 
   public function getParams(); 
   public function getParam($name, $default = null); 
} 

通常,一個典型的 MVC 應用程式有很多路由。每個路由都將按 LIFO 順序處理,並且只有一個路由將被匹配並返回。如果沒有匹配/返回任何路由,則應用程式將返回“頁面未找到”錯誤。Zend Framework 提供了一個處理路由的介面,即RouteStackInterface。此 RouteStackInterface 具有新增/刪除路由的選項。

RouteStackInterface 的完整列表如下:

namespace Zend\Mvc\Router;  
interface RouteStackInterface extends RouteInterface { 
   public function addRoute($name, $route, $priority = null); 
   public function addRoutes(array $routes); 
   public function removeRoute($name); 
   public function setRoutes(array $routes); 
}

Zend framework 提供了RouteStack 介面的兩種實現,它們分別是:

  • SimpleRouteStack
  • TreeRouteStack

路由型別

Zend framework 為 "Zend\Mvc\Router\Http" 名稱空間下的所有情況提供了許多現成的路由物件。為給定情況選擇和使用合適的路由物件就足夠了。

可用的路由如下:

  • Hostname - 用於匹配 URI 的主機部分。

  • Literal - 用於匹配精確的 URI。

  • Method - 用於匹配傳入請求的 HTTP 方法。

  • Part - 使用自定義邏輯匹配 URI 路徑段的一部分。

  • Regex - 使用正則表示式模式匹配 URI 路徑段。

  • Schema - 用於匹配 URI 模式,例如 http、https 等。

  • Segment - 用於透過將 URI 路徑拆分為多個段來匹配 URI 路徑。

讓我們看看如何編寫最常用的 Literal 和 Segment 路由。路由通常在每個模組的配置檔案中指定 - module.config.php

Literal 路由

通常,路由按 LIFO 順序查詢。Literal 路由用於對 URI 路徑進行精確匹配。

其定義如下:

$route = Literal::factory(array( 
   'route' => '/path', 
   'defaults' => array('controller' => 'Application\Controller\IndexController', 
      'action' => 'index',), 
));

上面的路由匹配請求 url 中的/path 並返回index 作為actionIndexController 作為控制器。

Segment 路由

當你的 url 應該包含可變引數時,使用分段路由。

其描述如下:

$route = Segment::factory(array( 
   'route' => '/:controller[/:action]', 
   'constraints' => array( 
      'controller' => '[a-zA-Z][a-zA-Z0-9_-]+', 
      'action' => '[a-zA-Z][a-zA-Z0-9_-]+', 
   ), 
   'defaults' => array( 
      'controller' => 'Application\Controller\IndexController', 
      'action' => 'index',), 
));

這裡,段由冒號表示,後跟字母數字字元。如果你保留一個可選段,則將其用括號括起來。每個段可能與其關聯的約束相關聯。每個約束都是一個正則表示式。

在 Tutorial 模組中配置路由

讓我們在 Tutorial 模組中新增一個 segment 路由。更新 Tutorial 模組配置檔案 - module.config.php (位於myapp/module/Tutorial/config)。

<?php  
namespace Tutorial;  
use Zend\ServiceManager\Factory\InvokableFactory; 
use Zend\Router\Http\Segment;  
return [ 
   'controllers' => [ 
      'factories' => [ 
         Controller\TutorialController::class => InvokableFactory::class, 
      ], 
   ], 
   'router' => [ 
      'routes' => [ 
         'tutorial' => [ 
            'type'    => Segment::class, 
               'options' => [ 
                  'route' => '/tutorial[/:action[/:id]]', 
                  'constraints' => [ 
                     'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 
                     'id'     => '[0-9]+', 
                  ], 
                  'defaults' => [
                     'controller' => Controller\TutorialController::class, 
                     'action'     => 'index', 
                  ], 
               ], 
            ], 
      ], 
   ], 
   'view_manager' => [ 
      'template_path_stack' => ['tutorial' => __DIR__ . '/../view',], 
   ], 
];

我們已經成功為Tutorial 模組添加了路由。完成 Tutorial 模組只差一步。我們需要為模組新增檢視,我們將在下一章學習。

廣告
© . All rights reserved.