Zend Framework - 路由

  • 简述

    路由将请求 URI 映射到特定控制器的方法。在本章中,我们将了解如何在Zend Framework 中实现路由。
    通常,任何 URI 都有三个部分 -
    • 主机名段
    • 路径段
    • 查询段
    例如,在 URI/URL − http://www.example.com/index?q=data 中,www.example.com 是主机名段,index是路径段,q=data 是查询段。通常,路由会根据一组约束检查“页”段。如果任何约束匹配,则返回一组值。其中一个主要值是控制器。
    在某些情况下,路由还会检查主机段、查询段、请求 HTTP 方法、请求 HTTP 标头等。
  • 路由 & 路由栈

    Route 是路由中的主要对象。Zend Framework 有一个特殊的路由对象接口,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对象。此路由匹配对象将匹配请求的详细信息作为参数提供。可以使用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 应用程序具有许多路由。此路由中的每条都将按后进先出顺序进行处理,并且将匹配并返回单个路由。如果没有匹配/返回的路由,则应用程序返回“Page not found”错误。Zend Framework 提供了一个处理路由的接口,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 路径。
    让我们看看如何编写最常用的文字和段路由。路由通常在每个模块的配置文件中指定 - module.config.php

    Literal 路由

    通常,路由按后进先出顺序进行查询。文本路由用于执行 URI 路径的精确匹配。
    它的定义如下图所示 -
    
    $route = Literal::factory(array( 
       'route' => '/path', 
       'defaults' => array('controller' => 'Application\Controller\IndexController', 
          'action' => 'index',), 
    ));
    
    上述路由与请求 URL 中的 /path 匹配,并返回index作为操作IndexController作为控制器。

    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 模块中添加一个段路由。更新教程模块配置文件 – module.config.phpmyapp/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模块添加了路由。在完成教程模块方面,我们只落后了一步。我们需要为模块添加 View,我们将在后续章节中学习。