📜  Zend框架-路由(1)

📅  最后修改于: 2023-12-03 15:35:49.700000             🧑  作者: Mango

Zend框架-路由

Zend框架具有强大的路由系统,使得Web应用程序的URL可以完全自定义。这是一个非常重要的功能,因为它可以使URL对用户更加友好,并同时允许你控制哪些URL将被处理。本文将介绍Zend框架的路由系统,包括基础知识、使用示例以及一些高级用法。

基础知识

Zend框架的路由系统是建立在 Zend\Mvc\Router 包上的,由三大部分组成:路由器(Router)、路由器链(Router Chain)和具体路由(Route)。

  • 路由器(Router): 顶级路由器,负责匹配URL,并决定哪个路由将处理它。你可以使用一个路由器来处理所有的URL,或者使用多个路由器为同一应用程序处理不同的URL前缀和域名。
  • 路由器链(Router Chain): 路由器链由许多路由器组成,它们按照优先级高低的顺序处理URL。这是一个非常有用的功能,因为它可以允许你在某些情况下使用特殊的路由规则。
  • 具体路由(Route): 具体路由决定了如何匹配URL和如何生成它们。每个具体路由都至少包含一个模式和至少一个处理程序方法。
使用示例

让我们来看一个简单的案例来介绍Zend框架的路由系统。我们想要编写一个在线书店,其中有几个页面:主页,图书列表页,图书详情页和购物车页。我们想要这些页面的URL看起来像这样:

  • 主页:/
  • 图书列表页:/books
  • 图书详情页:/books/{id}
  • 购物车页:/cart

为此,我们需要配置好路由规则。这里使用了 Segment 路由:

use Zend\Mvc\Router\Http\Segment;

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Segment::class,
                'options' => [
                    'route' => '/',
                    'defaults' => [
                        'controller' => 'BookController',
                        'action' => 'index',
                    ],
                ],
            ],
            'books' => [
                'type' => Segment::class,
                'options' => [
                    'route' => '/books[/:action[/:id]]',
                    'defaults' => [
                        'controller' => 'BookController',
                        'action' => 'index',
                    ],
                ],
            ],
            'cart' => [
                'type' => Segment::class,
                'options' => [
                    'route' => '/cart',
                    'defaults' => [
                        'controller' => 'CartController',
                        'action' => 'index',
                    ],
                ],
            ],
        ],
    ],
];

以上代码使用了三个 Segment 类型的具体路由,每一个路由都包含一个模式和默认控制器/操作类。注意 books 路由包含了动态片段 [:action][:id],用于匹配图书详情页的URL。

高级用法

尽管示例中的路由已经可以较为完美地满足我们的需求,Zend框架的路由系统还可以有更多的玩法。下面将讲述其中几个,以帮助你更好地利用Zend框架提供的路由功能完成自己的需求。

正则表达式路由

假设我们希望匹配 /books/cate-123-title.html 这种URL,其中123代表了书籍的类别,title代表了书籍的标题,我们可以使用正则表达式路由来完成这个需求:

use Zend\Mvc\Router\Http\Regex;

return [
    'router' => [
        'routes' => [
            'book' => [
                'type' => Regex::class,
                'options' => [
                    'regex' => '/books/cate-(?<cat>\d+)-(?<title>[a-zA-Z0-9_-]+)\.html',
                    'defaults' => [
                        '__NAMESPACE__' => 'Application\Controller',
                        'controller' => 'Book',
                        'action' => 'view',
                    ],
                    'spec' => '/books/cate-%cat%-title',
                ],
            ],
        ],
    ],
];

以上代码使用了 Regex 类型的具体路由,其中 regex 参数为我们定义的正则表达式,而 defaults 属性则设置需要使用的controller和action。我们还定义了一个 spec 属性,它可以根据当前占位符自动生成符合规则要求的 URL。

路由嵌套

当应用程序变得越来越复杂后,我们可能需要在路由系统中嵌套路由。例如,我们可能想要将我们的API和Web路由分开,并将它们组合在一起使用。

以下是如何在路由系统中创建嵌套路由:

use Zend\Router\Http\Segment;

return [
    'router' => [
        'routes' => [
            'api' => [
                'type'    => Segment::class,
                'options' => [
                    'route' => '/api[/:controller[/:id]]',
                    'constraints' => [
                        'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id'         => '[0-9]+',
                    ],
                    'defaults' => [
                        '__NAMESPACE__' => 'Application\Controller\Api',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ],
                ],
                
                'may_terminate' => true,
                
                'child_routes' => [
                    'furniture' => [
                        'type' => Segment::class,
                        'options' => [
                            'route' => '/furniture[/:action[/:id]]',
                            'defaults' => [
                                'controller' => 'Furniture',
                                'action' => 'list',
                            ],
                        ],
                    ],

                    'tools' => [
                        'type' => Segment::class,
                        'options' => [
                            'route' => '/tools[/:action[/:id]]',
                            'defaults' => [
                                'controller' => 'Tools',
                                'action' => 'list',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
];

以上代码中,我们定义了一个名称为 api 的基础路由,它具有一个 may_terminate 属性,使其子路由能够继续匹配请求。在其下面,我们定义了两个子路由,即 furnituretools,它们分别包含了自己的模式和控制器操作。

总结

Zend框架提供了强大的路由系统,它包含了 RouterRouterChainRoute 三个部分,并提供了丰富多样的路由类型和高级用法。通过学习和掌握Zend框架的路由系统,你可以轻松地制定和实现自己需要的URL规则,从而让你的Web应用程序具有更好的用户体验和性能表现。