路由组件¶
概览¶
The Phalcon\Mvc\Router组件允许你定义映射到接收并处理请求的控制器或处理器的路由。路由器有两种模式:MVC 模式和仅匹配模式。第一个模式适合与 MVC 应用一起使用。
<?php
use Phalcon\Mvc\Router;
$router = new Router();
$router->add(
'/admin/invoices/list',
[
'controller' => 'invoices',
'action' => 'list',
]
);
$router->handle(
$_SERVER["REQUEST_URI"]
);
常量¶
有两个常量可用于Phalcon\Mvc\Router组件,用于定义路由在处理堆栈中的位置。
POSITION_FIRST
POSITION_LAST
方法¶
Phalcon\Mvc\Router 构造函数
public function add(
string $pattern,
mixed $paths = null,
mixed $httpMethods = null,
int $position = Router::POSITION_LAST
): RouteInterface
use Phalcon\Mvc\Router;
$router->add("/about", "About::index");
$router->add(
"/about",
"About::index",
["GET", "POST"]
);
$router->add(
"/about",
"About::index",
["GET", "POST"],
Router::POSITION_FIRST
);
public function addConnect(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
CONNECT
public function addDelete(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
DELETE
public function addGet(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
GET
public function addHead(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
HEAD
public function addOptions(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
OPTIONS
public function addPatch(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
PATCH
public function addPost(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
POST
public function addPurge(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
PURGE
(Squid 和 Varnish 支持) public function addPut(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
PUT
public function addTrace(
string $pattern,
mixed $paths = null,
int $position = Router::POSITION_LAST
): RouteInterface
TRACE
public function attach(
RouteInterface $route,
int $position = Router::POSITION_LAST
): RouterInterface
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Router\Route;
class CustomRoute extends Route {
// ...
}
$router = new Router();
$router->attach(
new CustomRoute(
"/about",
"About::index",
["GET", "HEAD"]
),
Router::POSITION_FIRST
);
定义路由¶
Phalcon\Mvc\Router提供了高级路由功能。在 MVC 模式下,你可以定义路由并将它们映射到所需的控制器/动作。一个路由定义如下所示:
<?php
use Phalcon\Mvc\Router;
$router = new Router();
$router->add(
'/admin/invoices/list',
[
'controller' => 'invoices',
'action' => 'list',
]
);
$router->add(
'/admin/customers/list',
[
'controller' => 'customers',
'action' => 'list',
]
);
$router->handle(
$_SERVER["REQUEST_URI"]
);
第一个参数是add()
方法是你想要匹配的模式,并且可选地,第二个参数是一组路径。在上面的例子中,对于 URI/admin/invoices/list
,InvoicesController
将被加载,并且listAction
将会被调用。需要记住的是,路由器不会执行控制器和动作,它只收集这些信息,然后将其转发给Phalcon\Mvc\Dispatcher并由其来执行。
一个应用可以有多个路径,逐个定义路由可能是一项繁琐的任务。Phalcon\Mvc\Router提供了一种更简单的方式来注册路由。
<?php
use Phalcon\Mvc\Router;
$router = new Router();
$router->add(
'/admin/:controller/:action/:params',
[
'controller' => 1,
'action' => 2,
'params' => 3,
]
);
在上面的例子中,我们使用通配符使一个路由适用于多个 URI。例如,访问以下 URL (/admin/customers/view/12345/1
) 将产生:
控制器 | 动作 | 参数 | 参数 |
---|---|---|---|
customers | view | 12345 | 1 |
The add()
方法接收一个模式,该模式可以选择性地包含预定义的占位符和正则表达式修饰符。所有的路由模式必须以正斜杠字符开头 (/
)。所使用的正则表达式语法与PCRE 正则表达式.
注意
不需要添加正则表达式的定界符。所有路由模式都是不区分大小写的。
第二个参数定义如何将匹配的部分绑定到控制器/动作/参数。匹配的部分是由括号(圆括号)分隔的占位符或子模式。在上面给出的例子中,第一个匹配的子模式 (:controller
) 是路由的控制器部分,第二个是动作 (:action
), 然后是传递的任何参数 (:params
)。
这些占位符使路由表达式更具可读性和更容易理解。支持以下占位符:
占位符 | 正则表达式 | 匹配内容 |
---|---|---|
/:module | /([a-zA-Z0-9\_\-]+) | 仅包含字母数字字符的有效模块名 |
/:controller | /([a-zA-Z0-9\_\-]+) | 仅包含字母数字字符的有效控制器名 |
/:action | /([a-zA-Z0-9_-]+) | 仅包含字母数字字符的有效动作名 |
/:params | (/.*)* | 由斜杠分隔的可选词列表。只能在路由末尾使用此占位符 |
/:namespace | /([a-zA-Z0-9\_\-]+) | 单层命名空间名 |
/:int | /([0-9]+) | 整数参数 |
控制器名称会进行驼峰化处理,这意味着字符 (-
) 和 (_
) 会被移除,并且下一个字符会被转为大写。例如,some_controller
被转换为SomeController
.
由于你可以使用add()
方法添加任意数量的路由,因此添加路由的顺序表示它们的相关性。后添加的路由比之前添加的路由具有更高相关性。在内部,所有定义的路由将以相反的顺序遍历,直到Phalcon\Mvc\Router找到与给定 URI 匹配的那条并进行处理,忽略其余路由。
命名参数¶
下面的示例演示了如何为路由参数定义名称:
<?php
$router->add(
// 1 / 2 / 3 / 4
'/admin/([0-9]{4})/([0-9]{2})/([0-9]{2})/:params',
[
'controller' => 'invoices',
'action' => 'view',
'year' => 1, // ([0-9]{4})
'month' => 2, // ([0-9]{2})
'day' => 3, // ([0-9]{2})
'params' => 4, // :params
]
);
在上述示例中,路由没有定义controller
或action
。这些将被替换为固定值 (invoices
和view
)。用户永远不会知道请求所派发到的底层控制器。在控制器中,这些命名参数可以通过以下方式访问:
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
/**
* @property Dispatcher $dispatcher
*/
class InvoicesController extends Controller
{
public function viewAction()
{
// year
$year = $this->dispatcher->getParam('year');
// month
$month = $this->dispatcher->getParam('month');
// day
$day = $this->dispatcher->getParam('day');
// ...
}
}
请注意,参数的值是从调度器中获取的。还有另一种方法可以在模式内部创建命名参数:
<?php
$router->add(
'/admin/{year}/{month}/{day}/{invoiceNo:[0-9]+}',
[
'controller' => 'invoices',
'action' => 'view',
]
);
您可以像之前一样访问它们的值:
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
/**
* @property Dispatcher $dispatcher
*/
class InvoicesController extends Controller
{
public function viewAction()
{
// year
$year = $this->dispatcher->getParam('year');
// month
$month = $this->dispatcher->getParam('month');
// day
$day = $this->dispatcher->getParam('day');
// invoiceNo
$invoiceNo = $this->dispatcher->getParam('invoiceNo');
// ...
}
}
简洁语法¶
Phalcon\Mvc\Router还提供了一种替代性的更简洁的语法。以下示例产生相同的结果:
<?php
$router->add(
'/admin/{year:[0-9]{4}}/{month:[0-9]{2}}/{day:[0-9]{2}}/:params',
'Invoices::view'
);
$router->add(
'/admin/([0-9]{4})/([0-9]{2})/([0-9]{2})/:params',
[
'controller' => 'invoices',
'action' => 'view',
'year' => 1, // ([0-9]{4})
'month' => 2, // ([0-9]{2})
'day' => 3, // ([0-9]{2})
'params' => 4, // :params
]
);
数组与简洁语法¶
可以混合使用数组和简洁语法来定义路由,在这种情况下,请注意命名参数会根据其在路径中的定义位置自动添加到路由路径中:
<?php
$router->add(
'/admin/{year:[0-9]{4}}/([0-9]{2})/([0-9]{2})/:params',
[
'controller' => 'invoices',
'action' => 'view',
'month' => 2, // ([0-9]{2}) // 2
'day' => 3, // ([0-9]{2}) // 3
'params' => 4, // :params // 4
]
);
year
. 模块¶
您可以在路径中定义包含模块的路由。这尤其适用于多模块应用程序。您可以定义一个包括模块通配符的默认路由。
<?php
use Phalcon\Mvc\Router;
$router = new Router(false);
$router->add(
'/:module/:controller/:action/:params',
[
'module' => 1,
'controller' => 2,
'action' => 3,
'params' => 4,
]
);
使用上述路由时,您需要始终将模块名称作为URL的一部分。例如,对于以下URL:/admin/invoices/view/12345
,将会被处理为:
模块 | 控制器 | 动作 | 参数 |
---|---|---|---|
admin | invoices | view | 12345 |
或者您可以将特定路由绑定到特定模块:
<?php
$router->add(
'/login',
[
'module' => 'session',
'controller' => 'login',
'action' => 'index',
]
);
$router->add(
'/invoices/:action',
[
'module' => 'admin',
'controller' => 'invoices',
'action' => 1,
]
);
或者将其绑定到特定命名空间:
<?php
$router->add(
'/:namespace/login',
[
'namespace' => 1,
'controller' => 'login',
'action' => 'index',
]
);
需要单独传递完整的命名空间:
<?php
$router->add(
'/login',
[
'namespace' => 'Admin\Controllers',
'controller' => 'login',
'action' => 'index',
]
);
HTTP 方法¶
当您仅使用add()
添加路由时,该路由将对任何HTTP方法启用。有时我们可以限制路由到特定方法。这在创建RESTful应用程序时特别有用。
<?php
// GET
$router->addGet(
'/invoices/edit/{id}',
'Invoices::edit'
);
// POST
$router->addPost(
'/invoices/save',
'Invoices::save'
);
// POST/PUT
$router->add(
'/invoices/update',
'Invoices::update'
)->via(
[
'POST',
'PUT',
]
);
转换器¶
转换器是一段代码,允许您在参数发送给分发器
<?php
$route = $router->add(
'/products/{slug:[a-z\-]+}',
[
'controller' => 'products',
'action' => 'show',
]
);
$route->convert(
'slug',
function ($slug) {
return str_replace('-', '', $slug);
}
);
/products/new-ipod-nano-generation
。该convert
方法将把参数转换为newipodnanogeneration
. 转换器的另一个用例是当将模型绑定到路由时。这允许直接将模型传递到定义的动作中。
<?php
$route = $router->add(
'/products/{id}',
[
'controller' => 'products',
'action' => 'show',
]
);
$route->convert(
'id',
function ($id) {
return Product::findFirstById($id);
}
);
组¶
如果一组路由有共同的路径,为了便于维护,可以将它们分组。为此,我们使用Phalcon\Mvc\Router\Group组件
<?php
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Router\Group;
$router = new Router();
$invoices = new RouterGroup(
[
'module' => 'admin',
'controller' => 'invoices',
]
);
$invoices->setPrefix('/invoices');
$invoices->add(
'/list',
[
'action' => 'list',
]
);
$invoices->add(
'/edit/{id}',
[
'action' => 'edit',
]
);
$invoices->add(
'/view',
[
'controller' => 'common',
'action' => 'index',
]
);
$router->mount($invoices);
/invoices
。然后我们向该组添加更多路由,其中一些不带参数,一些带参数。最后一条路由允许我们使用不同于默认控制器的控制器(common
)。最后,我们将该组添加到路由器。 我们可以扩展Phalcon\Mvc\Router\Group组件,并在每个组中注册我们的路由。这使我们能够更好地组织应用程序的路由。
<?php
use Phalcon\Mvc\Router\Group;
class InvoicesRoutes extends Group
{
public function initialize()
{
$this->setPaths(
[
'module' => 'invoices',
'namespace' => 'Invoices\Controllers',
]
);
$this->setPrefix('/invoices');
$this->add(
'/list',
[
'action' => 'list',
]
);
$this->add(
'/edit/{id}',
[
'action' => 'edit',
]
);
$this->add(
'/view',
[
'controller' => 'common',
'action' => 'index',
]
);
}
}
现在我们可以在路由器中挂载自定义组类:
匹配路由¶
必须传入有效的URI给路由器,以便它可以处理并找到匹配的路由。默认情况下,路由URI来自重写引擎模块创建的$_GET['_url']
变量。几个与Phalcon配合非常出色的重写规则如下:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
在此配置中,任何对不存在文件或文件夹的请求都将发送到index.php
。以下示例展示了如何作为独立组件使用它:
<?php
use Phalcon\Mvc\Router;
$router = new Router();
// ...
$router->handle(
$_GET["_url"]
);
echo $router->getControllerName();
echo $router->getActionName();
$route = $router->getMatchedRoute();
_url
全局超变量中获取$_GET
元素,之后,我们可以获取控制器名称或者动作名称,甚至获取匹配的路由。 命名路由¶
添加到路由器的每条路由都会作为Phalcon\Mvc\Router\Route对象存储在内部。该类封装了每条路由的所有细节。例如,我们可以为路径赋予一个名称以在我们的应用中唯一标识它。如果您想从此生成URL的话,这将很有用。
<?php
$route = $router->add(
'/admin/{year:[0-9]{4}}/{month:[0-9]{2}}/{day:[0-9]{2}}/{id:[0-9]{4}',
'Invoices::view'
);
$route->setName('invoices-view');
然后,例如使用组件Phalcon\Url我们可以根据定义的名称构建路由:
<?php
// /admin/2019/12/25/1234
echo $url->get(
[
'for' => 'invoices-view',
'year' => '2019',
'month' => '12',
'day' => '25',
'id' => '1234',
]
);
默认行为¶
Phalcon\Mvc\Router提供了默认的行为,提供了简单的路由功能,总是期望一个URI并匹配以下模式:
例如,对于如下的URLhttps://dev.phalcon.od/download/linux/ubuntu.html
,此路由器将解释为:
控制器 | 动作 | 参数 |
---|---|---|
DownloadController | linuxAction | ubuntu.html |
如果您不希望路由器遵循此行为,则必须通过构造函数传入false
来创建路由器。
默认路由¶
当您的应用程序在没有指定任何路由的情况下被访问时,/
路由用来确定必须使用哪些路径来显示应用程序的初始页面
未找到(404)¶
如果在路由器中指定的路由没有一个匹配,您可以通过使用notFound
方法设置容器。
注意
定义一个404控制器/动作。$router = Phalcon\Mvc\Router(false);
默认值¶
您可以为module
, controller
和`action`定义默认值。当路由路径缺少这些元素之一时,路由器将自动使用设置的默认值。
<?php
$router->setDefaultModule('admin');
$router->setDefaultNamespace('Admin\Controllers');
$router->setDefaultController('index');
$router->setDefaultAction('index');
$router->setDefaults(
[
'controller' => 'index',
'action' => 'index',
]
);
结尾斜杠¶
有时,可能通过额外的/结尾斜杠访问路由。附加的斜杠将在调度器中产生“找不到”的状态,这不是我们想要的。您可以将路由器设置为自动删除处理路由末尾的斜杠。
或者,您可以修改特定路由以选择性地接受结尾斜杠:
<?php
$route = $router->add(
'/admin/:controller/status[/]{0,1}',
[
'controller' => 2,
'action' => 'status',
]
);
[/]{0,1}
允许可选的结尾斜杠 回调¶
有时,只有满足特定条件时才应匹配路由。您可以使用beforeMatch
回调向路由添加任意条件。如果此函数返回false
,该路由将被视为未匹配:
<?php
$route = $router->add(
'/login',
[
'module' => 'admin',
'controller' => 'session',
]
);
$route->beforeMatch(
function ($uri, $route) {
if (true === isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
$_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'
) {
return false;
}
return true;
}
);
false
如果不是的话 您可以创建一个过滤器类,以便将相同的功能注入到不同的路由中。
<?php
class AjaxFilter
{
public function check()
{
return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
}
要进行此设置,我们只需将类添加到beforeMatch
调用中。
<?php
$route = $router->add(
'/login',
[
'module' => 'admin',
'controller' => 'session',
]
);
$route->beforeMatch(
[
new AjaxFilter(),
'check'
]
);
最后,您可以使用beforeMatch
方法(或事件)来检查这是否是一次 AJAX 请求。
<?php
use Phalcon\Di\DiInterface;
use Phalcon\Http\Request;
use Phalcon\Mvc\Router\Route;
$route = $router->add(
'/login',
[
'module' => 'admin',
'controller' => 'session',
]
);
$route->beforeMatch(
function ($uri, $route) {
/**
* @var string $uri
* @var Route $route
* @var DiInterface $this
* @var Request $request
*/
$request = $this->getShared('request');
return $request->isAjax();
}
);
主机名¶
The Phalcon\Mvc\Router组件还允许主机名约束。这意味着特定的路由或一组路由仅在请求来源于特定主机名时才匹配。
<?php
$route = $router->add(
'/admin/invoices/:action/:params',
[
'module' => 'admin',
'controller' => 'invoices',
'action' => 1,
'params' => 2,
]
);
$route->setHostName('dev.phalcon.ld');
主机名也可以作为正则表达式传入:
<?php
$route = $router->add(
'/admin/invoices/:action/:params',
[
'module' => 'admin',
'controller' => 'invoices',
'action' => 1,
'params' => 2,
]
);
$route->setHostName('([a-z]+).phalcon.ld');
在使用路由组时,您可以为该组中的每个路由设置主机名约束。
<?php
use Phalcon\Mvc\Router\Group;
$invoices = new Group(
[
'module' => 'admin',
'controller' => 'invoices',
]
);
$invoices->setHostName('dev.phalcon.ld');
$invoices->setPrefix('/invoices');
$invoices->add(
'/',
[
'action' => 'index',
]
);
$invoices->add(
'/list',
[
'action' => 'list',
]
);
$invoices->add(
'/view/{id}',
[
'action' => 'view',
]
);
$router->mount($invoices);
测试¶
该组件没有任何依赖项。因此您可以创建单元测试来测试您的路由。
<?php
use Phalcon\Mvc\Router;
$testRoutes = [
'/',
'/index',
'/index/index',
'/index/test',
'/products',
'/products/index/',
'/products/show/101',
];
$router = new Router();
foreach ($testRoutes as $testRoute) {
// Handle the route
$router->handle($testRoute);
echo 'Testing ', $testRoute, '<br>';
// Check if some route was matched
if ($router->wasMatched()) {
echo 'Controller: ', $router->getControllerName(), '<br>';
echo 'Action: ', $router->getActionName(), '<br>';
} else {
echo "The route wasn't matched by any route<br>";
}
echo '<br>';
}
事件¶
与其他 Phalcon 组件类似,Phalcon\Mvc\Router在存在事件管理器时也会触发事件。可用的事件包括:
事件 | 当 |
---|---|
afterCheckRoutes | 检查完所有路由之后触发 |
beforeCheckRoute | 检查某个路由之前触发 |
beforeCheckRoutes | 检查所有已加载路由之前触发 |
beforeMount | 挂载新路由之前触发 |
matchedRoute | 当路由匹配时触发 |
notMatchedRoute | 当路由不匹配时触发 |
注解¶
该组件提供了一个与注解服务集成的变体。使用这种策略,您可以直接在控制器中编写路由,而不必将其添加到路由器组件中。
<?php
use Phalcon\Mvc\Router\Annotations;
$container['router'] = function () {
$router = new Annotations(false);
$router->addResource('Invoices', '/admin/invoices');
return $router;
};
false
以移除默认行为。之后,我们指示组件从InvoicesController
如果 URI 匹配/admin/invoices
. The InvoicesController
将需要具有以下实现:
<?php
/**
* @RoutePrefix('/admin/invoices')
*/
class InvoicesController
{
/**
* @Get(
* '/'
* )
*/
public function indexAction()
{
}
/**
* @Get(
* '/edit/{id:[0-9]+}',
* name='invoice-edit'
* )
*/
public function editAction($id)
{
}
/**
* @Route(
* '/save',
* methods={'POST', 'PUT'},
* name='invoice-save'
* )
*/
public function saveAction()
{
}
/**
* @Route(
* '/delete/{id:[0-9]+}',
* methods='DELETE',
* converters={
* id='MyConverters::checkId'
* }
* )
*/
public function deleteAction($id)
{
}
}
只有标记了有效注解的方法才会被用作路由。可用的注解包括:
注解 | 描述 | 使用 |
---|---|---|
Delete | 限制 HTTP 方法为DELETE | @Delete('/invoices/delete/{id}') |
Get | 限制 HTTP 方法为GET | @Get('/invoices/search') |
Options | 限制 HTTP 方法为OPTIONS | @Option('/invoices/info') |
Post | 限制 HTTP 方法为POST | @Post('/invoices/save') |
Put | 限制 HTTP 方法为PUT | @Put('/invoices/save') |
Route | 标记一个方法为路由。必须放置在方法的文档块中 | @Route('/invoices/show') |
RoutePrefix | 前缀,将被添加到每个路由 URI 的前面。必须放置在类的文档块中 | @RoutePrefix('/invoices') |
对于添加路由的注解,支持以下参数:
名称 | 描述 | 使用 |
---|---|---|
converters | 参数的转换器哈希表 | @Route('/posts/{id}/{slug}', converter={id='MyConverter::getId'}) |
methods | 允许的一个或多个 HTTP 方法 | @Route('/api/products', methods={'GET', 'POST'}) |
name | 路由的名称 | @Route('/api/products', name='get-products') |
paths | 路由的路径数组 | @Route('/invoices/view/{id}/{slug}', paths={module='backend'}) |
如果您在应用中使用了模块,最好使用addModuleResource()
方法:
<?php
use Phalcon\Mvc\Router\Annotations;
$container['router'] = function () {
$router = new Annotations(false);
$router->addModuleResource(
'admin',
'Invoices',
'/admin/invoices'
);
return $router;
};
Admin\Controllers\InvoicesController
如果 URI 以/admin/invoices
. 路由器还理解前缀,以确保路由能够尽可能快地解析。例如对于以下路由:
只有/clients
前缀可以在所有控制器中使用,从而加快查找速度。
依赖注入¶
您可以在容器设置期间注册路由器组件,使其在控制器或任何其他继承自Phalcon\Di\Injectable组件定义的。
您可以在您的引导文件中(例如index.php
或app/config/services.php
如果您使用了Phalcon 开发者工具)。
<?php
$container->set(
'router',
function () {
require __DIR__ . '/app/config/routes.php';
return $router;
}
);
您需要创建app/config/routes.php
并添加路由器初始化代码:
<?php
use Phalcon\Mvc\Router;
$router = new Router();
$router->add(
'/login',
[
'controller' => 'login',
'action' => 'index',
]
);
$router->add(
'/invoices/:action',
[
'controller' => 'invoices',
'action' => 1,
]
);
return $router;
自定义¶
您可以通过实现提供的接口来创建自己的组件:-Phalcon\Mvc\Router\GroupInterface - Phalcon\Mvc\Router\RouteInterface - Phalcon\Mvc\RouterInterface
示例¶
以下是自定义路由的示例:
<?php
// '/system/admin/a/edit/7001'
$router->add(
'/system/:controller/a/:action/:params',
[
'controller' => 1,
'action' => 2,
'params' => 3,
]
);
// '/en/news'
$router->add(
'/([a-z]{2})/:controller',
[
'controller' => 2,
'action' => 'index',
'language' => 1,
]
);
// '/en/news'
$router->add(
'/{language:[a-z]{2}}/:controller',
[
'controller' => 2,
'action' => 'index',
]
);
// '/admin/posts/edit/100'
$router->add(
'/admin/:controller/:action/:int',
[
'controller' => 1,
'action' => 2,
'id' => 3,
]
);
// '/posts/2015/02/some-cool-content'
$router->add(
'/posts/([0-9]{4})/([0-9]{2})/([a-z\-]+)',
[
'controller' => 'posts',
'action' => 'show',
'year' => 1,
'month' => 2,
'title' => 3,
]
);
// '/manual/en/translate.adapter.html'
$router->add(
'/manual/([a-z]{2})/([a-z\.]+)\.html',
[
'controller' => 'manual',
'action' => 'show',
'language' => 1,
'file' => 2,
]
);
// /feed/fr/hot-news.atom
$router->add(
'/feed/{lang:[a-z]+}/{blog:[a-z\-]+}\.{type:[a-z\-]+}',
'Feed::get'
);
// /api/v1/users/peter.json
$router->add(
'/api/(v1|v2)/{method:[a-z]+}/{param:[a-z]+}\.(json|xml)',
[
'controller' => 'api',
'version' => 1,
'format' => 4,
]
);
注意
在允许控制器和命名空间中使用正则表达式时,请小心处理字符。这些字符将成为类名,进而会与文件系统交互。因此,攻击者可能会访问未经授权的文件。一个安全的正则表达式是:/([a-zA-Z0-9\_\-]+)