我們從樣本非標準路線Zend的2路由器 - 可選參數未知
array(
'type' => 'Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
'priority' => -1000,
),
它可以理解如
/application
/application/some
/application/index/about
網址,但它不明白的URL像
/application/index/about/param1/val1/param2/val2/...
在Zend1被*,我們可以將其添加到像這樣的路線
'route' => '/:controller/:action/*',
*之後的所有參數都試圖用斜槓分割。問題:zend 2有沒有辦法創建具有未知參數名稱的路由?一種解決方案是創建自己的路由類型,但可能存在內置解決方案?
UPD:
我已經寫我自己Route類,它分析*上ROURE端,以及非必需的參數將在ZF1風格解析。
<?php
namespace Engine\Mvc\Router\Http;
use Zend\I18n\Translator\TranslatorInterface as Translator;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\RequestInterface as Request;
class Segment extends \Zend\Mvc\Router\Http\Segment
{
protected $unknownParameterParse = false;
protected $route = null;
public function __construct($route, array $constraints = [], array $defaults = [])
{
if ($route{mb_strlen($route)-1} == '*'){
$route = mb_substr($route, 0, mb_strlen($route)-1);
$this->unknownParameterParse = true;
}
$this->route = $route;
parent::__construct($route, $constraints, $defaults);
}
public function assemble(array $params = [], array $options = []) {
$path = parent::assemble($params, $options);
if ($this->unknownParameterParse){
$unknowns = [];
foreach($params as $key=>$value){
if (strpos($this->route, ':'.$key)===false){
$unknowns[] = $this->encode($key) . '/'. $this->encode($value);
}
}
if ($unknowns){
$path = rtrim($path, '/').'/'.implode('/', $unknowns);
}
}
return $path;
}
public function match(Request $request, $pathOffset = null, array $options = [])
{
if (!method_exists($request, 'getUri')) {
return;
}
$uri = $request->getUri();
$path = $uri->getPath();
$regex = $this->regex;
if ($this->translationKeys) {
if (!isset($options['translator']) || !$options['translator'] instanceof Translator) {
throw new Exception\RuntimeException('No translator provided');
}
$translator = $options['translator'];
$textDomain = (isset($options['text_domain']) ? $options['text_domain'] : 'default');
$locale = (isset($options['locale']) ? $options['locale'] : null);
foreach ($this->translationKeys as $key) {
$regex = str_replace('#' . $key . '#', $translator->translate($key, $textDomain, $locale), $regex);
}
}
if ($pathOffset !== null) {
$result = preg_match('(\G' . $regex . ')', $path, $matches, null, $pathOffset);
} else {
$result = preg_match('(^' . $regex . ($this->unknownParameterParse ? '' : '$') . ')', $path, $matches);
}
if (!$result) {
return;
}
$matchedLength = strlen($matches[0]);
$params = [];
foreach ($this->paramMap as $index => $name) {
if (isset($matches[$index]) && $matches[$index] !== '') {
$params[$this->decode($name)] = $this->decode($matches[$index]);
}
}
/*ENGINE get not defined params*/
if ($this->unknownParameterParse){
$otherParams = explode("/", trim(substr($path, strlen($matches[0])), "/"));
foreach($otherParams as $i=>$param){
if ($i%2 == 0){
$pairKey = $param;
}else{
$params[$pairKey] = $param;
}
}
}
/* endof get not defined params */
return new \Zend\Mvc\Router\Http\RouteMatch(array_merge($this->defaults, $params), $matchedLength);
}
}
怎麼說chaoss88它完美地做通配符路線:我們可以用分段式,並與通配符類型的子路徑父路徑。但上面的一些更親近的人。這樣的路線:
'route' => '/core/:controller[/:action]*'
工作良好。但是,如果您使用ZF2路由器作爲請求過濾的授權,通配符路由器存在安全問題 - 這就是爲什麼它已被棄用。但我認爲路由器是用於URL解析/組裝,而不是過濾:對於過濾/驗證ZF2有更好的解決方案。
我其實不知道它是否可以工作,但你可以嘗試[正則表達式路由](http://framework.zend.com/manual/current/en/modules/zend.mvc.routing.html#zend -mvc-router-http-regex) – jbrtrnd
Regexp沒有動態參數化。但是我已經解決了路由器的問題,擴展了\ Zend \ Mvc \ Router \ Http \ Segment。 –